ارسال الاشعارات لاجهزة متعددة GCM – Android – PHP – MySQL

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

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

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

# معاينة لدرس اليوم :

# كيف سوف تتم العملية :

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

# متطلبات قبل البدأ :

بعد قرائتك للدرس الأول, يجب أن تخرج بنتيجة وهي :
Project Number + API Server Key
ولا تنسى من الدرس الثاني معرفة ما لدينا من اكتفتي ولياوت.

# الاكتفتي واللياوت التي سوف ننشأها هذا الدرس كما السابق :

=== Package ===
– com.andrody.testandrody
—— Home_Activity.java
—— Main_Activity.java
– com.andrody.testgcm
—— Gcm_Application_Constants.java
—— Gcm_Broadcast_Receiver.java
—— Gcm_Notification_Intent_Service.java
—— Utility.java
=== Layout ===
– home.xml
– main.xml

# ما يتطلب عمله لإكمال الدرس :

* تطبيق ويب / GCM – PHP – MySQL Db.
* تطبيق اندرويد / Android – java .

# تجهيز تطبيق الويب :

– تطبيق الويب, وهو إنشاء ملفات داخل السيرفر – الاستضافة – وإنشاء قاعدة بيانات وربطها بهذه الملفات, ولمن لا يملك استضافة يستطيع الاستعانة بالاستضافة المحلية, يمكنه البحث عنها في جوجل وتركيبها في جهازه للتجربة. والسيرفر الداخلي مهم ومعظم مبرمجي المواقع يستخدمونه لقراءة الملفات البرمجية.

عموماً كما في الدرس السابق:
|*| نقوم بإنشاء قاعدة بيانات, وقمت بتسميتها andrody , وننشأ داخلها جدول بإسم gcmusers وداخل هذا الجدول نقوم بإنشاء ثلاثة حقول, id – emailid – gcmregid . ولكي يسهل عليك الأمر فقط انشأ قاعدة البيانات واضغط على خيار SQL Query box وضع فيه الامر التالي للإنشاء التلقائي لما ذكرت سابقاً :

CREATE TABLE IF NOT EXISTS `gcmusers` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `emailid` varchar(50) NOT NULL,
  `gcmregid` varchar(500) NOT NULL,
  PRIMARY KEY (`id`)
)

|*| نقوم بإنشاء مجلد داخل السيرفر بإسم gcm . ونقوم بوضع فيه الملفات التالية :

db_connect.php
لا تنسى بإن تقوم بتغيير معلومات الاتصال بالقاعدة كما لديك في السيرفر

<?php
 
class DB_Connect {
 
    // constructor
    function __construct() {
 
    }
 
    // destructor
    function __destruct() {
        // $this->close();
    }
 
    // Connecting to database
    public function connect() {
        define("DB_HOST", "localhost");
        define("DB_USER", "root"); // اسم المستخدم لقاعدة البيانات
        define("DB_PASSWORD", "13241324"); // كلمة المرور لقاعدة البيانات
        define("DB_DATABASE", "andrody"); // اسم قاعدة البيانات
        // connecting to mysql
        $con = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD);
        // selecting database
        mysql_select_db(DB_DATABASE);
 
        // return database handler
        return $con;
    }
 
    // Closing database connection
    public function close() {
        mysql_close();
    }
 
} 
?>

db_functions.php

<?php
 
class DB_Functions {
 
    private $db;
 
    function __construct() {
        include_once './db_connect.php';
        // Connect to database
        $this->db = new DB_Connect();
        $this->db->connect();
    }
    // destructor
    function __destruct() {
 
    }
    /**
     * Insert new user
     * 
     */
    public function insertUser($emailId, $gcmRegId) {
        // Insert user into database
        $result = mysql_query("INSERT INTO gcmusers (emailid,gcmregid) VALUES('$emailId','$gcmRegId')");        
        if ($result) {
            return true;
        } else {             
            return false;                      
        }
    }
    /**
     * Select all user
     * 
     */
     public function getAllUsers() {
        $result = mysql_query("select * FROM gcmusers");
        return $result;
    }
    /**
     * Get GCMRegId
     * 
     */
    public function getGCMRegID($emailID){
         $result = mysql_query("SELECT gcmregid FROM gcmusers WHERE emailid = "."'$emailID'");
         return $result;
    }
}
?>

