我已经尝试了大约 7,8 个教程并在这里阅读了至少 30,40 个答案,但都是徒劳的......我无法在我的手机上运行任何小部件。
每个小部件实现都不会更新我的小部件上的文本,也不会在单击时注册小部件。
例如本教程:http://blog.doityourselfandroid.com/2011/05/24/developing-android-home-screenwidgets/您可以下载代码,它在我 friend 的手机(android 2.3)上运行良好,但在我的手机上我可以看到接收器在 Log Cat 中发射但没有任何更新?
这是我当前的简单代码:
1. list
<receiver android:name=".TestWidgetProvider">
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/testwidgetprovider"
/>
<intent-filter >
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
</intent-filter>
</receiver>
<receiver android:name=".TestReceiver"/>
测试组件提供者
@Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds){ Log.d("CSV", "Called on onUpdate"); AlarmManager am=(AlarmManager) context.getSystemService(Context.ALARM_SERVICE); Calendar cal=Calendar.getInstance(); cal.add(Calendar.SECOND, 30); Intent intent=new Intent(context, TestReceiver.class); int N=appWidgetIds.length; for (int i=0; i<N; i++) { RemoteViews tt=new RemoteViews(context.getPackageName(), R.layout.testwidget); tt.setTextViewText(R.id.textView1,"UPDATED" +i); appWidgetManager.updateAppWidget(appWidgetIds[i], tt); Log.d("CSV", "Update widget, i = " +i + " widgetId=" + appWidgetIds[i] ); } intent.putExtra("id", appWidgetIds); intent.putExtra("duz", appWidgetIds.length); PendingIntent p1=PendingIntent.getBroadcast(context, 1, intent, 0); am.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 10000, p1); super.onUpdate(context, appWidgetManager, appWidgetIds);
测试接收者
public class TestReceiver extends BroadcastReceiver { private static final String tag="TestReceiver"; @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub int[] ID; Bundle extras=intent.getExtras(); ID=extras.getIntArray("id"); int duz=intent.getIntExtra("duz", 0); Log.d("CSV", "update widget id=" +ID); double b=Math.random(); int i=(int) ((b*10+1)%10); RemoteViews rv=new RemoteViews(context.getApplicationContext().getPackageName(), R.layout.testwidget); AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context.getApplicationContext()); for (int a=0; a<duz; i++) { rv.setTextViewText(R.id.textView1, "update random: " + a); appWidgetManager.updateAppWidget(ID[a], rv); Log.d("CSV", "Update widget, a = " +a + " widgetId=" + ID[a] ); } /* ComponentName provider = new ComponentName(context, TestWidgetProvider.class); appWidgetManager.updateAppWidget ( provider, rv); */
小部件 xml
<?xml version="1.0" encoding="utf-8"?> <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="200dp" android:minHeight="120dp" android:updatePeriodMillis="0" android:initialLayout="@layout/testwidget" android:resizeMode="horizontal|vertical" > </appwidget-provider>
请帮助我,我已经被困了好几天了...
编辑 1。我添加了第一个答案建议的主要 Activity ,但没有改变。
此外,第一次我在屏幕上设置小部件时,文本没有实际更新,就像它找不到小部件一样,但第二次我将小部件放在屏幕上时,它根据代码更改了文本在启用?
编辑 2:我已经发布了一个暂时解决了我的问题的答案,并更新了小部件
编辑 3. 我已将 Richard Le Mesurier 的答案标记为正确答案,因为他的演示代码非常详细地介绍了在进行网络操作时通过服务管理小部件。它涵盖了我的问题以及我要问的许多其他问题。如果您打算认真使用小部件,我建议您学习这个演示。
最佳答案
答案 2(更新工作演示链接)
正如对@JanBo 的 promise ,关于我如何解决这个问题的更多细节(免责声明 - 这只是我的意见,我希望就如何改进提出建设性意见)。
JanBo 有一个问题,一种更新方法有效,另一种失败。我建议他将它们组合成一个方法,在两种情况下都可以调用。
我在 GitHub 上有一个名为 StackFlairWidget 的概念验证演示小部件应用程序。它显示用户的 Stack Overflow“天赋”图像:
(此项目正在进行中 - 使用 POC Complete 提交查看与此问题相关的代码可能更容易。它有一些错误,但比 head 修订版更容易理解。)
这是一个允许对多个小部件进行不同配置的演示。你可以例如在项目中搜索“appWidgetId”以展示我如何围绕各种方法传递小部件 ID,从而使用户能够正确配置小部件。
它显示了将小部件更新代码卸载到服务内的线程中的模式,以免对您的 BroadcastReceiver
造成压力 - 随着项目的发展,您可能需要做类似的事情。
因为它只是一个演示应用程序,所以它包含许多评论、一些过于复杂的代码(从生产应用程序借来的)以及一些可怕的黑客攻击(我深表歉意)。
基本上,正如您所说,您的更新代码是正确的。首先,我的位于 FlairWidgetService
类中。它用图像更新给定的小部件:
public void updateWidget(int appWidgetId, Bitmap flair)
{
try
{
// set remote views
RemoteViews widgetUi = new RemoteViews(getPackageName(), R.layout.widget);
widgetUi.setImageViewBitmap(R.id.ivFlair, flair);
// open Settings on click
Intent flairSettings = new Intent(this, SettingsActivity.class);
flairSettings.putExtra(IntentExtra.Key.APP_WIDGET_ID, appWidgetId);
PendingIntent pendingIntentIp =
PendingIntent.getActivity(this, appWidgetId, flairSettings,
PendingIntent.FLAG_UPDATE_CURRENT);
widgetUi.setOnClickPendingIntent(R.id.ivFlair, pendingIntentIp);
/* UPDATE THE WIDGET INSTANCE */
try
{
AppWidgetManager widgetManager = AppWidgetManager.getInstance(this);
widgetManager.updateAppWidget(appWidgetId, widgetUi);
}
catch (Exception e)
{
Dbug.log("Failed to update widget");
}
}
catch (Exception e)
{
Dbug.log("Failed to update widget");
}
finally
{
// clean up
FlairWidgetService.this.stopSelf();
}
}
这不是唯一的方法,但我保证我会提供一些东西......祝你好运。
答案 1(根据编辑 1 对张贴者没有帮助)
看来您受到了 HoneyComb 中发生的安全升级的影响。
基本上,在较新版本的 Android 中,如果不先启动 Activity
,您就无法让小部件工作。
所以在项目中添加一个 Activity ,先运行它,我想你的小部件会更新。
一个很好的例子是使用设置样式 Activity ,或者可能和关于框类型的东西,来告诉用户一些关于您的小部件的信息。 (我在我的小部件中使用设置)。
更多信息:
关于android - android 4.0.3 上的小部件问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17674152/