推送通知在android中获得多次
Posted
技术标签:
【中文标题】推送通知在android中获得多次【英文标题】:Push notification getting mutiple times in android 【发布时间】:2016-03-23 08:37:39 【问题描述】:我使用 Eclipse 创建了一个移动应用程序。
服务器通过 GCM(在 php 中)发送推送通知。
第一次安装 APK 时,它会发送一个推送通知,该通知工作正常。第二次(同一设备上的同一个APP)发送两次,第三次,三次,依此类推。
我发现问题是由于添加了同一设备的多个 ID 造成的。因此,如果我手动删除所有 ID 并重新安装 APK,它将正常工作。
$url = 'https://android.googleapis.com/gcm/send';
$fields = array('registration_ids' => $registatoin_ids,'data' => $message,); $headers = array( 'Authorization: key=' . 'asbjadbdb','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_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);
echo $result;
安卓端
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(false,"Send error: " + extras.toString(),null,null,null);
else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED
.equals(messageType))
sendNotification(false,"Deleted messages on server: "
+ extras.toString(),null,null,null);
else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE
.equals(messageType))
// sendNotification("Message Received from Google GCM Server:\n\n"
// + extras.get(ApplicationConstants.MSG_KEY));
String name=extras.getString("name");
String address=extras.getString("address");;
sendNotification(true,name,address);
GcmBroadcastReceiver.completeWakefulIntent(intent);
【问题讨论】:
能否提供发送和接收通知的代码? 第一次安装APK时,它会发送一个推送通知,它工作正常。秒数(同一设备上的同一个APP)发送两次,第三次,三次,以此类推。 好的,但是通过向我们提供您为发送推送通知而编写的实际代码来帮助我们帮助您 @sharsadkk!先给我们看代码。 写你的php代码覆盖之前的push id,是一样的。 【参考方案1】:这就是我设法使用 PHP 通过 GCM 处理推送通知的方式。
服务器是一个复杂的 REST 服务器,但现在您只需要了解其中的一小部分。
接收并存储Push token
您需要Push token
来确定 GCM 应该在哪个设备上发送推送。因此,您需要存储它,但请记住它可能会发生变化,如果发生这种情况,您的应用程序需要将新的发送到服务器,并且需要在数据库中进行更改。
发送Push notification
要发送推送通知,我从数据库中恢复 Push token
,然后使用 PushSender
类实际发送 push notification
使用来自我的mysql
服务器的查询检索push token
。
PushSender
类的用法:
$push = new PushSender('The push title','The message',$push_token]);
$ret = $push->sendToAndroid();
// Check $ret value for errors or success
PushSender
类:
Class PushSender
private $title;
private $message;
private $pushtoken;
private static $ANDROID_URL = 'https://android.googleapis.com/gcm/send';
private static $ANDROID_API_KEY = 'YOUR-API-KEY';
public function __construct($title, $message, $pushtoken)
$this->title = $title;
$this->message = $message;
$this->pushtoken = $pushtoken;
public function sendToAndroid()
$fields = array(
'registration_ids' => array($this->pushtoken),
'data' => array( "title"=>$this->title, "message" => $this->message ),
);
$headers = array(
'Authorization: key=' . self::$ANDROID_API_KEY,
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, self::$ANDROID_URL);
curl_setopt( $ch, CURLOPT_POST, true );
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER , false );
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST , false );
curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode( $fields ) );
$result = curl_exec($ch);
if( curl_errno($ch) )
curl_close($ch);
return json_encode(array("status"=>"ko","payload"=>"Error: ".curl_error($ch)));
curl_close($ch);
return $result;
通过服务在 Android 中接收push notification
。
public class PushListenerService extends GcmListenerService
@Override
public void onMessageReceived(String from, Bundle data)
String message = data.getString("message");
// Do whatever you need to do
// Then send the notification
sendNotification(message);
private void sendNotification(String message)
Intent intent = new Intent(this, YourClass.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 = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.an_icon)
.setContentTitle(getString(R.string.app_name))
.setContentText(Helpers.getString(R.string.push_notification_message))
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
try
notificationBuilder
.setLargeIcon(Bitmap.createBitmap(((BitmapDrawable)getDrawable(R.drawable.your_icon)).getBitmap()));
catch (NullPointerException e)
e.printStackTrace();
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
【讨论】:
@sharsadkk 你需要更多解释或例子吗? 按照您上面的解释完成了。但是对于第二次安装,设备会收到 2 次通知 我将每次登录时间发送到 phpMyAdmin 。如果令牌相同而不做任何其他事情,则向 db 中添加新条目 您发布的与GCM
联系的代码嵌套在循环或类似内容中?你如何从数据库中检索推送令牌?您是否尝试在使用它之前在服务器上打印它(尝试:var_dump($registration_ids);
)以查看它是否仅包含 one 推送令牌(应该如此)或是否包含重复的推送令牌(可能导致多次发送)
对多个设备使用唯一用户名。所以我无法识别哪个设备令牌。总是大于 1以上是关于推送通知在android中获得多次的主要内容,如果未能解决你的问题,请参考以下文章