Tag: جافا

(إعداد السيرفر المحلي WAMP و MySQL) ربط تطبيق أندرويد مع 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 لعمل قائمة المستخدمين بالتنسيق الذي نحتاجه.

 

في هذا الدرس سنقوم بتنصيب و إعداد السيرفر المحلي وبناء قاعدة البيانات.

  • الخطوة الأولى: تنصيب السيرفر المحلي WAMP Server والتأكد من عمله على LocalHost

يوجد الكثير من البرامج التي تسمح لك بإعداد سيرفر محلي خاص ولكن في هذه السلسلة سوف نستخدم WAMP بإمكانك تحميل البرنامج من خلال هذا الرابط :

http://www.wampserver.com/en

بعد تثبيت WAMP قم بتشغيل البرنامج حتى تصبح أيقونة البرنامج خضراء كما في الصورة

wamp-green

للتأكد من عمل السيرفر قم بفتح المتصفح و اكتب في شريط العنوان http://localhost

من المفترض أن تحصل على صفحة مثل هذه

localhost

لعمل مشروع جديد اذهب إلى مجلد www الموجود في C:\wamp\www أو مكان ما قمت بتنصيب السيرفر

قم بعمل مجلد جديد وقم بتسميته “android-webservices” أو أي اسم تود إختياره حيث سنقوم بوضع جميع ملفات PHP الخاصة بالمشروع في هذا المجلد.

بداخل المجلد الذي أنشأته قم بإضافة ملف نص جديد قم بتسميته “index.php

قم بفتح هذا الملف بإستخدام أي محرر نصوص تفضله أنا أستخدم NotePad++  بداخل ملف “index.php” قم بكتابة الكود التالي

<?php

echo "This is my first PHP code";

?>

 

الآن في المتصفح قم بكتابة العنوان التالي (قم بتغيير android-webservice إلى اسم المجلد الذي قمت بإنشائه)

http://localhost/android-webservice

ستظهر لك صفحة مكتوب فيها “This is my first PHP code” كما هو موجود في الصورة التالية:

php-first

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

  • الخطوة الثانية: بناء قاعدة البيانات MySQL

قم بالتوجه إلى PHPMyAdmin من خلال هذا الرابط:

http://localhost/phpmyadmin

ثم انقر على Database

phpmyadmin

في حقل 

db-name

 

الآن قم بالنقر على Databases ثم انقر على اسم قاعدة البيانات التي أنشأتها. سيتم نقلك إلى صفحة إنشاء الجداول.

في هذا المشروع سأقوم بعمل جدول واحد فقط بإسم users  يحتوي على 4 أعمدة user_id , user_username, user_password, user_displayname

قم بوضع البيانات كما في الصورة التالية:

tabel

 

table-structure

كود SQL  لقاعدة البيانات و جدول users

--
-- Database: `android_webservices`
--
CREATE DATABASE IF NOT EXISTS `android_webservices` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
USE `android_webservices`;

-- --------------------------------------------------------

--
-- Table structure for table `users`
--

CREATE TABLE IF NOT EXISTS `users` (
  `user_id` int(11) NOT NULL AUTO_INCREMENT,
  `user_username` varchar(255) NOT NULL,
  `user_password` varchar(255) NOT NULL,
  `user_displayname` varchar(255) NOT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

 

  • إعداد ملف config.php للإتصال بقاعدة البيانات:

بعد أن قمنا بإنشاء قاعدة البيانات بقي علينا كتابة أكواد PHP  لنقوم بإضافة و حذف و تعديل قاعدة البيانات ولكن بدل أن نقوم بالإتصال بقاعدة البيانات في كل ملف PHP  سنقوم بكتابة بيانات الاتصال بقاعدة البيانات في ملف واحد بإسم config.php حيث سنقوم فقط بإضافة اسم الملف فقط في بداية كل ملف PHP  نقوم بإنشائه لاحقا.

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

هذا رابط الموقع :

http://forums.devshed.com/php-faqs-stickies-167/program-basic-secure-login-system-using-php-mysql-891201.html

الآن في مجلد android-webservice الذي أنشأناه في www قم بإنشاء ملف نص جديد بإسم config.php وضع به الكود التالي:

قم بتغيير البيانات التالية بما تتناسب معك

$username = "root";&nbsp;// غالبا اسم المستخدم هو root ان قمت بتغيير الاسم فقم بوضعه هنا
$password = "";&nbsp; // ان أضفت كلمة مرور لقاعدة البيانات فضعها هنا 
$host = "localhost";&nbsp;
$dbname = "android_webservices"; // قم بتغيير قاعدة البيانات باسم قاعدة البيانات لديك

 

كود ملف confog.php

<?php 
/***
* @Source: devshed
* @author E-Oreo
* http://forums.devshed.com/php-faqs-stickies-167/program-basic-secure-login-system-using-php-mysql-891201.html
*/
    // These variables define the connection information for your MySQL database 
	$username = "root"; 
    $password = ""; 
    $host = "localhost"; 
    $dbname = "android_webservices"; 

// UTF-8 is a character encoding scheme that allows you to conveniently store 
    // a wide varienty of special characters, like ¢ or €, in your database. 
    // By passing the following $options array to the database connection code we 
    // are telling the MySQL server that we want to communicate with it using UTF-8 
    // See Wikipedia for more information on UTF-8: 
    // http://en.wikipedia.org/wiki/UTF-8 
    $options = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'); 
     
    // A try/catch statement is a common method of error handling in object oriented code. 
    // First, PHP executes the code within the try block.  If at any time it encounters an 
    // error while executing that code, it stops immediately and jumps down to the 
    // catch block.  For more detailed information on exceptions and try/catch blocks: 
    // http://us2.php.net/manual/en/language.exceptions.php 
    try 
    { 
        // This statement opens a connection to your database using the PDO library 
        // PDO is designed to provide a flexible interface between PHP and many 
        // different types of database servers.  For more information on PDO: 
        // http://us2.php.net/manual/en/class.pdo.php 
        $db = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8", $username, $password, $options); 
    } 
    catch(PDOException $ex) 
    { 
        // If an error occurs while opening a connection to your database, it will 
        // be trapped here.  The script will output an error and stop executing. 
        // Note: On a production website, you should not output $ex->getMessage(). 
        // It may provide an attacker with helpful information about your code 
        // (like your database username and password). 
        die("Failed to connect to the database: " . $ex->getMessage()); 
    } 
     
    // This statement configures PDO to throw an exception when it encounters 
    // an error.  This allows us to use try/catch blocks to trap database errors. 
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
     
    // This statement configures PDO to return database rows from your database using an associative 
    // array.  This means the array will have string indexes, where the string value 
    // represents the name of the column in your database. 
    $db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); 
     
    // This block of code is used to undo magic quotes.  Magic quotes are a terrible 
    // feature that was removed from PHP as of PHP 5.4.  However, older installations 
    // of PHP may still have magic quotes enabled and this code is necessary to 
    // prevent them from causing problems.  For more information on magic quotes: 
    // http://php.net/manual/en/security.magicquotes.php 
    if(function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) 
    { 
        function undo_magic_quotes_gpc(&$array) 
        { 
            foreach($array as &$value) 
            { 
                if(is_array($value)) 
                { 
                    undo_magic_quotes_gpc($value); 
                } 
                else 
                { 
                    $value = stripslashes($value); 
                } 
            } 
        } 
     
        undo_magic_quotes_gpc($_POST); 
        undo_magic_quotes_gpc($_GET); 
        undo_magic_quotes_gpc($_COOKIE); 
    } 
     
    // This tells the web browser that your content is encoded using UTF-8 
    // and that it should submit content back to you using UTF-8 
    header('Content-Type: text/html; charset=utf-8'); 
     
    // This initializes a session.  Sessions are used to store information about 
    // a visitor from one web page visit to the next.  Unlike a cookie, the information is 
    // stored on the server-side and cannot be modified by the visitor.  However, 
    // note that in most cases sessions do still use cookies and require the visitor 
    // to have cookies enabled.  For more information about sessions: 
    // http://us.php.net/manual/en/book.session.php 
    session_start(); 

    // Note that it is a good practice to NOT end your PHP files with a closing PHP tag. 
    // This prevents trailing newlines on the file from being included in your output, 
    // which can cause problems with redirecting users.

?>

 

قمنا الآن بإعداد قاعدة البيانات و ملف الإتصال بقاعدة البيانات. في الدروس القادمة سوف نبدأ بتطوير ال Web Services المطلوبة و سأشرح بالتفصيل الممل طريقة عملها بالإضافة الى شرح JSON.

 

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

Updated: February 4, 2015 — 5:51 am

(بناء Web Service تقوم بعمل Login و Register) ربط تطبيق أندرويد مع 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 لعمل قائمة المستخدمين بالتنسيق الذي نحتاجه.

 

 

كود register.php

<?php
/***
 * @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
 */
 
require("config.php");

// في حال عدم وجود طلب POST 
// سنقوم بعرض فورم HTML  الموجود بآخر الكود
if(!empty($_POST)){

    // تأكد من أن المستخدم قام بإدخال جميع الحقول المطلوبة 
	// username , password, displayname  هي الحقول المطلوبة لتنفيذ هذا الكودdisplayname
    if(empty($_POST['username'])||empty($_POST['password'])||empty($_POST['displayname'])){
        
		// في حال عدم تعبئة أحد الحقول سنقوم بعرض رسالة تنبيه للمستخدم
		
		//  إنشاء بعض البيانات ليتم عرضها كـ JSON Object
		/*
		* الهدف من success   
		* التأكد من أن  عملية التسجيل تمت بنجاح ام لا
		* عند الحصول على القيمة صفر ، ذلك يعني لم تتحقق جميع الشروط المطلوبة لتسجيل الدخول 
		*/
		$response["success"] = 0; 
		
	    // الرسالة التي ستظهر للمستخدم أو المطور 
		// (حيث بإمكان المطور لاحقا وضع رسالة خاصة به كل ما يحتاجه فقط قيمة success)
		
        $response["message"] = "All Fields Required";
        
        //  نقوم بإيقاف السكريبت و نطبع رسالة JSON
        /* 
		* الدالة json_encode() 
		* نقوم هذه الدالة بتحويل قيمة response 
		* إلى JSON
        */
        die(json_encode($response));
    }
	
    // في حال عدم وجود أي خطأ سنقوم بتنفيذ الأسطر التالية
    
    // نتأكد من عدم وجود اسم مستخدم آخر في قاعدة البيانات باستخدام COUNT(*)
	// إذا كانت القيمة أكثر من 0 ذلك يعني وجود مستخدم آخر بنفس الإسم
    // ":user" فقط لحجز قيمة username  وتحويلها لنص قبل تنفيذ أمر sql
	// نقوم بعمل ذلك لحماية قاعدة البيانات من SQL injections
	
    $query = "SELECT COUNT(*) AS count 
				   FROM users 
				   WHERE 
				   user_username = :user";
    
    // نقوم بتحديث قيمة :user 
    $query_params = array(
        ':user' => $_POST['username']
    ); 
    
    
    
    // الآن نقوم بتنقيذ أمر SQL
    try{
        // يقوم هذا السطر بإعداد أمر SQL
        $stmt = $db->prepare($query);
		// يقوم هذا السطر بتنفيذ أمر SQL مع المتغيرات التي قمنا بإدخالها
        $result = $stmt->execute($query_params);
		
		// نقوم  الآن بحساب ناتج قيمة count 
		// PDO::FETCH_ASSOC
		// تقوم بإرجاع كل صف ناتج من الأمر كمصفوفة [column] => value
		while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
		$username_count = $row["count"];
		//print_r($row);
		}
			// الآن نتأكد ان كانت قيمة username_count
			// إذا كانت أكبر من 0  ذلك يعني وجود اسم مستخدم مسجل في قاعدة البيانات 
			if ($username_count > 0) {
			
				// نقوم بإعداد بيانات JSON 
				// ورسالة للمستخدم بإن اسم المستخدم متاح مسبقا
				$response["success"] = 0;
				$response["message"] = "That username is already taken. Please try again.";
				
				// نقوم بإيقاف السكريبت و نطبع رسالة JSON
				die(json_encode($response));
				
		}

		
    }catch(PDOException $ex){
        
		// في حال وجود خلل في من قاعدة البيانات 
		// نقوم باعداد بيانات JSON
		// ونعرض رسالة تنبيه للمستخدم
        $response["success"] = 0;
        $response["message"] = "Something went wrong. Please try again later";

		// نقوم بإيقاف السكريبت و نطبع رسالة JSON
        die(json_encode($response));
        
    }
   
	// إذا لم يحصل أي خلل حتى هذا السطر 
	// هذا يعني أنه بإمكانه إدخال بيانات المستخدم في قاعدة البيانات
	
    // الآن نقوم بإعداد أمر SQL  لإدخال بيانات المستخدم في قاعدة البيانات
	// :user, :pass نستخدم نفس الطريقة التي شرحتها بالأعلى لإدخال البيانات في قاعدة البيانات
    $query = "INSERT INTO 
					users (user_username, user_password, user_displayname) 
					VALUES 
					(:user, :pass, :displayname)";
    
    // نقوم بتشفير كلمة المرور 
    $encr_user_pass = md5($_POST['password']);
    
    
    // نقوم بتحديث قيمة المتغيرات :user, :pass ,:displayname
    $query_params = array(
        ':user' => $_POST['username'],
		// :pass قمنا بتحديثه بكلمة المرور المشفرة 
        ':pass' =>  $encr_user_pass,
		':displayname' => $_POST['displayname']
    );
    
    // نقوم بتنفيذ أمر SQL لإدخال اسم المستخدم و كلمة المرور في قاعدة البيانات 
    try {
        $stmt = $db->prepare($query);
        $result = $stmt->execute($query_params);
               
    } catch (PDOException $ex) {
       // في حال وجود خلل في من قاعدة البيانات 
		// نقوم باعداد بيانات JSON
		// ونعرض رسالة تنبيه للمستخدم
		
        $response["success"] = 0;
        $response["message"] = "The username is already in use, please try again later!";
		
		// نقوم بإيقاف السكريبت و نطبع رسالة JSON
        die(json_encode($response));
    }
	
	/*
	* إذا وصلنا إلى هذه السطر بدون أي مشاكل 
	* هذا يعني أنه تم ادخال اسم المسخدم وكلمة المرور بقاعدة البيانات بنجاح 
	*/
    
	// أخيرا سنقوم بتغيير قيمة success = 1
	// و رسالة تفيد بأنه تم ادخال البيانات بنجاح
    $response["success"] = 1;
    $response["message"] = "Username Successfully Added";
	
	// و أخيرا نعرض رسالة JSON  للمستخدم
    echo json_encode($response);
        
}else{
    ?>

<h1>Register</h1>
<form action="register.php" method="post">
    Username: <br/>
    <input type="text" name="username" placeholder="Username"/><br/>
    Password: <br/>
    <input name="password" type="password" placeholder="Password"/><br/>
    Display Name: <br/>
    <input type="text" name="displayname" placeholder="Display Name"/><br/>
    <input type="submit" value="Register User"/>
</form>
<?php
}

