单击应用程序小部件(远程视图)中的列表视图项目未启动活动

Posted

技术标签:

【中文标题】单击应用程序小部件(远程视图)中的列表视图项目未启动活动【英文标题】:Click on listview item in app widget (remoteviews) not launching activity 【发布时间】:2016-07-31 11:20:11 【问题描述】:

我正在尝试创建我的第一个应用小部件,并且我希望能够在单击某个项目时启动一个活动,但它不起作用。 这是我在 onUpdate() 中的代码:

Intent toastIntent = new Intent(context, TareaModificar.class);
toastIntent.putExtra("id", id);
PendingIntent toastPendingIntent = PendingIntent.getBroadcast(context, 0, toastIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
    remoteViews.setPendingIntentTemplate(R.id.widget_tareas_listview, toastPendingIntent);

以及我的 getViewAt() 中的代码:

Bundle extras = new Bundle();
    extras.putInt(WidgetTareas.id, cursor.getInt(0));
    Intent fillInIntent = new Intent();
    fillInIntent.putExtras(extras);
    remoteView.setOnClickFillInIntent(R.id.widget_tareas, fillInIntent);

id 是小部件提供程序中的全局字符串变量。

编辑我提供了所有代码,也许这样更容易提供帮助:

AppWidgetProvider 代码:

public class WidgetTareas extends AppWidgetProvider 
private String TAG = getClass().getSimpleName();
private DbAdapter dbAdapter;
public static final String id = "1";

public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) 
    for (int i = 0; i < appWidgetIds.length; ++i) 
        Log.d(TAG,"Se actualiza el widget: " +i);
        RemoteViews remoteViews = updateWidgetListView(context,
                appWidgetIds[i]);
        appWidgetManager.updateAppWidget(appWidgetIds[i],
                remoteViews);
    
    super.onUpdate(context, appWidgetManager, appWidgetIds);


private RemoteViews updateWidgetListView(Context context,
                                         int appWidgetId) 
    dbAdapter = new DbAdapter(context);
    dbAdapter.actualizaQueda(0);
    //which layout to show on widget
    RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.widget_tareas);

    //RemoteViews Service needed to provide adapter for ListView
    Intent svcIntent = new Intent(context, WidgetTareasService.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.widget_tareas_listview,
            svcIntent);

    Intent toastIntent = new Intent(context, TareaModificar.class);
    toastIntent.putExtra("id", id);
    toastIntent.setAction("ACTION_SHOW_TOAST");
    PendingIntent toastPendingIntent = PendingIntent.getBroadcast(context, 0, toastIntent,
            PendingIntent.FLAG_UPDATE_CURRENT);
    remoteViews.setPendingIntentTemplate(R.id.widget_tareas_listview, toastPendingIntent);
    return remoteViews;


@Override
public void onReceive(@NonNull Context context, @NonNull Intent intent) 
    super.onReceive(context, intent);
    Toast.makeText(context, "Intent received", Toast.LENGTH_SHORT).show();
    switch (intent.getAction()) 
        case "ACTION_SHOW_TOAST":
            //change your activity name
            int id = intent.getIntExtra("id", -1);
            context.startActivity(new Intent(context,
                    TareaModificar.class)
                    .setFlags(
                            Intent.FLAG_ACTIVITY_NEW_TASK));
            break;
    

RemoteViewsFactory 代码:

    @Override
public RemoteViews getViewAt(int position) 
    if (position == 0)
        cursor = dbAdapter.getTareasOrdenadoHacer(0);

    RemoteViews remoteView = new RemoteViews(
            context.getPackageName(), R.layout.a);
    Log.d(TAG,"Se carga la factoría");
    cursor.moveToPosition(position);
    String a = cursor.getString(cursor.getColumnIndex(dbAdapter.COL_A));
    remoteView.setTextViewText(R.id.tarea_widget_aa, dbAdapter.getAA(a));
    remoteView.setTextViewText(R.id.tarea_widget_tt, cursor.getString(cursor.getColumnIndex(dbAdapter.COL_T)));
    String queda = context.getString(R.string.en) +" "+ cursor.getString(cursor.getColumnIndex(dbAdapter.COL_Q)) +" "+context.getString(R.string.dias);
    remoteView.setTextViewText(R.id.tarea_widget_q, queda);

    remoteView.setTextViewText(R.id.tarea_widget_pos, position);


    // Next, we set a fill-intent which will be used to fill-in the pending intent template
    // which is set on the collection view in StackWidgetProvider.
    Bundle extras = new Bundle();
    extras.putInt(WidgetTareas.id, cursor.getInt(0));
    Intent fillInIntent = new Intent();
    fillInIntent.putExtras(extras);
    remoteView.setOnClickFillInIntent(R.id.widget_tareas, fillInIntent);
    return remoteView;

小部件布局代码:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_
android:layout_
android:id="@+id/widget_tareas"
android:background="@color/common_action_bar_splitter">
<TextView
    android:padding="10dp"
    android:layout_
    android:layout_
    android:textColor="@color/black"
    android:textSize="18sp"
    android:background="#E6E6E6"
    android:text="@string/tareas"/>
<ListView
    android:layout_
    android:layout_
    android:id="@+id/widget_tareas_listview"/>

