Appwidget не обновляется правильно
Я разработал приложение-виджет, это виджет коллекции и использую Loader для извлечения данных из базы данных, и когда пользователь нажимает на элемент списка, детали этих элементов будут намеренно сохраняться в связке, и основное действие будет запускаться с отображенной пользователю информацией в комплекте.
Мой код работает как задумано; однако я обеспокоен возможными крайними случаями того, как виджеты действительно работают, инициализируются и обновляются, о которых я не думал. Я обнаружил один крайний случай, подумав, что мой код работает правильно в течение 5 дней. Опять же, я новичок в разработке виджетов, и API для виджетов потребовалось много времени, чтобы обернуться.
вопрос
Кажется, что все с моим appwidget работает правильно на моем телефоне, но на моем планшете это работает правильно, ПОСЛЕ открытия приложения и добавления нового виджета на домашний экран. Если я сначала не открою приложение, то в моем виджете ничего не отобразится.
Кроме того, если мой планшет будет перезапущен или включен, то мои текущие виджеты ничего не будут отображать. Даже после открытия моего приложения мне нужно добавить новый виджет для моих других виджетов, чтобы они обновлялись.
Для моего телефона у меня редко будут проблемы, когда на виджете ничего не будет отображаться, если я не добавлю другой виджет. По крайней мере, я не могу ничего воспроизвести и гарантирую, что он не будет работать как на планшете.
Так как же это может работать почти полностью на моем телефоне, но на планшете все время возникают проблемы? И есть ли способ убедиться, что мои данные доступны, открываю я в приложении или нет, и перезагружаю ли я свое устройство или нет?
Код
GitHub Ссылка. Ссылки непосредственно на мой Hub Flavor, который реализует appwidget (папки java и res и файл манифеста)
Поставщик виджетов приложений
public class ResumeHubWidgetProvider extends AppWidgetProvider {
private static final String LAUNCH_RESUME_ACTION = "io.github.ciscorucinski.personal.intro.hub.LAUNCH_RESUME_ACTION";
private static Intent createIntent(Context context) {
return new Intent(context, ResumeHubWidgetProvider.class);
}
private static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
Intent serviceIntent = MyWidgetService.createIntent(context);
serviceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
serviceIntent.setData(Uri.parse(serviceIntent.toUri(Intent.URI_INTENT_SCHEME)));
// Construct the RemoteViews object
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.resume_hub_list_widget);
views.setRemoteAdapter(R.id.widget_list, serviceIntent);
Intent widgetProviderIntent = ResumeHubWidgetProvider.createIntent(context);
widgetProviderIntent.setAction(ResumeHubWidgetProvider.LAUNCH_RESUME_ACTION);
widgetProviderIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
serviceIntent.setData(Uri.parse(serviceIntent.toUri(Intent.URI_INTENT_SCHEME)));
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, widgetProviderIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
views.setPendingIntentTemplate(R.id.widget_list, pendingIntent);
// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// There may be multiple similar widgets active, so update all of them
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
@Override
public void onReceive(Context context, Intent intent) {
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
if (intent.getAction().equals(LAUNCH_RESUME_ACTION)) {
Timber.i("Intent Action is LAUNCH_RESUME_ACTION");
// Open the Resume activity with the user selected resume info
Bundle bundle = intent.getBundleExtra(CREATE_INTENT_BUNDLE);
context.startActivity(ResumeActivity
.createIntentWithFlags(context, bundle,
Intent.FLAG_ACTIVITY_NEW_TASK));
}
int appWidgetIds[] = appWidgetManager.getAppWidgetIds(new ComponentName(context, ResumeHubWidgetProvider.class));
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds, R.id.widget_list);
super.onReceive(context, intent);
}
}
адаптер
class HubWidgetAdapter implements RemoteViewsService.RemoteViewsFactory,
Loader.OnLoadCompleteListener<List<Resume.People>> {
private Context context;
private List<Resume.People> data;
private int appWidgetId;
private PeopleLoader loader;
HubWidgetAdapter(Context context, Intent intent) {
this.context = context;
appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
}
@Override
public RemoteViews getViewAt(int position) {
RemoteViews view = new RemoteViews(context.getPackageName(),
android.R.layout.simple_list_item_1);
Resume.People person = data.get(position);
view.setTextViewText(android.R.id.text1, person.seeking_position());
view.setTextColor(android.R.id.text1, Color.BLACK);
Bundle bundle = new Bundle();
bundle.putLong(ResumeActivity.ID, person._id());
bundle.putString(ResumeActivity.NAME, person.name());
bundle.putString(ResumeActivity.EMAIL, person.email());
bundle.putString(ResumeActivity.PHONE, person.phone());
bundle.putString(ResumeActivity.GITHUB, person.github());
bundle.putString(ResumeActivity.LINKEDIN, person.linkedin());
bundle.putString(ResumeActivity.SEEKING, person.seeking_position());
Intent intent = new Intent();
intent.putExtra(CREATE_INTENT_BUNDLE, bundle);
Timber.i("Bundled Person%s", intent);
view.setOnClickFillInIntent(android.R.id.text1, intent);
return view;
}
@Override
public void onLoadComplete(Loader<List<Resume.People>> loader, List<Resume.People> data) {
this.data = data;
}
@Override
public void onCreate() {
data = new ArrayList<>();
}
@Override
public void onDestroy() {
if (loader != null) {
loader.unregisterListener(this);
loader.cancelLoad();
loader.stopLoading();
loader = null;
}
data = null;
}
@Override public void onDataSetChanged() {
loader = new PeopleLoader(context);
loader.registerListener(0, this);
loader.startLoading();
}
@Override public int getCount() { return data.size(); }
@Override public RemoteViews getLoadingView() { return null; }
@Override public int getViewTypeCount() { return 1; }
@Override public long getItemId(int position) { return position; }
@Override public boolean hasStableIds() { return true; }
}
обслуживание
public class MyWidgetService extends RemoteViewsService {
static Intent createIntent(Context context) {
return new Intent(context, MyWidgetService.class);
}
@Override
public RemoteViewsFactory onGetViewFactory(Intent intent) {
return new HubWidgetAdapter(this.getApplicationContext(), intent);
}
}
Манифест (Hub Flavor)
Вариант Hub - это единственный аспект моего кода, в котором есть appwidgets, поэтому я включаю в него только файл Hub Manifest, который объединен с основным файлом Manifest.
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<activity
android:name="io.github.ciscorucinski.personal.intro.ui.ResumeActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar"/>
<receiver android:name="io.github.ciscorucinski.personal.intro.hub.ResumeHubWidgetProvider">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/resume_hub_list_widget_info" />
</receiver>
<service
android:name="io.github.ciscorucinski.personal.intro.hub.MyWidgetService"
android:exported="false"
android:permission="android.permission.BIND_REMOTEVIEWS" />
</application>
</manifest>