我实现使用GCM.I m到处令牌和实例ID成功,服务器也发送通知成功返回推送通知,但读音字无法reveive我的电话通知。请帮助!
下面是我的code
Android清单:
<?XML版本=1.0编码=UTF-8&GT?; <清单的xmlns:机器人=http://schemas.android.com/apk/res/android 包=com.example.appname 安卓版code =1 机器人:=的versionName1.0> <用途-SDK 安卓的minSdkVersion =14 机器人:targetSdkVersion =21/> <使用许可权的android:NAME =android.permission.INTERNET对/> <使用许可权的android:NAME =android.permission.ACCESS_NETWORK_STATE/> <使用许可权的android:NAME =android.permission.ACCESS_COARSE_LOCATION/> <使用许可权的android:NAME =android.permission.ACCESS_FINE_LOCATION/> <使用许可权的android:NAME =android.permission.WRITE_EXTERNAL_STORAGE/> <使用许可权的android:NAME =android.permission.READ_PHONE_STATE/> <使用许可权的android:NAME =android.permission.READ_EXTERNAL_STORAGE/> &所述;! - [开始gcm_permission] - GT; <使用许可权的android:NAME =com.google.android.c2dm.permission.RECEIVE/> <使用许可权的android:NAME =android.permission.WAKE_LOCK/> <! - [END gcm_permission] - > <允许机器人:名字=com.example.appname.permission.C2D_MESSAGE 安卓的ProtectionLevel =签名/> <使用许可权的android:NAME =com.example.appname.permission.C2D_MESSAGE/> <支持屏 机器人:anyDensity =真 机器人:largeScreens =真 机器人:normalScreens =真 机器人:smallScreens =真/> <应用 机器人:allowBackup =真 机器人:图标=@绘制/ APPICON 机器人:标签=@字符串/ APP_NAME 机器人:主题=@风格/ Theme.AppCompat.NoActionBar> <活动 机器人:名字=。Outlet.Activities.SplashActivity 机器人:标签=@字符串/ APP_NAME 机器人:screenOrientation =肖像> &所述;意图滤光器> <作用机器人:名字=android.intent.action.MAIN/> <类机器人:名字=android.intent.category.LAUNCHER/> &所述; /意图滤光器> &所述;意图滤光器> <作用机器人:名字=gcm_test_app_notification_click_action/> <类机器人:名字=android.intent.category.DEFAULT/> &所述; /意图滤光器> < /活性GT; <活动 机器人:名字=。Outlet.Activities.LoginActivity 机器人:screenOrientation =肖像/> <服务 机器人:名字=com.paypal.android.sdk.payments.PayPalService 机器人:出口=FALSE/> <活动机器人:名字=com.paypal.android.sdk.payments.PaymentActivity/> <活动机器人:名字=com.paypal.android.sdk.payments.LoginActivity/> <活动机器人:名字=com.paypal.android.sdk.payments.PaymentMethodActivity/> <活动机器人:名字=com.paypal.android.sdk.payments.PaymentConfirmActivity/> <活动 机器人:名字=io.card.payment.CardIOActivity 机器人:configChanges =keyboardHidden |方向/> <活动机器人:名字=io.card.payment.DataEntryActivity/> &所述;! - [开始gcm_receiver] - GT; <接收 机器人:名字=com.google.android.gms.gcm.GcmReceiver 机器人:出口=真 机器人:权限=com.google.android.c2dm.permission.SEND> &所述;意图滤光器> <作用机器人:名字=com.google.android.c2dm.intent.RECEIVE/> <作用机器人:名字=com.google.android.c2dm.intent.REGISTRATION/> <类机器人:名字=com.example.appname/> !< - <类机器人:名字=gcm.play.android.samples.com.gcmquickstart/> - > &所述; /意图滤光器> < /接收器> <! - [END gcm_receiver] - > &所述;! - [开始gcm_listener] - GT; <服务 机器人:名字=com.example.appname.CommonFiles.Push.MyGcmListenerService 机器人:出口=假> &所述;意图滤光器> <作用机器人:名字=com.google.android.c2dm.intent.RECEIVE/> &所述; /意图滤光器> < /服务> <! - [END gcm_listener] - > &所述;! - [开始instanceId_listener] - GT; <服务 机器人:名字=com.example.appname.CommonFiles.Push.MyInstanceIDListenerService 机器人:出口=假> &所述;意图滤光器> <作用机器人:名字=com.google.android.gms.iid.InstanceID/> &所述; /意图滤光器> < /服务> <! - [END instanceId_listener] - > <服务 机器人:名字=com.example.appname.CommonFiles.Push.RegistrationIntentService 机器人:出口=假> < /服务> < /用途> < /清单>
GCMIntentservice类: -
公共类MyGcmListenerService扩展GcmListenerService { 私有静态最后弦乐TAG =MyGcmListenerService; 公共静态最终诠释MESSAGE_NOTIFICATION_ID = 435345; / ** *收到消息时调用。 * *从发送的SenderID @参数。 *包含的信息数据作为键/值对@参数数据包的数据。 *对于SET键使用data.keySet()。 * / // [START RECEIVE_MESSAGE] @覆盖 公共无效onMessageReceived(String一个,捆绑数据){ 字符串消息= data.getString(信息); Log.d(TAG,发件人:+的); Log.d(TAG消息:+消息); 如果(from.startsWith(/主题/)){ //从一些主题接收到的消息。 }其他{ //正常的下行消息。 } // [START_EXCLUDE] / ** *生产应用程序通常会在这里处理消息。 *例如: - 与服务器同步。 * - 在本地数据库中存储的信息。 * - 更新UI。 * / / ** *在某些情况下可能是有用的,以显示一个通知向用户指示 *被接收的消息。 * / sendNotification的(消息); // [END_EXCLUDE] } // [END RECEIVE_MESSAGE] / ** *创建并显示包含接收到的GCM消息的简单的通知。 * * @参数消息GCM消息接收。 * / 私人无效sendNotification时(字符串消息){ 意向意图=新意图(这一点,LoginActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 的PendingIntent的PendingIntent = PendingIntent.getActivity(这一点,0 / *请求code * /,意图, PendingIntent.FLAG_ONE_SHOT); 乌里defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); NotificationCompat.Builder notificationBuilder =新NotificationCompat.Builder(本) .setSmallIcon(R.drawable.ic_launcher) .setContentTitle(GCM消息) .setContentText(消息) .setAutoCancel(真) .setSound(defaultSoundUri) .setContentIntent(的PendingIntent); NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify(MESSAGE_NOTIFICATION_ID / *通知ID * /,notificationBuilder.build()); }}
RegisterIntentService: -
公共类RegistrationIntentService扩展IntentService { 私有静态最后弦乐TAG =RegIntentService; 私有静态最后的String [] =主题{全球}; UserSession userSession; 公共RegistrationIntentService(){ 超(TAG); } @覆盖 保护无效onHandleIntent(意向意图){ 共享preferences共享preferences = preferenceManager.getDefaultShared preferences(本); userSession =新UserSession(本); 尝试{ // [START register_for_gcm] //最初这个调用出去的网络检索令牌,后续调用 //是本地的。 // [START的get_token] 实例id =实例ID InstanceID.getInstance(本); // R.string.gcm_defaultSenderId(发件人ID),通常是从谷歌-services.json的。 //见https://developers.google.com/cloud-messaging/android/start有关该文件的详细信息。 字符串标记= instanceID.getToken(的getString(R.string.gcm_defaultSenderId) GoogleCloudMessaging.INSTANCE_ID_SCOPE,NULL); userSession.saveGCMToken(标记); // [结束的get_token] Log.i(TAGGCM注册令牌:+令牌); // TODO:实施此方法的任何注册发送到您的应用程序的服务器。 sendRegistrationToServer(标记); //订阅主题频道 subscribeTopics(标记); //你要存储一个布尔值,表示生成的令牌是否已经 //发送到服务器。如果布尔是假的,送令牌服务器, //否则你的服务器应该已经收到了令牌。 共享preferences.edit()putBoolean(快速入门preferences.SENT_TOKEN_TO_SERVER,真实)。适用()。 // [END register_for_gcm] }赶上(例外五){ Log.d(TAG,无法完成令牌刷新,E); //如果在获取新的令牌或更新我们的注册数据发生异常 //第三方的服务器上,这保证了我们将在以后的时间尝试更新。 共享preferences.edit()putBoolean(快速入门preferences.SENT_TOKEN_TO_SERVER,假)。适用()。 } //通知登记已完成的UI,所以进度指示器可以隐藏。 意图registrationComplete =新意图(快速入门preferences.REGISTRATION_COMPLETE); LocalBroadcastManager.getInstance(本).sendBroadcast(registrationComplete); } / ** *坚持登记第三方服务器。 * *修改此方法将用户的注册GCM令牌任何服务器端帐户关联 *您的应用程序维护。 * * @参数令牌新的令牌。 * / 私人无效sendRegistrationToServer(字符串标记){ //添加自定义的实现,根据需要。 GCMHelper gcmHelper =新GCMHelper(本); gcmHelper.checkRegisterDevice(); } / ** *订阅感兴趣的任何话题GCM由主题不变的定义。 * * @参数令牌GCM令牌 *引发IOException若无法达成的GCM PubSub的服务 * / // [START subscribe_topics] 私人无效subscribeTopics(字符串标记)抛出IOException GcmPubSub PubSub的= GcmPubSub.getInstance(本); 对于(字符串主题:主题){ pubSub.subscribe(令牌/主题/+话题,NULL); } } // [END subscribe_topics]}
解决方案
您清单中有写 <允许机器人:名字=com.example.gcm.permission.C2D_MESSAGE 安卓的ProtectionLevel =签名/> <使用许可权的android:NAME =com.example.gcm.permission.C2D_MESSAGE/> 其中,com。示例是你的包名。但是,你的应用程序包的名字是com.example.appname 所以,你必须写 <允许机器人:名字=com.example.appname.permission.C2D_MESSAGE 安卓的ProtectionLevel =签名/> <使用许可权的android:NAME =com.example.appname.permission.C2D_MESSAGE/>
I am implementing push notification using GCM.I m getting the token and instance id successfully, the server is also returning success on sending the notification but i m unable to reveive notification on my phone. Please help!!!
Below is my code
Android Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.appname"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- [START gcm_permission] -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- [END gcm_permission] -->
<permission android:name="com.example.appname.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.appname.permission.C2D_MESSAGE" />
<supports-screens
android:anyDensity="true"
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true" />
<application
android:allowBackup="true"
android:icon="@drawable/appicon"
android:label="@string/app_name"
android:theme="@style/Theme.AppCompat.NoActionBar">
<activity
android:name=".Outlet.Activities.SplashActivity"
android:label="@string/app_name"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="gcm_test_app_notification_click_action"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity
android:name=".Outlet.Activities.LoginActivity"
android:screenOrientation="portrait" />
<service
android:name="com.paypal.android.sdk.payments.PayPalService"
android:exported="false" />
<activity android:name="com.paypal.android.sdk.payments.PaymentActivity" />
<activity android:name="com.paypal.android.sdk.payments.LoginActivity" />
<activity android:name="com.paypal.android.sdk.payments.PaymentMethodActivity" />
<activity android:name="com.paypal.android.sdk.payments.PaymentConfirmActivity" />
<activity
android:name="io.card.payment.CardIOActivity"
android:configChanges="keyboardHidden|orientation" />
<activity android:name="io.card.payment.DataEntryActivity" />
<!-- [START gcm_receiver] -->
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:exported="true"
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.example.appname" />
<!--<category android:name="gcm.play.android.samples.com.gcmquickstart" />-->
</intent-filter>
</receiver>
<!-- [END gcm_receiver] -->
<!-- [START gcm_listener] -->
<service
android:name="com.example.appname.CommonFiles.Push.MyGcmListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<!-- [END gcm_listener] -->
<!-- [START instanceId_listener] -->
<service
android:name="com.example.appname.CommonFiles.Push.MyInstanceIDListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID"/>
</intent-filter>
</service>
<!-- [END instanceId_listener] -->
<service
android:name="com.example.appname.CommonFiles.Push.RegistrationIntentService"
android:exported="false">
</service>
</application>
</manifest>
GCMIntentservice class:-
public class MyGcmListenerService extends GcmListenerService {
private static final String TAG = "MyGcmListenerService";
public static final int MESSAGE_NOTIFICATION_ID = 435345;
/**
* Called when message is received.
*
* @param from SenderID of the sender.
* @param data Data bundle containing message data as key/value pairs.
* For Set of keys use data.keySet().
*/
// [START receive_message]
@Override
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("message");
Log.d(TAG, "From: " + from);
Log.d(TAG, "Message: " + message);
if (from.startsWith("/topics/")) {
// message received from some topic.
} else {
// normal downstream message.
}
// [START_EXCLUDE]
/**
* Production applications would usually process the message here.
* Eg: - Syncing with server.
* - Store message in local database.
* - Update UI.
*/
/**
* In some cases it may be useful to show a notification indicating to the user
* that a message was received.
*/
sendNotification(message);
// [END_EXCLUDE]
}
// [END receive_message]
/**
* Create and show a simple notification containing the received GCM message.
*
* @param message GCM message received.
*/
private void sendNotification(String message) {
Intent intent = new Intent(this, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("GCM Message")
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(MESSAGE_NOTIFICATION_ID /* ID of notification */, notificationBuilder.build());
}
}
RegisterIntentService:-
public class RegistrationIntentService extends IntentService {
private static final String TAG = "RegIntentService";
private static final String[] TOPICS = {"global"};
UserSession userSession;
public RegistrationIntentService() {
super(TAG);
}
@Override
protected void onHandleIntent(Intent intent) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
userSession=new UserSession(this);
try {
// [START register_for_gcm]
// Initially this call goes out to the network to retrieve the token, subsequent calls
// are local.
// [START get_token]
InstanceID instanceID = InstanceID.getInstance(this);
// R.string.gcm_defaultSenderId (the Sender ID) is typically derived from google-services.json.
// See https://developers.google.com/cloud-messaging/android/start for details on this file.
String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId),
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
userSession.saveGCMToken(token);
// [END get_token]
Log.i(TAG, "GCM Registration Token: " + token);
// TODO: Implement this method to send any registration to your app's servers.
sendRegistrationToServer(token);
// Subscribe to topic channels
subscribeTopics(token);
// You should store a boolean that indicates whether the generated token has been
// sent to your server. If the boolean is false, send the token to your server,
// otherwise your server should have already received the token.
sharedPreferences.edit().putBoolean(QuickstartPreferences.SENT_TOKEN_TO_SERVER, true).apply();
// [END register_for_gcm]
} catch (Exception e) {
Log.d(TAG, "Failed to complete token refresh", e);
// If an exception happens while fetching the new token or updating our registration data
// on a third-party server, this ensures that we'll attempt the update at a later time.
sharedPreferences.edit().putBoolean(QuickstartPreferences.SENT_TOKEN_TO_SERVER, false).apply();
}
// Notify UI that registration has completed, so the progress indicator can be hidden.
Intent registrationComplete = new Intent(QuickstartPreferences.REGISTRATION_COMPLETE);
LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete);
}
/**
* Persist registration to third-party servers.
*
* Modify this method to associate the user's GCM registration token with any server-side account
* maintained by your application.
*
* @param token The new token.
*/
private void sendRegistrationToServer(String token) {
// Add custom implementation, as needed.
GCMHelper gcmHelper = new GCMHelper(this);
gcmHelper.checkRegisterDevice();
}
/**
* Subscribe to any GCM topics of interest, as defined by the TOPICS constant.
*
* @param token GCM token
* @throws IOException if unable to reach the GCM PubSub service
*/
// [START subscribe_topics]
private void subscribeTopics(String token) throws IOException {
GcmPubSub pubSub = GcmPubSub.getInstance(this);
for (String topic : TOPICS) {
pubSub.subscribe(token, "/topics/" + topic, null);
}
}
// [END subscribe_topics]
}
解决方案
You have write in manifest
<permission android:name="com.example.gcm.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.gcm.permission.C2D_MESSAGE" />
where com.example is your package name.
But your application package name is com.example.appname
So, you have to write
<permission android:name="com.example.appname.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.example.appname.permission.C2D_MESSAGE" />