Appwidget无法正确更新

时间:2016-07-01 17:42:16

标签: android android-widget android-appwidget android-loader android-appwidget-list

我开发了一个appwidget,它是一个集合小部件,使用Loader从数据库中检索数据,当用户点击列表项时,项目详细信息将保存到intent中的bundle中,并且将启动主要活动,并向用户显示捆绑信息。

我的代码按预期工作;但是,我担心小部件实际工作,初始化和更新的可能边缘情况,我没有想到。我认为我的代码正常工作了大约5天后,我发现了一个边缘案例。同样,我是小部件开发的新手,小部件的API花了我很多力气。

问题

使用我的appwidget的所有东西似乎都可以在我的手机上正常工作,但在我的平板电脑上,它可以在打开应用程序并在主屏幕上添加新小部件后正常工作。如果我没有先打开应用程序,那么我的小部件中就不会显示任何内容。

此外,如果我的平板电脑重新启动或打开电源,那么我当前的小部件将不会显示任何内容。即使在打开我的应用程序之后,我也必须为我的其他小部件添加一个新的小部件以进行更新。

对于我的手机,除非我添加其他小部件,否则我很少会在小部件上显示任何内容。至少我不能复制任何东西,并保证它不会像在平板电脑上那样工作。

那么这款手机怎么能在我的手机上完全正常工作,但我的平板电脑上一直有问题?有没有办法确保我的数据是否可用,无论我是否在应用程序上打开,以及我是否重新启动设备?

代码

GitHub Link。直接链接到我的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);
    }

}

Manifest(Hub Flavor)

Hub flavor是我的代码中唯一具有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>

0 个答案:

没有答案
相关问题