点击小部件以打开应用程序

Tap on Widget To Open App

数周以来,我一直在尝试通过点击小部件来打开我的应用程序,但似乎没有任何效果。我认为关于我的代码的某些事情使我的情况有所不同。我的小部件只是一个包含任务的列表。我将 post 整个 类 这样人们就可以看到发生了什么。

有人可以帮我解决这个问题吗?

列表提供者:

public class ListProvider implements RemoteViewsService.RemoteViewsFactory {
    private ArrayList<ListObject> listObjectList = new ArrayList<ListObject>();
    private Context context = null;
    private TinyDB tinyDB;

    private ArrayList<Integer> checkedPositions = new ArrayList<>();

    public ListProvider(Context context, Intent intent) {
        this.context = context;

        populateWidget();
    }

    private void populateWidget() {
        if(MainActivity.user != null) {

            checkedPositions.clear();

            for(int i = 0; i < MainActivity.user.getTaskLists().size(); i++){
                TaskList taskList = MainActivity.user.getTaskLists().get(i);

                listObjectList.add(new ListTitle(taskList.getName()));

                for (int j = 0; j < taskList.getTasks().size(); j++) {
                    ListItem listItem = new ListItem();
                    listItem.text = taskList.getTasks().get(j).getTitle();
                    listObjectList.add(listItem);

                    if(taskList.getTasks().get(j).isChecked()){
                        //if task is checked, add to checked list
                        checkedPositions.add(listObjectList.size() - 1);
                    }
                }

                listObjectList.add(new ListItem(" "));
            }
        }else{
            loadLastSavedList();
        }
    }

    @Override
    public int getCount() {
        return listObjectList.size();
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    /*
     *Similar to getView of Adapter where instead of View
     *we return RemoteViews
     *
     */
    @Override
    public RemoteViews getViewAt(int position) {
        RemoteViews remoteView = new RemoteViews(
                context.getPackageName(), R.layout.widget_list_item);

        ListObject listObject = listObjectList.get(position);

        //get whether item is a item or title
        if(listObject.getClass().equals(ListItem.class)) {
            //list item
            ListItem listItem = (ListItem) listObject;
            remoteView.setTextViewText(R.id.title, "");
            remoteView.setTextViewText(R.id.text, listItem.text);
        }else{
            //list title
            ListTitle listTitle = (ListTitle) listObject;
            remoteView.setTextViewText(R.id.text, "");
            remoteView.setTextViewText(R.id.title, listTitle.title);
        }

        //text size
        SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext());

        String textSize = SP.getString(context.getString(R.string.widget_pref_key_text_size), context.getString(R.string.medium));
        System.out.println(textSize);
        if (textSize.equals(context.getString(R.string.small))) {
            //small
            remoteView.setTextViewTextSize(R.id.text, TypedValue.COMPLEX_UNIT_SP, 14);
            remoteView.setTextViewTextSize(R.id.title, TypedValue.COMPLEX_UNIT_SP, 16);
        } else if (textSize.equals(context.getString(R.string.large))) {
            //large
            remoteView.setTextViewTextSize(R.id.text, TypedValue.COMPLEX_UNIT_SP, 22);
            remoteView.setTextViewTextSize(R.id.title, TypedValue.COMPLEX_UNIT_SP, 24);
        } else {
            //medium, default
            remoteView.setTextViewTextSize(R.id.text, TypedValue.COMPLEX_UNIT_SP, 18);
            remoteView.setTextViewTextSize(R.id.title, TypedValue.COMPLEX_UNIT_SP, 20);
        }

        //strikethrough if checked
        if(checkedPositions.contains(position)){
            remoteView.setInt(R.id.text, "setPaintFlags", Paint.STRIKE_THRU_TEXT_FLAG | Paint.ANTI_ALIAS_FLAG);
        }else{
            remoteView.setInt(R.id.text, "setPaintFlags", (~ Paint.STRIKE_THRU_TEXT_FLAG) & Paint.ANTI_ALIAS_FLAG);
        }


        return remoteView;
    }


