(تطوير كلاسات Register و Login وJSONParser ) ربط تطبيق أندرويد مع MySQL و PHP و JSON

السلام عليكم ورحمة الله وبركاته

(جاري تحديث الموضوع)

فهرس سلسلة دروس ربط تطبيق أندرويد مع MySQL و PHP و JSON :

  1. مقدمة وشرح توضيحي عن Web Services وعن المشروع.
  2. إعداد السيرفر المحلي WAMP و بناء قاعدة بيانات MySQL.
  3. التعامل مع PHP لبناء Web Service  تقوم بعمل Login و Register (مع شرح مبسط عن JSON) .
  4. التعامل مع PHP لبناء Web Service  بجلب بيانات المستخدمين الموجودة بقاعدة البيانات.
  5. بناء مشروع أندرويد  جديد و إعداد واجهة تطبيق الأندرويد.
  6. تطوير كلاسات Register و Login وJSONParser في أندرويد.
  7. تطوير UsersActivity و ListViewAdapter لعمل قائمة المستخدمين بالتنسيق الذي نحتاجه.

 

 

JSONParser.java

package com.ahmaadssb.androidwebservices;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.util.Log;

public class JSONParser {
	static InputStream is = null;
	static JSONObject jObj = null;
	static JSONArray jarray = null;
	static String json = "";

	// constructor
	public JSONParser() {

	}
	
	 public JSONArray getJSONArrayFromUrl(String url) {
		 
		 StringBuilder builder = new StringBuilder();
		 HttpClient client = new DefaultHttpClient();
         HttpGet httpGet = new HttpGet(url);
         
         try {
             HttpResponse response = client.execute(httpGet);
             StatusLine statusLine = response.getStatusLine();
             int statusCode = statusLine.getStatusCode();
             if (statusCode == 200) {
               HttpEntity entity = response.getEntity();
               InputStream content = entity.getContent();
               BufferedReader reader = new BufferedReader(new InputStreamReader(content));
               String line;
               while ((line = reader.readLine()) != null) {
                 builder.append(line);
               }
             } else {
               Log.e("==>", "Failed to download file");
             }
           } catch (ClientProtocolException e) {
             e.printStackTrace();
           } catch (IOException e) {
             e.printStackTrace();
           }
         
         // Parse String to JSON object
         try {
             jarray = new JSONArray( builder.toString());
         } catch (JSONException e) {
             Log.e("JSON Parser", "Error parsing data " + e.toString());
         }
		return jarray;
	 }
	
