アプリにプッシュ通知サービスを実装しています。Android developers.comのチュートリアルに従いましたが、残念ながら通知を受け取りませんでした。
登録 ID を正常に受信していますが、バック ED サービスが正常な応答を受信しても、デバイスはバックエンドから通知を受信しません。
ps : Google クラウド サーバーに通知を送信するバック エンド サービスの実装から確信しています。
この問題を解決するのを手伝ってくれる人はいますか..?、事前に感謝します。
以下に私の実装があります。
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ettamen.app"
android:versionCode="1"
android:versionName="1.0" >
<supports-screens
android:anyDensity="true"
android:largeScreens="true"
android:normalScreens="true"
android:resizeable="true"
android:smallScreens="true"
android:xlargeScreens="true" />
<!-- GCM connects to Internet Services. -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- GCM requires a Google account. -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<!-- Keeps the processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- Creates a custom permission so only this app can receive its messages. -->
<permission
android:name="com.ettamen.app.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.ettamen.app.permission.C2D_MESSAGE" />
<!-- This app has permission to register and receive data message. -->
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<!-- Network State Permissions to detect Internet status -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Permission to vibrate -->
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.SEND_SMS" />
<application
android:hardwareAccelerated="true"
android:icon="@drawable/icon"
android:label="@string/app_name" >
<activity
android:name="Ettamen"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale"
android:label="@string/app_name"
android:theme="@android:style/Theme.Black.NoTitleBar" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name="com.ettamen.app.pushnotifications.CordovaGCMBroadcastReceiver"
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.ettamen.app.pushnotifications" />
</intent-filter>
</receiver>
<service android:name="com.ettamen.app.pushnotifications.GCMIntentService" >
</service>
<activity android:name=".pushnotifications.PushHandlerActivity" >
</activity>
<service android:name="LocationUpdateService" >
</service>
</application>
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
</manifest>
MyReceiver.java
import com.ettamen.app.R;
import com.google.android.gms.gcm.GoogleCloudMessaging;
/*
* Implementation of GCMBroadcastReceiver that hard-wires the intent service to be
* com.plugin.gcm.GCMIntentService, instead of your_package.GCMIntentService
*/
public class CordovaGCMBroadcastReceiver extends BroadcastReceiver {
static final String TAG = "GCMDemo";
public static final int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
Context ctx;
@Override
public void onReceive(Context context, Intent intent) {
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context);
ctx = context;
String messageType = gcm.getMessageType(intent);
if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
sendNotification("Send error: " + intent.getExtras().toString());
} else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED
.equals(messageType)) {
sendNotification("Deleted messages on server: "
+ intent.getExtras().toString());
} else {
sendNotification("Received: " + intent.getExtras().toString());
}
setResultCode(Activity.RESULT_OK);
}
// Put the GCM message into a notification and post it.
private void sendNotification(String msg) {
mNotificationManager = (NotificationManager) ctx
.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(ctx, 0,
new Intent(ctx, PushHandlerActivity.class), 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
ctx).setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("GCM Notification")
.setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
.setContentText(msg);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
}
GCM インテント サービス
import android.app.ActivityManager.RunningTaskInfo; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.media.Ringtone; import android.media.RingtoneManager; import android.net.Uri; import android.os.Bundle; import android.support.v4.app.NotificationCompat; import android.util.Log; public class GCMIntentService extends GCMBaseIntentService { public static final int NOTIFICATION_ID = 237; private static final String TAG = "GCMIntentService"; public GCMIntentService() { super("GCMIntentService"); } @Override public void onRegistered(Context context, String regId) { } @Override public void onUnregistered(Context context, String regId) { } @Override protected void onMessage(Context context, Intent intent) { Log.d(TAG, "onMessage - context: " + context); // Extract the payload from the message Bundle extras = intent.getExtras(); if (extras != null) { createNotification(context, extras); } } public void createNotification(Context context, Bundle extras) { NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); String appName = getAppName(this); Intent notificationIntent = new Intent(this, PushHandlerActivity.class); notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); notificationIntent.putExtra("pushBundle", extras); PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT); NotificationCompat.Builder mBuilder = new NotificationCompat.Builder( context).setSmallIcon(context.getApplicationInfo().icon) .setWhen(System.currentTimeMillis()).setContentTitle(appName) .setTicker(appName).setContentIntent(contentIntent); String message = extras.getString("message"); if (message != null) { mBuilder.setContentText(message); } else { mBuilder.setContentText("<missing message content>"); } String msgcnt = extras.getString("msgcnt"); if (msgcnt != null) { mBuilder.setNumber(Integer.parseInt(msgcnt)); } mNotificationManager.notify((String) appName, NOTIFICATION_ID, mBuilder.build()); tryPlayRingtone(); } private void tryPlayRingtone() { try { Uri notification = RingtoneManager .getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification); r.play(); } catch (Exception e) { Log.e(TAG, "failed to play notification ringtone"); } } public static void cancelNotification(Context context) { NotificationManager mNotificationManager = (NotificationManager) context .getSystemService(Context.NOTIFICATION_SERVICE); mNotificationManager.cancel((String) getAppName(context), NOTIFICATION_ID); } private static String getAppName(Context context) { CharSequence appName = context.getPackageManager().getApplicationLabel( context.getApplicationInfo()); return (String) appName; } public boolean isInForeground() { ActivityManager activityManager = (ActivityManager) getApplicationContext() .getSystemService(Context.ACTIVITY_SERVICE); List<RunningTaskInfo> services = activityManager .getRunningTasks(Integer.MAX_VALUE); if (services.get(0).topActivity .getPackageName() .toString() .equalsIgnoreCase( getApplicationContext().getPackageName().toString())) return true; return false; } @Override public void onError(Context context, String errorId) { Log.e(TAG, "onError - errorId: " + errorId); }
}
- PushHandlerActivity
package com.ettamen.app.pushnotifications;
import com.ettamen.app.PushNotificationWorker;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
public class PushHandlerActivity extends Activity {
private static String TAG = "PushHandlerActivity";
/*
* this activity will be started if the user touches a notification that we
* own. We send it's data off to the push plugin for processing. If needed,
* we boot up the main activity to kickstart the application.
*
* @see android.app.Activity#onCreate(android.os.Bundle)
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v(TAG, "onCreate");
boolean isPushPluginActive = PushNotificationWorker.isActive();
if (!isPushPluginActive) {
forceMainActivityReload();
}
// processPushBundle(isPushPluginActive);
GCMIntentService.cancelNotification(this);
finish();
}
/**
* Takes the pushBundle extras from the intent, and sends it through to the
* PushPlugin for processing.
*/
private void processPushBundle(boolean isPushPluginActive) {
// Bundle extras = getIntent().getExtras();
//
// if (extras != null) {
//
// Bundle originalExtras = extras.getBundle("pushBundle");
//
// if ( !isPushPluginActive ) {
// originalExtras.putBoolean("coldstart", true);
// }
//
// PushPlugin.sendExtras(originalExtras);
// }
}
/**
* Forces the main activity to re-launch if it's unloaded.
*/
private void forceMainActivityReload() {
PackageManager pm = getPackageManager();
Intent launchIntent = pm
.getLaunchIntentForPackage(getApplicationContext()
.getPackageName());
startActivity(launchIntent);
}
}
- メイン アクティビティの登録コード:
private void getRegID(CallbackContext ctx) {
new AsyncTask<CallbackContext, Void, String>() {
CallbackContext context;
@Override
protected String doInBackground(CallbackContext... params) {
// TODO Auto-generated method stub
context = params[0];
String regid = "";
try {
if (gcm == null) {
gcm = GoogleCloudMessaging.getInstance(cordova
.getActivity());
}
regid = gcm.register(Constants.SENDER_ID);
} catch (IOException ex) {
Log.d("Exceptio:", ex.getMessage());
}
String message = "{\"ChannelURI\":\"" + regid + "\"}";
return message;
};
protected void onPostExecute(String result) {
try {
JSONObject jResult = new JSONObject(result);
context.success(jResult);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.execute(ctx);
}