从小部件启动活动
我正在尝试做一些本该很容易的事情,但是这让我发疯。 我试图在主屏幕小部件被按下时启动一个活动,例如小部件的configuration活动。 我想我已经在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将显示两条debugging线,但不包括Toast。 (任何想法为什么不呢?)然而,更令人烦恼的是,当我然后点击与PendingIntent相关联的button时,什么也没有发生。 我知道“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" />
有没有方法来testing故障的位置? 即是button没有正确链接到PendingIntent,或者PendingIntent或Intent没有findWidgetTest.class等错误?
非常感谢您的帮助!
史蒂夫
我有同样的问题。 我发现修正是通过appwidgetpipe理器调用更新。 这里是一个如何在onEnabled中做的例子。 看起来它需要在onEnabled和onUpdated中完成,以便当设备启动时,您的点击意图也是初始化的 – 在onUpdated中,参数已经提供了经理的参考,幸运的是。
@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); }
从死里复活,但我也有类似的问题,我想我终于解决了这个问题…就像你,我有一个PendingIntent,我附加到RemoteView。 有时会起作用,有时会失败。 这让我疯狂。
我从PendingIntent.getActivty()的工具提示中find的是:
请注意,该活动将在现有活动的上下文之外启动,因此您必须在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);
这对我来说,基于这里的信息,单词小部件示例,和教程在这里
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);
Toast没有显示的问题很容易,你不要调用show(),我总是这样做的错误…做
Toast.makeText(context, "Hello from onUpdate", Toast.LENGTH_SHORT).show();
代替
Toast.makeText(context, "Hello from onUpdate", Toast.LENGTH_SHORT);
史蒂夫,
你有没有发现问题? 我使用小部件,没有onEnabled技巧,它适用于我。 我很感兴趣,为什么它不适合你。
我的猜测:在你的原始代码请尝试
PendingIntent pendingIntent = PendingIntent.getActivity(context, 1, intent, 0);
代替
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
在将主窗口部件添加到主屏幕时,Logcat将显示两条debugging线,但不包括Toast。 (任何想法为什么不?)
不要尝试从BroadcastReceiver
启动Toasts
。
有没有方法来testing故障的位置?
在Eclipse中,通过adb logcat
,DDMS或DDMS透视看LogCat。 您可能会发现有关未find与给定Intent
相匹配的活动的警告。
我没有看到任何明显的问题。 你可能想看一看我的一本书例子 ,看看它是否适合你,以及它是否让你了解可能发生的事情。
您必须在res / xml / volume_changer_info.xml中定义您的configuration活动。 添加此标记并为configuration活动提供完全限定的path。
android:configure =“”
例如
<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"/>
我只是想在这里注意到这个地方,因为我一直(相当愚蠢)整晚都在为此而战。 基本上我正确地做了所有的意图代码,但没有任何启动。
问题是我不小心打了这样的电话
super.onUpdate(context, appWidgetManager, appWidgetIds);
在我的覆盖onUpdate()函数结束。
确保你没有这个电话超级,因为它会清除你设置的所有待决的意图!
我知道这个线程是古老的,但…其他答案描述了你的烧烤吐司问题。 至于为什么你的popup式活动不能触摸,你可能需要启用“更新”操作才能启动并调用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模式。 因此,我认为这可能会导致大量的应用程序小部件作者。 就好像应用程序小部件在没有这个机制的情况下也不够混乱。
另外一点:从Widget调用的Activity需要在Manifest文件中声明。 没有exception抛出,只是看起来没有任何反应