搭建GCM项目——服务端和客户端(二)

来源:互联网 发布:js输入框输入数据事件 编辑:程序博客网 时间:2024/05/05 13:46

现在先来完成GCM的客户端,首先创建android项目,名字就是之前在Google Console中注册的那个 DemoProject

创建完成之后,用Android SDK Manager确认你的SDK中已经下载了extras中的Google Cloud Messaging for Android Library已经安装,如果没有,请下载

之后在项目中导入gcm.jar,位置在:..\adt-bundle-windows-x86_64-20131030\sdk\extras\google\gcm\gcm-client\dist

现在开始可以着手写Service了

(1) 在Manifest文件夹定义的package中创建GCMIntentService (一定要是这个名字!!),详细代码如下


[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package com.example.pushproject;  
  2.   
  3. import com.google.android.gcm.GCMBaseIntentService;  
  4.   
  5. import android.R.anim;  
  6. import android.app.Notification;  
  7. import android.app.NotificationManager;  
  8. import android.app.PendingIntent;  
  9. import android.app.Service;  
  10. import android.content.Context;  
  11. import android.content.Intent;  
  12. import android.graphics.Color;  
  13. import android.os.Handler;  
  14. import android.os.IBinder;  
  15. import android.os.Looper;  
  16. import android.util.Log;  
  17. import android.widget.Toast;  
  18.   
  19. public class GCMIntentService  extends GCMBaseIntentService {  
  20.     public static final String SENDERID="";  
  21.     public GCMIntentService() {  
  22.         super(SENDERID);  
  23.     }  
  24.   
  25.     @Override  
  26.     protected void onError(Context arg0, String arg1) {  
  27.         Log.v("GCMIntentService""onError");    
  28.     }  
  29.   
  30.     @Override  
  31.     protected void onMessage(Context arg0, Intent arg1) {  
  32.         String titleString=arg1.getStringExtra("title");  
  33.         String contentString=arg1.getStringExtra("content");  
  34.         showNotification(titleString,contentString);  
  35.     }  
  36.     @Override  
  37.     protected void onRegistered(Context arg0, String arg1) {  
  38.         Log.v("GCMIntentService""onRegistered success ");  
  39.     }  
  40.   
  41.     @Override  
  42.     protected void onUnregistered(Context arg0, String arg1) {  
  43.         Log.v("GCMIntentService""onUnregistered");    
  44.     }  
  45.     public void showNotification(String title,String content){  
  46.         NotificationManager manager=(NotificationManager)this.getSystemService(android.content.Context.NOTIFICATION_SERVICE);  
  47.         Notification notification=new Notification(R.drawable.ic_launcher,title,System.currentTimeMillis());  
  48.         notification.flags |= Notification.FLAG_ONGOING_EVENT; // 将此通知放到通知栏的"Ongoing"即"正在运行"组中     
  49.         notification.flags |= Notification.FLAG_SHOW_LIGHTS;    
  50.         notification.defaults = Notification.DEFAULT_LIGHTS;  
  51.         notification.ledARGB = Color.BLUE;    
  52.         notification.ledOnMS =5000//闪光时间,毫秒  
  53.                 
  54.      // 设置通知的事件消息    
  55.         CharSequence contentTitle =title; // 通知栏标题    
  56.         CharSequence contentText =content; // 通知栏内容    
  57.         Intent notificationIntent =new Intent(); // 点击该通知后要跳转的Activity    
  58.         PendingIntent contentItent = PendingIntent.getActivity(this0, notificationIntent, 0);    
  59.         notification.setLatestEventInfo(this, contentTitle, contentText, contentItent);    
  60.            
  61.    // 把Notification传递给NotificationManager    
  62.        manager.notify(0, notification);     
  63.           
  64.     }  
  65. }  

其中SENDERID就是之前在GOOGLE console中申请的Project Number, 按照我们之前的例子,它应该是1023569414169

(2) 修改MainActivity

在MainActivity中,我们将注册好的Registration ID发送到服务器端存储起来,注意不要在主线程中使用HttpClient发送消息,应该写一个新的AsyncTask发送

另外,registration ID的注册可能存在一点点延迟现象,所以在这里使用定时器,确认返回ID后再发送,代码如下:


[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package com.example.pushproject;  
  2.   
  3. import java.util.Timer;  
  4. import java.util.TimerTask;  
  5.   
  6. import org.apache.http.HttpResponse;  
  7. import org.apache.http.client.HttpClient;  
  8. import org.apache.http.client.methods.HttpGet;  
  9. import org.apache.http.impl.client.DefaultHttpClient;  
  10.   
  11. import android.R.integer;  
  12. import android.app.Activity;  
  13. import android.os.AsyncTask;  
  14. import android.os.Bundle;  
  15. import android.view.Menu;  
  16. import android.view.View;  
  17. import android.widget.Button;  
  18.   
  19. import com.google.android.gcm.GCMRegistrar;  
  20.   
  21. public class MainActivity extends Activity {  
  22.     private String regIdString;  
  23.     private Button unButton;  
  24.     public static String accessUrl="http://请使用详细地址,使用127.0.0.1是发送不出去的:8080";  
  25.     @Override  
  26.     protected void onCreate(Bundle savedInstanceState) {  
  27.         super.onCreate(savedInstanceState);  
  28.         setContentView(R.layout.activity_main);  
  29.         // Register  
  30.         GCMRegistrar.checkDevice(this);  
  31.         GCMRegistrar.checkManifest(this);  
  32.         regIdString = GCMRegistrar.getRegistrationId(this);  
  33.         if (regIdString.equals("")) {  
  34.             GCMRegistrar.register(this, GCMIntentService.SENDERID);  
  35.             // when register device to GCM, it got time delay. So we use Timer send registerID to our app server  
  36.             Timer timer=new Timer();  
  37.             timer.schedule(new GetRegistrationID(), 5000);  
  38.         }     
  39.         // Test button, if click, you can remove registered and device can not  
  40.         // get notification any more  
  41.         unButton = (Button) findViewById(R.id.unreg);  
  42.         unButton.setOnClickListener(new View.OnClickListener() {  
  43.             @Override  
  44.             public void onClick(View v) {  
  45.                 GCMRegistrar.unregister(getBaseContext());  
  46.             }  
  47.         });  
  48.     }  
  49.   
  50.     @Override  
  51.     public boolean onCreateOptionsMenu(Menu menu) {  
  52.         getMenuInflater().inflate(R.menu.main, menu);  
  53.         return true;  
  54.     }  
  55.   
  56.     class UpdateRegistrationDTask extends AsyncTask {  
  57.         @Override  
  58.         protected Object doInBackground(Object... arg0) {  
  59.             regIdString=arg0[0].toString();  
  60.             String urlString = accessUrl+"/DemoProject/GetDeviceId.do"  
  61.                     + "?deviceId=" + regIdString;  
  62.             HttpGet httpGet = new HttpGet(urlString);  
  63.             HttpClient httpClient = new DefaultHttpClient();  
  64.             try {  
  65.                 HttpResponse response = httpClient.execute(httpGet);  
  66.                   
  67.             } catch (Exception e) {  
  68.                 e.printStackTrace();  
  69.             }  
  70.             return null;  
  71.         }  
  72.     }         
  73.     class GetRegistrationID extends TimerTask{  
  74.         @Override  
  75.         public void run() {  
  76.             String testString=GCMRegistrar.getRegistrationId(getApplicationContext());  
  77.             new UpdateRegistrationDTask().execute(testString);  
  78.         }  
  79.           
  80.     }  
  81. }  

(3)修改Manifest.xml文件,添加许可,我的XML文件如下,仅供大家参考

[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     package="com.example.demoprojecgt"  
  4.     android:versionCode="1"  
  5.     android:versionName="1.0" >  
  6.   
  7.     <uses-sdk  
  8.         android:minSdkVersion="8"  
  9.         android:targetSdkVersion="18" />  
  10.     <permission    
  11.         android:name="com.example.demoproject.permission.C2D_MESSAGE"    
  12.         android:protectionLevel="signature"/>    
  13.     <uses-permission  android:name="com.example.demoproject.permission.C2D_MESSAGE"/>    
  14.     <uses-permission  android:name="com.google.android.c2dm.permission.RECEIVE"/>    
  15.     <uses-permission  android:name="android.permission.INTERNET"/>    
  16.     <uses-permission  android:name="android.permission.GET_ACCOUNTS"/>    
  17.     <uses-permission  android:name="android.permission.WAKE_LOCK"/>    
  18.     <application  
  19.         android:allowBackup="true"  
  20.         android:icon="@drawable/ic_launcher"  
  21.         android:label="@string/app_name"  
  22.         android:theme="@style/AppTheme" >  
  23.         <activity  
  24.             android:name="com.example.pushproject.MainActivity"  
  25.             android:label="@string/app_name" >  
  26.             <intent-filter>  
  27.                 <action android:name="android.intent.action.MAIN" />  
  28.   
  29.                 <category android:name="android.intent.category.LAUNCHER" />  
  30.             </intent-filter>  
  31.         </activity>  
  32.         <receiver    
  33.             android:name="com.google.android.gcm.GCMBroadcastReceiver"    
  34.             android:permission="com.google.android.c2dm.permission.SEND">    
  35.             <intent-filter>    
  36.                 <action    
  37.                     android:name="com.google.android.c2dm.intent.RECEIVE"/>    
  38.                 <action    
  39.                     android:name="com.google.android.c2dm.intent.REGISTRATION"/>    
  40.                 <category    
  41.                     android:name="com.example.demoproject"/>    
  42.             </intent-filter>    
  43.         </receiver>    
  44.         <service  
  45.             android:name=".GCMIntentService">  
  46.         </service>  
  47.     </application>  
  48.   
  49. </manifest>  


下面是一些permission的说明

1. com.google.android.c2dm.permission.RECEIVE 使得Android app可以向GCM注册,且获得信息

2. android.permission.INTERNET 使得Android app可以向第三方服务器发送registration ID

3. android.permission.GET_ACCOUNTS 当Android系统低于4.0.4的时候,使得GCM获得用户的Google账户

4. android.permission.WAKE_LOCK 这是可选项,如果你希望你的app在sleeping状态下也能接收信息的话,请添加该permission

5. applicationPackage + ".permission.C2D_MESSAGE"   该permission防止别的app注册并获得推送消息。该permission必须严格遵守该规范,否则你的app将不会接收任何推送消息

6.       定义了com.google.android.c2dm.intent.RECEIVE 的receiver。 该receiver同时要定义com.google.android.c2dm.SEND 许可,这样就只有GCM框架可以给他发送消息。如果你的app使用IntentService,那么这个receiver必须是WakefulBroadcastReceiver的实例。

7. 最后确定你的app最低版本在8以上,如果想要使用GCM服务的话

注意,在permission和第一个uses-permission中,将其中的包名改为你们自己的,同时需要修改的还有receiver中的category

至此,Client部分结束

0 0
原创粉丝点击