Я реализовал обмен сообщениями GCM в своем приложении и на сервере, и все работает нормально, но не на каждом телефоне!
Основная проблема заключается в следующем:
Когда приложение открыто, я получаю сообщение GCM и генерирую уведомление, как и предполагалось, но когда приложение закрывается, я вижу (через LOGCAT), что сообщение было получено, но отменено -> «Приемник вещания, результат = ОТМЕНА».
Следующее, что я не могу заставить свои службы приложений работать в фоновом режиме. Пока я «закрываю» свое приложение из меню «последние действия», оно также останавливается в фоновом режиме (в разделе «Настройки» -> «Приложения» -> «MY_APP» -> принудительная остановка отключена).
Я провел много исследований и думаю, что причина может заключаться в том, что Huawei P8 (основное тестовое устройство) принудительно автоматически закрывает все приложения, когда вы смахиваете их с вкладки «Недавние действия». Но если это так, другие приложения, такие как «Facebook», «Viber» и т. д., не будут отправлять мне push-уведомления.
Манифест.xml
<receiver
android:name="com.happyhour.gcm.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.REBOOT"/>
<action android:name="android.intent.action.PACKAGE_REPLACED"/>
<action android:name="android.intent.action.BATTERY_CHANGED"/>
<action android:name="android.intent.action.USER_PRESENT"/>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.happyhour.main" />
</intent-filter>
</receiver>
<service
android:name="com.happyhour.gcm.GcmIntentService" >
</service>
<receiver android:name="com.happyhour.gcm.UpdateReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<action android:name="android.intent.action.PACKAGE_INSTALL"/>
<data android:path="com.happyhour.main"
android:scheme="package" />
</intent-filter>
</receiver>
GCMBroadCastReceiver
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Log.i("GcmBroadcast",intent.getExtras().toString());
SharedPreferences settings = context.getSharedPreferences("MyPrefsFile", 0);
if (settings.getBoolean("my_first_time", true)) {
//the app is being launched for first time, do something
//do nothing
// record the fact that the app has been started at least once
settings.edit().putBoolean("my_first_time", false).commit();
}else{
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);
}
}
}
GCMIntentService
public class GcmIntentService extends IntentService {
private String TAG = "GcmIntent";
public static final int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
public GcmIntentService() {
super("GcmIntentService");
}
@Override
public void onCreate(){
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
onHandleIntent(intent);
return START_STICKY;
}
@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.
Log.i(TAG, "Received: " + extras.toString());
String messageType = gcm.getMessageType(intent);
Log.i(TAG, "Message type:" + messageType);
if (!extras.isEmpty()) { // has effect of unparcelling Bundle
/*
* 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_MESSAGE.equals(messageType)) {
Log.i(TAG, "Completed work @ " + SystemClock.elapsedRealtime());
// Post notification of received message.
sendNotification(extras.getString("message"), extras.getString("title"));
Log.i(TAG, "Received: " + extras.toString());
}
}
// Release the wake lock provided by the WakefulBroadcastReceiver.
GcmBroadcastReceiver.completeWakefulIntent(intent);
}
// Put the message into a notification and post it.
// This is just one simple example of what you might choose to do with
// a GCM message.
private void sendNotification(String msg, String title) {
mNotificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
if(title.isEmpty()){
title="Happy Hour plus";
}
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, SplashScreen.class), 0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_stat_notification)
.setContentTitle(title)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg))
.setContentText(msg)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setVibrate(new long[] {250,250,250,250})
.setAutoCancel(true);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
public boolean checkApp(){
ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
// get the info from the currently running task
List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
ComponentName componentInfo = taskInfo.get(0).topActivity;
if (componentInfo.getPackageName().equalsIgnoreCase("com.happyhour.main")) {
return true;
} else {
return false;
}
}
}
Я сбит с толку! Не могу найти корень причины.
Заранее спасибо.