Pro météo app ب أندرويد الجزء الأول


فهاد التطبيق الجديد من سلسلة أندرويد غادي نشوفو كيفاش نقادو Pro météo app فغادي نخدمو بواحد ل api لي سبق خدمنا بها لي هي openweathermap ولي غادي تمكنا من الحصول على أحوال الطقس للمدينة لي حنا فيها بالإضافة للمدن لي بغينا فسبق درنا تطبيق بحال هكا ولكن هادا شويه مختلف على الأول.

نظرة سريعة بالفيديو

1- الملف activity_main.xml

فأول حاجة غادي نديرو غادي نزيدو project جديد ف android studio ختار Basic Activity سميه ProClimaApp من بعد ميتزاد غادي تمشي للمجلد res/layout فيه كاين ملف activity_main.xml هادا هو الملف ديال الصفحة الرئيسية ديالنا فيه الكود لي فيه كاين les textviews لي غادي ياخدو المدينة والحرارة ولImageView لي غادي تاخد ل icon لي كتعبرعلى حالة السماء ول ImageButton لي كتمكن من التنقل للصفحة لي كتمكن من إدخال مدينة جديدة وكل واحد عندو ل id ديالو لي بيه غادي نسترجعوه فالملف MainActivity لي غادي نشوفوه من بعد الكود ديال activity_main.xml هو :

                                <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/weather_pic"
    tools:context="com.example.belasri.proclimaapp.MainActivity">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="@string/position"
        android:id="@+id/position"
        android:textColor="@color/white"
        android:textSize="40sp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_marginBottom="70dp"/>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@color/white"
        android:textSize="90sp"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="@string/default_temp"
        android:id="@+id/temp"
        android:layout_below="@+id/ChButtonCity"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"/>
    <ImageButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/ChButtonCity"
        android:src="@drawable/change_city_symbol_small"
        android:background="@null"
        android:layout_alignParentTop="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"/>
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="220dp"
        android:layout_centerVertical="true"
        android:layout_alignParentStart="true">
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/weatherImage"
            android:src="@drawable/dunno"
            />
    </FrameLayout>
</RelativeLayout>
                            

2- االملف WeatherModel.java

فالمجلد java زيد class java سميها WeatherModel فيها غادي تكون des variables لي كاتاخد جميع المعلومات الخاصة بحالة الطقس الحرارة المدينة والصورة وفيها ل getters لي غادي يمكنوني ملي ن créer l'objet نسترجع هاد القيم فعندي ل fonction getJsonData لي كترجعنا objet de type WeatherModel ولي كتاخد JSONObject لي غادي يجينا من ل api لي هضرنا عليها فالمقدمة فيلا بغيتي ت tester يمكنلك تجرب بهاد الرابط:

ولي فيه الحراراة والمدينة ول condition ولي على أساسها كنعرض ل icon ولي كنرجعوها بل fonction updateIcon والصور غادي تلقاهم ف source code الكود ديال الملف هو:

                                package com.example.belasri.proclimaapp;

import org.json.JSONException;
import org.json.JSONObject;

/**
 * Created by belasri on 25/10/2017.
 */

public class WeatherModel {
    private String temp;
    private String city;
    private String icon;
    private int condition;

    public static WeatherModel getJsonData(JSONObject jsonObject){
        try {
            WeatherModel weatherModel = new WeatherModel();
            weatherModel.city = jsonObject.getString("name");
            weatherModel.condition = jsonObject.getJSONArray("weather").getJSONObject(0).getInt("id");
            weatherModel.icon = updateIcon(weatherModel.condition);
            double temp = jsonObject.getJSONObject("main").getDouble("temp")- 273.15;
            int tempConverted = (int) Math.rint(temp);
            weatherModel.temp = Integer.toString(tempConverted);
            return weatherModel;
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return null;
    }
    private static String updateIcon(int condition) {
        if (condition >= 0 && condition < 300) {
           return "tstorm1";
        } else if (condition >= 300 && condition < 500) {
           return "light_rain";
        } else if (condition >= 500 && condition < 600) {
              return "shower3";
        } else if (condition >= 600 && condition <= 700) {
              return "snow4";
        } else if (condition >= 701 && condition <= 771) {
               return "fog";
        } else if (condition >= 772 && condition < 800) {
               return "tstorm3";
        } else if (condition == 800) {
              return "sunny";
        } else if (condition >= 801 && condition <= 804) {
                return "cloudy2";
        } else if (condition >= 900 && condition <= 902) {
             return "tstorm3";
        } else if (condition == 903) {
             return "sunny";
        } else if (condition >= 905 && condition <= 1000) {
              return "tstorm3";
        }
         return "dunno";
   }

    public String getTemp() {
        return temp + "°";
    }

    public String getCity() {
        return city;
    }

    public String getIcon() {
        return icon;
    }
}
                            

3- الملف MainActivity.java

فالمجلد java كاين الملف الرئيسي ديالنا ولي هو MainActivity.java ولي فيه الكود لي غادي يمكن من عرض المعلومات لي جبدنا من l'api ولي عندنا ل url ول key باش غادي نخدمو فمنبعد مكنسترجع les textviews ول imageview ول imagebutton لي زدنا فالملف activity_main.xml أول حاجة كنخدم بل fonction getCurrentWeather ولي كتمكن من استرجاع الإحدائيات ديال المستخدم وكنرسلوها لل url ديالنا باستخدام واحد android library سميتها Android Asynchronous Http Client ولي الموقع ديالها  من هنا 

فمنبعد غادي نشوفوا كيفاش نزيدوها لل projet ديالنا منبعد كاين onRequestPermissionsResult لي كتطلب لإدن من من المستخدم باش تستعمل ل position ولي يلا عطاها كتنفد ل fonction getCurrentWeather منبعد كاين ل fonction sendData لي كترسل ل paramétres للرابط منبعد كتسترجع ل response لي كتعطيها لل fonction getJsonData لي منبعد مكن créer l'objet من la classe WeatherModel كنرسلو لل fonction setData لي كتزيد الحرارة والمدينة وال icon ف textviews ول imageview الكود ديال الملف هو:

