Разбор Нажмите регистрации Android уведомление устройство только один раз на одном устройстве

? Mayur Raval @ | Original: StackOverFlow
---

Каждый я использую сервис разбора для Push Notification в мое приложение . но это зарегистрировать все время, когда я повторно установить приложение в одной задаче device.Then в том, что одно устройство получит несколько уведомлений о каждой из них. Я сделал некоторый код для регистрации, которая показана ниже. пожалуйста, помогите мне, спасибо заранее .

Parse.initialize(this, PARSE_APP_ID, PARSE_CLIENT_KEY);
ParseACL defaultACL = new ParseACL();
defaultACL.setPublicReadAccess(true);
ParseACL.setDefaultACL(defaultACL, true);
PushService.setDefaultPushCallback(this, MainActivity.class);
ParseInstallation.getCurrentInstallation().getInstallationId();
ParseInstallation.getCurrentInstallation().saveInBackground();

И Подписка на новости:

PushService.subscribe(this, userName, Detail.class);

In Manifest

Above

  <permission
    android:name="com.example.app.permission.C2D_MESSAGE"
    android:protectionLevel="signature" />

  <uses-permission android:name="com.example.app.permission.C2D_MESSAGE" />

В теге приложения:

    <receiver android:name="com.parse.ParseBroadcastReceiver" >
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <action android:name="android.intent.action.USER_PRESENT" />
            <action android:name="act" />
        </intent-filter>
    </receiver>

    <receiver android:name="com.app.example.PushReceiver" >

        <intent-filter>
            <action android:name="act" />
            </action>
        </intent-filter>
    </receiver>

    <receiver
        android:name="com.parse.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" />
            <action android:name="act" />
            <category android:name="com.example.app" />
        </intent-filter>
    </receiver>

И каждый раз, когда я установке, показать ошибку, которая показана ниже.

03-10 12:18:48.555: E/ParseCommandCache(12709): Failed to run command.
03-10 12:18:48.555: E/ParseCommandCache(12709): com.parse.ParseException: at least one ID field (installationId,deviceToken) must be specified in this operation
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.ParseCommand$3.then(ParseCommand.java:348)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$10.run(Task.java:452)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$1.execute(Task.java:68)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.completeImmediately(Task.java:448)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.continueWith(Task.java:322)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.continueWith(Task.java:333)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$8.then(Task.java:385)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$8.then(Task.java:1)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$11.run(Task.java:485)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$1.execute(Task.java:68)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.completeAfterTask(Task.java:481)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.access$9(Task.java:477)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$7.then(Task.java:350)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$7.then(Task.java:1)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.runContinuations(Task.java:514)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.access$5(Task.java:510)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at   com.parse.Task$TaskCompletionSource.trySetResult(Task.java:569)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$TaskCompletionSource.setResult(Task.java:603)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$11$1.then(Task.java:497)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$11$1.then(Task.java:1)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$10.run(Task.java:452)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$1.execute(Task.java:68)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.completeImmediately(Task.java:448)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.access$8(Task.java:444)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$6.then(Task.java:315)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$6.then(Task.java:1)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.runContinuations(Task.java:514)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.access$5(Task.java:510)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$TaskCompletionSource.trySetResult(Task.java:569)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$TaskCompletionSource.setResult(Task.java:603)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$11$1.then(Task.java:497)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$11$1.then(Task.java:1)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$10.run(Task.java:452)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$1.execute(Task.java:68)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.completeImmediately(Task.java:448)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.continueWith(Task.java:322)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.continueWith(Task.java:333)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$11.run(Task.java:489)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$1.execute(Task.java:68)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.completeAfterTask(Task.java:481)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.access$9(Task.java:477)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$7.then(Task.java:350)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$7.then(Task.java:1)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.runContinuations(Task.java:514)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task.access$5(Task.java:510)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$TaskCompletionSource.trySetResult(Task.java:569)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$TaskCompletionSource.setResult(Task.java:603)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at com.parse.Task$3.run(Task.java:228)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:152)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:265)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
03-10 12:18:48.555: E/ParseCommandCache(12709):     at java.lang.Thread.run(Thread.java:841)

Я хочу зарегистрировать только один раз для на устройстве . должно быть непроблема, если приложение установлено несколько раз в device.please мне помочь, спасибо заранее.

На мой случай Samsung вкладке 3 регистров в два раза с тем же UniqueID . Является UniqueID отмечен как уникального столбца в разбора данных? Или мы должны сделать его уникальным ? если да, то как?

---

Top 5 ответ

1Eran @

PushService.subscribe Кажется кэшировать подписку на локальном диске, чтобы избежать повторного подписавшись когда вы запускаете приложение несколько раз.

Это то, чтопервый параметр этого метода используется для:

Контекст - используется для доступа к локальным хранения для кэширования   Подписка, поэтому он должен в настоящее время             бытьжизнеспособным контекст .

