Ошибка при выполнении UnregisterReceiver () в AppWidgetProvider - PullRequest
0 голосов
/ 27 июня 2018

В моем приложении я регистрирую широковещательный приемник, который прослушивает изменение подключения, если при обновлении виджета нет сетевого подключения, и я хочу отменить его регистрацию, если при обновлении имеется подключение к Интернету. Проблема, с которой я борюсь, заключается в том, чтобы заставить тот же экземпляр получателя отменить его регистрацию, поскольку при обновлении приложения создается новый экземпляр appwidgetprovide, поэтому у меня нет ссылки на этот экземпляр. Я попытался сохранить его в SharedPreferences, но это выдает ошибку: получатель не зарегистрирован.

    public void decideBroadcastState(Context context){
    // get the network receiver from shared preferences
    preferencesReceiver = Preferences.getSavedObjectFromPreference(context, Constants.SHARED_BROADCAST, this.getBroadcastKey(), NetworkReceiver.class);
    // If there is an internet connection, turn off the broadcast
    if(isInternetConnection){
        // stop listening for a connectivity change
        // If a broadcast was registered, cancel it.
        if(preferencesReceiver != null){
            context.unregisterReceiver(preferencesReceiver);
            Preferences.deleteCurrencyPref(context, Constants.SHARED_BROADCAST, this.getBroadcastKey());
        }

    }// If there's no internet connection, create a new broadcast
    else{
        // Create an intent that will look for a network connection, and will update the
        // widgets, once there is one.

        // if it doesn't exist, create one.
        if(preferencesReceiver == null){
            final String connectivityChange = "android.net.conn.CONNECTIVITY_CHANGE";
            IntentFilter intentFilter = new IntentFilter(connectivityChange);
            // register it
            // mReceiver is a new instance of the broadcast
            context.getApplicationContext()
                    .registerReceiver(mReceiver, intentFilter);
            // Store it in preferences
            Preferences.saveCurrencyPref(context, Constants.SHARED_BROADCAST, this.getBroadcastKey(), mReceiver);
        }
    }

}

Вот мой класс предпочтений:

public class Preferences {

// Write the prefix to the SharedPreferences object for this widget.
public static void saveCurrencyPref(Context context, String filePlace, String preferenceKey, Object anObject) {

    SharedPreferences sharedPref = context.getSharedPreferences(filePlace, Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPref.edit();

    Gson gson = new Gson();
    String json = gson.toJson(anObject);
    editor.putString(preferenceKey, json);
    editor.apply();

}

// Read the prefix from the SharedPreferences object for this widget.
public static <NetworkReceiver> NetworkReceiver  getSavedObjectFromPreference(Context context, String filePlace, String preferenceKey, Class<NetworkReceiver> classType) {
    SharedPreferences sharedPreferences = context.getSharedPreferences(filePlace, Context.MODE_PRIVATE);
    if (sharedPreferences.contains(preferenceKey)) {
        final Gson gson = new Gson();
        String json = sharedPreferences.getString(preferenceKey, "");
        NetworkReceiver obj = gson.fromJson(json, classType);
        return obj;
    }
    return null;
}



static void deleteCurrencyPref(Context context, String filePlace, String preferenceKey) {
    SharedPreferences sharedPref = context.getSharedPreferences(filePlace, Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPref.edit();
    editor.remove(preferenceKey);
    editor.apply();
}

}

Ответы [ 2 ]

0 голосов
/ 28 июня 2018

Прежде всего AppWidgetProvider - это BroadcastReceiver на стероидах, поэтому его жизненный цикл такой же, как и для BroadcastReceiver. BroadcastReceiver в основном живет 15 секунд (если вы не используете goAsync ()), выполняя свою работу в основном потоке, и умирает после этого (так что ваш процесс тоже умирает). Поэтому зарегистрировать динамический BroadcastReceiver в AppWidgetProvider не самая лучшая идея для этого, поэтому Android предлагает вам использовать Service (Foreground Service с уведомлением для Android O) для регистрации ваших динамических приемников и прослушивания каких-либо событий.

0 голосов
/ 27 июня 2018

При использовании GSON для хранения и извлечения объекта в SharedPreferences вы сериализуете и десериализуете объект. Это не даст вам тот же экземпляр объекта, но копию объекта с теми же значениями. Если вы хотите узнать больше о том, как это работает, найдите сериализацию и кучу Java.

Вы должны иметь возможность хранить BroadcastReceiver в статическом поле в вашем appWidgetProvider. Я не знаю, что именно вы делаете, но вам не нужно больше одного экземпляра BroadcastReceiver.

...