insertuser.php

<?php
include_once './db_functions.php';
//Create Object for DB_Functions clas
$db = new DB_Functions(); 
$emailID = $_POST["emailId"];
$regId = $_POST["regId"];
$res = $db->insertUser($emailID, $regId);
echo "Email Id ".$emailID." RegId ".$regId ;
if ($res) {
    echo "GCM Reg Id bas been shared successfully with Server";
} else {             
    echo "Error occured while sharing GCM Reg Id with Server web app";                      
}
?>

processmessage.php
لا تنسى بتغيير API Server Key كما لديك في مشروعك في جوجل

<?php
	//Generic php function to send GCM push notification
   function sendPushNotificationToGCM($registation_ids, $message) {
		//Google cloud messaging GCM-API url
        $url = 'https://android.googleapis.com/gcm/send';
        $fields = array(
            'registration_ids' => $registation_ids,
            'data' => $message,
        );
		// Update your Google Cloud Messaging API Key
		if (!defined('GOOGLE_API_KEY')) {
			define("GOOGLE_API_KEY", "API Server Key"); 		
		}
        $headers = array(
            'Authorization: key=' . GOOGLE_API_KEY,
            'Content-Type: application/json'
        );
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);	
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
        $result = curl_exec($ch);				
        if ($result === FALSE) {
            die('Curl failed: ' . curl_error($ch));
        }
        curl_close($ch);
        return $result;
    }
?>
<?php
 include_once 'db_functions.php';
    $db = new DB_Functions();
  $selUsers = $_POST['sendmsg'];
  if(empty($selUsers))
  {
    echo("You didn't select any users.");
  }
  else
  {
	$resp = "<tr id='header'><td>GCM Response [".date("h:i:sa")."]</td></tr>";
    $userCount = count($selUsers);
	$greetMsg = $_POST['message'];
	$respJson = $greetMsg;
	$registation_ids = array();
	for($i=0; $i < $userCount; $i++)
    {
	    $gcmRegId = $db->getGCMRegID($selUsers[$i]);
		$row = mysql_fetch_assoc($gcmRegId);
		//Add RegIds retrieved from DB to $registration_ids
		array_push($registation_ids, $row['gcmregid']);
    }
	// JSON Msg to be transmitted to selected Users
	$message = array("m" => $respJson);
	$pushsts = sendPushNotificationToGCM($registation_ids, $message);
	$resp = $resp."<tr><td>".$pushsts."</td></tr>";
	echo "<table>".$resp."</table>";
  }

?>

send.php

<html>
<head><title>ارسال اشعارات للمستخدمين</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<style>
body {
  font: normal medium/1.4 sans-serif;
}
div.greetblock, div.serverresponse {
  border-collapse: collapse;
  width: 100%;
  margin-left: auto;
  margin-right: auto;
  align: center;
}
tr > td {
  padding: 0.25rem;
  text-align: center;
  border: 1px solid #ccc;
}
tr:nth-child(even) {
  background: #fff;
 
}
tr:nth-child(odd) {
  background: #37B8EB;
  color: #fff;
}
tr#header{
background: #37B8EB;
}
 
div#norecord{
margin-top:10px;
width: 15%;
margin-left: auto;
margin-right: auto;
}
input,select{
cursor: pointer;
}
img{
margin-top: 10px;
height: 200px;
width: 300px;
}
select{
width: 200px
}
div.leftdiv{
width: 45%;
padding: 0 10px;
float: left;
border: 1px solid #ccc;
margin: 5px;
height: 320px;
text-align:center;
}
div.rightdiv{
width: 45%;
padding: 0 10px;
float: right;
border: 1px solid #ccc;
margin: 5px;
height: 320px;
text-align:center;
}
hidediv{
display: none;
}
p.header{
height: 40px;
background-color: #37B8EB;
color: #fff;
text-align:center;
margin: 0;
margin-bottom: 10px;
}
textarea{
font-size: 25px;
font-weight: bold;
border: 2px solid #37B8EB;
margin-bottom: 10px;			
text-align: center;
padding: 10px;
}
button{
			background-color: #37B8EB;
			border: 5px solid #37B8EB;
			padding: 10px;
			cursor: pointer;
			color: #fff;
			font-weight: bold;
			}

