小部件和 setOnClickPendingIntent

Posted

技术标签:

【中文标题】小部件和 setOnClickPendingIntent【英文标题】:Widgets and setOnClickPendingIntent 【发布时间】:2013-06-26 07:48:20 【问题描述】:

这里是完整的android开发新手,请注意。

我正在尝试开发一个主屏幕小部件,它允许您点击小部件来拨打预定义的号码。我可以创建小部件并将其添加到主屏幕,但是,当我尝试使用 setOnClickPendingIntent 使小部件可点击时,它不会启动活动。我正在使用的代码如下:

public void onUpdate(Context context, AppWidgetManager appWidgetManager,
          int[] appWidgetIds) 
    RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
              R.layout.callwidget_layout);
    Log.d("stuff", "remoteview defined");
    Intent callIntent = new Intent(Intent.ACTION_CALL);
    Log.d("stuff", "intent created");
    callIntent.setData(Uri.parse("tel:"+8888888));
    Log.d("stuff", "intent data added");
    PendingIntent clickPI=PendingIntent
            .getBroadcast(context, 0,
                          callIntent,
                          PendingIntent.FLAG_UPDATE_CURRENT);
    Log.d("stuff", "pending intent created");

    remoteViews.setOnClickPendingIntent(R.layout.callwidget_layout, clickPI);
    Log.d("stuff", "setonclickpendingintent created");


Log.d 方法工作正常,因为它们显示在 logcat 输出中,但点击小部件没有任何作用。 logcat 上没有显示其他错误消息。是不是我做错了什么?

更新:将 setOnClickPendingIntent 更改为引用 ID 为“callbutton” (remoteViews.setOnClickPendingIntent(R.id.callbutton, clickPI);) 的按钮,并尝试将这三行代码添加到 onUpdate 方法中:

ComponentName myWidget = new ComponentName(context, WidgetProvider.class);
appWidgetManager.getInstance(context).updateAppWidget(myWidget, remoteViews);
Log.d("stuff", "widget updated");

再次,Log.d 方法有效,提示小部件更新正常,但点击按钮仍然没有任何作用。

更新 2:PendingIntent clickPI=PendingIntent.getBroadcast 更改为 PendingIntent clickPI=PendingIntent.getActivity 也没有任何作用。

【问题讨论】:

【参考方案1】:

好的,所以我有一些解决这个问题的方法,直到我找到一个实际的解决方案。这涉及启动一个活动,该活动反过来启动我想要的意图。我一开始想避免这种情况,但是哦,好吧。

我的新代码,供任何可能需要的人使用:

public void onUpdate(Context context, AppWidgetManager appWidgetManager,
          int[] appWidgetIds) 
    RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
              R.layout.callwidget_layout);
    Log.d("stuff", "remoteview defined");
    Intent callIntent = new Intent(context, CallActivity.class);
    PendingIntent clickPI=PendingIntent
            .getActivity(context, 0,
                          callIntent,
                          PendingIntent.FLAG_UPDATE_CURRENT);
    Log.d("stuff", "pending intent created");

    remoteViews.setOnClickPendingIntent(R.id.callbutton, clickPI);
    Log.d("stuff", "setonclickpendingintent created");
    ComponentName myWidget = new ComponentName(context, WidgetProvider.class);
    appWidgetManager.getInstance(context).updateAppWidget(myWidget, remoteViews);
    Log.d("stuff", "widget updated");


CallActivity.java:

package com.example.callzepolice;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;

public class CallActivity extends Activity 

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_call);
        Intent callIntent = new Intent(Intent.ACTION_CALL);
        Log.d("stuff", "intent created");
        callIntent.setData(Uri.parse("tel:"+8888888));
        Log.d("stuff", "intent data added");
        startActivity(callIntent);
    

    @Override
    public boolean onCreateOptionsMenu(Menu menu) 
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.call, menu);
        return true;
    


【讨论】:

我只是尝试了这个,没有运气。虽然我正在尝试启动一项服务,而不是一项活动......有什么提示吗?【参考方案2】:

remoteViews.setOnClickPendingIntent(R.layout.callwidget_layout, clickPI);

您应该在布局中引用视图。不是布局。

编辑:如果这是整个方法,那么您也错过了 appWidgetmanager.updateWidgetAppWidget(...) 调用。

编辑 2:当您真正想向接收者广播消息时,您使用 getBroadcast(...)。对于呼叫活动,您需要getActivity(...)

【讨论】:

我又试了一次,这次在小部件中使用 id 为“callbutton”的按钮,并将您引用的行更改为remoteViews.setOnClickPendingIntent(R.id.callbutton, clickPI);。得到相同的结果。 如果这是整个更新代码,您似乎缺少通过您在此方法中获得的 appWidgetManager 对象的更新调用本身。 添加更新调用仍然没有任何作用。不过,我使用了public void updateAppWidget (ComponentName provider, RemoteViews views) 方法,如果这有什么不同的话。【参考方案3】:

使用ACTION_DIAL,而不是ACTION_CALL

查看文档。例如。获取系统意图要求的通用意图指南,例如how to initiate a phone call 和 documentation on ACTION_CALL 说:

注意:对于哪些应用程序可以启动 称呼;大多数应用程序应该使用ACTION_DIAL。

还有:

... Log.d 方法有效,提示小部件更新正常...

成功的Log.d() 表明代码已到达那里(断点将是确定这一点的另一种方法),但它不能证明小部件已成功更新。您在那里有一个有用的假设,即小部件已更新,问题出在此之后,例如错误的意图。测试该假设的一种方法是使您的更新明显改变小部件,例如TextView 中的文本。

【讨论】:

以上是关于小部件和 setOnClickPendingIntent的主要内容,如果未能解决你的问题,请参考以下文章

Android:配置小部件(不同小部件实例的相同 setOnClickPendingIntent 附加功能)

Android 小部件 - 使用带有远程视图的 setOnClickPendingIntent 未收到 Intent

Android:小部件 - 在远程视图上使用 setOnclickPendingIntent 时出现空指针异常?

为啥 setOnClickPendingIntent 不起作用?

无法在 Activity 中获取小部件 ID

定期更新小部件 TextView 的简单方法