我的服务器正在将消息发送到gcm serer,响应代码为200.但我的OnMessageReceiver未被调用,因此我没有收到消息。
公共类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>
公共类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);
}
}
//更新主要
公共类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
}
});
}
}
答案 0 :(得分:1)
将您的清单中的reciever
替换为receiver
。
此外,请确保您的应用成功获得令牌(注册设备ID)。希望这有帮助!
我的宣言:
<?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>
此外,请在发送后检查您的服务器端响应。如果GCM消息已成功发送,您可能会得到如下所示的响应消息:
{"multicast_id":6371085842931382567,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1240780242421810%4c427ca6f9fd7ecd"}]}
关于获取令牌,首先,我检查SharedPreferences,如果为空,则从Google服务器获取令牌(设备注册ID)。令牌将存储在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();
}
}
答案 1 :(得分:0)
更改此行
机器人:名称=&#34; .MyGcmListenerService&#34;
而不是上线
android:name =&#34;你的包.MyGcmListenerService&#34;
示例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>
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);
}
}
从清单中删除以下行
<permission android:name="com.example.caesar.gcm.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
清单
<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" />