?>

 

كود login.php

<?php
/***
 * @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
 */
 
require('config.php');

// في حال عدم وجود طلب POST 
// سنقوم بعرض فورم HTML  الموجود بآخر الكود
if(!empty($_POST)){
    
	// تأكد من أن المستخدم قام بإدخال جميع الحقول المطلوبة 
	// username , password  هي الحقول المطلوبة لتنفيذ هذا الكود
    if(empty($_POST['username'])||empty($_POST['password'])){
	// في حال عدم تعبئة أحد الحقول سنقوم بعرض رسالة تنبيه للمستخدم
		
		//  إنشاء بعض البيانات ليتم عرضها كـ JSON Object
		/*
		* الهدف من success   
		* التأكد من أن  عملية التسجيل تمت بنجاح ام لا
		* عند الحصول على القيمة صفر ، ذلك يعني لم تتحقق جميع الشروط المطلوبة لتسجيل الدخول 
		*/
		
        $response["success"] = 0;
		
	    // الرسالة التي ستظهر للمستخدم أو المطور 
		// (حيث بإمكان المطور لاحقا وضع رسالة خاصة به كل ما يحتاجه فقط قيمة success)
		
        $response["message"] = "All Fields Required";
		
		//  نقوم بإيقاف السكريبت و نطبع رسالة JSON
        /* 
		* الدالة json_encode() 
		* نقوم هذه الدالة بتحويل قيمة response 
		* إلى JSON
        */
        die(json_encode($response));
    }
	
	 // في حال عدم وجود أي خطأ سنقوم بتنفيذ الأسطر التالية
    
    // نقوم بكتابة أمر SQL للتأكد من وجود اسم المستخدم
    // ":user" فقط لحجز قيمة username  وتحويلها لنص قبل تنفيذ أمر sql
	// نقوم بعمل ذلك لحماية قاعدة البيانات من SQL injections
    
    $query = "
            SELECT * FROM `users` 
            WHERE
            user_username = :user
             ";
			 
	// نقوم بتحديث قيمة :user
    $query_params = array(
        ':user' => $_POST['username']
    );
	
	// الآن نقوم بتنقيذ أمر SQL
    try {
		// يقوم هذا السطر بإعداد أمر SQL
        $stmt = $db->prepare($query);
		
		// يقوم هذا السطر بتنفيذ أمر SQL مع المتغيرات التي قمنا بإدخالها
        $result = $stmt->execute($query_params);
    } catch (PDOException $ex) {
	
		// في حال وجود خلل في من قاعدة البيانات 
		// نقوم باعداد بيانات JSON
		// ونعرض رسالة تنبيه للمستخدم		
        $response['success'] = 0 ;
        $response['message'] = "Database Error1, Please try Again";
        die(json_encode($response));
    }
	
	/*
	* إذا لم يحصل أي خلل حتى هذا السطر 
	* ذلك يعني ان اسم المستخدم موجود في قاعدة البيانات
	*/
	
	// الآن علينا التأكد من كلمة المرور
	
	// أولا سنقوم بكتابة متغير is_login ليكون قيمته false 
	$is_login = false;
    
	// سنقوم بتشفير الباسوود المدخل بنفس طريقة التشفير المستخدمة في register.php
    $encr_user_pass = md5($_POST['password']);
    
	// سنقوم بجلب جميع الصفوف الناتجة من أمر SQL
	// في هذه الحالة سيكون  هناك صف واحد فقط لأنه لن يكون هناك اسم مستخدم مكرر
	$row = $stmt->fetch();
	
	// في حال وجود صفوف ناتجة من أمر SQL
    if ($row){
        // نقوم بمقارنة كلمة المرور المشفرة مع كلمة المرور الموجودة في قاعدة البيانات
        if($encr_user_pass === $row['user_password']){
			// في حال تطابق كلمة المرور
			// سنقوم بتغيير قيمة is_login الى true
            $is_login = true;
        }
    }
    

	/*
	* أخيرا إن كانت قيمة is_login = true
	* فهذا يعني أن اسم المستخدم و كلمة المرور صحيحة 
	* 
	*  غير ذلك فسنعرض رسالة خطأ للمستخدم
	*/
    if($is_login){
		// في حال تم تحقيق الشرط 
		// سنقوم بتغيير  success = 1
		// و رسالة تفيد بأنه تسجيل الدخول بنجاح
        $response["success"] = 1;
        $response["message"] = "Login Successful";
	
	// و أخيرا نعرض رسالة JSON  للمستخدم
        die(json_encode($response));
    }else{
		// في حال تم تحقيق الشرط 
		// سنقوم بتغيير  success = 0
		// و رسالة بأن اسم المستخدم أو كلمة المرور خاطئة
        $response["success"] = 0;
        $response["message"] = "username or password Incorrect";
		// و أخيرا نعرض رسالة JSON  للمستخدم
        die(json_encode($response));
    }
    
}else{
?>
<h1>Login</h1>
<form action="login.php" method="post">
    Username: <br/>
    <input type="text" name="username" placeholder="Username"/><br/>
    Password:<br/>
    <input type="password" name="password" placeholder="Password"/><br/>
    <input type="submit" value="Login"/>
    <a href="register.php">Register</a>
</form>
<?php
}
?>

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

