Intereting Posts
Пользовательский вид onMeasure: как получить ширину по высоте Ошибка: ConnectionResult {statusCode = INTERNAL_ERROR, разрешение = null} Gson – конвертировать из Json в типизированный ArrayList <T> Горизонтальный LinearLayout в Анко Android Studio – удалить модуль – IncorrectOperationException: не следует изменять внешнюю команду документа или отменять прозрачность Gradle: идентификатор ресурса не найден для атрибута при использовании flavors и packageName ANDROID: Есть ли бесплатный сторонний медиаплеер для потоковой передачи видео в формате MPEG4? Действие камеры по умолчанию не завершено. Нажмите кнопку OK. IllegalArgumentException: радиус должен быть> 0 Получение доступа к кешу медиаплеера Camerainfo.orientation дает неправильный ответ Android. Используйте WebView для оценки строки javascript и возврата значения. Каков наилучший способ «настройки приложения» в Android? Как применить стиль ко всем кнопкам приложения для Android Получить последнее вставленное значение из базы данных sqlite Android

Android GCM и несколько токенов

Я регистрируюсь в GCM с помощью GoogleCloudMessaging.getInstance (контекст); И сохранить полученный токен на устройстве. Затем отправьте его на сервер и связать с учетной записью пользователя. Если я удалю свое приложение без выхода из системы и установки снова и войдите в систему с другим пользователем, я получаю новый токен и отправлю его на сервер. И когда нажатие посылается первому пользователю, я вижу их, когда я вошел в систему со вторым пользователем.

Почему GCM посылает мне разные токены и как я могу это обработать?

Solutions Collecting From Web of "Android GCM и несколько токенов"

Добро пожаловать в чудесный мир дублированных сообщений от Google Cloud Messaging . Когда это происходит, движок GCM позволяет Canonical IDs решить его. Это может произойти из-за того, что вы зарегистрировались с несколькими идентификаторами для одного и того же устройства или потому, что сервер GCM не получил вызов unregister() когда приложение было удалено. Используя канонические идентификаторы, ваш идентификатор будет последней зарегистрированной вами регистрацией.

В соответствии с GCM reference об этом:

Канонические идентификаторы

На стороне сервера, пока приложение ведет себя хорошо, все должно работать нормально. Однако, если ошибка в приложении вызывает несколько регистраций для одного и того же устройства, может быть сложно согласовать состояние, и вы можете получить дубликаты сообщений.

GCM предоставляет средство, называемое «идентификаторы канонической регистрации», чтобы легко восстановить из этих ситуаций. Идентификатор канонической регистрации определяется как идентификатор последней регистрации, запрошенной вашим приложением. Это идентификатор, который сервер должен использовать при отправке сообщений на устройство.

Если позже вы попытаетесь отправить сообщение с использованием другого регистрационного идентификатора, GCM обработает запрос, как обычно, но он будет содержать идентификатор канонической регистрации в поле registration_id ответа. Обязательно замените идентификатор регистрации, хранящийся на вашем сервере, этим каноническим идентификатором, так как в конечном итоге идентификатор, который вы используете, перестанет работать.

Больше информации здесь .

Также есть практический пример о том, как это сделать, может быть полезно:

  • Канонический идентификатор регистрации и формат идентификатора сообщения

При удалении приложения я испытывал изменения идентификатора регистрации, пытаясь отправить сообщения в приложение во время его удаления (до получения ошибки NotRegistered ), а затем снова установить.

Костин Манолаче из Google предлагает изменить регистрационные идентификаторы таким образом:

Предлагаемое / обходное решение – генерировать свой собственный случайный идентификатор, сохраненный, например, в качестве общего предпочтения. В каждом обновлении приложения вы можете загрузить идентификатор и потенциально новый идентификатор регистрации. Это также может помочь отслеживать и отлаживать изменения обновления и регистрации на стороне сервера.

Конечно, это работает только тогда, когда приложение остается установленным (поскольку общие настройки удаляются вместе с приложением). Однако, если устройство имеет внешнее хранилище, вы можете сохранить там свой идентификатор, а когда приложение будет установлено снова, загрузите сохраненный идентификатор из внешнего хранилища. Таким образом, вы узнаете новый регистрационный идентификатор, а старый идентификатор регистрации будет принадлежать тому же устройству.

Кроме того, вы должны обрабатывать ответы на канонические регистрационные идентификаторы от Google на своем сервере, как указано в другом ответе.

Вы можете отправить идентификатор устройства Android вместе с идентификатором регистрации. Идентификатор устройства Android уникален и остается неизменным при повторной установке приложения и изменяется только в том случае, если устройство перезагружено.

Пример. Как получить уникальный идентификатор устройства на Android?