                                package com.example.belasri.proclimaapp;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.JsonHttpResponseHandler;
import com.loopj.android.http.RequestParams;

import org.json.JSONObject;

import cz.msebera.android.httpclient.Header;

public class MainActivity extends AppCompatActivity {
    final int REQUEST_CODE = 123;
    final String URL = "http://api.openweathermap.org/data/2.5/weather";
    final String KEY = "9883d8493cbbfcd643e0837c6ca20314";
    // Time between location updates (5000 milliseconds or 5 seconds)
    final long TIME = 5000;
    // Distance between location updates (1000m or 1km)
    final float DISTANCE = 1000;
    TextView mCity;
    ImageView mImage;
    TextView mTemperature;
    String locationProvider = LocationManager.NETWORK_PROVIDER;
    // TODO: Declare a LocationManager and a LocationListener here:
    LocationManager mLocationManager;
    LocationListener mLocationListener;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mCity = (TextView) findViewById(R.id.position);
        mImage = (ImageView) findViewById(R.id.weatherImage);
        mTemperature = (TextView) findViewById(R.id.temp);
        ImageButton changeCityBtn = (ImageButton) findViewById(R.id.ChButtonCity);
        changeCityBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this,ChangeCityActivity.class);
                startActivity(intent);
            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        String newCity = getIntent().getStringExtra("city");
        if(newCity != null){
            getNewCityWeather(newCity);
        }else{
            getCurrentWeather();
        }
    }
    private void getNewCityWeather(String newCity) {
        RequestParams params = new RequestParams();
        params.put("q",newCity);
        params.put("appid",KEY);
        sendData(params);
    }
    private void getCurrentWeather() {
        mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        mLocationListener = new LocationListener() {
            @Override
            public void onLocationChanged(Location location) {
                Log.d("climateApp : ","location changed");
                String latitude = String.valueOf(location.getLatitude());
                String longitude = String.valueOf(location.getLongitude());
                Log.d("latitude : ",latitude);
                Log.d("longitude : ",longitude);
                RequestParams params = new RequestParams();
                params.put("lat",latitude);
                params.put("lon",longitude);
                params.put("appid",KEY);
                sendData(params);
            }

            @Override
            public void onStatusChanged(String s, int i, Bundle bundle) {

            }

            @Override
            public void onProviderEnabled(String s) {

            }

            @Override
            public void onProviderDisabled(String s) {

            }
        };
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION},REQUEST_CODE);
            return;
        }
        mLocationManager.requestLocationUpdates(locationProvider, TIME, DISTANCE, mLocationListener);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if(requestCode == REQUEST_CODE){
            if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                Log.d("climateApp : ","permission accepté");
                getCurrentWeather();
            }else{
                Log.d("climateApp : ","permission refusé");
            }
        }
    }
    private void sendData(RequestParams params){
        AsyncHttpClient client = new AsyncHttpClient();
        client.get(URL,params,new JsonHttpResponseHandler(){
            @Override
            public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
                Log.d("climateApp : ","Response :" + response.toString());
                WeatherModel weatherModel = WeatherModel.getJsonData(response);
                setData(weatherModel);
            }

            @Override
            public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONObject errorResponse) {
                Log.d("climateApp : ","Echoué :" + throwable.toString());
                Log.d("climateApp : ","Status Code :" + statusCode);
                Toast.makeText(MainActivity.this, "Erreur!", Toast.LENGTH_SHORT).show();
            }
        });
    }
    private void setData(WeatherModel weather){
        mTemperature.setText(weather.getTemp());
        mCity.setText(weather.getCity());
        int imageId = getResources().getIdentifier(weather.getIcon(),"drawable",getPackageName());
        mImage.setImageResource(imageId);
    }

    @Override
    protected void onPause() {
        super.onPause();
        if(mLocationManager != null){
            mLocationManager.removeUpdates(mLocationListener);
        }
    }
}
                            

4- إضافة Android Asynchronous Http Client

باش تزيد Android Asynchronous Http Client للتطبيق كتدير تعديل على الملف build.gradle ديال ل Module App وكتزيد فيه هاد السطر وكتكليكي على sync :

                                    compile 'com.loopj.android:android-async-http:1.4.9'
                                


إشترك في قناتنا على اليوتيوب

بحث في الموقع


إشترك للتوصل بالجديد