diff --git a/.gitignore b/.gitignore index 44d0c2c..16f9437 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,6 @@ .DS_Store /build /captures +app/build/* +app/.settings/* weatherAPI.postman_collection.json diff --git a/.idea/misc.xml b/.idea/misc.xml index 47b8ea6..5d19981 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,30 +1,31 @@ - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 6564d52..94a25f7 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 395ce85..b007282 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -4,7 +4,7 @@ android { compileSdkVersion 29 buildToolsVersion '29.0.3' defaultConfig { - applicationId "com.example.miguelf03kai.wetherapp" + applicationId "com.miguelf03kai.weatherapp" minSdkVersion 23 targetSdkVersion 23 versionCode 1 @@ -24,11 +24,9 @@ dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.4.0' - //dependence for recycleview library compile 'com.android.support:recyclerview-v7:23.0.+' compile 'com.android.support:cardview-v7:23.0.+' - // below line is used for volley library compile 'com.android.volley:volley:1.1.1' // dependence for picasso diff --git a/app/src/androidTest/java/com/example/miguelf03kai/wetherapp/ApplicationTest.java b/app/src/androidTest/java/com/miguelf03kai/wetherapp/ApplicationTest.java similarity index 100% rename from app/src/androidTest/java/com/example/miguelf03kai/wetherapp/ApplicationTest.java rename to app/src/androidTest/java/com/miguelf03kai/wetherapp/ApplicationTest.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8c0d0e1..90005f9 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,6 +1,6 @@ + package="com.miguelf03kai.weatherapp"> @@ -13,7 +13,7 @@ android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> - + diff --git a/app/src/main/ic_close-web.png b/app/src/main/ic_close-web.png index 2ebcca2..b66f3a5 100644 Binary files a/app/src/main/ic_close-web.png and b/app/src/main/ic_close-web.png differ diff --git a/app/src/main/ic_close-web2.png b/app/src/main/ic_close-web2.png new file mode 100644 index 0000000..6f6e631 Binary files /dev/null and b/app/src/main/ic_close-web2.png differ diff --git a/app/src/main/ic_launcher-web.png b/app/src/main/ic_launcher-web.png index 1f4fb97..9611390 100644 Binary files a/app/src/main/ic_launcher-web.png and b/app/src/main/ic_launcher-web.png differ diff --git a/app/src/main/java/com/example/miguelf03kai/wetherapp/Cards.java b/app/src/main/java/com/example/miguelf03kai/wetherapp/Cards.java deleted file mode 100644 index ce73ca0..0000000 --- a/app/src/main/java/com/example/miguelf03kai/wetherapp/Cards.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.example.miguelf03kai.wetherapp; - -import android.content.Context; -import android.support.v7.widget.RecyclerView; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.TextView; - -import com.squareup.picasso.Picasso; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; - -public class Cards extends RecyclerView.Adapter { - - private static Context context; - private ArrayList Atime,Atemp,Aspeed,Aimg; - - public Cards(ArrayList Atime,ArrayList Atemp,ArrayList Aspeed,ArrayList Aimg) { - this.Atime = Atime; - this.Atemp = Atemp; - this.Aspeed = Aspeed; - this.Aimg = Aimg; - } - - @Override - public Cards.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list,parent,false); - ViewHolder vh = new ViewHolder(v); - return vh; - } - - @Override - public void onBindViewHolder(Cards.ViewHolder holder, int position) { - - holder.temp.setText(Atemp.get(position)+"°c"); - holder.speed.setText(Aspeed.get(position)+ " km/h"); - - SimpleDateFormat input = new SimpleDateFormat("yyyy-MM-dd hh:mm"); - SimpleDateFormat output = new SimpleDateFormat("hh:mm aa"); - - try{ - Date t = input.parse(Atime.get(position)); - holder.time.setText(output.format(t)); - }catch(ParseException e){ - e.printStackTrace(); - } - - Picasso.with(Cards.context).load(Aimg.get(position)).into(holder.img); - } - - @Override - public int getItemCount() { - return Atime.size(); - } - - public class ViewHolder extends RecyclerView.ViewHolder{ - - public TextView temp,time,speed; - public ImageView img; - - public ViewHolder(View itemView){ - super(itemView); - temp = (TextView) itemView.findViewById(R.id.card); - time = (TextView) itemView.findViewById(R.id.textView6); - speed = (TextView) itemView.findViewById(R.id.textView7); - img = (ImageView) itemView.findViewById(R.id.imageView2); - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/example/miguelf03kai/wetherapp/MainActivity.java b/app/src/main/java/com/example/miguelf03kai/wetherapp/MainActivity.java deleted file mode 100644 index b43ef87..0000000 --- a/app/src/main/java/com/example/miguelf03kai/wetherapp/MainActivity.java +++ /dev/null @@ -1,279 +0,0 @@ -package com.example.miguelf03kai.wetherapp; - -import android.content.Context; -import android.content.pm.PackageManager; -import android.location.Address; -import android.location.Geocoder; -import android.location.Location; -import android.location.LocationManager; -import android.support.v4.app.ActivityCompat; -import android.support.v7.app.AppCompatActivity; -import android.os.Bundle; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; -import android.util.Log; -import android.view.View; -import android.view.WindowManager; -import android.widget.ImageView; -import android.widget.ProgressBar; -import android.widget.RelativeLayout; -import android.widget.SearchView; -import android.widget.TextView; -import android.widget.Toast; - -import com.android.volley.Request; -import com.android.volley.RequestQueue; -import com.android.volley.Response; -import com.android.volley.VolleyError; -import com.android.volley.toolbox.JsonObjectRequest; -import com.android.volley.toolbox.Volley; -import com.squareup.picasso.Picasso; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.IOException; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Locale; - - -public class MainActivity extends AppCompatActivity { - - private ProgressBar loader; - private ImageView ivCondition,background; - private TextView degree,conditionTv,cityTv,tvRegion,tvCountry,tvLocalTime; - private SearchView search; - private RelativeLayout content; - - ArrayList time,temp,speed,image; - - RecyclerView recyclerView; - RecyclerView.Adapter adapter; - RecyclerView.LayoutManager layoutManager; - - private LocationManager locationManager; - private int PERMISSION_CODE = 1; - String cityName; - - String nightBG = "https://p0.pxfuel.com/preview/788/12/912/astrophotography-stars-clouds-sky.jpg"; - String dayBG = "https://p1.pxfuel.com/preview/158/967/699/sky-clouds-texture-background.jpg"; - - api API; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - //to make the application full screen - getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); - - setContentView(R.layout.activity_main); - - loader = (ProgressBar)findViewById(R.id.pbLoader); - content = (RelativeLayout)findViewById(R.id.content); - search = (SearchView)findViewById(R.id.searchField); - degree = (TextView)findViewById(R.id.tvDeqree); - conditionTv = (TextView)findViewById(R.id.tvCondition); - cityTv = (TextView)findViewById(R.id.tvCityName); - tvRegion = (TextView)findViewById(R.id.tvRegion_Value); - tvCountry = (TextView)findViewById(R.id.tvCountry_Value); - ivCondition = (ImageView)findViewById(R.id.ivWatherIcon); - background = (ImageView)findViewById(R.id.background); - tvLocalTime = (TextView)findViewById(R.id.tvLocalTime); - - API = new api(); - - recyclerView = (RecyclerView)findViewById(R.id.rvCards); - recyclerView.setHasFixedSize(true); - layoutManager = new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false); - recyclerView.setLayoutManager(layoutManager); - - Picasso.with(MainActivity.this).load(dayBG).into(background); - - //used for controlling location updates - locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); - - //check permission for location api - if(ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this,android.Manifest.permission.ACCESS_COARSE_LOCATION)!=PackageManager.PERMISSION_GRANTED){ - //ask for permission - ActivityCompat.requestPermissions(MainActivity.this,new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION},PERMISSION_CODE); - } - - //this takes last location provided by network, if not have no information about location, will be returned null - Location location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); - - if(location != null) - cityName = getCityName(location.getLongitude(), location.getLatitude()); - else - cityName = "sydney"; - - getWeather(API.checkWaether(cityName)); - - search.setOnQueryTextListener(new SearchView.OnQueryTextListener() { - @Override - public boolean onQueryTextSubmit(String query) { - content.setVisibility(View.GONE); - loader.setVisibility(View.VISIBLE); - - getWeather(API.checkWaether(query)); - return false; - } - - @Override - public boolean onQueryTextChange(String newText) { - return false; - } - }); - } - - //handle user choice - @Override - public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { - if(requestCode==PERMISSION_CODE){ - if(grantResults.length>0 && grantResults[0]==PackageManager.PERMISSION_GRANTED){ - Toast.makeText(getApplicationContext(),"Permission Granted", Toast.LENGTH_LONG).show(); - } - else{ - Toast.makeText(getApplicationContext(), "Please provide the permission", Toast.LENGTH_LONG).show(); - finish(); - } - } - } - - private String getCityName(double longitude, double latitude){ - String cityName = "Not found"; - Geocoder gcd = new Geocoder(getBaseContext(), Locale.getDefault()); - - try { - - List
addresses = gcd.getFromLocation(latitude,longitude,10); - /*for (type variableName : arrayName) { - // code block to be executed - }*/ - for(Address adr: addresses){ - if(adr!=null){ - String city = adr.getLocality(); - if(city!=null && !city.equals("")){ - cityName = city; - }else{ - Log.d("TAG","City not Found"); - } - - } - } - /** - * The Geocoder class requires a backend service that is not included in the core android framework. - * The Geocoder query methods will return an empty list if there no backend service in the platform. - * Use the isPresent() method to determine whether a Geocoder implementation exists. - * */ - /*if(gcd.isPresent()) - cityName = "Service exist"; - else - cityName = "Service not exist"; - */ - }catch (IOException e){ - e.printStackTrace(); - } - - return cityName; - } - - //return local time formatted - public String dateTimeFormatting(String time){ - String pattern = "yyyy-MM-dd HH:mm"; - Date date = null; - SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern); - try { - date = simpleDateFormat.parse(time); - } catch (ParseException e) { - e.printStackTrace(); - } - SimpleDateFormat formatting = new SimpleDateFormat("E dd MMMM hh:mm a"); - String formatedDate = formatting.format(date); - return formatedDate; - } - - - public void getWeather(String url){ - RequestQueue queue = Volley.newRequestQueue(MainActivity.this); - - JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener() { - @Override - public void onResponse(JSONObject response) { - //hide progress bar. - loader.setVisibility(View.GONE); - // show app content - content.setVisibility(View.VISIBLE); - try { - //get json objects from server response - JSONObject location = response.getJSONObject("location"); - JSONObject current = response.getJSONObject("current"); - JSONObject forecastday = response.getJSONObject("forecast").getJSONArray("forecastday").getJSONObject(0); - JSONArray hour = forecastday.getJSONArray("hour"); - - // setting data to all views. - cityTv.setText(location.getString("name")); - degree.setText(current.getString("temp_c")+"°c"); - conditionTv.setText(current.getJSONObject("condition").getString("text")); - tvRegion.setText(location.getString("region")); - tvCountry.setText(location.getString("country")); - tvLocalTime.setText(dateTimeFormatting(location.getString("localtime"))); - - //load the image from url using picasso library. - if(current.getInt("is_day") == 0) - Picasso.with(MainActivity.this).load(nightBG).into(background); - else - Picasso.with(MainActivity.this).load(dayBG).into(background); - - Picasso.with(MainActivity.this).load("https:"+current.getJSONObject("condition").getString("icon")).into(ivCondition); - - - time = new ArrayList<>(); - temp = new ArrayList<>(); - speed = new ArrayList<>(); - image = new ArrayList<>(); - - for(int i = 0;i < hour.length();i++){ - JSONObject hourObj = hour.getJSONObject(i); - String timeObj = hourObj.getString("time"); - String temperature = hourObj.getString("temp_c"); - String imageObj = "https:"+hourObj.getJSONObject("condition").getString("icon"); - String wind = hourObj.getString("wind_kph"); - - - time.add(timeObj); - temp.add(temperature); - speed.add(wind); - image.add(imageObj); - } - - adapter = new Cards(time,temp,speed,image); - recyclerView.setAdapter(adapter); - - } catch (JSONException e) { - - e.printStackTrace(); - } - } - }, new Response.ErrorListener() { - - @Override - public void onErrorResponse(VolleyError error) { - - loader.setVisibility(View.GONE); - content.setVisibility(View.VISIBLE); - - Toast.makeText(MainActivity.this, "No matching location found.", Toast.LENGTH_LONG).show(); - } - }); - - queue.add(jsonObjectRequest); - - } - -} diff --git a/app/src/main/java/com/example/miguelf03kai/wetherapp/api.java b/app/src/main/java/com/example/miguelf03kai/wetherapp/api.java deleted file mode 100644 index 54aa615..0000000 --- a/app/src/main/java/com/example/miguelf03kai/wetherapp/api.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.example.miguelf03kai.wetherapp; - -public class api { - - public String checkWaether(String city){ - - String url = "http://api.weatherapi.com/v1/forecast.json?key=e04229e6c12c4b9dadf112621213110&q="+city+"&days=1&aqi=no&alerts=no"; - - return url; - } -} \ No newline at end of file diff --git a/app/src/main/java/com/miguelf03kai/weatherapp/MainActivity.java b/app/src/main/java/com/miguelf03kai/weatherapp/MainActivity.java new file mode 100644 index 0000000..0432ee0 --- /dev/null +++ b/app/src/main/java/com/miguelf03kai/weatherapp/MainActivity.java @@ -0,0 +1,246 @@ +package com.miguelf03kai.weatherapp; + +import android.content.Context; +import android.content.pm.PackageManager; +import android.location.Geocoder; +import android.location.Location; +import android.location.LocationManager; +import android.support.v4.app.ActivityCompat; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.util.Log; +import android.view.View; +import android.view.WindowManager; +import android.widget.ImageView; +import android.widget.ProgressBar; +import android.widget.RelativeLayout; +import android.widget.SearchView; +import android.widget.TextView; +import android.widget.Toast; + +import com.android.volley.Request; +import com.android.volley.RequestQueue; +import com.android.volley.Response; +import com.android.volley.VolleyError; +import com.android.volley.toolbox.JsonObjectRequest; +import com.android.volley.toolbox.Volley; +import com.miguelf03kai.weatherapp.cards.CardView; +import com.miguelf03kai.weatherapp.utils.Formatter; +import com.miguelf03kai.weatherapp.utils.WeatherAPI; +import com.miguelf03kai.weatherapp.utils.Localization; +import com.squareup.picasso.Picasso; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.Locale; + + +public class MainActivity extends AppCompatActivity { + + private ProgressBar loaderProgressBar; + private ImageView conditionIconImageView, backgroundImageView; + private TextView degreeTextView, conditionTextView, cityTextView, regionTextView, countryTextView, localTimeTextView; + private SearchView searchView; + private RelativeLayout contentRelativeLayout; + + ArrayList time, temp, speed, image; + + RecyclerView recyclerView; + RecyclerView.Adapter adapterRecycleView; + RecyclerView.LayoutManager layoutManagerRecycleView; + + private LocationManager locationManager; + private int PERMISSION_CODE = 1; + String cityName; + + String nightBG = "https://p0.pxfuel.com/preview/788/12/912/astrophotography-stars-clouds-sky.jpg"; + String dayBG = "https://p1.pxfuel.com/preview/158/967/699/sky-clouds-texture-background.jpg"; + + WeatherAPI weatherAPI; + Localization localization; + Formatter formatter; + + Location location; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Turn the application full screen + getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, + WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); + + setContentView(R.layout.activity_main); + + loaderProgressBar = (ProgressBar)findViewById(R.id.loaderProgressBar); + contentRelativeLayout = (RelativeLayout)findViewById(R.id.contentRelativeLayout); + searchView = (SearchView)findViewById(R.id.searchView); + degreeTextView = (TextView)findViewById(R.id.deqreeTextView); + conditionTextView = (TextView)findViewById(R.id.conditionTextView); + cityTextView = (TextView)findViewById(R.id.cityNameTextView); + regionTextView = (TextView)findViewById(R.id.regionTextView); + countryTextView = (TextView)findViewById(R.id.countryTextView); + conditionIconImageView = (ImageView)findViewById(R.id.conditionIconImageView); + backgroundImageView = (ImageView)findViewById(R.id.backgroundImageView); + localTimeTextView = (TextView)findViewById(R.id.localTimeTextView); + + recyclerView = (RecyclerView)findViewById(R.id.cardsRecycleView); + recyclerView.setHasFixedSize(true); + layoutManagerRecycleView = new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,false); + recyclerView.setLayoutManager(layoutManagerRecycleView); + + Picasso.with(MainActivity.this).load(dayBG).into(backgroundImageView); + + weatherAPI = new WeatherAPI(); + localization = new Localization(); + + // Used for controlling location updates + locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); + + // Check permission for location api + if(ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != + PackageManager.PERMISSION_GRANTED && + ActivityCompat.checkSelfPermission(this,android.Manifest.permission. + ACCESS_COARSE_LOCATION) != + PackageManager.PERMISSION_GRANTED){ + // Ask for permission + ActivityCompat.requestPermissions(MainActivity.this, + new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION, + android.Manifest.permission.ACCESS_COARSE_LOCATION}, + PERMISSION_CODE); + } + + try { + /* This takes last location provided by network, if not have no information about location, + will be returned null */ + location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); + } + catch (Exception ex){ + Log.i("PERMISSION ERROR", ex.getMessage()); + } + + if(location != null) + cityName = localization.getCityName(location.getLongitude(), location.getLatitude(), + new Geocoder(getBaseContext(), + Locale.getDefault())); + else + cityName = "sydney"; + + getAndShowWeatherData(weatherAPI.requestUrl(cityName)); + + searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { + @Override + public boolean onQueryTextSubmit(String query) { + contentRelativeLayout.setVisibility(View.GONE); + loaderProgressBar.setVisibility(View.VISIBLE); + + getAndShowWeatherData(weatherAPI.requestUrl(query)); + return false; + } + + @Override + public boolean onQueryTextChange(String newText) { + return false; + } + }); + } + + // Handle user choice + @Override + public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { + if(requestCode==PERMISSION_CODE){ + if(grantResults.length>0 && grantResults[0]==PackageManager.PERMISSION_GRANTED){ + Toast.makeText(getApplicationContext(),"Permission Granted", Toast.LENGTH_LONG).show(); + } + else{ + Toast.makeText(getApplicationContext(), "Please provide the permission, in order to " + + "find your region automatically.", Toast.LENGTH_LONG).show(); + } + } + } + + void getAndShowWeatherData(String url){ + RequestQueue queue = Volley.newRequestQueue(MainActivity.this); + formatter = new Formatter(); + + JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null, + new Response.Listener() { + @Override + public void onResponse(JSONObject response) { + // Hide progress bar. + loaderProgressBar.setVisibility(View.GONE); + // Show app content + contentRelativeLayout.setVisibility(View.VISIBLE); + try { + // Get JSON objects from server response + JSONObject location = response.getJSONObject("location"); + JSONObject current = response.getJSONObject("current"); + JSONObject forecastday = response.getJSONObject("forecast").getJSONArray("forecastday") + .getJSONObject(0); + JSONArray hour = forecastday.getJSONArray("hour"); + + // Setting data to all views. + cityTextView.setText(location.getString("name")); + degreeTextView.setText(current.getString("temp_c")+"°c"); + conditionTextView.setText(current.getJSONObject("condition").getString("text")); + regionTextView.setText(location.getString("region")); + countryTextView.setText(location.getString("country")); + localTimeTextView.setText(formatter.dateTimeFormatting(location.getString("localtime"))); + + // Load the image from url using picasso library. + if(current.getInt("is_day") == 0) + Picasso.with(MainActivity.this).load(nightBG).into(backgroundImageView); + else + Picasso.with(MainActivity.this).load(dayBG).into(backgroundImageView); + + Picasso.with(MainActivity.this).load("https:"+current.getJSONObject("condition") + .getString("icon")) + .into(conditionIconImageView); + + time = new ArrayList<>(); + temp = new ArrayList<>(); + speed = new ArrayList<>(); + image = new ArrayList<>(); + + for(int i = 0;i < hour.length();i++){ + JSONObject hourObj = hour.getJSONObject(i); + String timeObj = hourObj.getString("time"); + String temperature = hourObj.getString("temp_c"); + String imageObj = "https:"+hourObj.getJSONObject("condition").getString("icon"); + String wind = hourObj.getString("wind_kph"); + + time.add(timeObj); + temp.add(temperature); + speed.add(wind); + image.add(imageObj); + } + + adapterRecycleView = new CardView(time, temp, speed, image); + recyclerView.setAdapter(adapterRecycleView); + + } catch (JSONException e) { + + e.printStackTrace(); + } + } + }, new Response.ErrorListener() { + + @Override + public void onErrorResponse(VolleyError error) { + + loaderProgressBar.setVisibility(View.GONE); + contentRelativeLayout.setVisibility(View.VISIBLE); + + Toast.makeText(MainActivity.this, "No matching location found.", Toast.LENGTH_LONG).show(); + } + }); + + queue.add(jsonObjectRequest); + + } +} diff --git a/app/src/main/java/com/miguelf03kai/weatherapp/cards/CardView.java b/app/src/main/java/com/miguelf03kai/weatherapp/cards/CardView.java new file mode 100644 index 0000000..23d40cc --- /dev/null +++ b/app/src/main/java/com/miguelf03kai/weatherapp/cards/CardView.java @@ -0,0 +1,76 @@ +package com.miguelf03kai.weatherapp.cards;; + +import android.content.Context; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import com.miguelf03kai.weatherapp.R; +import com.squareup.picasso.Picasso; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; + +public class CardView extends RecyclerView.Adapter { + + private static Context context; + private ArrayList arrayTime, arrayTemp, arraySpeed, arrayImage; + + public CardView(ArrayList arrayTime,ArrayList arrayTemp,ArrayList arraySpeed, + ArrayList arrayImage) { + this.arrayTime = arrayTime; + this.arrayTemp = arrayTemp; + this.arraySpeed = arraySpeed; + this.arrayImage = arrayImage; + } + + @Override + public CardView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_list,parent,false); + ViewHolder viewHolder = new ViewHolder(v); + return viewHolder; + } + + @Override + public void onBindViewHolder(CardView.ViewHolder holder, int position) { + + holder.temp.setText(arrayTemp.get(position)+"°c"); + holder.speed.setText(arraySpeed.get(position)+ " km/h"); + + SimpleDateFormat input = new SimpleDateFormat("yyyy-MM-dd hh:mm"); + SimpleDateFormat output = new SimpleDateFormat("hh:mm aa"); + + try{ + Date t = input.parse(arrayTime.get(position)); + holder.time.setText(output.format(t)); + }catch(ParseException e){ + e.printStackTrace(); + } + + Picasso.with(CardView.context).load(arrayImage.get(position)).into(holder.conditionIconCardImageView); + } + + @Override + public int getItemCount() { + return arrayTime.size(); + } + + public class ViewHolder extends RecyclerView.ViewHolder{ + + public TextView temp, time, speed; + public ImageView conditionIconCardImageView; + + public ViewHolder(View itemView){ + super(itemView); + temp = (TextView) itemView.findViewById(R.id.tempTextView); + time = (TextView) itemView.findViewById(R.id.timeTextView); + speed = (TextView) itemView.findViewById(R.id.speedTextView); + conditionIconCardImageView = (ImageView) itemView.findViewById(R.id.conditionIconCardImageView); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/miguelf03kai/weatherapp/utils/Formatter.java b/app/src/main/java/com/miguelf03kai/weatherapp/utils/Formatter.java new file mode 100644 index 0000000..f994045 --- /dev/null +++ b/app/src/main/java/com/miguelf03kai/weatherapp/utils/Formatter.java @@ -0,0 +1,27 @@ +package com.miguelf03kai.weatherapp.utils; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class Formatter { + + // Return location time formatted + public String dateTimeFormatting(String time){ + String pattern = "yyyy-MM-dd HH:mm"; + String formatedDate = ""; + Date date = null; + SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern); + + try { + date = simpleDateFormat.parse(time); + SimpleDateFormat formatting = new SimpleDateFormat("E dd MMMM hh:mm a"); + formatedDate = formatting.format(date); + } + catch (ParseException e) { + e.printStackTrace(); + } + + return formatedDate; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/miguelf03kai/weatherapp/utils/Localization.java b/app/src/main/java/com/miguelf03kai/weatherapp/utils/Localization.java new file mode 100644 index 0000000..43033b0 --- /dev/null +++ b/app/src/main/java/com/miguelf03kai/weatherapp/utils/Localization.java @@ -0,0 +1,35 @@ +package com.miguelf03kai.weatherapp.utils; + +import android.location.Address; +import android.location.Geocoder; +import android.util.Log; + +import java.io.IOException; +import java.util.List; + +public class Localization { + + public String getCityName(double longitude, double latitude, Geocoder geocoder){ + String cityName = "Not found"; + + try { + List
addresses = geocoder.getFromLocation(latitude,longitude,10); + + for(Address adr: addresses){ + if(adr!=null){ + String city = adr.getLocality(); + if(city!=null && !city.equals("")){ + cityName = city; + }else{ + Log.d("TAG", "City not Found"); + } + } + } + } + catch (IOException e){ + e.printStackTrace(); + } + + return cityName; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/miguelf03kai/weatherapp/utils/WeatherAPI.java b/app/src/main/java/com/miguelf03kai/weatherapp/utils/WeatherAPI.java new file mode 100644 index 0000000..794c41b --- /dev/null +++ b/app/src/main/java/com/miguelf03kai/weatherapp/utils/WeatherAPI.java @@ -0,0 +1,12 @@ +package com.miguelf03kai.weatherapp.utils; + +public class WeatherAPI { + + private String key = ""; + + public String requestUrl(String city){ + String url = "http://api.weatherapi.com/v1/forecast.json?key="+key+"&q="+city+ + "&days=1&aqi=no&alerts=no&lang="; + return url; + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 1d3316e..2e28d77 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -3,25 +3,27 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" + xmlns:app="http://schemas.android.com/apk/res/android" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:id="@+id/main" - tools:context="com.example.miguelf03kai.wetherapp.MainActivity" - android:background="#989898"> + tools:context="com.example.miguelf03kai.weatherapp.MainActivity" + android:background="#000"> + android:id="@+id/backgroundImageView" + android:scaleType="centerCrop" + android:background="#4ca9ff" /> @@ -29,7 +31,7 @@ @@ -38,7 +40,7 @@ android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" android:text="City Name" - android:id="@+id/tvCityName" + android:id="@+id/cityNameTextView" android:textColor="#ffffff" android:layout_alignParentTop="true" android:layout_marginBottom="10dp" @@ -50,8 +52,8 @@ @@ -59,9 +61,9 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Today's Weather Forecast" - android:id="@+id/tvTodaysForecast" + android:id="@+id/todaysForecastLabelTextView" android:textColor="#ffffff" - android:layout_below="@+id/tvCondition" + android:layout_below="@+id/conditionTextView" android:layout_marginTop="70dp" android:layout_alignParentLeft="true" android:textStyle="bold" @@ -72,7 +74,7 @@ android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" android:text="0.0°c" - android:id="@+id/tvDeqree" + android:id="@+id/deqreeTextView" android:textColor="#fff" android:textSize="55dp" android:layout_centerHorizontal="true" @@ -84,8 +86,8 @@ android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceSmall" android:text="Condition" - android:id="@+id/tvCondition" - android:layout_below="@+id/ivWatherIcon" + android:id="@+id/conditionTextView" + android:layout_below="@+id/conditionIconImageView" android:layout_centerHorizontal="true" android:textColor="#fff" android:layout_marginTop="5dp" @@ -93,21 +95,20 @@ android:textSize="16dp" /> + android:layout_below="@+id/todaysForecastLabelTextView" + android:layout_marginTop="10dp" /> @@ -115,28 +116,28 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceSmall" - android:id="@+id/tvRegion_Value" + android:id="@+id/regionTextView" android:textColor="#fff" - android:layout_alignTop="@+id/tvRegion" - android:layout_toEndOf="@+id/tvRegion" /> + android:layout_alignTop="@+id/regionLabelTextView" + android:layout_toEndOf="@+id/regionLabelTextView" /> + android:layout_alignTop="@+id/countryLabelTextView" + android:layout_toEndOf="@+id/countryLabelTextView" /> @@ -145,9 +146,9 @@ android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceSmall" android:text="localtime" - android:id="@+id/tvLocalTime" + android:id="@+id/localTimeTextView" android:textColor="#fff" - android:layout_below="@+id/tvCityName" + android:layout_below="@+id/cityNameTextView" android:layout_marginBottom="10dp" android:textAlignment="center" android:layout_alignParentStart="true" /> @@ -155,14 +156,15 @@ + android:layout_below="@+id/localTimeTextView" + android:layout_alignParentStart="true" + app:closeIcon="@layout/searchview_close_icon" /> diff --git a/app/src/main/res/layout/card.xml b/app/src/main/res/layout/card_layout.xml similarity index 100% rename from app/src/main/res/layout/card.xml rename to app/src/main/res/layout/card_layout.xml diff --git a/app/src/main/res/layout/list.xml b/app/src/main/res/layout/card_list.xml similarity index 75% rename from app/src/main/res/layout/list.xml rename to app/src/main/res/layout/card_list.xml index 7d302bb..7d88496 100644 --- a/app/src/main/res/layout/list.xml +++ b/app/src/main/res/layout/card_list.xml @@ -4,25 +4,25 @@ android:layout_width="100dp" android:layout_height="150dp" android:id="@+id/cardView" - android:background="@layout/card" + android:background="@layout/card_layout" android:layout_margin="2dp"> @@ -49,10 +49,10 @@ \ No newline at end of file diff --git a/app/src/main/res/layout/sv_background.xml b/app/src/main/res/layout/search_view_layout.xml similarity index 100% rename from app/src/main/res/layout/sv_background.xml rename to app/src/main/res/layout/search_view_layout.xml diff --git a/app/src/main/res/layout/searchview_close_icon.xml b/app/src/main/res/layout/searchview_close_icon.xml new file mode 100644 index 0000000..cf5d360 --- /dev/null +++ b/app/src/main/res/layout/searchview_close_icon.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_close.png b/app/src/main/res/mipmap-hdpi/ic_close.png index 1798238..9638770 100644 Binary files a/app/src/main/res/mipmap-hdpi/ic_close.png and b/app/src/main/res/mipmap-hdpi/ic_close.png differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png index 7100e04..c9ed96b 100644 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_close.png b/app/src/main/res/mipmap-mdpi/ic_close.png index 61920ae..f1ff9ae 100644 Binary files a/app/src/main/res/mipmap-mdpi/ic_close.png and b/app/src/main/res/mipmap-mdpi/ic_close.png differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png index 79995c5..bc10a16 100644 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_close.png b/app/src/main/res/mipmap-xhdpi/ic_close.png index 01af66c..6e80b69 100644 Binary files a/app/src/main/res/mipmap-xhdpi/ic_close.png and b/app/src/main/res/mipmap-xhdpi/ic_close.png differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png index 619ffcb..88c7b05 100644 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_close.png b/app/src/main/res/mipmap-xxhdpi/ic_close.png index 0ed3c3a..6e7084a 100644 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_close.png and b/app/src/main/res/mipmap-xxhdpi/ic_close.png differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index 9ff845e..b1208cd 100644 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_close.png b/app/src/main/res/mipmap-xxxhdpi/ic_close.png index c2f06f5..e3b4915 100644 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_close.png and b/app/src/main/res/mipmap-xxxhdpi/ic_close.png differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index 40478fb..37cead4 100644 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index f36f9bf..c14eb35 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -2,7 +2,7 @@ #3F51B5 #303F9F - #4640ff + #ffffff #292D36 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8d56f22..6b7d8ab 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,3 +1,3 @@ - wetherApp + WeatherApp diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 1f6ebf9..f143ad6 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -11,5 +11,4 @@ @android:color/white @android:color/white - diff --git a/app/src/test/java/com/example/miguelf03kai/wetherapp/ExampleUnitTest.java b/app/src/test/java/com/miguelf03kai/wetherapp/ExampleUnitTest.java similarity index 100% rename from app/src/test/java/com/example/miguelf03kai/wetherapp/ExampleUnitTest.java rename to app/src/test/java/com/miguelf03kai/wetherapp/ExampleUnitTest.java diff --git a/settings.gradle b/settings.gradle index e7b4def..9d495b3 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':app' +include ':app' \ No newline at end of file