Подтвердить что ты не робот

Запуск активности из виджета

Я пытаюсь сделать что-то, что действительно должно быть довольно легко, но это сводит меня с ума. Я пытаюсь запустить действие, когда нажимается виджет главного экрана, например, активность конфигурации для виджета. Я думаю, что я последовал за словом учебник на веб-сайте разработчиков 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 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 и т.д.?

Большое спасибо за вашу помощь!

Стив

4b9b3361

Ответ 1

У меня была такая же проблема. Я обнаружил, что исправление заключается в вызове обновления через диспетчер appwidget. вот пример того, как это сделать в 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); 
} 

Ответ 2

Возвращаясь назад из мертвых, но у меня была аналогичная проблема, и я думаю, что, наконец, решил ее... как и вы, у меня был PendingIntent, который я подключил к RemoteView. Иногда это сработало, и иногда это терпит неудачу. Это сводило меня с ума.

Что я нашел из всплывающей подсказки в PendingIntent.getActivty():

Обратите внимание, что действие будет запущено за пределами контекста существующего действия, поэтому вы должны использовать флаг запуска Intent.FLAG_ACTIVITY_NEW_TASK в Intent.

Итак, я добавил:

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);

Ответ 3

Это сработало для меня, основываясь на информации здесь, примере виджета слова и учебника здесь

       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); 

Ответ 4

Проблема с тостом, не показывающим, проста, вы не вызываете show(), ошибку, которую я всегда делаю тоже... сделать

Toast.makeText(context, "Hello from onUpdate", Toast.LENGTH_SHORT).show();

вместо

Toast.makeText(context, "Hello from onUpdate", Toast.LENGTH_SHORT);

Ответ 5

Стив,

Вы нашли проблему? Я использую виджет, и он отлично работает для меня без onEnabled трюка. Меня интересует, почему это не для вас.

Мое предположение: в исходном коде попробуйте

PendingIntent pendingIntent = PendingIntent.getActivity(context, 1, intent, 0);

вместо

PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);

Ответ 6

При добавлении виджета к рабочий стол, Logcat показывает два отладки линий, но не Toast. (Любые идеи, почему бы и нет?)

Не пытайтесь запустить Toasts с BroadcastReceiver.

Есть ли способ проверить, где ошибка это?

Посмотрите на LogCat с помощью adb logcat, DDMS или перспективы DDMS в Eclipse. Вы можете найти предупреждения о том, чтобы не найти действие, соответствующее указанному Intent.

Я не вижу никакой очевидной проблемы. Возможно, вы захотите взглянуть на один из моих примеров в книге и посмотреть, работает ли это для вас, и если это дает вам представление о том, что может быть запущен.

Ответ 7

вы должны определить свою конфигурационную активность в 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"/>

Ответ 8

Я просто хотел отметить это здесь, где я был (довольно глупо), сражаясь всю ночь. В основном я правильно использовал код намерения, но ничего не было запущено.

Проблема заключалась в том, что у меня случайно был такой вызов

super.onUpdate(context, appWidgetManager, appWidgetIds);

в конце моей функции Overridden onUpdate().

Убедитесь, что вы НЕ НАЙДИТЕ, чтобы этот вызов был супер, поскольку он очистит все ожидающие намерения, которые вы настроили!

Ответ 9

Я знаю, что эта тема древняя, но... Другие ответы описывают проблему сжигания тоста. Что касается того, почему ваша всплывающая активность не запускается при прикосновении, вам может потребоваться активировать действие "обновление", чтобы запустить и вызвать ваш метод 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, который я видел раньше. Поэтому я думаю, что это, скорее всего, привлечет большое количество авторов виджета приложений. Как будто виджеты приложений не сбивали с толку без этого механизма.

Ответ 10

Еще одна точка: активность, вызываемая из виджета, должна быть объявлена ​​в файле манифеста. Никакое исключение не выбрасывается, просто похоже, что ничего не происходит...