</style>
<script>
function sendMsg(){
var msgLength = $.trim($("textarea").val()).length;
var checkedCB = $("input[type='checkbox']:checked").length;
if( checkedCB == 0){
    alert("يجب عليك اختار جهاز واحد على الأقل لارسال له الرسالة");
}else if(msgLength == 0){
    alert("الرجاء كتابة رسالة لارسالها, حقل الرسالة فارغ");
}else{
    var formData = $(".wrapper").find("input").serialize() + "&imgurl="+ $("#festival").val() + "&message=" + $("textarea").val();    
    $.ajax({type: "POST",data: formData, url: "processmessage.php", success:function(res){
        $(".greetblock").slideUp(1000);
        $(".serverresponse").prepend(res).hide().fadeIn(2000);
    }});
}
}
$(function(){
    $(".serverresponse").hide()
    $("input[type='checkbox']").click(function(){
        if($(this).is(':checked')){
            $(this).parent().css("border","3px solid #008800");
        }else{
            $(this).parent().css("border","0px");
        }
    });
 
    $("div.leftdiv, div.rightdiv").hover(function(){
        $(this).css("background","#FAFAFA");
    },function(){
        $(this).css("background","#fff");
    });
 
    $("#festival").change(function(){
        $("img").attr("src",$(this).val());
    });
 
    $("#sendmsg").click(function(){
        $(".serverresponse").fadeOut(300,function(){
            $(".greetblock").fadeIn(1000);
        });        
    });
});
</script>
</head>
<body>
<?php
    include_once 'db_functions.php';
    $db = new DB_Functions();
    $users = $db->getAllUsers();
    if ($users != false)
        $no_of_users = mysql_num_rows($users);
    else
        $no_of_users = 0;    
?>
<?php
    if ($no_of_users > 0) {
?>
 
<div class="greetblock">
<table border="1" width="100%" cellspacing="0" cellpadding="0">
	<tr>
		<td bgcolor="#FFFFFF" align="center" valign="top"><font color="#37B8EB"><b>تحديد لمن تريد ارسال الرسالة </b></font>
<table width="100%">
<tr id="header"><td>الآي دي</td><td>الايميل</td><td>اختار</td></tr>
<?php
    while ($row = mysql_fetch_array($users)) {
?> 
<tr>
<td><span><?php echo $row["id"] ?></span></td>
<td><span><?php echo $row["emailid"] ?></span></td>
<td><span class="wrapper"><input type="checkbox" name="sendmsg[]" value="<?php echo $row["emailid"] ?>"/></span></td>
</tr>
<?php } ?>
</table>
		<p><b><font color="#37B8EB">BY: </font><a href="https://andrody.com/">
		<font color="#37B8EB">AndRody.com</font></a></b></td><p>
		<td bgcolor="#FFFFFF"><p align="center">

		<b><font size="5" color="#37B8EB">Test GCM - AndRoid - PHP - MySQL</font></b></p>
		<p>

		<textarea cols="45" rows="5" value="txtarea" placeholder="اكتب هنا رسالتك"></textarea></p>

		<p>
<button onclick="sendMsg()">ارسال الرسالة</button></p>
</td>
	</tr>
</table>
</div>
<div class="serverresponse hidediv">
<center><button id="sendmsg">ارسال مرة اخرى</button></center>
</div>
<?php }else{ ?>
<div id="norecord">
<font color="#37B8EB"><b>لا يوجد تسجيلات حتى الآن </b></font>
</div>
<?php } ?>
 
</body>
</html>

ملاحظة : ملف send.php هو الرئيسية التي سوف تفتحها لارسال اشعارات الى المستخدمين + تستطيع تغير اسم الملف دون مشاكل.
** من لديه خبرة بـ php يستطيع دمج الملفات السابقة كلها في ملف واحد 🙂

# تجهيز تطبيق الاندرويد :

بالنسبة لـ اللياوت كما في الدرس السابق تماماً, ولا شك تستطيع تصميم التطبيق كما يحلو لك, فقط هذه عينة سريعة فالغرض برمجياً. ولا تنسى المعرفات المرتبطات بالاكتفتي إذا غيرت التصميم ~