    @Override
    public RemoteViews getLoadingView() {
        return null;
    }

    @Override
    public int getViewTypeCount() {
        return 1;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    @Override
    public void onCreate() {
        loadLastSavedList();
    }

    private void loadLastSavedList() {
        //load up saved items
        tinyDB = new TinyDB(context);
        ArrayList<String> strings = tinyDB.getListString(context.getString(R.string.saved_key));
        System.out.println(strings.size());

        //full up listItems
        for(int i = 0; i < strings.size(); i++) {
            if(i == 0){
                //first object, title
                listObjectList.add(new ListTitle(strings.get(i)));
            }else if(strings.get(i - 1).equals(" ")){
                //title
                listObjectList.add(new ListTitle(strings.get(i)));
            }else{
                //list item
                listObjectList.add(new ListItem(strings.get(i)));
            }
        }
    }

    @Override
    public void onDataSetChanged() {
        listObjectList.clear();
        populateWidget();

        //save list items
        ArrayList<String> strings = new ArrayList<>();
        for(ListObject listObject: listObjectList){
            if(listObject.getClass().equals(ListItem.class)) {
                //list item
                ListItem listItem = (ListItem) listObject;
                strings.add(listItem.text);
            }else{
                //list title
                ListTitle listTitle = (ListTitle) listObject;
                strings.add(listTitle.title);
            }
        }

        tinyDB = new TinyDB(context);
        tinyDB.putListString(context.getString(R.string.saved_key), strings);
    }

    @Override
    public void onDestroy() {

    }

}

WidgetProvider:

public class WidgetProvider extends AppWidgetProvider {

    /**
     * this method is called every 30 mins as specified on widgetinfo.xml
     * this method is also called on every phone reboot
     **/
    @Override
    public void onUpdate(Context context, AppWidgetManager
            appWidgetManager, int[] appWidgetIds) {

/*int[] appWidgetIds holds ids of multiple instance
 * of your widget
 * meaning you are placing more than one widgets on
 * your homescreen*/
        final int N = appWidgetIds.length;
        for (int i = 0; i < N; i++) {
            RemoteViews remoteViews = updateWidgetListView(context,
                    appWidgetIds[i]);

            appWidgetManager.updateAppWidget(appWidgetIds[i],
                    remoteViews);
        }
        super.onUpdate(context, appWidgetManager, appWidgetIds);
    }

    private RemoteViews updateWidgetListView(Context context,
                                             int appWidgetId) {

        //which layout to show on widget
        RemoteViews remoteViews = new RemoteViews(
                context.getPackageName(), R.layout.widget_layout);

        //RemoteViews Service needed to provide adapter for ListView
        Intent svcIntent = new Intent(context, WidgetService.class);
        //passing app widget id to that RemoteViews Service
        svcIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
        //setting a unique Uri to the intent
        //don't know its purpose to me right now
        svcIntent.setData(Uri.parse(
                svcIntent.toUri(Intent.URI_INTENT_SCHEME)));
        //setting adapter to listview of the widget
        remoteViews.setRemoteAdapter(appWidgetId, R.id.listViewWidget,
                svcIntent);
        //setting an empty view in case of no data
        remoteViews.setEmptyView(R.id.listViewWidget, R.id.empty_view);

        return remoteViews;
    }
}

提前致谢!

您没有任何代码告诉 Android 当用户单击列表项时您希望执行任何操作。

getViewAt() 中,您需要创建一个 Intent,用附加项填充它(例如,识别与此列表行关联的数据),然后调用 setOnClickFillInIntent() RemoteViews 应该响应点击事件。

然后,在您的 AppWidgetProvideronUpdate() 中,您需要在 RemoteViews 上调用 setPendingIntentTemplate() 来保存您的 ListView(或 StackView 或您正在使用的任何东西),其中此 PendingIntent 包装一个 Intent 以在用户点击 ListView.

中的项目时填充和调用

This sample app 通过创建一个显示 25 个拉丁单词列表并响应对每个单词的点击的应用小部件来演示这一点。