درس برمجة تطبيق طقس { الجزء الاول }

في هذا الدرس سنقوم بالتعلم بعض الاشياء المهمة في برمجة الاندرويد وايضا كيفية البرمجة باسرع الطرق وابسطها باستخدام المكتبات وايضا طريقة التعامل مع API JSON وطريقة الاتصال بالانترنت ويقيم هذا الدرس ب{السهل الممتنع ? }.

فيديو للنتيجة النهائية :

 

جميل   ? .

نبدأ :

١ – انشئ تطبيق جديد :

المتطلبات :

compileSdkVersion 23
buildToolsVersion "22.0.1"
minSdkVersion 15
targetSdkVersion 23

الـdependencies المطلوبة في ملف gradel :

compile 'com.android.support:appcompat-v7:23.0.0'
compile 'com.android.support:cardview-v7:23.0.0'
compile 'com.android.support:design:23.0.0'
compile 'com.android.support:percent:23.0.0'
compile 'com.github.pwittchen:weathericonview:1.0.0'
compile 'com.jakewharton:butterknife:7.0.1'

 

٢- استخدام API الطقس :

استخدمت API المقدمة من http://api.openweathermap.org وهي مجانية تماما .

عند فتح هذا الرابط http://api.openweathermap.org/data/2.5/weather?q=london&units=metric&lang=ar ستظهر لك نتيجة مشابهه للموجودة بالاسفل { بحكم ان الطقس متغير } .
تلاحظ في الرابط ارسلنا “prameter” للغة وايضا قياس درجة الحرارة يكون بـC

{
"coord": {
"lon": -0.13,
"lat": 51.51
},
"weather": [
{
"id": 803,
"main": "Clouds",
"description": "غيوم متناثره",
"icon": "04n"
}
],
"base": "cmc stations",
"main": {
"temp": 13.63,
"pressure": 1020,
"humidity": 87,
"temp_min": 12.78,
"temp_max": 14.44
},
"wind": {
"speed": 3.1,
"deg": 210
},
"clouds": {
"all": 80
},
"dt": 1440810861,
"sys": {
"type": 1,
"id": 5093,
"message": 0.0132,
"country": "GB",
"sunrise": 1440824864,
"sunset": 1440874454
},
"id": 2643743,
"name": "London",
"cod": 200
}

.وكان الناتج Json .

ماهو Json قبل نكمل ومن ايش يتكون  ?  ؟  

جيسون او Json وهو نوع من انواع البيانات الخفيفة والسريعة وقليلة الحجم والمستخدمة بشكل كبير من المواقع المشهورة مثل تويتر وانستقرام .. الخ . 

يتكون من Array و Object  :

  • Array تبدا بهذا القوس ] وماقبلها يكون الاسم الخاص بها .
  • Object تبدا بهذ القوس } وماقبلها الاسم الخاص بها .

بالصورة التالية ستوضح لك الصورة بشكل كامل .

ARRY

نرجع للرابط السابق ونقوم بمعرفة array و object :

  • coord ؛ object
  • weather ; array
  • wind ; object
  • clouds ; object
  • sys ; opject

عرفنا API و Json ومكوناته والان نبدأ في تطبيق الاندرويد وطريقة الاتصال .


 

٣ – الاتصال بالرابط واسترجاع البيانات :

في تطبيق الاندرويد قبل الاتصال بالانترنت نحتاج الى اضافة Permissions في ملف AndroidManifest.xml 

Permissions : اعطاء التطبيق الصلاحية للوصول الى بعض خصائص النظام او الاتصال بالانترنت او معرفة موقع المستخدم وهي احدى خصائص الامان في الاندرويد حتى يكون المستخدم على حذر عند تثبيت التطبيقات .

تكون اضافة الوصول للانترنت في manifest بهذا الشكل:

    <uses-permission android:name="android.permission.INTERNET" />

نقوم الان بكتابة الـClass المسئول عن الاتصال بالانترنت .

 public class AsyncForAll extends AsyncTask<String, Void, JSONObject> {


        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            // show loading progress
            progressbar.setVisibility(View.VISIBLE);
            // hide cardview before display weather information
            cardview.setVisibility(View.GONE);
        }

        @Override
        protected JSONObject doInBackground(String... params) {
            url = params[0].replaceAll(" ", "%20").replaceAll("#", "%23")
                    .replaceAll("\n", "%20").trim();
            System.out.println("------- Async Task Url  " + params[0].replaceAll(" ", "%20").replaceAll("#", "%23")
                    .replaceAll("\n", "%20").trim());

                jObject = jParser.getJSONFromUrl(url);


            return jObject;
        }

        @Override
        protected void onPostExecute(JSONObject result) {
            progressbar.setVisibility(View.GONE);
            cardview.setVisibility(View.VISIBLE);
            Log.w("json", jObject.toString());
            if (jObject.toString().contains("Error: Not found city")) {
                Snackbar.make(toolbar, "تاكد من اسم المدينة", Snackbar.LENGTH_LONG)
                        .show();
            } else {
                JSONArray info = null;
                try {
                    info = jObject.getJSONArray("weather");
                    description.setText(info.getJSONObject(0).getString("description"));
                    JSONObject main = jObject.getJSONObject("main");
                    temp.setText(String.valueOf(main.getInt("temp")));
                    humidity.setText(String.valueOf(main.getInt("humidity")));
                    icon.setIconResource(getString(icon(info.getJSONObject(0).getString("icon"))));
                    speed.setText(String.valueOf(jObject.getJSONObject("wind").getString("speed")));
                    clouds.setText(String.valueOf(jObject.getJSONObject("clouds").getString("all")));
                } catch (JSONException e) {
                    e.printStackTrace();
                }

            }
        }

    }