Layout :

main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#ff8b0000"
    android:gravity="center"
    android:orientation="vertical"
    android:padding="15dp"
    tools:context=".Main_Activity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="40dp"
        android:text="Test GCM App"
        android:textColor="#fff"
        android:textSize="35sp"
        android:textStyle="bold" />


    <EditText
        android:id="@+id/email"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="#ffff00"
        android:hint="Your Email"
        android:padding="15dp"
        android:singleLine="true"
        android:textColor="#FF0000" />

    <Button
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="25dp"
        android:background="#fdfdfd"
        android:onClick="RegisterUser"
        android:text="Register"
        android:textColor="#000"
        android:textSize="20sp" />
</LinearLayout>

home.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_centerInParent="true"
    android:background="#ff8b0000"
    android:gravity="center"
    android:orientation="vertical"
    android:padding="15dp"
    tools:context=".Home_Activity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="40dp"
        android:text="Welcome My Friend"
        android:textColor="#fff"
        android:textSize="25sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/message"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:background="#fff"
        android:hint="سوف تظهر هنا الرسالة التي سوف يتم ارسالها المبرمج من السيرفر"
        android:padding="10dp"
        android:textColor="#000"
        android:textSize="20dp" />

</LinearLayout>

Activities :

Main_Activity.java
رسائل التوست هنا الكثيرة تستطيع الاستغناء عن معظمها كما إنك تستطيع اختصار الكود أكثر

package com.andrody.testandrody;


import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import com.andrody.testgcm.Gcm_Application_Constants;
import com.andrody.testgcm.Utility;
import com.google.android.gms.gcm.GoogleCloudMessaging;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;

import java.io.IOException;

public class Main_Activity extends Activity {
    ProgressDialog prgDialog;
    RequestParams params = new RequestParams();
    GoogleCloudMessaging gcmObj;
    Context applicationContext;
    String regId = "";

    public static final String REG_ID = "regId";
    public static final String EMAIL_ID = "eMailId";
    EditText enter_email; // الحقل النصي الذي سوف يقوم المستخدم بإدخال ايميله داخله

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        applicationContext = getApplicationContext();
        enter_email = (EditText) findViewById(R.id.email);

        prgDialog = new ProgressDialog(this);
        // Set Progress Dialog Text
        prgDialog.setMessage("جاري التسجيل.."); // نص يعرض بعد ادخال ايميل بشكل سليم ووجود خدمات جوجل بلاي بالجهاز
        // Set Cancelable as False
        prgDialog.setCancelable(false);

        SharedPreferences prefs = getSharedPreferences("UserDetails",
                Context.MODE_PRIVATE);
        String registrationId = prefs.getString(REG_ID, "");