	public JSONObject getJSONFromUrl(String url) {
		// making HTTP Request
		try {
			// Construct the client and the HTTP request.
			DefaultHttpClient httpClient = new DefaultHttpClient();
			HttpPost httpPost = new HttpPost(url);

			// Execute the POST request and store the response locally.
			HttpResponse httpResponse = httpClient.execute(httpPost);

			// Extract data from the response.
			HttpEntity httpEntity = httpResponse.getEntity();

			// Open an inputStream with the data content.
			is = httpEntity.getContent();
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		try {
			// Create a BufferedReader to parse through the inputStream.
			BufferedReader reader = new BufferedReader(new InputStreamReader(
					is, "iso-8859-1"), 8);

			// Declare a string builder to help with the parsing.
			StringBuilder sb = new StringBuilder();
			// Declare a string to store the JSON object data in string form.
			String line = null;

			// Build the string until null.
			while ((line = reader.readLine()) != null) {
				sb.append(line + "\n");
			}

			// Close the input stream.
			is.close();
			// Convert the string builder data to an actual string.
			json = sb.toString();
		} catch (Exception e) {
			Log.e("Buffer Error", "Error converting result " + e.toString());
		}

		// try to 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;
	}

	// function get json from url
	// by making HTTP POST or GET mehtod
	public static JSONObject makeHttpRequest(String loginUrl, String method, List<NameValuePair> params) {
		// making HTTP Request
		try {
			// check for request method
			if(method == "POST"){
				DefaultHttpClient httpClient = new DefaultHttpClient();
				HttpPost httpPost = new HttpPost(loginUrl);
				httpPost.setEntity(new UrlEncodedFormEntity(params));
				HttpResponse httpResponse = httpClient.execute(httpPost);
				
				HttpEntity httpEntity = httpResponse.getEntity();
				is = httpEntity.getContent();
			}else 
				// check for request method
				if(method == "GET"){
					DefaultHttpClient httpClient = new DefaultHttpClient();
					String paramString = URLEncodedUtils.format(params, "utf-8");
					loginUrl += "?" + paramString;
					HttpGet httpGet = new HttpGet(loginUrl);
					HttpResponse httpResponse = httpClient.execute(httpGet);
					HttpEntity httpEntity = httpResponse.getEntity();
					is = httpEntity.getContent();
			}
			
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		try {
				BufferedReader  reader = new BufferedReader(
					new InputStreamReader(is, "iso-8859-1"),8);
				StringBuilder sb = new StringBuilder();
				String  line = null;
			
				while((line = reader.readLine()) != null){
					sb.append(line + "\n");
				}
				is.close();
				json = sb.toString();
			} catch (IOException e) {
				Log.d("Buffer Error","Error Converting Reesult "+e.toString());
			}
		
		// try parse the string to JSON Object
		try {
			jObj = new JSONObject(json);
		} catch (JSONException e) {
			Log.e("JSON Parser", "Error Parsing data" + e.toString());
		}

		// return JSON String
		return jObj;
	}

	public static JSONObject getJSONfromURL(String url) {
        InputStream is = null;
        String result = "";
        JSONObject jArray = null;
 
        // Download JSON data from URL
        try {
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost(url);
            HttpResponse response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();
            is = entity.getContent();
 
        } catch (Exception e) {
            Log.e("log_tag", "Error in http connection " + e.toString());
        }
 
        // Convert response to string
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    is, "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            is.close();
            result = sb.toString();
        } catch (Exception e) {
            Log.e("log_tag", "Error converting result " + e.toString());
        }
 
        try {
 
            jArray = new JSONObject(result);
        } catch (JSONException e) {
            Log.e("log_tag", "Error parsing data " + e.toString());
        }
 
        return jArray;
    }
}

 

MainActivity.java  (المسؤول عن عملية تسجيل الدخول)

/***
 * @author Ahmed Saleh
 * Created by ahmadssb on 2014-12-13
 * Website: http://www.ahmadssb.com
 * Email: [email protected]
 * Facebook: https://www.facebook.com/ahmadssbblog
 * Twitter: https://twitter.com/ahmadssb
 * YouTube: http://www.youtube.com/user/ahmadssbblog
 */

package com.ahmaadssb.androidwebservices;

import java.util.ArrayList;
import java.util.List;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;

import android.support.v7.app.ActionBarActivity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends ActionBarActivity implements OnClickListener {
	private EditText user, pass;
	private Button login, register;

	private ProgressDialog pDialog;

	JSONParser jsonParser = new JSONParser();

	// من خلال شبكة الواي فاي
	private static String LOGIN_URL = "http://192.168.1.103/GoogleDrive/android-webservice1/login.php";

	// من خلال Android emulator
	// private static String LOGIN_URL = "http://10.0.2.2/GoogleDrive/android-webservice1/login.php";

	// من خلال رابط الموقع على الانترنت
	// private static String LOGIN_URL = "http://www.YOUR-DOMAIN.com/GoogleDrive/android-webservice1/login.php";

	/***
	 * كما فعلنا في ملفات PHP قمنا بوضع مفاتيح (متغيرات) ل JSON يفضل أن نقوم
	 * بتعريفها كـ static final لأنها قيم ثابتة سنحتاجها لاحقا
	 */
	private static final String TAG_SUCCESS = "success";
	private static final String TAG_MESSAGE = "message";
	private static final String TAG_USERNAME = "username";
	private static final String TAG_PASSWORD = "password";

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		user = (EditText) findViewById(R.id.edtUsername);
		pass = (EditText) findViewById(R.id.edtPassword);

		login = (Button) findViewById(R.id.btnLogin);

		register = (Button) findViewById(R.id.btnRegisterUser);

		login.setOnClickListener(this);

		register.setOnClickListener(this);

	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		case R.id.btnLogin:
			// عند الضغط على Login
			// نقوم بتفعيل كلاس AttemptLogin()
			new AttemptLogin().execute();
			break;
		case R.id.btnRegisterUser:
			Intent i = new Intent(MainActivity.this, RegisterActivity.class);
			startActivity(i);
			break;

		default:
			break;
		}
	}

	/***
	 * 
	 * @author Ahmadssb في هذا الكلاس سنقوم بالإتصال برابط تسجيل الدخول ونقوم
	 *         بإضافة الباراميترز المطلوبة username , Password ومن ثم الحصول على
	 *         JSON Response وأخيرا حسب قيمة success نقرر ما سنقوم بعمله
	 * 
	 */

	class AttemptLogin extends AsyncTask<String, String, String> {

		boolean failure = false;

		// نقوم بعرض ProgressDialog
		// حتى تنتهي جميع الأوامر الموجودة في doInBackground()
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			pDialog = new ProgressDialog(MainActivity.this);
			pDialog.setMessage("محاولة تسجيل الدخول ...");
			pDialog.setIndeterminate(false);
			pDialog.setCancelable(true);
			pDialog.show();
		}

		@Override
		protected String doInBackground(String... args) {
			// TODO Auto-generated method stub

			int success;
			// نقوم بتسجيل البيانات الموجودة في حقول username و password كنص
			String username = user.getText().toString();
			String password = pass.getText().toString();
			try {
				// نقوم ببناء الباراميترز المطلوبة لعملية تسجيل الدخول
				List<NameValuePair> params = new ArrayList<NameValuePair>();
				params.add(new BasicNameValuePair(TAG_USERNAME, username));
				params.add(new BasicNameValuePair(TAG_PASSWORD, password));

				// فقط لتتبع ما يحصل في LogCat
				Log.d("request!", "starting");

				// نقوم بارسال طلب POST الى رابط تسجيل الدخول مع إضافة الباراميتيرز
				// للحصول على JSON Objects 
				JSONObject json = JSONParser.makeHttpRequest(LOGIN_URL, "POST",	params);

				// فقط لتتبع ما يحصل في LogCat
				Log.d("Login attempt", json.toString());

				// نضع قيمة success والتي حصلنا عليها من JSON
				// بداخل المتغير success
				success = json.getInt(TAG_SUCCESS);

				/*
				 * في حال كانت قيمة success = 1 يعني ذلك انه تم التسجيل بنجاح
				 * أكتب الأمر الذي تريد تنفيذه سواء نقل المستخدم الى أكتيفيتي
				 * أخر أو اي شي تريده
				 * 
				 * ******************************** أما في حالة قيمة success = 0
				 * يعني انه توجد مشكلة سواء من المستخدم أو من السيرفر المستضيف
				 * حينها أكتب الأمر الذي تريده
				 */
				if (success == 1) {
					Log.d("Login Successful!", json.toString());

					Intent i = new Intent(MainActivity.this,
							UsersActivity.class);

					startActivity(i);
					return json.getString(TAG_MESSAGE);
				} else {
					Log.d("Login Failure!", json.getString(TAG_MESSAGE));
					return json.getString(TAG_MESSAGE);

				}
			} catch (JSONException e) {
				e.printStackTrace();
			}

			return null;

		}

		protected void onPostExecute(String file_url) {
			// نقوم بإخفاء الدايلوج بعد الانتهاء
			pDialog.dismiss();

			// نقوم بعرض الرسالة الناتجة من دالة doInBackground()
			if (file_url != null) {
				Toast.makeText(MainActivity.this, file_url, Toast.LENGTH_LONG)
						.show();

			}

		}

	}

}

 

RegisterActivity.java

/***
 * @author Ahmed Saleh
 * Created by ahmadssb on 2014-12-13
 * Website: http://www.ahmadssb.com
 * Email: [email protected]
 * Facebook: https://www.facebook.com/ahmadssbblog
 * Twitter: https://twitter.com/ahmadssb
 * YouTube: http://www.youtube.com/user/ahmadssbblog
 */

package com.ahmaadssb.androidwebservices;

import java.util.ArrayList;
import java.util.List;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class RegisterActivity extends Activity implements OnClickListener {
	private EditText user, pass, displayname;
	private Button btnRegister;

	private ProgressDialog pDialog;

	JSONParser jsonParser = new JSONParser();

	// من خلال شبكة الواي فاي
	private static String REGISTER_URL = "http://192.168.1.103/GoogleDrive/android-webservice1/register.php";


	// من خلال Android emulator
	// private static String REGISTER_URL = "http://10.0.2.2/GoogleDrive/android-webservice1/register.php";

	// من خلال رابط الموقع على الانترنت
	// private static String REGISTER_URL = "http://www.YOUR-DOMAIN.com/GoogleDrive/android-webservice1/register.php";


	/***
	 * كما فعلنا في ملفات PHP 
	 * قمنا بوضع مفاتيح (متغيرات) ل JSON
	 * يفضل أن نقوم بتعريفها كـ static final
	 * لأنها قيم ثابتة سنحتاجها لاحقا 
	 */
	private static final String TAG_SUCCESS = "success";
	private static final String TAG_MESSAGE = "message";
	private static final String TAG_USERNAME = "username";
	private static final String TAG_PASSWORD = "password";
	private static final String TAG_DISPLAYNAME = "displayname";

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.register_layout);


		user = (EditText) findViewById(R.id.edtRegisterUserName);
		pass = (EditText) findViewById(R.id.edtRegisterPassword);
		displayname = (EditText) findViewById(R.id.edtRegisterDisplayName);

		btnRegister = (Button) findViewById(R.id.btnRegister);
		btnRegister.setOnClickListener(this);

	}

	@Override
	public void onClick(View arg0) {
		// TODO Auto-generated method stub
		new Register().execute();
	}

	/***
	 * 
	 * @author Ahmadssb 
	 * في هذا الكلاس سنقوم بالإتصال برابط تسجيل مستخدم جديد  ونقوم
	 * ارسال الباراميترز المطلبوية ussername , password, displayname
	 * ومن ثم نحصل على JSON Response
	 * وأخيرا حسب قيمة success نقرر ما سنقوم بعمله
	 * 
	 */
	class Register extends AsyncTask<String, String, String> {

		boolean failure = false;

		// نقوم بعرض ProgressDialog
		// حتى تنتهي جميع الأوامر الموجودة في doInBackground()
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			pDialog = new ProgressDialog(RegisterActivity.this);
			pDialog.setMessage("محاولة تسجيل مستخدم جديد...");
			pDialog.setIndeterminate(false);
			pDialog.setCancelable(true);
			pDialog.show();
		}

		@Override
		protected String doInBackground(String... args) {
			// TODO Auto-generated method stub
			// نقوم بتسجيل البيانات الموجودة في حقول username و password و displayname كنص

			int success;
			String username = user.getText().toString();
			String password = pass.getText().toString();
			String sdisplayname = displayname.getText().toString();
			try {
				// نقوم ببناء الباراميترز المطلوبة لعملية تسجيل الدخول
				List<NameValuePair> params = new ArrayList<NameValuePair>();
				params.add(new BasicNameValuePair(TAG_USERNAME, username));
				params.add(new BasicNameValuePair(TAG_PASSWORD, password));
				params.add(new BasicNameValuePair(TAG_DISPLAYNAME, sdisplayname));

				//فقط لتتبع ما يحصل في LogCat
				Log.d("request!", "starting");
				
				// نقوم بارسال طلب POST الى رابط تسجيل الدخول مع إضافة الباراميتيرز
				// للحصول على JSON Objects 
				JSONObject json = JSONParser.makeHttpRequest(REGISTER_URL,"POST", params);
				//فقط لتتبع ما يحصل في LogCat
				Log.d("Register attempt", json.toString());

				// نضع قيمة success والتي حصلنا عليها من JSON
				// بداخل المتغير success
				success = json.getInt(TAG_SUCCESS);

				/*
				 * في حال كانت قيمة success = 1 يعني ذلك انه تم التسجيل بنجاح
				 * أكتب الأمر الذي تريد تنفيذه سواء نقل المستخدم الى أكتيفيتي
				 * أخر أو اي شي تريده
				 * 
				 * ******************************** أما في حالة قيمة success = 0
				 * يعني انه توجد مشكلة سواء من المستخدم أو من السيرفر المستضيف
				 * حينها أكتب الأمر الذي تريده
				 */
				if (success == 1) {
					Log.d("User Created!", json.toString());
					finish();
					return json.getString(TAG_MESSAGE);
				} else {
					Log.d("Register Failure!", json.getString(TAG_MESSAGE));
					return json.getString(TAG_MESSAGE);

				}
			} catch (JSONException e) {
				e.printStackTrace();
			}

			return null;

		}

		protected void onPostExecute(String file_url) {
			// نقوم بإخفاء الدايلوج بعد الانتهاء
			pDialog.dismiss();
			
			// نقوم بعرض الرسالة الناتجة من دالة doInBackground()
			if (file_url != null) {
				Toast.makeText(RegisterActivity.this, file_url,
						Toast.LENGTH_LONG).show();
			}

		}

	}

}

 

بإمكانك تحميل المشروع من خلال GitHub :
https://github.com/ahmadssb/Android-PHP-MySQL-JSON-Tutorial.git

Updated: February 4, 2015 — 5:53 am

(تطوير UsersActivity و ListViewAdapter) ربط تطبيق أندرويد مع MySQL و PHP و JSON

السلام عليكم ورحمة الله وبركاته

(جاري تحديث الموضوع)

فهرس سلسلة دروس ربط تطبيق أندرويد مع MySQL و PHP و JSON :

  1. مقدمة وشرح توضيحي عن Web Services وعن المشروع.
  2. إعداد السيرفر المحلي WAMP و بناء قاعدة بيانات MySQL.
  3. التعامل مع PHP لبناء Web Service  تقوم بعمل Login و Register (مع شرح مبسط عن JSON) .
  4. التعامل مع PHP لبناء Web Service  بجلب بيانات المستخدمين الموجودة بقاعدة البيانات.
  5. بناء مشروع أندرويد  جديد و إعداد واجهة تطبيق الأندرويد.
  6. تطوير كلاسات Register و Login وJSONParser في أندرويد.
  7. تطوير UsersActivity و ListViewAdapter لعمل قائمة المستخدمين بالتنسيق الذي نحتاجه.

 

 

