GCM不是在客户端接收消息 [英] gcm not receiving message on client side

查看:211
本文介绍了GCM不是在客户端接收消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的服务器将消息发送到为200的响应code中的GCM塞雷尔语,但我的OnMessageReceiver是没有得到因此被称为即时通讯没有得到消息。

公共类MyGcmListenerService扩展GcmListenerService {

 私有静态最后弦乐TAG =MyGcmListenerService;
私有静态诠释no_calls;
    @覆盖
    公共无效onMessageReceived(String一个,捆绑数据){
        字符串消息= data.getString(信息);
        Log.d(TAG,发件人:+的);
        Log.d(TAG消息:+消息);        通过out.println(打印内容);        的System.out.println(信息+消息+由+从);        sendNotification的(消息);
    }私人无效sendNotification时(字符串消息){    的System.out.println(信息+消息+由);    意向意图=新意图(这一点,MainActivity.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)新NotificationCompat.Builder(本)
            .setSmallIcon(R.drawable.ic_setting_dark)
            .setContentTitle(GCM消息)
            .setContentText(消息)
            .setAutoCancel(真)
            .setSound(defaultSoundUri)
            .setContentIntent(的PendingIntent);    NotificationManager notificationManager =
            (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);    notificationManager.notify(0 / *标识的通知* /,notificationBuilder.build());
}

}

 <?XML版本=1.0编码=UTF-8&GT?;
<清单的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    包=com.example.caesar.gcm>    <采用-SDK安卓的minSdkVersion =9机器人:targetSdkVersion =21/>    <使用许可权的android:NAME =android.permission.INTERNET对/>
    <使用许可权的android:NAME =android.permission.WAKE_LOCK/>
    <使用许可权的android:NAME =com.google.android.c2dm.permission.RECEIVE/>    <允许机器人:名字=com.example.caesar.gcm.permission.C2D_MESSAGE
        安卓的ProtectionLevel =签名/>
    <使用许可权的android:NAME =com.example.caesar.gcm.permission.C2D_MESSAGE/>    <使用许可权的android:NAME =android.permission.ACCESS_NETWORK_STATE/>
    <使用许可权的android:NAME =com.example.gcm.permission.C2D_MESSAGE/>
    <应用
        机器人:allowBackup =真
        机器人:图标=@的mipmap / ic_launcher
        机器人:标签=@字符串/ APP_NAME
        机器人:主题=@风格/ AppTheme>        < reciever
        机器人:名字=com.google.android.gms.gcm.GcmReceiver
            机器人:出口=真
        机器人:权限=com.google.android.c2dm.permission.SEND>
        &所述;意图滤光器>
            <作用机器人:名字=com.google.android.c2dm.intent.RECEIVE/>
            <类机器人:名字=com.example.caesar.gcm/>
        &所述; /意图滤光器>    < / reciever>
        <服务
            机器人:MyGcmListenerServiceNAME =
            机器人:出口=假>
            &所述;意图滤光器>
                <作用机器人:名字=com.google.android.c2dm.intent.RECEIVE/>
            &所述; /意图滤光器>
        < /服务>        <活动
            机器人:名字=。MainActivity
            机器人:标签=@字符串/ APP_NAME>
            &所述;意图滤光器>
                <作用机器人:名字=android.intent.action.MAIN/>                <类机器人:名字=android.intent.category.LAUNCHER/>
            &所述; /意图滤光器>
        < /活性GT;        &所述;元数据
            机器人:名字=com.google.android.gms.version
            机器人:值=@整数/ GOOGLE_PLAY_SERVICES_VERSION/>
    < /用途>< /清单>