        if (!TextUtils.isEmpty(registrationId)) {
            Intent i = new Intent(applicationContext, Home_Activity.class);
            i.putExtra("regId", registrationId);
            startActivity(i);
            finish();
        }

    }

   // الدالة التي تحدث بعد الضغط على زر التسجيل
    public void RegisterUser(View view) {
        String emailID = enter_email.getText().toString(); // سترنج الايميل الذي تم ادخاله

        if (!TextUtils.isEmpty(emailID) && Utility.validate(emailID)) {

                registerInBackground(emailID);

        }
        // إذا كان الايميل خاطئ
        else {
            Toast.makeText(applicationContext, "من فضلك قم بإدخال بريدك الالكتروني بشكل صحيح",
                    Toast.LENGTH_LONG).show();
        }
    }

    // AsyncTask to register Device in GCM Server
    private void registerInBackground(final String emailID) {
        new AsyncTask<Void, Void, String>() {
            @Override
            protected String doInBackground(Void... params) {
                String msg = "";
                try {
                    if (gcmObj == null) {
                        gcmObj = GoogleCloudMessaging
                                .getInstance(applicationContext);
                    }
                    regId = gcmObj
                            .register(Gcm_Application_Constants.GOOGLE_PROJ_ID);
                    msg = "Registration ID :" + regId;

                } catch (IOException ex) {
                    msg = "Error :" + ex.getMessage();
                }
                return msg;
            }

            @Override
            protected void onPostExecute(String msg) {
                if (!TextUtils.isEmpty(regId)) {
                    storeRegIdinSharedPref(applicationContext, regId, emailID);
                    Toast.makeText(
                            applicationContext,
                            "Registered with GCM Server successfully.\n\n"
                                    + msg, Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(
                            applicationContext,
                            "Reg ID Creation Failed.\n\nEither you haven't enabled Internet or GCM server is busy right now. Make sure you enabled Internet and try registering again after some time."
                                    + msg, Toast.LENGTH_LONG).show();
                }
            }
        }.execute(null, null, null);
    }

    // Store RegId and Email entered by User in SharedPref
    private void storeRegIdinSharedPref(Context context, String regId,
                                        String emailID) {
        SharedPreferences prefs = getSharedPreferences("UserDetails",
                Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = prefs.edit();
        editor.putString(REG_ID, regId);
        editor.putString(EMAIL_ID, emailID);
        editor.commit();
        storeRegIdinServer(regId, emailID);

    }

    // Share RegID and Email ID with GCM Server Application (Php)
    private void storeRegIdinServer(String regId2, String emailID) {
        prgDialog.show();
        params.put("emailId", emailID);
        params.put("regId", regId);
        System.out.println("Email id = " + emailID + " Reg Id = " + regId);
        // Make RESTful webservice call using AsyncHttpClient object
        AsyncHttpClient client = new AsyncHttpClient();
        client.post(Gcm_Application_Constants.APP_SERVER_URL, params,
                new AsyncHttpResponseHandler() {
                    // When the response returned by REST has Http
                    // response code '200'
                    @Override
                    public void onSuccess(String response) {
                        // Hide Progress Dialog
                        prgDialog.hide();
                        if (prgDialog != null) {
                            prgDialog.dismiss();
                        }
                        Toast.makeText(applicationContext,
                                "Reg Id shared successfully with Web App ",
                                Toast.LENGTH_LONG).show();
                        Intent i = new Intent(applicationContext,
                                Home_Activity.class);
                        i.putExtra("regId", regId);
                        startActivity(i);
                        finish();
                    }

                    // When the response returned by REST has Http
                    // response code other than '200' such as '404',
                    // '500' or '403' etc
                    @Override
                    public void onFailure(int statusCode, Throwable error,
                                          String content) {
                        // Hide Progress Dialog
                        prgDialog.hide();
                        if (prgDialog != null) {
                            prgDialog.dismiss();
                        }
                        // When Http response code is '404'
                        if (statusCode == 404) {
                            Toast.makeText(applicationContext,
                                    "Requested resource not found",
                                    Toast.LENGTH_LONG).show();
                        }
                        // When Http response code is '500'
                        else if (statusCode == 500) {
                            Toast.makeText(applicationContext,
                                    "Something went wrong at server end",
                                    Toast.LENGTH_LONG).show();
                        }
                        // When Http response code other than 404, 500
                        else {
                            Toast.makeText(
                                    applicationContext,
                                    "Unexpected Error occcured! [Most common Error: Device might "
                                            + "not be connected to Internet or remote server is not up and running], check for other errors as well",
                                    Toast.LENGTH_LONG).show();
                        }
                    }
                });
    }

}

Home_Activity.java

package com.andrody.testandrody;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

/**
 * Created by Abboudi_Aliwi on 13/05/2015.
 */
public class Home_Activity extends Activity {
    TextView view_msg;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.home);

        view_msg = (TextView) findViewById(R.id.message);
    }
    public void onResume()
    {
        super.onResume();
        String str = getIntent().getStringExtra("msg"); // سترنج فيه رسالة المسج التي أتت من السيرفر
        if (str != null) {
            view_msg.setText(str); // وضع رسالة المسج داخل الفيو مسج والذي هو النص المعروض للمستخدم
        }
    }
}

Gcm_Application_Constants.java
لا تنسى بتغيير رقم المشروع هنا والرابط كذلك حسب ما موجود لديك

package com.andrody.testgcm;

/**
 * Created by Abboudi_Aliwi on 13/05/2015.
 */
public interface Gcm_Application_Constants {
    // رابط صفحة الربط مع السيرفر لتسجيل الاي دي
    static final String APP_SERVER_URL = "http://192.168.1.10/gcm/insertuser.php"; // غير الرابط حسب الموجود لديك