ListViewAdapter.java

/***
 * @author Ahmed Saleh
 * Created by ahmadssb on 2014-12-13
 * Website: http://www.ahmadssb.com
 * Email: [email protected]
 * Facebook: https://www.facebook.com/ahmadssbblog
 * Twitter: https://twitter.com/ahmadssb
 * YouTube: http://www.youtube.com/user/ahmadssbblog
 */

package com.ahmaadssb.androidwebservices;

import java.util.ArrayList;
import java.util.HashMap;

import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class ListViewAdapter extends BaseAdapter {

	// نقوم بتعريف المتغيرات المطلوبة
	Context context;
	LayoutInflater inflater;
	ArrayList<HashMap<String, String>> data;
	HashMap<String, String> resultp = new HashMap<String, String>();

	// تعريف الكونستركتر 
	// حيث يحتوي على المتغيرات 
	//context = اسم الكلاس 
	// arraylist = مصفوفة users التي سنحصل عليها من JSONArray
	public ListViewAdapter(Context context,
			ArrayList<HashMap<String, String>> arraylist) {
		this.context = context;
		// هنا سنتعامل مع المصفوفة التي حصلنا عليها من الكونستركتر لكي نتحكم بمحتوياتها ونضعها في single_user_layout
		data = arraylist;
	}

	@Override
	public int getCount() {
		// نحصل على حجم data 
		// والتي هي عدد مصفوفة JSON
		return data.size();
	}

	@Override
	public Object getItem(int position) {
		return null;
	}

	@Override
	public long getItemId(int position) {
		return 0;
	}

	/***
	 * في هذه الدالة سنقوم بالربط مع  single_user_layout
	 * و نقوم بتعريف كل كائن TextView 
	 * و من ثم نقوم بأخذ القيم الموجودة في data
	 * وربطها مع كل TextView
	 */
	public View getView(final int position, View convertView, ViewGroup parent) {

		// تعريف متغيرات TextView المطلوبة
		TextView tvUserID, tvUsername, tvDisplayName;

		// نقوم بتعريف inflater 
		// LayoutInflater : توضيح مبسط
		// يسمح لك بتحويل اي كائن (نص-زر-صورة...الخ) الى View Objects 
		inflater = (LayoutInflater) context
				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

		// نقوم بتعريف itemView Object 
		// inflater.inflate (int resource, ViewGroup root, boolean attachToRoot)
		// resource = single_user_layout بمعنى التصميم الذي تود التحكم بمحتوياته
		// ViewGroup root = parent نفس الباراميتر الموجود في getViwe() و الهدف منه الحصول على أول عنصر في ملف التصميم
		View itemView = inflater.inflate(R.layout.single_user_layout, parent, false);

		// نحصل على موضع الداتا
		// بمعنى آخر ان كان هناك 4 مستخدمين حصلنا على بياناتهم من JSON Array
		// كل مستخدم له مصفوفة تحتوي على id - username - displayname 
		// هنا نحن نحدد موضع المصفوفة للمستخدم
		// فإذا كانت 2 سنحصل على بيانات المستخدم رقم 2
		resultp = data.get(position);

		// نقوم بتعين كل متغير TextView بما هو موجود في ملف single_user_layout
		tvUserID = (TextView) itemView.findViewById(R.id.txtID);
		tvUsername = (TextView) itemView.findViewById(R.id.txtUsername);
		tvDisplayName = (TextView) itemView.findViewById(R.id.txtDisplayName);

		// نقوم بوضع بيانات TextView في أماكنها
		tvUserID.setText(resultp.get(UsersActivity.TAG_USER_ID));
		tvUsername.setText(resultp.get(UsersActivity.TAG_USER_USERNAME));
		tvDisplayName.setText(resultp.get(UsersActivity.TAG_USER_DISPLAYNAME));

		// اخيرا نقوم بإرجاع itemView 
		return itemView;
	}

}

 

UsersActivity.java

/***
 * @author Ahmed Saleh
 * Created by ahmadssb on 2014-12-13
 * Website: http://www.ahmadssb.com
 * Email: [email protected]
 * Facebook: https://www.facebook.com/ahmadssbblog
 * Twitter: https://twitter.com/ahmadssb
 * YouTube: http://www.youtube.com/user/ahmadssbblog
 */
package com.ahmaadssb.androidwebservices;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.http.NameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Toast;

public class UsersActivity extends Activity {
	
	// Declare Variables
	JSONObject jsonobject;
	JSONArray jsonArrayUsers;
	
	ListView listview;
	ListViewAdapter adapterListView;
	
	ProgressDialog mProgressDialog;
	
	ArrayList<HashMap<String, String>> arraylistUsers;
	
	// JSON parser Class
	JSONParser jsonParser = new JSONParser();

	// من خلال شبكة الواي فاي
	private static String USERS_URL = "http://192.168.1.103/GoogleDrive/android-webservice1/users.php";

	// من خلال Android emulator
	// private static String USERS_URL = "http://10.0.2.2/GoogleDrive/android-webservice1/users.php";

	// من خلال رابط الموقع على الانترنت
	// private static String USERS_URL = "http://www.YOUR-DOMAIN.com/GoogleDrive/android-webservice1/users.php";

	
	// JSON IDS:
	static final String TAG_SUCCESS = "success";
	static final String TAG_USERS_LIST = "users";
	static final String TAG_USER_ID = "id";
	static final String TAG_USER_USERNAME = "username";
	static final String TAG_USER_DISPLAYNAME = "displayname";
	private static final String TAG_MESSAGE = "message";
    
	@Override 
	public void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		setContentView(R.layout.users_layout);