Updated: February 4, 2015 — 5:52 am

(بناء Web Service تقوم بجلب بيانات المستخدمين) ربط تطبيق أندرويد مع 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 لعمل قائمة المستخدمين بالتنسيق الذي نحتاجه.

 

 

كود users.php

<?php
/***
 * @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
 */
 
require("config.php");

// نقوم بكتابة أمر لجلب جميع الحقول الموجودة في جدول users
$query = "SELECT * FROM users";

//  نقوم بتنفيذ أمر SQL
try {
    $stmt = $db->prepare($query);
    $result = @$stmt->execute($query_params);
} catch (PDOException $ex) {
	// في حال وجود خلل في من قاعدة البيانات 
	// نقوم باعداد بيانات JSON
	// ونعرض رسالة تنبيه للمستخدم		
    $response["success"] = 0;
    $response["message"] = "Database Error";
}

// سنقوم بجلب جميع الصفوف الناتجة من أمر SQL
$rows = $stmt->fetchAll();

// في حال وجود صفوف ناتجة من أمر SQL
if ($rows){
	//  في حال وجود صفوف ناتجة من أمر SQL
	// نقوم بتعبئة بيانات JSON
	// بداية بوضع قيمة success = 1 
	// ونضع رسالة في message
    $response["success"] = 1;
    $response["message"] = "Users Available";
	
	/*******************************************************************************
	 * بما أننا سنقوم بجلب جميع بيانات المستخديم في جدول users
	 * فذلك يعني أننا سنستخدم JSON Array
	 * حيث أن كل مصفوفة تحتوي على بيانات مستخدم واحد مثل id , username , displayname
	 * لذلك سنقوم بوضع users كاسم للمصفوفة 
	 * وبداخل كل مصفوفة سنقوم بوضع بيانات كل مستخدم 
	 *****************************************************************************/
	
	// أولا سنقوم بتسمية المصفوفة users 
    $response["users"] = array();
    
	// بعد ذلك سنقوم بعملية تكرار في قاعدة البيانات لجلب بيانات المستخدم التالية
	// user_id	-  user_username	-  user_displayname	
    foreach ($rows as $row){
		// أولا سنقوم بدمج جميع هذه البيانات  في مصفوفة فرعية بمتغير باسم single_user
        $single_user = array();
		
		// ثم لكل key في single_user
		// سنقوم بوضع value خاصة بها في قاعدة البيانات
		// لتظهر لاحقا في JSON بهذا الشكل 
		
        $single_user["id"] = $row["user_id"];
        $single_user["username"] = $row["user_username"];
        $single_user["displayname"] = $row["user_displayname"];
        
        // أخيرا سنقوم بدمج مصفوفة $single_user مع مصفوفة $response["users"]
		array_push($response["users"], $single_user);
    }
    
    // و أخيرا نعرض رسالة JSON  للمستخدم
    echo json_encode($response);
}else{
		// في حال عدم وجود مستخدمين في قاعدة البيانات 
		// سنقوم بتغيير  success = 0
		// و رسالة للمستخدم بعدم وجود مستخدمين 
    $response["success"] = 0;
    $response["message"] = "No Users Available";
	
	// و أخيرا نعرض رسالة JSON  للمستخدم
    die(json_encode($response));
}
?>

 

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

