从小部件启动活动

Ste*_*ley 36 android android-widget

我正在尝试做一些真正应该很容易的事情,但它让我发疯.我正在尝试在按下主屏幕窗口小部件时启动活动,例如窗口小部件的配置活动.我想我已经在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);
    }
}
Run Code Online (Sandbox Code Playgroud)

}

将小部件添加到主屏幕时,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" />
Run Code Online (Sandbox Code Playgroud)

有没有办法测试故障的位置?即错误是按钮没有正确链接到PendingIntent,或者PendingIntent或Intent没有找到WidgetTest.class等?

非常感谢您的帮助!

史蒂夫

Bre*_*and 22

把这种方式从死里复活,但是我遇到了类似的问题,我想我终于解决了它......就像你一样,我有一个PendingIntent,我附加到了RemoteView.有时它会起作用,有时会失败.这让我发疯了.

我从PendingIntent.getActivty()的工具提示中发现的是:

请注意,活动将在现有活动的上下文之外启动,因此您必须在Intent中使用Intent.FLAG_ACTIVITY_NEW_TASK启动标志.

所以,我补充说:

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Run Code Online (Sandbox Code Playgroud)

到目前为止,我见过的示例代码没有这样做,但它解决了我的问题; 现在可以可靠地启动"设置"活动.

完整的代码运行良好......

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);
Run Code Online (Sandbox Code Playgroud)


myl*_*ock 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); 
} 
Run Code Online (Sandbox Code Playgroud)


小智 7

这对我有用,基于这里的信息,单词widget示例和这里的教程

       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); 
Run Code Online (Sandbox Code Playgroud)