Я пытаюсь сделать что-то, что действительно должно быть довольно легким, но это сводит меня с ума. Я пытаюсь запустить действие, когда виджет главного экрана нажимается, такие как действие конфигурации для виджета. Я думаю, что следовал дословно учебному руководству на веб-сайте Разработчиков 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);
}
}
}
При добавлении виджета к homescreen Logcat показывает две строки отладки, хотя не Тост. (Какие-либо идеи, почему нет?) Однако более раздражающий то, что, когда я тогда нажимаю на кнопку с PendingIntent, связанным с ним, ничего не происходит вообще. Я знаю, что действие "WidgetTest" может работать, потому что, если я настроил Намерение из основного вида деятельности, оно запускается прекрасный.
В случае, если это имеет значение, вот Файл манифеста Android:
<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 или Намерение не находят WidgetTest.class и т.д.?
Большое спасибо за Вашу справку!
Steve
] У меня был тот же вопрос. Я обнаружил, что исправление заключается в вызове обновления через менеджер приложений. Вот пример, как это сделать в 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);
}
] Проблема с тем, что тост не отображается, проста, вы не вызываете show (), ошибка, которую я всегда делаю ... do
Toast.makeText(context, "Hello from onUpdate", Toast.LENGTH_SHORT).show();
вместо
Toast.makeText(context, "Hello from onUpdate", Toast.LENGTH_SHORT);
При добавлении виджета к Домашний экран, Логкат показывает два отладочные строки, хотя и не Тост. (Есть идеи, почему бы и нет?)
Не пытайтесь запустить Toasts
из BroadcastReceiver
.
Есть ли способ проверить, где произошла ошибка. is?
Посмотрите на LogCat, через adb logcat
, DDMS, или с точки зрения DDMS в Eclipse. Вы можете найти предупреждения о том, что не найдено активности, соответствующей данному Intent
.
Я не вижу очевидной проблемы. Возможно, Вы захотите взглянуть на один из моих примеров из книги и посмотреть, работает ли это на Вас, и дает ли это Вам представление о том, что может быть пешком.
.Стив,
Вы нашли проблему? Я использую виджет, и он отлично работает у меня без трюка onEnabled. Мне интересно, почему это не для вас.
Я предполагаю: в исходном коде попробуйте
PendingIntent pendingIntent = PendingIntent.getActivity(context, 1, intent, 0);
вместо
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
вы должны определить свою конфигурационную активность в res/xml/volume_changer_info.xml. Добавьте этот тег и укажите полный путь к конфигурационной активности.
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"/>