Отправка Push Notification на несколько устройств аналогична отправке на отдельное устройство. Просто сохраните регистрационный токен всего зарегистрированного устройства на свой сервер. И при вызове push-уведомления с curl (я предполагаю, что вы используете php как серверную). Поместите весь идентификатор регистрации в массив. Это пример кода

 <?php //Define your GCM server key here define('API_ACCESS_KEY', 'your server api key'); //Function to send push notification to all function sendToAll($message) { $db = new DbOperation(); $tokens = $db->getAllToken(); $regTokens = array(); while($row = $tokens->fetch_assoc()){ array_push($regTokens,$row['token']); } sendNotification($regTokens,$message); } //function to send push notification to an individual function sendToOne($email,$message){ $db = new DbOperation(); $token = $db->getIndividualToken($email); sendNotification(array($token),$message); } //This function will actually send the notification function sendNotification($registrationIds, $message) { $msg = array ( 'message' => $message, 'title' => 'Android Push Notification using Google Cloud Messaging', 'subtitle' => 'www.simplifiedcoding.net', 'tickerText' => 'Ticker text here...Ticker text here...Ticker text here', 'vibrate' => 1, 'sound' => 1, 'largeIcon' => 'large_icon', 'smallIcon' => 'small_icon' ); $fields = array ( 'registration_ids' => $registrationIds, 'data' => $msg ); $headers = array ( 'Authorization: key=' . API_ACCESS_KEY, 'Content-Type: application/json' ); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://android.googleapis.com/gcm/send'); 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); curl_close($ch); $res = json_decode($result); $flag = $res->success; if($flag >= 1){ header('Location: index.php?success'); }else{ header('Location: index.php?failure'); } } 

В приведенном выше коде мы извлекаем токен регистрации из таблицы mysql. Для отправки на все устройства нам нужны все токены. И для отправки отдельного устройства нам нужен токен только для этого устройства.

Источник: пример Google Cloud Messaging

Сначала, когда вы отправляете уведомление, отправляйте идентификатор пользователя с ним и спросите, есть ли id в sharedpreference == comming или нет

Если вы отправляете уведомления всем пользователям, и может быть, у кого-то есть 2 уведомления, пока он должен получить только один

Создайте файл на своем сервере и с любым номером скажите 0, затем, когда вы хотите отправить уведомление, отправьте это число с ним, затем добавьте его к этому номеру ++, чтобы быть новым номером в следующем уведомлении, с каждым новым

В приложении android app добавьте переменную и пусть эта переменная = переменная comming с сервера после добавления уведомления, но вам нужно спросить, есть if(number_in_your_service!=server_number) // добавить уведомление

Любое количество уведомлений, отправленных только одним, появится

 public class GcmIntentService extends IntentService { public static int openintent; public static final int NOTIFICATION_ID = 1; private static final String TAG = "GcmIntentService"; private static String number_in_your_service="somethingneversend"; NotificationCompat.Builder builder; public GcmIntentService() { super("GcmIntentService"); } @Override protected void onHandleIntent(Intent intent) { Bundle extras = intent.getExtras(); GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this); String messageType = gcm.getMessageType(intent); if (!extras.isEmpty()) { // has effect of unparcelling Bundle if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType)) { } else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType)) { // If it's a regular GCM message, do some work. } else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) { // This loop represents the service doing some work. for (int i = 0; i < 5; i++) { Log.i(TAG, "Working... " + (i + 1) + "/5 @ " + SystemClock.elapsedRealtime()); try { Thread.sleep(100); } catch (InterruptedException e) { } } Log.i(TAG, "Completed work @ " + SystemClock.elapsedRealtime()); // Post notification of received message. sendNotification(extras); Log.i(TAG, "Received: " + extras.toString()); } } // Release the wake lock provided by the WakefulBroadcastReceiver. GcmBroadcastReceiver.completeWakefulIntent(intent); } private void sendNotification(Bundle extras) { if((extras.getString("server_number")).equals(number_in_your_service)) { Intent intent = new Intent(this, Main_Page_G.class); intent.putExtra("frame",100); intent.putExtra("bundle",extras); final PendingIntent contentIntent = PendingIntent.getActivity(this, 120, intent, PendingIntent.FLAG_UPDATE_CURRENT); NotificationManager mNotificationManager; NotificationCompat.Builder mBuilder = new NotificationCompat.Builder( GcmIntentService.this).setContentTitle("name") .setContentText("content") .setDefaults(Notification.DEFAULT_SOUND) .setContentInfo("Test") .setSmallIcon(R.drawable.rehablogo2) .setAutoCancel(true); mBuilder.setContentIntent(contentIntent); mNotificationManager = (NotificationManager) GcmIntentService.this .getSystemService(Context.NOTIFICATION_SERVICE); mNotificationManager.notify(id, mBuilder.build()); id=Integer.parseInt(extras.getString("id")); } } }