公共类MainActivity延伸活动{

  Google云端通讯GCM;
串REGID;
TextView的填充mDisplay;
TextView中的TextView;
字符串SENDER_ID =;
公共静态最后弦乐EXTRA_MESSAGE =消息;
公共静态最后弦乐PROPERTY_REG_ID =registration_id;
私有静态最后弦乐PROPERTY_APP_VERSION =appVersion;
上下文语境;AsyncHttpClient客户端=新AsyncHttpClient();静态最后弦乐TAG =GCMDemo;串乱=;
@覆盖
保护无效的onCreate(捆绑savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.activity_main);    填充mDisplay =(的TextView)findViewById(R.id.display);    TextView的=(的TextView)findViewById(R.id.textView);
    上下文= getApplicationContext();    // GCM注册。
    如果(checkPlayServices()){
        GCM = GoogleCloudMessaging.getInstance(本);
        REGID = getRegistrationId(上下文);        textView.setText(REGID);        SendID();
        如果(regid.isEmpty()){
            registerInBackground();
        }
    }其他{
        Log.i(TAG,没有有效的谷歌Play服务APK找到。);
    }
}公共无效SendID(){
    最后RequestParams PARAMS =新RequestParams();
    params.put(ID,REGID);    client.post(,则params,新JsonHtt presponseHandler(){        @覆盖
        公共无效调用onStart(){
            //调用请求启动之前
        }        公共无效的onSuccess(INT状态code,preferenceActivity.Header []头,响应的JSONObject){        }        公共无效onFailure处(INT状态code,preferenceActivity.Header []头,JSONObject的errorResponse,Throwable的E){
            //调用时响应HTTP状态是4XX(例如,401,403,404)
        }        @覆盖
        公共无效onRetry(INT retryNo){
            //当请求被称为重试
        }
    });
}
私人布尔checkPlayServices(){    INT状态= GooglePlayServicesUtil.isGooglePlayServicesAvailable(本);
    如果(状态!= ConnectionResult.SUCCESS){
        如果(GooglePlayServicesUtil.isUserRecoverableError(状态)){
            Log.i(TAG,将String.valueOf(状态));
        }其他{
            Toast.makeText(这一点,该设备不被支持。
                    Toast.LENGTH_LONG).show();
            完();
        }
        返回false;
    }
    返回true;
}私人无效registerInBackground(){
    新的AsyncTask<太虚,太虚,字符串>(){
        @覆盖
        保护字符串doInBackground(虚空...... PARAMS){
            弦乐味精=;
            尝试{
                如果(GCM == NULL){
                    GCM = GoogleCloudMessaging.getInstance(上下文);
                }
                REGID = gcm.register(SENDER_ID);
                味精=设备注册,注册ID =+ REGID;                //你应该通过HTTP的注册ID发送到服务器,
                //所以它可以使用GCM / HTTP或CCS将消息发送到您的应用程序。
                //你的服务器的请求应该如果您的应用程序进行身份验证
                //正在使用的帐户。
                sendRegistrationIdToBackend();                //对于这个演示:我们不需要发送它,因为该设备
                //会向上游消息发送到回显服务器
                //在邮件中使用'从'地址的消息。                //坚持的注册ID - 无需再次注册。
                storeRegistrationId(背景下,REGID);
            }赶上(IOException异常前){
                味精=错误:+ ex.getMessage();
                //如果有错误,不要只是不断地尝试注册。
                //要求用户再次点击一个按钮,或执行
                //指数回退。
            }
            返回味精;
        }        私人无效storeRegistrationId(上下文的背景下,字符串REGID){
            最后一个共享preferences preFS = getGCM preferences(背景);
            INT appVersion = getAppVersion(背景);
            Log.i(TAG,+ appVersion应用版本保存REGID);
            共享preferences.Editor编辑器= prefs.edit();
            editor.putString(PROPERTY_REG_ID,REGID);
            editor.putInt(PROPERTY_APP_VERSION,appVersion);
            editor.commit();
        }        @覆盖
        保护无效onPostExecute(弦乐味精){
            mDisplay.append(MSG +\\ n);
        }
    } .execute(NULL,NULL,NULL);
}
私人无效sendRegistrationIdToBackend(){
    //你的实现在这里。
}
私人字符串getRegistrationId(上下文的背景下){
    最后一个共享preferences preFS = getGCM preferences(背景);
    字符串registrationId = prefs.getString(PROPERTY_REG_ID,);
    如果(registrationId.isEmpty()){
        Log.i(TAG,注册没找到。);
        返回;
    }
    //检查应用程序是更新;如果是这样,它必须清除注册ID
    //因为现有的注册ID不能保证一起工作
    //新的应用程序版本。
    INT registeredVersion = prefs.getInt(PROPERTY_APP_VERSION,Integer.MIN_VALUE的);
    INT CURRENTVERSION = getAppVersion(背景);
    如果(registeredVersion!= CURRENTVERSION){
        Log.i(TAG,应用版本改变了。);
        返回;
    }
    返回registrationId;
}
私有静态诠释getAppVersion(上下文的背景下){
    尝试{
        PackageInfo packageInfo = context.getPackageManager()
                .getPackageInfo(context.getPackageName(),0);
        返回packageInfo.version code;
    }赶上(PackageManager.NameNotFoundException E){
        //不应该发生
        抛出新的RuntimeException(无法获取包名:+ E);
    }
}私人共享preferences getGCM preferences(上下文的背景下){
    //此示例应用程序仍然存在共享preferences的注册ID,但
    //你如何存储的注册ID在你的应用程序是由你。
    返回getShared preferences(Activity.class.getSimpleName()
            Context.MODE_PRIVATE);
}

}