( цитата из http://parse.com/docs/android/api/com/parse/PushService.html ) .

Однако, когда вы удалите приложение, локальное хранилище для этого приложения стирается из памяти устройства, так чтоновая установка будет вызывать PushService.subscribe перерегистрировать в Google Cloud Messaging. Еслирегистрация нового возвращает новый регистрационный номер, анализировать будет иметь два идентификаторы регистрации, которые могут быть использованы для отправки уведомления толчка для вашего приложения, и оба из них будут связаны с тем же именем пользователя, которую вы предоставили, чтобы subscribe . Поэтому, направив уведомление, что имя пользователя будет отправить его в обоих идентификаторов регистрации, заставляя его прибыть в два раза.

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

2Mayur Raval @

Я получил его после обновления таблицы с посыла уникальный идентификатор андроид устройства .

 String  android_id = Secure.getString(getApplicationContext().getContentResolver(),Secure.ANDROID_ID);         
    Log.e("LOG","android id >>" + android_id);

    PushService.setDefaultPushCallback(this, MainActivity.class);

    ParseInstallation installation = ParseInstallation.getCurrentInstallation();
    installation.put("UniqueId",android_id);

    installation.saveInBackground();

Это обновление сырьевого, но это не повторной регистрации устройства .

3Sheraz Ahmad Khilji @

Я также сталкиваются с этой проблемы. Я, конечно, решить ее по телефону ниже метод в моей деятельности в onCreate()

/**
     * Initialize Push Messaging Service and subscribe to all-users channel
     */
    private void initParsePushMessaging() {
        ParseInstallation parseInstallation = ParseInstallation
                .getCurrentInstallation();
        //You might skip this if
        if (ParseUser.getCurrentUser() != null) {
            parseInstallation.put("user",
                    ParseUser.getCurrentUser());
        }
        if (parseInstallation.getObjectId() != null)
            parseInstallation.saveInBackground(new SaveCallback() {

                @Override
                public void done(ParseException e) {
                    PushService.subscribe(getApplicationContext(),"channel_name",
                            MainHomeActivity.class);
                }
            });

    }

Несмотря на то, что не полностью решить мою проблему, но сейчас мое приложение не висит и не более ANR- за этого реализации Разбор . Если я повторно установить приложение и запустить его сейчас, топриложение создает новую запись для установки и удаления этопоследний. Единственная проблема заключается в том, чтоCHANNEL_NAME не подписан на этой перспективе, но при следующем запускеканала успешно подписаны .

4user1201239 @

Я думаю, Mukul предоставил большую код облако для этого вопроса

here it is

Parse.Cloud.beforeSave(Parse.Installation, function(request, response) {
Parse.Cloud.useMasterKey();
var query = new Parse.Query(Parse.Installation);
query.equalTo("owner", request.user);
query.equalTo("uniqueID", request.object.get("uniqueID"));
query.first().then(function(duplicate) {
    if (typeof duplicate === "undefined") {
        console.log("Duplicate does not exist,New installation");
        response.success();
    } else {
        console.log("Duplicate exist..Trying to delete " + duplicate.id);
        duplicate.destroy().then(function(duplicate) {
            console.log("Successfully deleted duplicate");
            response.success();
        }, function() {
            console.log(error.code + " " + error.message);
            response.success();
        });

    }
}, function(error) {
    console.warn(error.code + error.message);
    response.success();
});
});

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

вотссылка нато же самое с лучшего объяснения по Mukul  https://www.parse.com/questions/check-for-duplicate-installations-of-same-user-on-re-installation-of-app

5Albert Vila @

То, что работало для меня, чтобы избавиться от этого исключения использовал saveEventually() вместо saveInBackground() .

Здесь у вас есть http://stackoverflow.com/a/27151459/4034572 мой ответ на подобный вопрос .

Я думаю, что saveEventually() являетсялучшим вариантом, потому что это гарантирует, чтоустановка будет всегда сохраняется, независимо от наличия netwwork . В отличие от этого, saveInBackground() естьшанс, чтоспасбросок проваливается из-за отсутствия сетевых подключений . Кроме того, с saveEventually() вам не нужно делать каких-либо проверки ошибок, которые вы должны сделать вSaveCallback() с saveInBackground() .

Что касается дубликатов уведомлений, это не должно произойти, если вы используете последнюю Разбор SDK ( это не произошло со мной с версии 1.7.1 ) . Былошибка, которая была теперь решена . См http://stackoverflow.com/q/24590804/4034572 и https://developers.facebook.com/bugs/1520221558200050/ .

Обратите внимание, что в первый разпользователь получает уведомление после переустановки приложения, это уведомление может быть доставлено в два раза. Это случилось со мной, но происходит только для самого первого уведомления. (См ссылку FB для более подробной информации. ) После этого дубликата уведомлениястарой установки будут удалены автоматически Parse . Это мой опыт.

Если вы пытаетесь, чтобы избежать отправки дубликатов уведомлений по реализации какая-то логика в CloudCode (с использованием BeforeSave, что вызывает при сохранении новой установки, проверьте, еслиприложение уже установлено в устройство и удаления старую установку ), не делать что ! Там не нужно. Разбор сделает это за вас: это будет удалить старую версию :)