布局代码:

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_
android:layout_
android:padding="10dp"
android:id="@+id/widget_tareas_item">
<LinearLayout
    android:layout_
    android:layout_
    android:orientation="vertical">
    <TextView
        android:layout_
        android:layout_
        android:textColor="@color/black"
        android:text="99"
        android:gravity="center_horizontal"
        android:id="@+id/tarea_widget_q"/>
    <TextView
        android:layout_
        android:layout_
        android:textColor="@color/black"
        android:gravity="center_horizontal"
        android:text="pos"
        android:id="@+id/tarea_widget_pos"/>
</LinearLayout>

<LinearLayout
    android:layout_
    android:layout_
    android:paddingLeft="10dp"
    android:orientation="vertical">
    <TextView
        android:layout_
        android:layout_
        android:text="New Text"
        android:textColor="@color/black"
        android:id="@+id/tarea_widget_aa" />
    <TextView
        android:layout_
        android:layout_
        android:textColor="@color/black"
        android:text="sad"
        android:id="@+id/tarea_widget_tt" />
</LinearLayout>

【问题讨论】:

目前出了什么问题?请解释 @JhamanDas 当我从小部件中单击一个项目时没有任何反应我想开始活动 TareaModificar 【参考方案1】:

所以我终于设法让它工作了。我所做的是从here 获取代码并更改最小值,所以:

在 WidgetTareas 类中,添加:

public static final String TAREA_MODIFICAR = "TAREAMODIFICAR";
public static final String EXTRA_ITEM = "1";

在 onUpdate() 方法中:

Intent toastIntent = new Intent(context, WidgetTareas.class);
        toastIntent.setAction(WidgetTareas.TAREA_MODIFICAR);
        toastIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
        PendingIntent toastPendingIntent = PendingIntent.getBroadcast(context, 0, toastIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);
        remoteViews.setPendingIntentTemplate(R.id.widget_tareas_listview, toastPendingIntent);
        appWidgetManager.updateAppWidget(appWidgetIds[i], remoteViews);

接收方法:

public void onReceive(Context context, Intent intent) 
    AppWidgetManager mgr = AppWidgetManager.getInstance(context);
    if (intent.getAction().equals(TAREA_MODIFICAR)) 
        int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
                AppWidgetManager.INVALID_APPWIDGET_ID);
        int viewIndex = intent.getIntExtra(EXTRA_ITEM, 0);
        Intent i = new Intent(context, TareaModificar.class);
        i.putExtra("id",String.valueOf(viewIndex));
        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(i);
        Toast.makeText(context, "Vista pulsada es: " + viewIndex, Toast.LENGTH_SHORT).show();
    
    super.onReceive(context, intent);

最后在 WidgetTareasService 类中:

Bundle extras = new Bundle();
    extras.putInt(WidgetTareas.EXTRA_ITEM, cursor.getInt(0));
    Intent fillInIntent = new Intent();
    fillInIntent.putExtras(extras);
    remoteView.setOnClickFillInIntent(R.id.widget_tareas_item, fillInIntent);

【讨论】:

【参考方案2】:

您必须在小部件提供程序的 onReceive 中管理操作。

在 getViewAt 方法中准备好你的意图:

Intent toastIntent = new Intent(context, TareaModificar.class);
toastIntent.putExtra("id", id);
toastIntent.setAction("ACTION_SHOW_TOAST");
PendingIntent toastPendingIntent = PendingIntent.getBroadcast(context, 0, toastIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
    remoteViews.setPendingIntentTemplate(R.id.widget_tareas_listview, toastPendingIntent);

在你的 onReceive 中,管理它:

  @Override
    public void onReceive(@NonNull Context context, @NonNull Intent intent) 
        super.onReceive(context, intent);
        switch (intent.getAction()) 

            case "ACTION_SHOW_TOAST":
                  //change your activity name
                  int id = intent.getIntExtra("id", -1);
                   context.startActivity(new Intent(context,
                    TareaModificar.class)
                    .setFlags(
                    Intent.FLAG_ACTIVITY_NEW_TASK)

                break;
        
   

【讨论】:

1.您确定第一段代码会转到 getViewAt() 吗?因为这个方法是在Factory而不是provider,也许你想说在方法onUpdate()中? 2. Android Studio 要求我为常量 (SyncStateContract) 导入一个类,但是当我导入它时,它说找不到 ACTION_SHOW_GCM_NEWS。我做错了什么? @androidjunior 我的错,它是我的代码的一部分,忘记删除它。 更正了代码。试试吧。如果你愿意,我可以提供一个带有 listview 的小部件提供程序。代码可能在 onUpdate。 还是不行,我已经更新了所有代码,这样可能更容易找到我做错了什么。当收到意图时我也写了一个 Toast,但它只在创建小部件时显示。

以上是关于单击应用程序小部件(远程视图)中的列表视图项目未启动活动的主要内容,如果未能解决你的问题,请参考以下文章

Android 无法使用列表视图加载主屏幕小部件

如何在按钮单击 FLUTTER 上刷新列表小部件数据

单击按钮刷新时如何刷新小部件列表视图?

更新小部件列表视图

Android - 在 ViewFlipper 中的多个视图之间切换

Flutter ListView 与不同的小部件和列表项