//更新主

公共类MainActivity延伸活动{

  Google云端通讯GCM;
TextView的填充mDisplay;
TextView中的TextView;
公共静态最后弦乐EXTRA_MESSAGE =消息;
公共静态最后弦乐PROPERTY_REG_ID =registration_id;
私有静态最后弦乐PROPERTY_APP_VERSION =appVersion;
上下文语境;AsyncHttpClient客户端=新AsyncHttpClient();静态最后弦乐TAG =GCMDemo;
上下文mContext =这一点;串乱=;
@覆盖
保护无效的onCreate(捆绑savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.activity_main);
    填充mDisplay =(的TextView)findViewById(R.id.display);    TextView的=(的TextView)findViewById(R.id.textView);
    共享preferences应用preFS = mContext.getShared preferences(com.example.caesar.gcm,Context.MODE_PRIVATE);
    字符串标记=应用prefs.getString(令牌,);
    如果(token.isEmpty()){
        尝试{
            getGCMToken(1048700326431); //项目编号:XXXX项目编号:0123456789为:https://console.developers.google.com/project / ...            textView.setText(标记);
        }赶上(例外前){
            ex.printStackTrace();
        }
    }
}私人无效getGCMToken(最后弦乐senderId)抛出异常{
    新的AsyncTask<太虚,太虚,太虚>(){
        @覆盖
        保护无效doInBackground(虚空...... PARAMS){
            字符串标记=;
            尝试{
                实例id =实例ID InstanceID.getInstance(mContext);
                令牌= instanceID.getToken(senderId,GoogleCloudMessaging.INSTANCE_ID_SCOPE,NULL);
                如果(标记=空&安培;!&安培;!token.isEmpty()){
                    共享preferences应用preFS = mContext.getShared preferences(com.example.caesar.gcm,Context.MODE_PRIVATE);
                    共享preferences.Editor prefsEditor =应用prefs.edit();
                    prefsEditor.putString(令牌,令牌);
                    prefsEditor.apply();
                }
                Log.i(GCM_Token令牌);                textView.setText(标记);                SendID(标记);            }赶上(IOException异常五){
                e.printStackTrace();
            }
            返回null;
        }
    }。执行();
}公共无效SendID(字符串标记){
    最后RequestParams PARAMS =新RequestParams();
    params.put(ID,令牌);    client.post(https://death-sarodh.c9.io/gcm,则params,新JsonHtt presponseHandler(){        @覆盖
        公共无效调用onStart(){
            //调用请求启动之前
        }        公共无效的onSuccess(INT状态code,preferenceActivity.Header []头,响应的JSONObject){        }        公共无效onFailure处(INT状态code,preferenceActivity.Header []头,JSONObject的errorResponse,Throwable的E){
            //调用时响应HTTP状态是4XX(例如,401,403,404)
        }        @覆盖
        公共无效onRetry(INT retryNo){
            //当请求被称为重试
        }
    });
}

}