		new DownloadJSON().execute();
	}
	
	


	/***
	 * 
	 * @author Ahmadssb 
	 * في هذا الكلاس سنقوم بالإتصال برابط تسجيل مستخدم جديد  ونقوم
	 * ومن ثم نحصل على JSON Response
	 * وأخيرا حسب قيمة success نقرر ما سنقوم بعمله
	 * 
	 */
	private class DownloadJSON extends AsyncTask<Void, Void, Void> {
		int status;

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			
		}

		@Override
		protected Void doInBackground(Void... params) {
			// نقوم بتعريف ArrayList 
			arraylistUsers = new ArrayList<HashMap<String, String>>();
			
			try {
				
				List<NameValuePair> param = new ArrayList<NameValuePair>();
				//فقط لتتبع ما يحصل في LogCat
				Log.d("request!", "Starting");
				

				// نقوم بارسال طلب POST الى رابط Users 
				// للحصول على JSON Objects 
			jsonobject = JSONParser.makeHttpRequest(USERS_URL,"POST",param);

			//فقط لتتبع ما يحصل في LogCat
			Log.d("Loding Restaurant", jsonobject.toString());
			

			// نضع قيمة success والتي حصلنا عليها من JSON
			// بداخل المتغير success
			status = jsonobject.getInt(TAG_SUCCESS);
			
			if(status != 0)
			{
				// نقوم بالحصول على مصفوفة users في JSON 
				jsonArrayUsers = jsonobject.getJSONArray(TAG_USERS_LIST);


				for (int i = 0; i < jsonArrayUsers.length(); i++) {
					HashMap<String, String> map = new HashMap<String, String>();
					JSONObject jsonobject = jsonArrayUsers.getJSONObject(i);
					
					// نقوم بالحصول على JSON Objects مع قيمة كل Object 
					// ونقوم بحفظها في كائن HashMap 
					map.put(TAG_USER_ID, jsonobject.getString(TAG_USER_ID));
					map.put(TAG_USER_USERNAME, jsonobject.getString(TAG_USER_USERNAME));
					map.put(TAG_USER_DISPLAYNAME, jsonobject.getString(TAG_USER_DISPLAYNAME));
					
					
					// نقوم بحفظ البيانات المخزنة في map  بداخل arraylistUsers
					arraylistUsers.add(map);
				}
				//فقط لتتبع ما يحصل في LogCat
				Log.d("jsonArrayKioskRestaurant Size:", ""+arraylistUsers.size());
				
				
				
			}else{
				//فقط لتتبع ما يحصل في LogCat
				Log.d("Loding Restaurant Failure!", jsonobject.getString(TAG_MESSAGE));
			}
					
			
			} catch (JSONException e) {
				Log.e("Error", e.getMessage());
				e.printStackTrace();
			}
			return null;
		}

		@Override
		protected void onPostExecute(Void args) {

			if (status != 0) {
				
				// أولا نقوم بتعريف listView
				listview = (ListView) findViewById(R.id.listView1);
				// نقوم بإرسال بيانات المصفوفة arraylistUsers بداخل ListViewAdapter
				// حيث ان ListViewAdapter سيتكفل بتنسيق البيانات 
				adapterListView = new ListViewAdapter(UsersActivity.this, arraylistUsers);
				// نقوم بتعيين adapterListView بداخل listView
				listview.setAdapter(adapterListView);
				
				//  في حال كنت تريد ان تقوم بتنفيذ امر معين عند النقر على احد الحقول في ListView
				// عليك استدعاء الدالة setOnItemClickListener()
				listview.setOnItemClickListener(new OnItemClickListener() {

					@Override
					public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
						
						TextView tvUserID = (TextView) (arg1.findViewById(R.id.txtID));
						String sUserID = tvUserID.getText().toString();
						TextView tvUsername = (TextView) (arg1.findViewById(R.id.txtUsername));
						String sUsername = tvUsername.getText().toString();
						TextView tvDisplayName = (TextView) (arg1.findViewById(R.id.txtDisplayName));
						String sDisplayName = tvDisplayName.getText().toString();
						
						Toast.makeText(UsersActivity.this, sUserID + " - " + sUsername + " - " + sDisplayName, Toast.LENGTH_LONG).show();
						

					}
				});
				
			}
			
		}
	}	
}

بإمكانك تحميل المشروع من خلال GitHub :

https://github.com/ahmadssb/Android-PHP-MySQL-JSON-Tutorial.git

Updated: February 4, 2015 — 5:55 am

مللت من الاسئلة اللي تقلل من كفائتنا نحن العرب

 

map_arab

بصراحة مللت من الاسئلة اللي تقلل من كفائتنا نحن العرب ترى والله فينا عباقرة ومعروفين ولكن نحن اللي ما نبحث عنهم وبصراحة من حقهم يشتغلوا في شركات اجنبية دام جماعتنا ما يعترفوا فيهم.

حبايبي لمن نتكلم عن مشروع كبير ناجح من شركات كبيرة

  • مو شرط الحكومة لها دور (اقصد منذ نشأتها).
  • اغلب شركات البرمجيات (او اي مجال) الكبيرة كان عددهم ينعد على الاصابع او ما بدأت و بعدين حصلوا على الدعم وزاد عددهم وزاد تطوير برامجها.
  • لو ان عددهم ما زال كما هو ما راح تسمع عنهم ابدا ولكن ما قام برفع مستوى الشركة الا موظفيها (شركة مع موظفين قليلين مهما كانت شهرتها ما اسمها شركة كبيرة).
  • عند ذكرك لاسم شركة وتمدح فيها فانت تمدح كل موظف في تلك الشركة من الفراش (عامل النظافة) الى مديرها
  • الشركة لها سنين تطور المنتج وما تم اشتهاره الا بعد ما تم اصدار تحديثات مستمرة له.

الحين خليني اتكلم عن نفس الموظفين في هذه الشركات الكبيرة مهما كانت اسم او تخصص الشركة

حط في بالك ان الشركة حتى لو ان مؤسسها او مديرها من جنسية ما (مثلا امريكي) مو معناه انه كل موظفيها امريكان او حتى كل ما يقومون باصداره من نفس الشركة (الا بعض الشركات تقوم بعمل كل شي بنفسها ولكن برضو ليس جميع موظفيها من نفس الجنسية (امريكان))