Updated: February 4, 2015 — 5:52 am

(إعداد واجهة تطبيق الأندرويد) ربط تطبيق أندرويد مع 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 لعمل قائمة المستخدمين بالتنسيق الذي نحتاجه.

 

 

AndroidManifest.xml

لا تنسى تغيير اسم الباكج
package=”com.ahmaadssb.androidwebservices”

<?xml version="1.0" encoding="utf-8"?>
<!-- 

 @author Ahmadssb
 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"
 -->

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    
    package="com.ahmaadssb.androidwebservices"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />

 <uses-permission android:name="android.permission.INTERNET"></uses-permission>
 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
 
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        
        <activity android:label="Register Activity" android:name=".RegisterActivity"></activity>
        
        <activity android:label="Users Activity" android:name=".UsersActivity"></activity>
    </application>

</manifest>

 

activity_main.xml

<!-- 

 @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

 -->

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/LinearLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.ahmaadssb.androidwebservices.MainActivity" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="إسم المستخدم"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <EditText
        android:id="@+id/edtUsername"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center"
        android:ems="10" >

        <requestFocus />
    </EditText>

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="كلمة المرور"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <EditText
        android:id="@+id/edtPassword"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center"
        android:ems="10"
        android:inputType="textPassword" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center" >

        <Button
            android:id="@+id/btnLogin"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="0.5"
            android:text="تسجيل الدخول" />

        <Button
            android:id="@+id/btnRegisterUser"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="0.5"
            android:text="مستخدم جديد" />

    </LinearLayout>