解决方案

替换 reciever 在舱单接收
此外,请确保您的应用程序顺利拿到令牌(注册设备ID)。希望这有助于!

我的清单:

 <?XML版本=1.0编码=UTF-8&GT?;
<清单的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    包=com.example.gcmclient><使用许可权的android:NAME =android.permission.INTERNET对/>
<使用许可权的android:NAME =android.permission.GET_ACCOUNTS/>
<使用许可权的android:NAME =android.permission.WAKE_LOCK/>
<使用许可权的android:NAME =com.google.android.c2dm.permission.RECEIVE/><允许机器人:名字=com.example.gcm.permission.C2D_MESSAGE
    安卓的ProtectionLevel =签名/>
<使用许可权的android:NAME =com.example.gcm.permission.C2D_MESSAGE/>
<应用
    机器人:allowBackup =真
    机器人:图标=@的mipmap / ic_launcher
    机器人:标签=@字符串/ APP_NAME
    机器人:主题=@风格/ AppTheme>
    <接收
        机器人:名字=com.google.android.gms.gcm.GcmReceiver
        机器人:出口=真
        机器人:权限=com.google.android.c2dm.permission.SEND>
        &所述;意图滤光器>
            <作用机器人:名字=com.google.android.c2dm.intent.REGISTRATION/>
            <作用机器人:名字=com.google.android.c2dm.intent.RECEIVE/>
            <类机器人:名字=com.example.gcm/>
        &所述; /意图滤光器>
    < /接收器>
    <服务机器人。service.GcmServiceNAME =机器人:出口=假>
        &所述;意图滤光器>
            <作用机器人:名字=com.google.android.c2dm.intent.RECEIVE/>
        &所述; /意图滤光器>
    < /服务>    <服务机器人:名字=机器人service.LoggingService:出口=FALSE/>    <活动
        机器人:名字=。MainActivity
        机器人:标签=@字符串/ APP_NAME
        机器人:clearTaskOnLaunch =假
        机器人:finishOnTaskLaunch =真正的>
        &所述;意图滤光器>
            <作用机器人:名字=android.intent.action.MAIN/>            <类机器人:名字=android.intent.category.LAUNCHER/>
        &所述; /意图滤光器>
    < /活性GT;
< /用途>< /清单>

此外,检查后发送你断绝侧响应。也许你会得到像下面这样如果GCM消息发送成功地响应消息:

<$p$p><$c$c>{\"multicast_id\":6371085842931382567,\"success\":1,\"failure\":0,\"canonical_ids\":0,\"results\":[{\"message_id\":\"0:1240780242421810%4c427ca6f9fd7ecd\"}]}

关于获得令牌,首先,我检查共享preferences,如果为空,从谷歌服务器获取令牌(设备注册ID)。令牌将被存储在共享preferences用于其他用途/提供至服务器端应用

 公共类MainActivity延伸活动{上下文mContext =这一点;@覆盖
保护无效的onCreate(捆绑savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.activity_main);
    ...
    共享preferences应用preFS = mContext.getShared preferences(com.example.gcmclient_ preferences,Context.MODE_PRIVATE);
    字符串标记=应用prefs.getString(令牌,);
    如果(token.isEmpty()){
        尝试{
            getGCMToken(0123456789); //项目编号:XXXX项目编号:0123456789为:https://console.developers.google.com/project / ...
        }赶上(例外前){
            ex.printStackTrace();
        }
    }
    ...
}
...私人无效getGCMToken(最后弦乐senderId)抛出异常{
    新的AsyncTask&LT;太虚,太虚,太虚&GT;(){
        @覆盖
        保护字符串doInBackground(虚空...... PARAMS){
            字符串标记=;
            尝试{
                实例id =实例ID InstanceID.getInstance(mContext);
                令牌= instanceID.getToken(senderId,GoogleCloudMessaging.INSTANCE_ID_SCOPE,NULL);
                如果(标记=空&安培;!&安培;!token.isEmpty()){
                    共享preferences应用preFS = mContext.getShared preferences(com.example.gcmclient_ preferences,Context.MODE_PRIVATE);
                    共享preferences.Editor prefsEditor =应用prefs.edit();
                    prefsEditor.putString(令牌,令牌);
                    prefsEditor.commit();
                }
                Log.i(GCM_Token令牌);
            }赶上(IOException异常五){
                e.printStackTrace();
            }
            返回null;
        }
    }。执行();
}
}

