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

Манифест Android:

<receiver android:name="com.whizzapps.stpsurniki.widget.UrnikWidget">
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
        </intent-filter>
        <meta-data 
            android:name="android.appwidget.provider"
            android:resource="@xml/app_widget_info"/>
    </receiver>

XML поставщика виджета приложения:

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="80dp"
    android:minHeight="40dp"
    android:updatePeriodMillis="10"
    android:initialLayout="@layout/app_widget"
    android:widgetCategory="home_screen" >
</appwidget-provider>

AppWidgetProvider класс:

public class UrnikWidget extends AppWidgetProvider {

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
        int[] appWidgetIds) {
    super.onUpdate(context, appWidgetManager, appWidgetIds);

    Log.i("TAG", "onUpdate");
    }
}

Я создал простой виджет с TextView в нем, который отображает определенное слово, в нем еще нет никакой логики, так как я все еще учусь работать с виджетами. Как видите, я сделал log.i, чтобы увидеть, когда на самом деле вызывается onUpdate, и моя проблема в том, что он вызывается только в первый раз, когда я помещаю виджет на свой домашний экран.

Я знаю, что интервал обновления в 10 миллисекунд слишком мал и не должен использоваться из-за разряда батареи, но Я ИСПОЛЬЗУЮ 10 мс только для целей тестирования.

Почему onUpdate выполняется только один раз, а не каждые 10 мс? И как мне лучше всего обновить виджет, если он мне нужен только в определенные часы? Скажем, мне нужно, чтобы мой виджет обновлялся только в 7, 8 и 15 часов. Это возможно? Спасибо!

3
Guy 10 Мар 2014 в 21:19

1 ответ

Лучший ответ

Да, обновлять виджет с интервалом в 10 миллисекунд - очень плохая идея.

У меня та же проблема, что и у вас, и я пробую много разных решений.

Если вы хотите часто обновлять свой виджет, есть два решения:

  1. Используйте AlarmMenager и затем запустите Intent каждый интервал в миллисекундах
  2. Использовать Сервис и обновлять RemoteView

Первый очень хорош, когда вы создаете часы и вам нужен интервал в 1 секунду. Но когда вам нужен интервал <1 секунды, это не бог - проблема с намерением задержки. Для вашей цели использования Service RemoteView не является стандартным представлением, поэтому вы можете обновить это представление из любого места, это код:

public class WidgetService extends Service {

private ScheduledExecutorService scheduleTaskExecutor;

public WidgetService() {
}

@Override
public void onDestroy() {
    super.onDestroy();
    scheduleTaskExecutor.shutdownNow();
    scheduleTaskExecutor = null;
}

@Override
public void onCreate() {
    super.onCreate();
    scheduleTaskExecutor = Executors.newScheduledThreadPool(1);
}

@Override
public void onStart(Intent intent, int startId) {
    super.onStart(intent, startId);

    final Context cx = this;
    final long startTime = SystemClock.uptimeMillis();
    scheduleTaskExecutor.scheduleWithFixedDelay(new Runnable() {
        @Override
        public void run() {
           //logic here for example
           RemoteViews rv = new RemoteViews(this.getPackageName(), getLayoutId());

        }
    }, 0, 10, TimeUnit.MILLISECONDS);
}

@Override
public IBinder onBind(Intent intent) {
    return null;
}

}

Будьте осторожны с методом onUpdate, существует очень серьезная ошибка, и метод onUpdate вызывается, даже если ваш виджет не отображается, поэтому Android создает фантомные виджеты, http://code.google.com/p/android/issues/detail?id=2539,

1
Łukasz Woźniczka 25 Апр 2014 в 00:37