我想使用GCM(Google云管理)从PHP文件向Android应用发出触发上推通知。但是调用PHP文件时出现错误。
PHP Script:
<?php
function sendPushNotificationToGCM($registration_ids, $message) {
//Google cloud messaging GCM-API url
$url = 'https://android.googleapis.com/gcm/send';
$fields = array(
'registration_ids' => $registration_ids,
'data' => $message,
);
// Google Cloud Messaging GCM API Key
define("API_KEY", "xxxxxxxxxxxxxxxxxxxx");
$headers = array(
'Authorization: key=' . API_KEY,
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
$result = curl_exec($ch);
if ($result === FALSE) {
die('Curl failed: ' . curl_error($ch));
}
curl_close($ch);
return $result;
}
?>
<?php
if(!empty($_GET["shareRegId"])) {
$gcmRegID = $_POST["regId"];
$server = 'localhost';
$username = 'user';
$password = '12345678';
$database = 'db';
$conn = mysql_connect($server, $username, $password);
$db = mysql_select_db($database);
$command = "SELECT * FROM `regids` WHERE (`RegID` = '$gcmRegID');";
$a = mysql_query($command);
$r = mysql_num_rows($a);
$s = "DELETE FROM `regids` WHERE (`RegID` = '');";
if ($r) {
echo "gcm-regID available in database";
}
else {
$query = "INSERT INTO `regids` (`RegID`) VALUES ('$gcmRegID');";
mysql_query($query);
echo "done!";
}
mysql_query($s);
mysql_close();
exit;
}
//Code to get GCM RegIDs from the database and sending the alert
$pushStatus = "";
if(!empty($_GET["push"])) {
$server = 'localhost';
$username = 'pkmantig_administrator';
$password = 'pkmantigravity';
$database = 'pkmantig_phmonitoring';
//Connect to the database
$conn = mysql_connect($server, $username, $password);
$db = mysql_select_db($database);
$query = "SELECT * FROM `regids`;";
$result = mysql_query($query);
$n = mysql_numrows($result);
mysql_close();
$RegistrationIDs = array();
$i = 0;
while ($i < $n) {
$RegistrationIDs[$i] = mysql_result($result,$i,"RegID");
$i++;
}
$pushMessage = $_GET["message"];
$message = array("m" => $pushMessage);
$pushStatus = sendPushNotificationToGCM($RegistrationIDs, $message);
echo $pushMessage;
echo $pushStatus;
echo json_encode($RegistrationIDs);
}
?>
用于通知的Android应用类-GCMNotificationIntentS.java
Java Script:
package com.pkmemas.phiot;
import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.google.android.gms.gcm.GoogleCloudMessaging;
public class GCMNotificationIntentS extends IntentService {
public static final int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
public GCMNotificationIntentS() {
super("GcmIntentService");
}
public static final String TAG = "GCMNotificationIntentS";
@Override
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
String messageType = gcm.getMessageType(intent);
if (!extras.isEmpty()) {
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());
} else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE
.equals(messageType)) {
for (int i = 0; i < 3; i++) {
Log.i(TAG,
"Working... " + (i + 1) + "/5 @ "
+ SystemClock.elapsedRealtime());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
}
Log.i(TAG, "Completed work @ " + SystemClock.elapsedRealtime());
sendNotification("" + extras.get(Connection.MESSAGE_KEY));
Log.i(TAG, "Received: " + extras.toString());
}
}
GcmBroadcastR.completeWakefulIntent(intent);
}
private void sendNotification(String msg) {
Log.d(TAG, "Preparing to send notification...: " + msg);
mNotificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
Intent pendingIntent = new Intent(this, DisplayText.class);
pendingIntent.putExtra("message", msg.substring(msg.lastIndexOf(" ")));
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
pendingIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
this).setSmallIcon(R.drawable.gcm_cloud)
.setContentTitle("PH Notification")
.setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
.setContentText(msg);
mBuilder.setContentIntent(contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
Log.d(TAG, "Notification sent successfully.");
}
当我打开应用程序并触发PHP文件时,出现如下错误:
Error Message:
09-06 13:58:47.843 21060-21377/com.pkmemas.phiot E/AndroidRuntime: FATAL EXCEPTION: IntentService[GcmIntentService]
Process: com.pkmemas.phiot, PID: 21060
java.lang.StringIndexOutOfBoundsException: length=3; index=-1
at java.lang.String.substring(String.java:1935)
at com.pkmemas.phiot.GCMNotificationIntentS.sendNotification(GCMNotificationIntentS.java:79)
at com.pkmemas.phiot.GCMNotificationIntentS.onHandleIntent(GCMNotificationIntentS.java:63)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:68)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:172)
at android.os.HandlerThread.run(HandlerThread.java:65)
当我没有打开应用程序并触发PHP文件时,出现如下错误:
Error Message:
09-06 14:25:04.397 23516-23516/com.pkmemas.phiot E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.pkmemas.phiot, PID: 23516
java.lang.RuntimeException: Unable to start receiver com.pkmemas.phiot.GcmBroadcastR: java.lang.IllegalStateException: Not allowed to start service Intent { act=com.google.android.c2dm.intent.RECEIVE flg=0x1000010 pkg=com.pkmemas.phiot cmp=com.pkmemas.phiot/.GCMNotificationIntentS (has extras) }: app is in background uid UidRecord{bb6ef96 u0a161 RCVR idle procs:1 seq(0,0,0)}
at android.app.ActivityThread.handleReceiver(ActivityThread.java:3273)
at android.app.ActivityThread.-wrap17(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1689)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:172)
at android.app.ActivityThread.main(ActivityThread.java:6637)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: java.lang.IllegalStateException: Not allowed to start service Intent { act=com.google.android.c2dm.intent.RECEIVE flg=0x1000010 pkg=com.pkmemas.phiot cmp=com.pkmemas.phiot/.GCMNotificationIntentS (has extras) }: app is in background uid UidRecord{bb6ef96 u0a161 RCVR idle procs:1 seq(0,0,0)}
at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1505)
at android.app.ContextImpl.startService(ContextImpl.java:1461)
at android.content.ContextWrapper.startService(ContextWrapper.java:644)
at android.content.ContextWrapper.startService(ContextWrapper.java:644)
at android.support.v4.content.WakefulBroadcastReceiver.startWakefulService(WakefulBroadcastReceiver.java:99)
at com.pkmemas.phiot.GcmBroadcastR.onReceive(GcmBroadcastR.java:18)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:3266)
at android.app.ActivityThread.-wrap17(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1689)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:172)
at android.app.ActivityThread.main(ActivityThread.java:6637)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
如果有人知道使android收到通知的解决方案,请通过您的评论告诉我。非常感谢。