my server is sending the message to the gcm serer with a response code of 200. but my OnMessageReceiver is not getting called therefore im not getting the message.

public class MyGcmListenerService extends GcmListenerService {

private static final String TAG = "MyGcmListenerService";
private static int no_calls;


    @Override
    public void onMessageReceived (String from, Bundle data){
        String message = data.getString("message");
        Log.d(TAG, "From: " + from);
        Log.d(TAG, "Message: " + message);

        out.println("print something");

        System.out.println("Message" + message + "from" + from);

        sendNotification(message);
    }



private void sendNotification(String message) {

    System.out.println("Message" + message + "from");

    Intent intent = new Intent(this, MainActivity.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 = (NotificationCompat.Builder) new NotificationCompat.Builder(this)
            .setSmallIcon(R.drawable.ic_setting_dark)
            .setContentTitle("GCM Message")
            .setContentText(message)
            .setAutoCancel(true)
            .setSound(defaultSoundUri)
            .setContentIntent(pendingIntent);

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

    notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}

}

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.caesar.gcm" >

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

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

    <permission android:name="com.example.caesar.gcm.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />
    <uses-permission android:name="com.example.caesar.gcm.permission.C2D_MESSAGE" />

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="com.example.gcm.permission.C2D_MESSAGE" />


    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >



        <reciever
        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"/>
            <category android:name="com.example.caesar.gcm" />
        </intent-filter>

    </reciever>
        <service
            android:name=".MyGcmListenerService"
            android:exported="false" >
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            </intent-filter>
        </service>

        <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>

        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
    </application>

</manifest>

public class MainActivity extends Activity {

GoogleCloudMessaging gcm;
String regid;
TextView mDisplay;
TextView textView;
String SENDER_ID = "";
public static final String EXTRA_MESSAGE = "message";
public static final String PROPERTY_REG_ID = "registration_id";
private static final String PROPERTY_APP_VERSION = "appVersion";
Context context;

AsyncHttpClient client = new AsyncHttpClient();

static final String TAG = "GCMDemo";

String mess = "";


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

    mDisplay = (TextView) findViewById(R.id.display);

    textView = (TextView) findViewById(R.id.textView);


    context = getApplicationContext();