دوختنا ? .

انتظر شوي وراح تفهم معي هذا الـClass وريث من AsyncTask والذي يقوم بعمليات الاتصال التي تستغرق وقت كالاتصال بالانترنت لدينا ومن ثم عرض النتائج للمستخدم.

ويتكون AsyncTask من ثلاث دوال رئيسية وهي :

  • onPreExecute() : هنا نقوم بالاعداد للمهمة ونقوم بعرض ProgressBar للمستخدم .لينتظر العملية وعرض النتيجة.
  • doInBackground(Params…) : هنا نقوم بتنفيذ المهمة وارجاع النتائج وهنا في درسنا سنقوم بعملية الاتصال بالانترنت واسترجاع JsonObject.
  • onPostExecute(Result) : هنا نكون خلاص انتهينا من المهمة ونعرض النتائج للمستخدم ولا ننسنا نخفي ProgressBar .

عند نسخ الكود السابق ستظهر لكم الكثير من الاخطاء بما ان الـClass منسوخ من التطبيق الي اشرح عليه .

نحتاج مع الكود السابق هذا الـClass :

import android.util.Log;

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

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;

public class JSONParser {

	static JSONObject jObj = null;
	static String json = "";

	// constructor
	public JSONParser() {

	}

	public JSONObject getJSONFromUrl(String url) {
		HttpURLConnection c = null;
		try {
			URL u = new URL(url);
			c = (HttpURLConnection) u.openConnection();
			c.setRequestMethod("GET");
			c.setRequestProperty("Content-length", "0");
			c.setUseCaches(false);
			c.setAllowUserInteraction(false);
			c.setConnectTimeout(6000);
			c.setReadTimeout(1000);
			c.connect();
			int status = c.getResponseCode();

			switch (status) {
				case 200:
				case 201:
					BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream()));
					StringBuilder sb = new StringBuilder();
					String line;
					while ((line = br.readLine()) != null) {
						sb.append(line + "\n");
					}
					br.close();
					json = sb.toString();
			}

		} catch (IOException ex) {
			Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
		} finally {
			if (c != null) {
				try {
					c.disconnect();
				} catch (Exception ex) {
					Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
				}
			}
		}
		// try parse the string to a JSON object
		try {
			jObj = new JSONObject(json);
		} catch (JSONException e) {
			Log.e("JSON Parser", "Error parsing data " + e.toString());
		}
		// return JSON String
		return jObj;


	}


}

الـClass السايق ببساطة يتصل بالرابط ويقوم بارجاع البيانات كـString ومن ثم نقوم بتحويلها الى JsonObject فقط

 

الحين انت شرحت AsyncTask وطريقة الاتصال واسترجاع البيانات ،، طيب كيف ارسل الرابط للـAsyncTask ? ؟

ببساطة نكتب هذا السطر في Activity او Fragment الي بنقوم فيه بعملية الاتصال بالانترنت :

                                    new AsyncForAll().execute("http://api.openweathermap.org/data/2.5/weather?q=" + search.getText().toString() + "&units=metric&lang=ar");

 

بعد هذا الدرس صرنا نعرف API ويعني ايش Json ومن ايش يتكون وبعد صار عندنا معلومات عن الصلاحيات في التطبيق وكيف اتصل بالانترنت عن طريق AsyncTask واهم الدوال الي نحتاجها فيه راح نكمل ان شاء الله في الدرس الجاي تصميم الواجهة وعرض البيانات المستخدم ،

شاركوني في التعليقات سواء بالاقتراحات او الاسئلة .

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *

3 أفكار عن “درس برمجة تطبيق طقس { الجزء الاول }”

  1. شكرا لك اخي الكريم على الشروحات المتميزة .

    لاكن تواجهني مشكله في Fragments لا استطيع استخدام json فيهاا حاولت بنفس الطريقه هذي لاكن لا فائده

  2. السلام عليكم ..
    اخي اواجه مشكله عند كتابه ملف الـ JsonPraser.java
    يطلع لي اخطاء كثير بالملف وانا استخدم sdk23
    وبعد بحث طويل جدا توصلت الا انه sdk 23 لاتدعم هذه الطريقه بل تدعم HttpURLConnection , وانا لا اعرف لها لو تكرمت ممكن تشرحها بدرس بسط يعني كيف نستدعي بيانات Json لتطبيق بشكل ListView
    بحيث انها تدعم android lollipop 6