Подтвердить что ты не робот

Каковы причины, по которым GCM ID недоступен в некоторых случаях в android

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

Он работает нормально в 60-70% случаях, но другие 30-40% он не работает. Таким образом, остальные пользователи никогда не получают уведомления, которое полезно только для них.

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

String msg = "";
int exceptionOccurRetry = 0;
while (exceptionOccurRetry < 5) {
    try {
        if (gcm == null) {
            gcm = GoogleCloudMessaging.getInstance(context);
        }
        int retry = 0;
        while (retry < 5 && regid.length() == 0) {
            regid = gcm.register(SENDER_ID);

            ++retry;
        }

        msg = "Device registered, registration ID=" + regid;

        if (!regid.equals("")) {
            // You should send the registration ID to your
            // server
            // over HTTP, so it
            // can use GCM/HTTP or CCS to send messages to your
            // app.
            sendRegistrationIdToBackend();
        }
        break;
    } catch (IOException ex) {
        msg = "Error :" + ex.getMessage();
        exceptionOccurRetry++;
    }
}

Мы смотрим, каковы причины, по которым идентификатор GCM недоступен для некоторых пользователей.

Мы знаем только одну причину: если пользовательское устройство не имеет сервисов Google Play, установленных на телефоне пользователя, это не сработает.

Мы рассмотрим еще несколько причин для решения этой проблемы.

4b9b3361

Ответ 1

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

Следует также отметить, что идентификатор GCM должен быть обновлен, если ваша версия приложения изменилась. Вы должны сохранить уникальный идентификатор устройства до SharedPreferences и всегда проверять, совпадает ли он, иначе вы должны снова инициировать процесс регистрации.

Также рекомендуется обновлять идентификатор время от времени.

Ответ 2

Члены нашей команды пытаются отправить уведомление, если оно терпит неудачу, они ждут около 60 миллисекунд или секунд (я не уверен), чтобы это push-уведомление было отправлено повторно, если оно все еще не работает, они ожидают дважды время и т.д.

И вы должны оценить ответ от google, есть строка с ошибкой:

std::string error = response["results"][0]["error"].asString();

Что дает вам информацию, если была перемещена учетная запись пользователя, если вы можете ее использовать:

Json::Value newRegistrationId = response["results"][0]["registration_id"];

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

Ответ 3

Если gcm id равно null, попробуйте запустить фоновое задание и получите id.check ниже код

 private void registerInBackground() {
        new AsyncTask() {
            @Override
            protected String doInBackground(Object[] params) {
                String msg = "";
                try {
                    if (gcm == null) {
                        gcm = GoogleCloudMessaging.getInstance(context);
                    }
                    regid = gcm.register(SENDER_ID);
                    msg = "Device registered, registration ID=" + regid;


                    sendRegistrationIdToBackend();


                    // Persist the regID - no need to register again.
                    storeRegistrationId(context, regid);
                } catch (IOException ex) {
                    msg = "Error :" + ex.getMessage();


                }
                return msg;
            }

            @Override
            protected void onPostExecute(Object msg) {
//                mDisplay.append(msg + "\n");

            }
        }.execute(null, null, null);
    }

Ответ 4

Check if app was updated; if so, it must clear the registration ID since the existing registration ID is not guaranteed to work with the new app version.

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

Ответ 5

Если ваш вопрос сосредоточен на регистрации идентификатора, вы можете игнорировать мой ответ. Извините, мой ответ может быть неправильным ответом на ваш вопрос.

Я просто хочу показать, что на доставку сообщений может влиять какой-то другой "фактор".

  • Вы отправляете все сообщения только одному получателю?

    Одной из наиболее полезных функций в GCM является поддержка до 1000 получателей для одного сообщения. http://developer.android.com/training/cloudsync/gcm.html#

    Иногда наш PHP также теряет отправку сообщений зарегистрированному устройству...

  • Сообщение должно быть меньше 4K (в вашем GCM есть фотографии?)

  • Возможно, вы уже прочитали это.

    Реализация GCM-клиента на Android

    http://developer.android.com/google/gcm/client.html

Ответ 6

Является ли этот фрагмент кода внутри asyncTask, если это не так, может быть ваша ошибка в определенной версии (не помню, какая). gcm-регистрация по какой-либо причине дает NetworkOnMainThreadException, позже они обновились, но я уже эту ту же проблему некоторое время назад, это кусок кода, который я использовал, надеется, что он поможет вам:

private void performRegisterGCM(){
    //Check for GCM availability
    if(checkPlayServices(this)){
        // If this check succeeds, proceed with normal processing.
        // Otherwise, prompt user to get valid Play Services APK.
        gcm = GoogleCloudMessaging.getInstance(this);
        String regId = mPreferences.getGcmRegistrationId();
        if (regId.isEmpty()){
            RegisterGCM();
        }else{
            log.d("regId: "+regId);
        }
    } else {
        // Status is a random integer
        GooglePlayServicesUtil.getErrorDialog(status, this, RQS_GooglePlayServices).show();
    }
}

public static boolean checkPlayServices(Activity mActivity){
    int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(mActivity);
    return resultCode == ConnectionResult.SUCCESS
}

 private void RegisterGCM(){
    new AsyncTask<Void,Void,String>() {
        @Override
        protected String doInBackground(Void... params) {
            String regid = "";
            try{
                if (gcm == null) {
                    gcm = GoogleCloudMessaging.getInstance(mContext);
                }
                regid = gcm.register(Util.SENDER_ID);
            }catch(Exception e){
                log.e(e.getMessage());
            }
            return regid;
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            mPreferences.setGcmRegistrationId(s);
            //TODO send regid to server with all the other info
            sendGCMIDtoBackend(s);
        }
    }.execute(null, null, null);
}

Обратите внимание, что checkPlayServices также дал мне много проблем, я сделал это так:

public static boolean checkPlayServices(Activity mActivity){
    int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(mActivity);
    if(resultCode!= ConnectionResult.SUCCESS) {
        if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)){
            GooglePlayServicesUtil.getErrorDialog(
                    resultCode,
                    mActivity,
                    PLAY_SERVICES_RESOLUTION_REQUEST
            ).show();
        } else{
            log.d("DEVICE NOT SUPPORTED");
            exit(true);
        }
        return false;
    }
    return true;
}

Затем изменил его, как вы можете видеть в первом фрагменте кода, потому что по какой-то причине, когда он попадает в isUserRecoverableError (результат), он дает много головных болей... Все здесь, из фактического рабочего проекта и фрагменты кода были получены в http://developer.android.com/google/gcm/client.html и изменены для правильной работы. Надеюсь, это поможет вам, Удачи...

Ответ 7

Как насчет бэкэнда? Если вы удалите идентификатор из базы данных сервера, пользователь никогда не получит уведомление, если вы не обновите версию приложения?