    //  GCM registration.
    if (checkPlayServices()) {
        gcm = GoogleCloudMessaging.getInstance(this);
        regid = getRegistrationId(context);

        textView.setText(regid);

        SendID();


        if (regid.isEmpty()) {
            registerInBackground();
        }
    } else {
        Log.i(TAG, "No valid Google Play Services APK found.");
    }
}

public void SendID(){
    final RequestParams params = new RequestParams();
    params.put("id", regid);

    client.post("", params, new JsonHttpResponseHandler() {



        @Override
        public void onStart() {
            // called before request is started
        }

        public void onSuccess(int statusCode, PreferenceActivity.Header[] headers, JSONObject response) {

        }

        public void onFailure(int statusCode, PreferenceActivity.Header[] headers, JSONObject errorResponse, Throwable e) {
            // called when response HTTP status is "4XX" (eg. 401, 403, 404)
        }

        @Override
        public void onRetry(int retryNo) {
            // called when request is retried
        }
    });


}
private boolean checkPlayServices() {

    int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
    if (status != ConnectionResult.SUCCESS) {
        if (GooglePlayServicesUtil.isUserRecoverableError(status)) {
            Log.i(TAG, String.valueOf(status));
        } else {
            Toast.makeText(this, "This device is not supported.",
                    Toast.LENGTH_LONG).show();
            finish();
        }
        return false;
    }
    return true;
}

private void registerInBackground() {
    new AsyncTask<Void,Void,String>() {
        @Override
        protected String doInBackground(Void... params) {
            String msg = "";
            try {
                if (gcm == null) {
                    gcm = GoogleCloudMessaging.getInstance(context);
                }
                regid = gcm.register(SENDER_ID);
                msg = "Device registered, registration ID=" + regid;

                // You should send the registration ID to your server over HTTP,
                // so it can use GCM/HTTP or CCS to send messages to your app.
                // The request to your server should be authenticated if your app
                // is using accounts.
                sendRegistrationIdToBackend();

                // For this demo: we don't need to send it because the device
                // will send upstream messages to a server that echo back the
                // message using the 'from' address in the message.

                // Persist the registration ID - no need to register again.
                storeRegistrationId(context, regid);
            } catch (IOException ex) {
                msg = "Error :" + ex.getMessage();
                // If there is an error, don't just keep trying to register.
                // Require the user to click a button again, or perform
                // exponential back-off.
            }
            return msg;
        }

        private void storeRegistrationId(Context context, String regId) {
            final SharedPreferences prefs = getGCMPreferences(context);
            int appVersion = getAppVersion(context);
            Log.i(TAG, "Saving regId on app version " + appVersion);
            SharedPreferences.Editor editor = prefs.edit();
            editor.putString(PROPERTY_REG_ID, regId);
            editor.putInt(PROPERTY_APP_VERSION, appVersion);
            editor.commit();
        }

        @Override
        protected void onPostExecute(String msg) {
            mDisplay.append(msg + "\n");
        }
    }.execute(null, null, null);
}
private void sendRegistrationIdToBackend() {
    // Your implementation here.
}


private String getRegistrationId(Context context) {
    final SharedPreferences prefs = getGCMPreferences(context);
    String registrationId = prefs.getString(PROPERTY_REG_ID, "");
    if (registrationId.isEmpty()) {
        Log.i(TAG, "Registration not found.");
        return "";
    }
    // Check if app was updated; if so, it must clear the registration ID
    // since the existing registration ID is not guaranteed to work with
    // the new app version.
    int registeredVersion = prefs.getInt(PROPERTY_APP_VERSION, Integer.MIN_VALUE);
    int currentVersion = getAppVersion(context);
    if (registeredVersion != currentVersion) {
        Log.i(TAG, "App version changed.");
        return "";
    }
    return registrationId;
}


private static int getAppVersion(Context context) {
    try {
        PackageInfo packageInfo = context.getPackageManager()
                .getPackageInfo(context.getPackageName(), 0);
        return packageInfo.versionCode;
    } catch (PackageManager.NameNotFoundException e) {
        // should never happen
        throw new RuntimeException("Could not get package name: " + e);
    }
}

private SharedPreferences getGCMPreferences(Context context) {
    // This sample app persists the registration ID in shared preferences, but
    // how you store the registration ID in your app is up to you.
    return getSharedPreferences(Activity.class.getSimpleName(),
            Context.MODE_PRIVATE);
}

}

//updated main

public class MainActivity extends Activity {

GoogleCloudMessaging gcm;
TextView mDisplay;
TextView textView;
public static final String EXTRA_MESSAGE = "message";
public static final String PROPERTY_REG_ID = "registration_id";
private static final String PROPERTY_APP_VERSION = "appVersion";
Context context;

AsyncHttpClient client = new AsyncHttpClient();

static final String TAG = "GCMDemo";


Context mContext = this;

String mess = "";


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


    mDisplay = (TextView) findViewById(R.id.display);

    textView = (TextView) findViewById(R.id.textView);


