Служба не перезапускается после сброса "Очистить память" + appWidget
Я построил appWidget, который регистрирует некоторые сервисы по его методу onEnabled().
Проблема заключается в том, что после того, как я использую встроенную в Task Manager функцию "Очистить память" /Ram, происходит сбой представления appWidget (для всего текста TextView appWidgets установлено значение по умолчанию (TextView)), а службы перестают работать и никогда не перезапускаются.
Это происходит только через некоторое время, когда виджет установлен, и если я очищаю Memmory/Ram сразу после установки виджета, ошибка не произойдет, но я предполагаю, что это связано со способом очистки памяти в диспетчере задач.
Итак, наконец, мой вопрос: есть ли способ заставить систему Android перезапустить эти службы? как и другие виджеты приложений, которые я скачал через маркет, похоже, продолжает нормально работать после этой процедуры.
Будем рады идеям и решениям! Спасибо заранее, Гал:)
некоторый код, который я использую:
метод onEnabled() в appWidget:
@Override
public void onEnabled(Context context) {
super.onEnabled(context);
Intent newinIntent = new Intent(context, CallService_1x1.class);
context.startService(newinIntent);
newinIntent = new Intent(context, SmsService_1x1.class);
context.startService(newinIntent);
}
Некоторые методы одного из Сервисов (другие сервисы очень похожи, поскольку это их абстрактный метод):
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
Log.d("SERVICE-SMS","CallMonitorService - onStartCommand created");
return START_STICKY;
}
@Override
public void onCreate() {
super.onCreate();
context = this.getApplicationContext();
Log.d("SERVICE-SMS","CallMonitorService created");
registerObserver();
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
@Override
public void onDestroy() {
unregisterObserver();
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
/**
* Start the service to process that will run the content observer
*/
public static void beginStartingService(Context context) {
Log.d("SERVICE-SMS","CallMonitorService: beginStartingService()");
context.startService(new Intent(context, CallService.class));
}
/**
* Called back by the service when it has finished processing notifications,
* releasing the wake lock if the service is now stopping.
*/
public static void finishStartingService(Service service) {
Log.d("SERVICE-SMS","CallMonitorService: finishStartingService()");
service.stopSelf();
}
3 ответа
После долгих исследований и некоторых попыток решено!:)
Просто добавил BroadcastReciever, слушающий изменения и обновления пакетов:
зарегистрировать получателя в файле манифеста:
<receiver android:name=".receivers.onRestartReciever">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<action android:name="android.intent.action.PACKAGE_RESTARTED" />
<data android:scheme="package" android:path="my.Package.Path" />
</intent-filter>
- PACKAGE_REPLACED - вызывается, в частности, для уведомления об обновлении приложения.
- PACKAGE_RESTARTED - вызывается, когда большинство очистителей памяти очищают память.
- строка "data" используется для мониторинга действий, применяемых к конкретному пакету.
В этом приемнике я снова запускаю свои службы и перезапускаю представление виджета (в этом случае вызывая его метод onUpdate()):
public class onRestartReciever extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Log.d("DEBUG", "onRestartReciever");
// Register Services
MyWidget_1x1.registerServices(context);
MyWidget_2x2.registerServices(context);
// reInitialize appWidgets
AppWidgetManager appWidgetManager=AppWidgetManager.getInstance(context);
MyWidget_1x1 widget1x1=new CallWidgi();
widget1x1.onUpdate
(context,
AppWidgetManager.getInstance(context),
widget1x1.getIDs(context, appWidgetManager));
MyWidget_2x2 widget2x2=new CallWidgi2();
widget2x1.onUpdate(context,
AppWidgetManager.getInstance(context),
widget2x2.getIDs(context, appWidgetManager));
}
}
registerServices (Context) - это статический метод в моих классах AppWidgetProvider (MyWidget_1x1/MyWidget_2x2), который регистрирует необходимые службы.
Надеюсь, это поможет вам тоже =]
Приведенный выше материал перехватывает событие перезагрузки, но не может перехватить событие очистки памяти, поскольку android.intent.action.PACKAGE_RESTARTED не отправляется самому пакету.
Я решил это, добавив Сервис. Эта служба вызывает метод onCreate() для события очистки памяти. Обратите внимание, что вы должны запустить службу с помощью вызова startService, который я вызываю из AppWidgetProvider.
Intent i= new Intent(context, CTService.class);
// potentially add data to the intent
i.putExtra("KEY1", "Value to be used by the service");
ComponentName name = context.startService(i);
Сервисный код выглядит так:
@Override
public void onCreate()
{
Log.d(TAG,"onCreate");
ping();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG,"onStartCommand: "+intent.getAction());
//TODO do something useful
ping();
return Service.START_STICKY;
}
с ping
фактические вещи, которые заставляют сенсорные события на виджетах работать.
Спасибо за успешное исследование вашего собственного решения. Вы указали мне в правильном направлении. У меня была похожая проблема, когда приложение больше не обновлялось после перезагрузки или выключения питания, а также не реагировало на нажатия кнопок.
Сначала я добавил в манифест следующее:
<receiver android:name=".BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
Затем я создал файл BootReceiver.java с чем-то вроде следующего. В моем случае мне пришлось воссоздать будильник и ожидающие намерения для кнопок.
public class BootReceiver extends BroadcastReceiver
{
/*
* after reboot widget appears to stop working and becomes unresponsive to clicks
* this broadcast receiver will create new alarm and refresh pending intents
*/
@Override
public void onReceive(Context context, Intent intent)
{
/* do your stuff here, mostly just copy&paste from other places */
}
}
Некоторая заслуга в этом также идет: оповещения о сближении не работают после перезагрузки телефона