</LinearLayout>

 

register_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- 

 @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

 -->

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textView1"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="اسم المستخدم"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <EditText
        android:id="@+id/edtRegisterUserName"
        android:layout_gravity="center"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10" >

        <requestFocus />
    </EditText>

    <TextView
        android:id="@+id/textView2"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="الإسم الكامل"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <EditText
        android:id="@+id/edtRegisterDisplayName"
        android:layout_gravity="center"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10" />

    <TextView
        android:id="@+id/textView3"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="كلمة المرور"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <EditText
        android:id="@+id/edtRegisterPassword"
        android:layout_gravity="center"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="textPassword" />

    <Button
        android:id="@+id/btnRegister"
        android:layout_gravity="center"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="تسجيل" />

</LinearLayout>

 

users_layout.xml

 

<?xml version="1.0" encoding="utf-8"?>
<!-- 

 @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

 -->

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ListView>

</LinearLayout>

 

single_user_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- 

 @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

 -->

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <ImageView
            android:id="@+id/imageView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="5dp"
            android:src="@drawable/ic_launcher" />

        <android.support.v7.widget.Space
            android:id="@+id/space1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="0.1"
            android:orientation="vertical" >

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content" >

                <TextView
                    android:id="@+id/txtID"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Large "
                    android:textAppearance="?android:attr/textAppearanceLarge" />

                <android.support.v7.widget.Space
                    android:id="@+id/space2"
                    android:layout_width="5dp"
                    android:layout_height="wrap_content" />

                <TextView
                    android:id="@+id/txtUsername"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="0.6"
                    android:text="Large"
                    android:textAppearance="?android:attr/textAppearanceLarge" />

            </LinearLayout>

            <TextView
                android:id="@+id/txtDisplayName"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:layout_gravity="center"
                android:text="Large "
                android:textAppearance="?android:attr/textAppearanceLarge" />

        </LinearLayout>

    </LinearLayout>

</LinearLayout>

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

Updated: February 4, 2015 — 5:52 am

(تطوير كلاسات 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