    SharedPreferences appPrefs = mContext.getSharedPreferences("com.example.caesar.gcm", Context.MODE_PRIVATE);
    String token = appPrefs.getString("token", "");
    if (token.isEmpty()) {
        try {
            getGCMToken("1048700326431");// Project ID: xxxx Project Number: 0123456789 at https://console.developers.google.com/project/...

            textView.setText(token);


        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}



private void getGCMToken(final String senderId) throws Exception {
    new AsyncTask<Void, Void, Void>() {
        @Override
        protected Void doInBackground(Void... params) {
            String token = "";
            try {
                InstanceID instanceID = InstanceID.getInstance(mContext);
                token = instanceID.getToken(senderId, GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
                if (token != null && !token.isEmpty()) {
                    SharedPreferences appPrefs = mContext.getSharedPreferences("com.example.caesar.gcm", Context.MODE_PRIVATE);
                    SharedPreferences.Editor prefsEditor = appPrefs.edit();
                    prefsEditor.putString("token", token);
                    prefsEditor.apply();
                }
                Log.i("GCM_Token", token);

                textView.setText(token);

                SendID(token);

            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    }.execute();
}

public void SendID(String token){
    final RequestParams params = new RequestParams();
    params.put("id", token);

    client.post("https://death-sarodh.c9.io/gcm", params, new JsonHttpResponseHandler() {



        @Override
        public void onStart() {
            // called before request is started
        }

        public void onSuccess(int statusCode, PreferenceActivity.Header[] headers, JSONObject response) {

        }

        public void onFailure(int statusCode, PreferenceActivity.Header[] headers, JSONObject errorResponse, Throwable e) {
            // called when response HTTP status is "4XX" (eg. 401, 403, 404)
        }

        @Override
        public void onRetry(int retryNo) {
            // called when request is retried
        }
    });


}

}

解决方案

Replace reciever in your Manifest by receiver. Moreover, make sure your app successfully got the token (registration device Id). Hope this helps!

My Manifest:

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

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

<permission android:name="com.example.gcm.permission.C2D_MESSAGE"
    android:protectionLevel="signature" />
<uses-permission android:name="com.example.gcm.permission.C2D_MESSAGE" />


<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <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.REGISTRATION" />
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <category android:name="com.example.gcm" />
        </intent-filter>
    </receiver>
    <service android:name=".service.GcmService" android:exported="false">
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
        </intent-filter>
    </service>

    <service android:name=".service.LoggingService" android:exported="false" />

    <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:clearTaskOnLaunch="false"
        android:finishOnTaskLaunch="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

</manifest>

Moreover, check your sever-side response after sending. Perhaps you will get response message like the following if GCM message sucessfully sent:

{"multicast_id":6371085842931382567,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1240780242421810%4c427ca6f9fd7ecd"}]}

About getting token, firstly, I check SharedPreferences, if empty, get token (device registration id) from Google server. Token will be stored in SharedPreferences for other use / providing to server-side app.

public class MainActivity extends Activity {

Context mContext = this;   

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ...
    SharedPreferences appPrefs = mContext.getSharedPreferences("com.example.gcmclient_preferences", Context.MODE_PRIVATE);
    String token = appPrefs.getString("token", "");
    if (token.isEmpty()) {
        try {
            getGCMToken("0123456789"); // Project ID: xxxx Project Number: 0123456789 at https://console.developers.google.com/project/...
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    ...
}
...

private void getGCMToken(final String senderId) throws Exception {
    new AsyncTask<Void, Void, Void>() {
        @Override
        protected String doInBackground(Void... params) {
            String token = "";
            try {
                InstanceID instanceID = InstanceID.getInstance(mContext);
                token = instanceID.getToken(senderId, GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
                if (token != null && !token.isEmpty()) {
                    SharedPreferences appPrefs = mContext.getSharedPreferences("com.example.gcmclient_preferences", Context.MODE_PRIVATE);
                    SharedPreferences.Editor prefsEditor = appPrefs.edit();
                    prefsEditor.putString("token", token);
                    prefsEditor.commit();
                }
                Log.i("GCM_Token", token);
            } catch (IOException e) {
                e.printStackTrace();
            }    
            return null;            
        }           
    }.execute();
}   
}

这篇关于GCM不是在客户端接收消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