الموظفين الذين يعملون في تلك الشركات الكبيرة يكونون من كل جنسيات العالم (ومن ضمنها الجنسيات العربية) فما في اي شركة في العالم تكون 100% موظفيها من نفس الجنسية أصلا (وليس مجنس .. اجنبي حاصل على جنسية دولة اخرى)

اخي الكريم العربي الفاهم والعاقل

النقطة اللي ابى اوصلها هي انه بما انه ما في دولة ولا شركة قامت بعمل منتج كبير او صغير الا وكان العاملين في هذا المنتج من جنسيات وديانات مختلفة

من حقك ان تحلم بعمل شي عالمي ويكون 100% عربي (استثني من هذا الاجهزة الاجنبية اللي بتستخدمها لصناعة هذا المنتج العربي)

لكن رجاءا لا تبالغ في مدح الشركات الاجنبية وكأن جميع موظفيها من نفس الجنسية ترى كما ذكرت سابقا فيها موظفين عرب يعني الشي اللي تستخدمه سواء نظام تشغيل او اي برنامج او اي شي في النت داخل في صناعتها ايادي عربية نفخر بهم

الامر الاخر (موجه تحديدا للشركات وليس للافراد) من قال لكم ان نحن العرب ليس لدينا عقول عربية كبيرة والله العظيم انه اي من الشركات سواء صغيرة او كبيرة تقول مثل هذا الكلام فهم ($#%@#%@)

يوجد أسامي لعقول عربية كبيرة ومنتجاتهم اصبحت عالمية يكفي تشوف المساهمات العربية التي عرضت في “ملتقى المغردين العرب” الاخير

لكن خليني اركز الان في متسابقي برنامج “نجوم العلوم” (تابع من الدقيقة 2:37 الى 7:55)

طبعا كلهم مبدعين ومثلهم كثير جدا لكن لم يجدوا دعم من الشركات العربية (#$%^&$#) بعضهم حصل على دعم من حكومتاتهم ولكن اغلبهم فتح مشاريعه بالخارج لانه وجد الدعم من الغرب

فلو سمحت يا شركاتنا العربية الموقرة ان كنت ما تعرف عربي مبدع فهذا شي عادي ومشكلتك الخاصة

اما انك تسب وتقلل من كفائة العرب فانكتم (اصمت) أفضل.

 

أحد مواضيعي السابقة لي في Arabia I/O

https://arabia.io/go/1295

 

Updated: December 10, 2014 — 3:01 pm

“التقليد” و “تطوير مشاريع سابقة” بدل البدء من الصفر من وجهة نظري

bigstock_Graph_analysis_11233205

 

السلام عليكم ورحمة الله وبركاته

أحببت أن أتحدث عن موضوع تقليد المواقع المختلفة من وجهة نظري الشخصية

لو قارنا بين المواقع العالمية في بداية نشأتها (وليس الوقت الحالي) مثلا  :

التقليد
  • جووجل و ياهو و مايكروسوفت ,,, جميعهم مقلدين بعض في خدمة البحث (لا ادري من منهم بدأ الفكرة ومن الممكن ولا احد منهم بدئها وكلهم مقلدين اول موقع ابتكر خاصية البحث)
    نفس الشي ينطبق على الشركات الثلاثة في خدمة الماسنجر حيث كان يوجد قبلهم برامج تقدم نفس فكرة الماسنجر مثل ICQ
  • بالمثل فيسبوك و تويتر و جوجل بلس وغيرهم ,,, جميعهم يقدمون نفس الفكرة اللي كانت مواقع قبلها تقدمها مثل hi5 و فريندستار و ماي سبيس ويمكن مواقع اقدم منهم
  • بالمثل في مواقع التجارة الالكترونية مثل امازون و ايباي و علي بابا و غيرهم ,,, كلهم يقدمون نفس الفكرة في البيع والشراء

ولاحظ ان “امازون” كان بدايته فقط في بيع الكتب ومن ثم انتقل الى بيع باقي المنتجات (لا ادري ان بدأ ذلك قبل او بعد مواقع التجارة الالكترونية الاخرى)

لكن في نهاية الامر جميعهم يقدمون الخدمة (الكترونيا) بنفس الطريقة تقريبا

  • دروب بوكس و بوكس و جوجل درايف (جوجل دوكس سابقا) ,,, لو كنت تستخدم جوجل دوكس سابقا قبل تغيير اسمه لم يكن هناك اي فرق ابدا لانه كان بامكانك رفع اي نوع من الملفات التي تريد الى جوجل دوكس وتشاركها مع الغير حتى انه كان هناك اسعار لزيادة المساحة وكلهم يقوموا بنفس الخدمة
  • ونفس الشي ينطبق على الاندرويد و الايفون فجميعهم انتهوا بتقليد بعض الان وهم الاثنين اساسا مقلدين بعض المميزات التي كانت موجودة في الاجهزة الكفية وبعض الاجهزة الالكترونبة قديما

لا ادري ان كان الاجانب في ذلك الزمان يقولون ما نقوله الان (هذا الشركة أ تقلد تلك ب) حتى ان قالو ذلك اليوم ممكن تغير رأيهم واصبحوا يتهموا الشركة ب بتقليد الشركة أ ونسوا من قلد من من البداية


 

الحين لو فكرت في الموضوع قليلا وتتبعت كيف قامت الشركات بتطوير خدماتها التي كانت “تقليد” في بدايتها واصبحت ما هي عليه الان هذا كله لم يكن “شختك بختك” يعني ليست عشوائبا او صدفة 🙂

المهم جميع الشركات (حسب وجهة نظري) لديهم خطة مدروسة لمدة من الزمن لكي يقوموا بتطوير شي معين في الخدمة وينافسوا الشركات الاخرى التي تقدم نفس الخدمة ويوم بعد يوم تجدهم مرة اخرى يضيفون نفس التطويرات الجديدة التي قامت بها الشركات المنافسة.

نفس الامر ينطبق على الحياة العملية فمثلا شركات الدهانات جميع الشركات تقوم بتقديم نفس المنتج الاساسي من الدهانات وهو شي استاندرد على كل الشركات في العالم (انا اتكلم عن الدهانات الاساسية) الفرق يكون في شي بسيط جدا

بالاضافة الى الانواع الاخرى من الدهانات التي تقدمها الشركة وهي التي تعتمد على قوة سمعة الشركة

سبب وضعي لهذا الموضوع كثرة الناس المتعصبة لشركات معينة للاخرى وكثر الهرج عن التقليد فلان يقلد فلان وخصوصا في المشاريع العربية مثلا “سوق كوم” و “كوبون

جميعهم مقلدين “افكار” مواقع اجنبية وهذا مو عيب ان كانت هذه الخدمة غير موجودة في مجتمعنا العربي وبحاجة إليه

وهذا يقودني الى القسم الثاني من العنوان وهو:

تطوير مشاريع سابقة
  • فبريد الهوتميل مطوره الاساسي “هندي” ثم اشترته مايكروسوفت واصبح الناس يعتقدون انه مطوري الموقع “امريكان”
  • نظام الاندرويد ليس من صنع جوجل ولكنهم قامو بشرائه من مطورين اخرين في 2005 ومن ثم قامت جوجل بتطويره قبل اصداره رسميا عام 2007 وكل عام تقوم بتحديث النظام الى ما وصل اليه الان
  • وبالمثل شركة ابل قرأت قبل سنوات قليلة قامت بشراء خدمة Quattro لتحسين خدمة الدعايات لديها (او انه لم يكن عندها اساسا خدمة الدعايات iAds) ما اذكر الخبر بالتفصيل ولكن الفكرة انهم قاموا بشراء منتج جاهز وثم قاموا بتطويره وتحسينه بحسب متطلباتهم

تعمدت اني اذكر اكبر ثلاث شركات في مجال التكنولوجيا خصوصا في هذا الموضوع لأبين وجهة نظري

ليس عيبا ان تقوم بتقليد شركات اخرى او حتى تعتمد على مشاريع سابقة في بداية عملك ولكن عليك ان تقوم بدراسة المشروع جيدا وتحليله من البداية الى النهاية وخذ وقتك في هذه الفترة ليسهل بعد ذلك القيام بتطويره و تقديم محتوى مميز ومختلف عن المواقع الاخرى وان كانت هناك فكرة لا تزال جديدة عند الغرب وليست منتشرة بكثرة ان كانت مميزة باعتقادي انه من الافضل ان تقوم بتقليدها والاهم من ذلك قم بازالة الامور الغير ضرورية واضافة خدمات جديدة مميزة اخرى (حيث انها ليست منتشرة بعد)

صراحة ما ادري ان كان موضوعي واضح ام لا لأني مواصل حاليا 22 ساعة من غير نوم ,, مجرد اكتب ما يخطر في بالي حاليا

وشكرا

 

أحد مواضيعي السابقة لي في Arabia I/O

https://arabia.io/go/594

Updated: December 10, 2014 — 4:18 pm

هل توجد خصوصية في الإنترنت؟


 

السلام عليكم ورحمة الله وبركاته

كثر الحديث عن موضوع الخصوصية (Privacy) في مواقع التواصل الاجماعي (Facebook, Twitter, Google Plus) و الشركات الكبرى مثل جوجل و ابل ومايكروسوفت وغيرها…

اغلب من تحدث عن الخصوصية في تلك المواقع يتفقوا على امر واحد تقريبا ألا و هو أن تلك المواقع تقوم بحفظ جميع بيانات مستخدميها في سيرفراتهم و أن بإمكانهم التحكم بها أو تعقب جميع حركات مستخدميها ومعرفة أماكنهم، وقد أيضا يقوموا ببيع بيانات مستخدميها للحكومات و نحوها.

بالفعل جميع ما قيل صحيح ولكن أنا كمهندس برمجيات ومطور ويب و تطبيقات للهواتف الذكية لدي وجهة نظر مختلفة كليا عن كل ما قيل عن تلك المواقع والشركات.
لأكون واضحاً معكم وجهة نظري من ناحية (تقنية) فجميع ما تقوم به تلك المواقع من حفظ بيانات مستخدميها والتحكم بها و تعقب حركات مستخدميها وزوارها بإمكان أي موقع صغيراً كان أو ضخما أن يقوم به، هذا إن كان صاحب الموقع من أصحاب النفوس الضعيفة.

قبل أن اتحدث عن الخصوصية في الانترنت لنتحدث عن الخصوصية في الحياة الواقعية، جميعنا نتفق أن بإمكان شركات الاتصالات في اي بلد كان ان تقوم بالتنصت على المحادثات التي تقوم بها. (لا أعلم إن كانت تقوم بحفظ تلك التسجيلات في سيرفراتهم)

ولكن لا يمكن للشركة (بحسب العقد المتفق أو قوانين الدولة) أن تقوم بالتنصت على محادثات عملائها بدون أمر رسمي من الحكومة أو أي جهة رسمية.

لذلك لنفترض مثلا (وهذا لا يمكن أن يحصل إلا بأمر رسمي) أنهم قاموا بالتنصت على مكالمتك وأنت تتحدث مع الأهل أو لديك عمل وتريد التحدث مع زميل لك عن أسرار العمل. أليس بإمكانهم التنصت عليك أيضا؟ بما أن لديهم صلاحية لذلك فهذا لا يعني أنهم لا يستطيعوا اختراق القانون والتنصت على مكالمتك.

بالتأكيد لا يتم التنصت إلا ان كنت شخص مجرم و يريدوا التوصل إليك غير ذلك لن يتم من الأساس إصدار قرار التنصت عليك.

ما يحصل في الإنترنت أمر مشابه، فجميع المواقع في الانترنت بإمكانها بمجرد دخولك على الموقع التوصل على عنوان IP الخاص بك وهذا ليس إختراقا لجهازك أو أي شي مماثل، ولكن الهدف الرئيسي من هذا هو عمل إحصائيات للموقع كعدد الزوار و معرفة زيارات الموقع من أي دولة و أي مدينة و نحو ذلك.

فأنا كمدير لموقع معين بإمكاني معرفة بيانات كثيرة عنك من خلال فقط عنوان IP الخاص بك كموقعك في الكرة الأرضية ليس فقط الدولة والمدينة ولكن موقعك التقريبي على الخريطة ، بالإضافة الى معرفة مزود خدمة الانترنت لديك. و أيضا لنقل أنه تم اختراق جهازك من خلال أحد الهكرز وقام بفتح منفذ Port معين على جهازك بإمكاني تجربة جميع المنافذ (ولو أنها عملية طويلة جدا) ولكنها ممكنة.

كما قلت هذا فقط بمجرد دخولك للموقع ولكن لنقل أنك قمت بالتسجيل بالموقع فأنت بذلك قمت بحفظ بياناتك في قاعدة بيانات هذا الموقع و إن قمت بكتابة مواضيع أو ردود في ذلك الموقع فجميعها تكون محفوظة في قاعدة بيانات الموقع

ما أريد الوصول إليه انه جميع البيانات التي تقوم بإدخالها في أي موقع كان فسوف تحفظ في قاعدة بيانات ذلك الموقع فعندما يزيد عدد مستخدمي هذا الموقع و تزيد شهرة الموقع فبالتأكيد ستزيد البيانات المسجلة في ذلك الموقع.

حينها لدى مدير الموقع قاعدة ضخمة من بيانات المستخدمين وجميع ما قاموا بعمله في موقعه، حينها يأتي التخوف من ذلك الموقع من نشر بيانات مستخدميه.

فمن بادئ الأمر لماذا (أنا) متصفح للإنترنت و مستخدم عادي للإنترنت أقوم بوضع بيانات حساسة ودقيقة في تلك المواقع. فالهدف من جميع المواقع نشر محتوياتها (مقالات أو فديوهات) لكافة متصفحي الانترنت ونشر نظرتهم الخاصة لبعض المواضيع.

لذلك (أنا) المستخدم العادي للإنترنت الملام الأول في حالة أنني قمت بنشر بعض الصور أو البيانات الخاصة و الحساسة جدا بي في تلك المواقع.

من المفترض أن لا نلوم أصحاب تلك المواقع على أخطاء نحن في الأساس كنا السبب الرئيسي فيها، فلا تنسى أنهم قاموا بتقديم تلك الخدمة مجانا لك. ولكن الواقع لا يوجد شيء مجاني فليس من الضروري أن يكسبوا بضعا من النقود منك ولكن فهم يستفيدوا من عدد المستخدمين الضخم ليروجوا لبعض الخدمات الأخرى كالإعلانات و كثير منا يعلم كمية الخيارات الضخمة التي يستطيع المعلن التحكم بها لنشر منتجه من تحديد الدولة والمدينة وحتى العمر والجنس واللغة وغيرها الكثير.

قمت بالتوضيح (تقنيا) في هذا الفديو موضوع الخصوصية على الإنترنت ومن وخبرتي السابقة في هذا المجال، فلا توجد خصوصية (بالمعنى المتعارف عليه) في الانترنت بشكل عام ،
ولكن الخصوصية الحقيقية تعتمد عليك (أنت) أولاً بمعرفتك بما تقوم بنشره على الإنترنت و بعد ذلك ما يقوم (مدراء تلك المواقع ) بالبيانات التي قمت بنشرها في موقعهم.
فكما قلت لكم سابقا هذه مجرد وجهة نظر (تقنية) فإن أصبت فمن الله وإن أخطأت فمن نفسي والشيطان ،وأتمنى من الأخوة التقنيين تصحيحي.

Updated: August 28, 2014 — 6:17 pm

فتح الصندوق لهاتف OPPO Find 7a

بسم الله الرحمن الرحيم

 

فتح الصندوق لهاتف OPPO Find 7a

 

فيديو:

 

صور:

 

المواصفات:

مقاييس أبعاد 152.6 × 75 × سماكة 9.2 mm
الوزن 170 جرام
مقاس الشاشة 5.5 أنش
درجة وضوح 1080p Full HD (1920 x 1080 pixels), 403 PPI
Screen type IPS panel by JDI, 1000:1 contrast ratio مع 16 مليون لون
Touchscreen Multi-touch, capacitive screen, Gorilla Glass 3, Touch-on-Lens Technology, support for gloved and wet touch input
Battery 2800 ملي أمبير مع تقنية الشحن السريع من OPPO باسم Rapid Charge
السعة الداخلية 16 جيجابايت مع 12 جيجابايت للمستخدم فقط
ذاكرة خارجية يدعم حتى 128 جيجابايت  microSD card
الكاميرا الخلفية 13 ميجابيكسل وفتحة العدسة  f/2.0 بمعالج Sony Exmor IMX214 BSI sensor
الكاميرا الأمامية 5.0 ميجابيكسل مع زاوية عرض 80 درجة وفتحة العدسة  f/2.0
Scene modes Normal, Super Zoom, HDR, Panorama, Beautify, Slow Shutter, Audio Photo, GIF mode, RAW mode, Smart Scene, Portrait, Landscape, Sports, Night
تصوير فيديو 4K  @ 30 fps, 1080p  @ 60 fps, 720p slow motion video @120 fps
NFC Yes
الشبكات GSM/GPRS/EDGE: 850/900/1800/1900MHz
WCDMA: 850/900/1900/2100MHz
FDD-LTE: Bands B1/3/7/20
TD-LTE: Band B40
المعالج Qualcomm Snapdragon 801 (MSM8974AB)
سرعة المعالج 2.3GHz رباعي النواة
معالج رسوميات Adreno 330
الذاكرة العشوائية 2 جيجابايت
تقنيات USB OTG, Bluetooth 4.0, 5G Wi-Fi 802.11 b/g/n, Wi-Fi Direct, Wi-Fi Display, GPS, GLONASS
الوايرلس Dual-bandمع  802.11a/ac/b/g/n
الشحن اللاسلكي لا
النظام ColorOS, based on Android 4.3

 

 

Updated: May 13, 2014 — 12:43 pm