简体   繁体   English

gcm 未在客户端收到消息

[英]gcm not receiving message on client side

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.我的服务器正在向 gcm serer 发送消息,响应代码为 200。但是我的 OnMessageReceiver 没有被调用,因此我没有收到消息。

public class MyGcmListenerService extends GcmListenerService {公共类 MyGcmListenerService 扩展 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 {公共类 MainActivity 扩展 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 {公共类 MainActivity 扩展 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 .更换reciever在你的清单receiver Moreover, make sure your app successfully got the token (registration device Id).此外,请确保您的应用程序成功获取令牌(注册设备 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:如果 GCM 消息发送成功,您可能会收到如下响应消息:

{"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.关于获取令牌,首先,我检查 SharedPreferences,如果为空,则从 Google 服务器获取令牌(设备注册 ID)。 Token will be stored in SharedPreferences for other use / providing to server-side app.令牌将存储在 SharedPreferences 中以供其他用途/提供给服务器端应用程序。

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();
}   
}

Change this line改变这一行

android:name=".MyGcmListenerService" android:name=".MyGcmListenerService"

instead of above line而不是上面的线

android:name="your package.MyGcmListenerService" android:name="你的包.MyGcmListenerService"

example com.yourappname.gcm.GcmIntentService示例 com.yourappname.gcm.GcmIntentService

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

simple example code for BroadCastReceiver. BroadCastReceiver 的简单示例代码。

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

IntentService意图服务

public class GcmIntentService extends IntentService {
 @Override
protected void onHandleIntent(Intent intent) {
    Bundle extras = intent.getExtras();
    GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
    // The getMessageType() intent parameter must be the intent you received
    // in your BroadcastReceiver.
    String messageType = gcm.getMessageType(intent);

    if (!extras.isEmpty()) {  // has effect of unparcelling Bundles
        /*
         * Filter messages based on message type. Since it is likely that GCM
         * will be extended in the future with new message types, just ignore
         * any message types you're not interested in, or that you don't
         * recognize.
         */
        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());
            // If it's a regular GCM message, do some work.
        } else if (GoogleCloudMessaging.
                MESSAGE_TYPE_MESSAGE.equals(messageType)) {
          Log.e(":::gcm message",extras.getString("key");

        }
    }
    // Release the wake lock provided by the WakefulBroadcastReceiver.
    GcmBroadcastReceiver.completeWakefulIntent(intent);
}
}

Remove below line from your manifest从清单中删除以下行

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

Manifest显现

<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<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" />
    <receiver
        android:name="com.yourappname.gcm.GcmBroadcastReceiver"
        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.gcm" />
        </intent-filter>
    </receiver>
<service android:name="com.yourappname.gcm.GcmIntentService" />

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM