GCM+PHP+MYSQLと組み合わせたアプリを作ろうとしています。私のアプリはGoogleサーバーから登録IDを取得してサーバーに保存できますが、デバイスにメッセージを送信するとonReceive()メソッドが正しく動作しないようです(Google API17を使用したgenymotion Htc One 4.2.2)。
私のサーバーが示すエコーフォーム:
{"multicast_id":6654020603006207086,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1383807091667423%6852480ef9fd7ecd"}]}
したがって、サーバー部分は正常に動作する可能性があると思います。
メッセージを送信する前に、アプリは以下の通知を受けました:
Recieved:Bundle[mParcelledData.dataSize=48]
しかし、メッセージフォームサーバーは消え、 onRecive(...) には何も起こりませんでした。
ここでサーバーのトピックを読みましたが、まだ理由がわかりません。
GCMIntentService を使用せずに Broadcastreceiver を実装するだけです。これは、一部の参照が Google の参照よりも簡単であるためです。
この質問は私を2日間悩ませました、助けてくださいm(_ _)m ..
これが私のマニフェストです:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.csie.gcmtest"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<permission android:name="com.csie.gcmtest.permission.C2D_MESSAGE" android:protectionLevel="signature"></permission>
<uses-permission android:name="com.csie.gcmtest.permission.C2D_MESSAGE"/>
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.csie.gcmtest.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>
<receiver
android:name=".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.csie.gcmtest" />
</intent-filter>
</receiver>
</application>
</manifest>
主な活動:
public class MainActivity extends Activity {
GoogleCloudMessaging gcm;
String SENDER_ID = "327943842431"; //project ID
Context context;
String strRegId;
TextView tvRegisterMsg;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvRegisterMsg = (TextView) findViewById(R.id.tvRegisterMsg);
context = getApplicationContext();
// initial GCM
gcm = GoogleCloudMessaging.getInstance(this);
// register with Google.
new AsyncTask<Void,String,String>() {
@Override
protected String doInBackground(Void... params) {
String msg = "";
try {
if (gcm == null) {
gcm = GoogleCloudMessaging.getInstance(context);
}
strRegId = gcm.register(SENDER_ID);
msg = "Device registered, registration id=" + strRegId;
// send id to our server
sendRegIdToServer(strRegId);
} catch (IOException ex) {
msg = "Error :" + ex.getMessage();
}
return msg;
}
@Override
protected void onPostExecute(String msg) {
tvRegisterMsg.append(msg + "\n");
}
}.execute(null, null, null);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private void sendRegIdToServer(final String strId) {
new AsyncTask<Void,String,String>() {
@Override
protected String doInBackground(Void... params) {
String strResponseCode = "";
HttpPost httpRequest = new HttpPost("http://89.0.1.213/android_add.php");
List<NameValuePair> p = new ArrayList<NameValuePair>();
p.add(new BasicNameValuePair("data", strId));
try {
/* 發出HTTP request */
httpRequest.setEntity(new UrlEncodedFormEntity(p, HTTP.UTF_8));
/* 取得HTTP response */
HttpResponse httpResponse = new DefaultHttpClient().execute(httpRequest);
strResponseCode = Integer.toString(httpResponse.getStatusLine().getStatusCode());
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return strResponseCode;
}
@Override
protected void onPostExecute(String msg) {
tvRegisterMsg.append("status code: " + msg + "\n");
}
}.execute(null, null, null);
}
}
放送受信機:
public class GcmBroadcastReceiver 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) {
Log.i("onReceive","fuck");
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());
Log.i("onReceive","fuck_type_error");
} else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED .equals(messageType)) {
sendNotification("Deleted messages on server: " + intent.getExtras().toString());
Log.i("onReceive","deleted");
} else {
sendNotification("Received: " + intent.getExtras().toString());
Log.i("onReceive","received:"+ intent.getExtras().toString());
}
setResultCode(Activity.RESULT_OK);
Log.i("onReceive","fuck done");
}
// 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, MainActivity.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());
}
}