    // رقم المشروع على جوجل
    static final String GOOGLE_PROJ_ID = "71439801010"; // غير الرقم إلى رقم المشروع الذي أنشتئه
    // الرسالة التي تأتي من السيرفر
    static final String MSG_KEY = "m"; //

}

Gcm_Broadcast_Receiver.java

package com.andrody.testgcm;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.WakefulBroadcastReceiver;

/**
 * Created by Abboudi_Aliwi on 13/05/2015.
 */
public class Gcm_Broadcast_Receiver extends WakefulBroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // Explicitly specify that GcmIntentService will handle the intent.
        ComponentName comp = new ComponentName(context.getPackageName(),
                Gcm_Notification_Intent_Service.class.getName());
        // Start the service, keeping the device awake while it is launching.
        startWakefulService(context, (intent.setComponent(comp)));
        setResultCode(Activity.RESULT_OK);
    }

}

Gcm_Notification_Intent_Service.java

package com.andrody.testgcm;

import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;

import com.andrody.testandrody.Home_Activity;
import com.andrody.testandrody.R;
import com.google.android.gms.gcm.GoogleCloudMessaging;

/**
 * Created by Abboudi_Aliwi on 13/05/2015.
 */
public class Gcm_Notification_Intent_Service extends IntentService {
    // Sets an ID for the notification, so it can be updated
    public static final int notifyID = 9001;

    public Gcm_Notification_Intent_Service() {
        super("GcmIntentService");
    }


    @Override
    protected void onHandleIntent(Intent intent) {
        Bundle extras = intent.getExtras();
        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);

        String messageType = gcm.getMessageType(intent);

        if (!extras.isEmpty()) {
            if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR
                    .equals(messageType)) {
                sendNotification("Send error: " + extras.toString());
            } else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED
                    .equals(messageType)) {
                sendNotification("Deleted messages on server: "
                        + extras.toString());
            } else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE
                    .equals(messageType)) {

                sendNotification(""    + extras.get(Gcm_Application_Constants.MSG_KEY)); //When Message is received normally from GCM Cloud Server
            }
        }
        Gcm_Broadcast_Receiver.completeWakefulIntent(intent);
    }

    private void sendNotification(String msg) {
        Intent resultIntent = new Intent(this, Home_Activity.class);
        resultIntent.putExtra("msg", msg);
        PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0,
                resultIntent, PendingIntent.FLAG_ONE_SHOT); // لظهور الاشعار مرة واحدة بعد الضغط عليه يختفي

        NotificationCompat.Builder mNotifyBuilder;
        NotificationManager mNotificationManager;

        mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        mNotifyBuilder = new NotificationCompat.Builder(this)
                .setContentTitle("رسالة جديدة")
                .setSmallIcon(R.mipmap.ic_launcher);
        // Set pending intent
        mNotifyBuilder.setContentIntent(resultPendingIntent);

        // Set Vibrate, Sound and Light
        int defaults = 0;
        defaults = defaults | Notification.DEFAULT_LIGHTS;
        defaults = defaults | Notification.DEFAULT_VIBRATE;
        defaults = defaults | Notification.DEFAULT_SOUND;

        mNotifyBuilder.setDefaults(defaults);
        // Set the content for Notification
        mNotifyBuilder.setContentText("لديك رسالة جديدة من السيرفر");
        // Set autocancel
        mNotifyBuilder.setAutoCancel(true);
        // Post a notification
        mNotificationManager.notify(notifyID, mNotifyBuilder.build());
    }
}

Utility.java

package com.andrody.testgcm;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by Abboudi_Aliwi on 13/05/2015.
 */
public class Utility {
    private static Pattern pattern;
    private static Matcher matcher;
    //Email Pattern
    private static final String EMAIL_PATTERN =
            "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@"
                    + "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";

    /**
     * Validate Email with regular expression
     *
     * @param email
     * @return true for Valid Email and false for Invalid Email
     */
    public static boolean validate(String email) {
        pattern = Pattern.compile(EMAIL_PATTERN);
        matcher = pattern.matcher(email);
        return matcher.matches();
    }
}

AndroidManifest.xml
لمن يريد شرح الملف يراجع الدرس السابق

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.andrody.testandrody"
    android:installLocation="preferExternal">

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

    <permission
        android:name="com.andrody.testandrody.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />

    <uses-permission android:name="com.andrody.testandrody.permission.C2D_MESSAGE" />

    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.VIBRATE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />

        <activity
            android:name=".Main_Activity"
            android:label="@string/app_name"
            android:noHistory="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".Home_Activity"
            android:configChanges="orientation|keyboardHidden"
            android:label="@string/app_name"
            android:noHistory="true"></activity>

        <receiver
            android:name="com.andrody.testgcm.Gcm_Broadcast_Receiver"
            android:permission="com.google.android.c2dm.permission.SEND">
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <action android:name="com.google.android.c2dm.intent.REGISTRATION" />

                <category android:name="com.andrody.testandrody" />
            </intent-filter>
        </receiver>

        <service android:name="com.andrody.testgcm.Gcm_Notification_Intent_Service" />

    </application>

</manifest>

** بالنسبة لك كمبرمج مبتدئ أو متوسط الخبرة الاكتفتي المؤثرة لديك :
– Main_Activity / قليلاً فقط لتسجيل المستخدم.
– Gcm_Notification_Intent_Service معالجة الرسالة .
– Home_Activity / ظهور الرسالة للمستخدم.
جرب التعديل عليها حسب راحتك, للتدرب عليها أكثر فهي أكثر أهمية لك من غيرها.

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

# تطوير للدرس :
من سوف يستفيد من هذا الدرس هم أصحاب الخبرة والتعامل مع قواعد البيانات, تطبيق الويب هذا جداً بسيط, يستطيع المبرمج الذي يتعامل مع لغة PHP إنشاء زر مثلاً حذف إيميل, تعديل, تحديد الكل, إضافة خاصية مع التسجيل هل أنت ذكر أو أنثى, لأرسال اخبار للذكر مختلفة عن الانثى, كم عمرك ؟!. . وجعل هذه المعلومات تظهر في تطبيق الويب بناءاً عليها يستطيع المبرمج أن يحدد الفئة المطلوبة لارسال له ما يناسبه.
كما إن تستطيع بعد وصول الرسالة الى المستخدم حفظها في التطبيق, واستخدامها إن كانت مثلاً تطبيق حكم يومية, أو مثلاً مقال يتم تخزينه في التطبيق للرجوع إليه.
** قلت هذه المعلومة فقط لأوضح إن الأمر ليس ببسيط كما تشاهده بالمعاينة, فحسب خبرة المبرمج يستطيع تطوير هذا الأمر للأستفادة منه في أقصى درجاته.

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

عن عبدالقادر عليوي

مواليد 1996 , سوري الجنسية, طالب علم, لدي شغوف كبير في تعلم كل ما يتعلق بالانترنت من تطوير وحماية, أحب القراءة كثيراً .. هدفي نشر العلم بشتى أنواعه ومجالاته, متابع من الدرجة الأولى لـ الدكتور ابراهيم الفقي و الشيخ أحمد ديدات - رحمهم الله -.

شاهد أيضاً

التقنيات التي نستطيع برمجة تطبيقات والعاب الاندرويد بها

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

تعلم برمجة تطبيق اندرويد لمدونتك البلوجر (1)

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

عرض صورة في التطبيق من فايربيس

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

5 تعليقات

  1. يعطيك العافيه انا قمت بعمل نفس الخطوات واشتغل الحمد لله بس عندما اقوم ب الضغط على ال notification المسج المعروض في Text view هو null
    ارجو الاجابه للضروره القصوى استخدمتها ب المشروع ومناقشتي اقتربت

  2. عبد الله

    هل يمكنك اضافة زر لتحديد جميع ايميلات المستخدمين بضغطة زر واحدة عوضا عن ضغط امام ايميل كل شخص وشكراً على الشرح.

  3. ممكن الsource code? لاني ماقادرة اعمل كوبي

  4. محمد عبدالرحمن

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

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

ضع بصمتك بتعليق يعبر عن امتنانك

هذا الموقع يستخدم Akismet للحدّ من التعليقات المزعجة والغير مرغوبة. تعرّف على كيفية معالجة بيانات تعليقك.