我正在尝试做一些真的应该很容易的事情,但这让我发疯了。我正在尝试在按下主屏幕窗口小部件时启动活动,例如窗口小部件的配置活动。我想我已经在Android开发者网站上一字不差地跟着教程,甚至还有一些非正式的教程,但我必须错过一些重要的东西,因为它不起作用。
以下是代码:
public class VolumeChangerWidget extends AppWidgetProvider {
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds){
final int N = appWidgetIds.length;
for (int i=0; i < N; i++) {
int appWidgetId = appWidgetIds[i];
Log.d("Steve", "Running for appWidgetId " + appWidgetId);
Toast.makeText(context, "Hello from onUpdate", Toast.LENGTH_SHORT);
Log.d("Steve", "After the toast line");
Intent intent = new Intent(context, WidgetTest.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
views.setOnClickPendingIntent(R.id.button, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
}
将小部件添加到主屏幕时,Logcat会显示两条调试行,但不会显示Toast。 (任何想法为什么不呢?)然而,更令人烦恼的是,当我点击与PendingIntent相关联的按钮时,根本没有任何事情发生。我知道“WidgetTest”活动可以运行,因为如果我在主要活动中设置了一个Intent,它会正常启动。
如果重要,这里是Android Manifest文件:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.steve"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".Volume_Change_Program"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".WidgetTest"
android:label="@string/hello">
<intent_filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent_filter>
</activity>
<receiver android:name=".VolumeChangerWidget" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/volume_changer_info" />
</receiver>
</application>
<uses-sdk android:minSdkVersion="3" />
有没有办法测试故障的位置?即按钮没有正确链接到PendingIntent,或者PendingIntent或Intent没有找到WidgetTest.class等错误?
非常感谢你的帮助!
史蒂夫
答案 0 :(得分:22)
让这个方式从死里复活,但我遇到了类似的问题,我想我终于解决了它...就像你一样,我有一个挂在RemoteView上的PendingIntent。有时它会起作用,有时会失败。这让我发疯了。
我从PendingIntent.getActivty()的工具提示中发现的是:
请注意,活动将在现有活动的上下文之外启动,因此您必须在Intent中使用Intent.FLAG_ACTIVITY_NEW_TASK启动标记。
所以,我补充道:
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
到目前为止,我见过的示例代码没有这样做,但它解决了我的问题;现在可以可靠地启动“设置”活动。
运行良好的完整代码......
Intent intent = new Intent(context, Settings.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appId); // Identifies the particular widget...
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// Make the pending intent unique...
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
PendingIntent pendIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.wwwidget);
views.setOnClickPendingIntent(R.id.widget, pendIntent);
appWidgetManager.updateAppWidget(appId,views);
答案 1 :(得分:9)
我遇到了同样的问题。我发现修复是通过appwidget管理器调用更新。这是一个如何在onEnabled中执行此操作的示例。它似乎需要在onEnabled和onUpdated中完成,这样当设备启动时你的点击意图也是初始化的 - 在onUpdated中,params已经提供了对经理的引用,幸运的是。
@Override
public void onEnabled(Context context) {
//Log.v("toggle_widget","Enabled is being called");
AppWidgetManager mgr = AppWidgetManager.getInstance(context);
//retrieve a ref to the manager so we can pass a view update
Intent i = new Intent();
i.setClassName("yourdoman.yourpackage", "yourdomain.yourpackage.yourclass");
PendingIntent myPI = PendingIntent.getService(context, 0, i, 0);
//intent to start service
// Get the layout for the App Widget
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.togglelayout);
//attach the click listener for the service start command intent
views.setOnClickPendingIntent(R.id.toggleButton, myPI);
//define the componenet for self
ComponentName comp = new ComponentName(context.getPackageName(), ToggleWidget.class.getName());
//tell the manager to update all instances of the toggle widget with the click listener
mgr.updateAppWidget(comp, views);
}
答案 2 :(得分:7)
这对我来说很有用,基于这里的信息,小部件样本和the tutorial here
Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
// first param is app package name, second is package.class of the main activity
ComponentName cn = new ComponentName("com....","com...MainActivity");
intent.setComponent(cn);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent myPI = PendingIntent.getActivity(context, 0, intent, 0);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_word);
views.setOnClickPendingIntent(R.id.widget, myPI);
AppWidgetManager mgr = AppWidgetManager.getInstance(context);
mgr.updateAppWidget(comp, views);
答案 3 :(得分:4)
Toast没有显示的问题很简单,你不要调用show(),这个错误我总是这样做... 做
Toast.makeText(context, "Hello from onUpdate", Toast.LENGTH_SHORT).show();
而不是
Toast.makeText(context, "Hello from onUpdate", Toast.LENGTH_SHORT);
答案 4 :(得分:1)
史蒂夫,
你找到了问题吗?我使用小部件,没有onEnabled技巧它对我很好。我很感兴趣为什么它不适合你。
我的猜测:请在原始代码中尝试
PendingIntent pendingIntent = PendingIntent.getActivity(context, 1, intent, 0);
而不是
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
答案 5 :(得分:0)
将小部件添加到 主屏幕,Logcat显示两个 调试行,虽然不是Toast。 (任何想法为什么不?)
请勿尝试从Toasts
启动BroadcastReceiver
。
有没有办法测试故障的位置 是
通过adb logcat
,DDMS或Eclipse中的DDMS透视图查看LogCat。您可能会发现有关未找到与给定Intent
匹配的活动的警告。
我没有看到任何明显的问题。你可能想看看one of my book examples,看看它是否适合你,以及它是否让你知道可能正在发生的事情。
答案 6 :(得分:0)
您必须在res / xml / volume_changer_info.xml中定义配置活动。添加此标记并提供配置活动的完全限定路径。
android:configure =“”
e.g。
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="200dip"
android:minHeight="100dip"
android:updatePeriodMillis="60000"
android:initialLayout="@layout/widget_loading"
android:configure = "org.raza.ConfigureWidgetActivity"/>
答案 7 :(得分:0)
我知道这个帖子很古老,但...... 其他答案描述了你烧焦的Toast问题。至于您的弹出活动无法在触摸时启动的原因,您可能需要启用“更新”操作才能启动并调用onUpdate()方法。为此,我认为您需要添加“APPWIDGET_UPDATE”操作,如下所示:
<activity android:name=".WidgetTest" android:label="@string/hello">
<intent_filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent_filter>
</activity>
如果您打算覆盖这些方法,请同样添加APPWIDGET_ENABLED和APPWIDGET_DISABLED操作。
这似乎是一个非常不寻常的API,需要您声明要调用的重写方法。获取父级自定义版本的常用方法是简单地覆盖/实现它们。也许这个奇怪的模式有一个很好的理由,但它不是我以前见过的Java模式。因此,我认为它可能会绊倒大量的应用程序小部件作者。如果没有这种机制,app小部件就不会让人感到困惑。
答案 8 :(得分:0)
还有一点:需要在Manifest文件中声明从Widget调用的Activity。没有例外,只是看起来没有任何反应......
答案 9 :(得分:-1)
我只是想在这里注意到这一点,因为我(非常愚蠢地)整晚都在与这场斗争。基本上我正确地完成了所有的意图代码,但没有任何东西可以启动。
问题是我不小心接到了这样的电话
super.onUpdate(context, appWidgetManager, appWidgetIds);
在我的Overridden onUpdate()函数结束时。
确保不要对super进行此调用,因为它会清除您设置的所有待处理意图!