代码之家  ›  专栏  ›  技术社区  ›  Steve Haley

从小部件启动活动

  •  36
  • Steve Haley  · 技术社区  · 16 年前

    我正试图做一件本应该很容易的事,但这让我发疯。我试图在按下主屏幕小部件时启动一个活动,例如小部件的配置活动。我想我已经逐字逐句地关注了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);
        }
    }
    

    }

    如果有必要,以下是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" />
    

    有没有办法测试故障在哪里?也就是说,是因为按钮没有正确链接到PendingEvent,还是PendingEvent或Intent没有找到WidgetTest.class,等等?

    非常感谢你的帮助!

    10 回复  |  直到 16 年前
        1
  •  9
  •   mylock    16 年前

    @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
  •  22
  •   Brent Chartrand    15 年前

    方式

    我从PendingEvent.getActivty()上的工具提示中发现:

    请注意,活动将在现有活动的上下文之外启动,因此必须在Intent中使用Intent.FLAG\u activity\u NEW\u TASK launch标志。

    因此,我补充说:

    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
  •  7
  •   kdahlhaus    15 年前

    基于这里的信息、word widget示例和 the tutorial here

           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
  •  4
  •   JohanS    16 年前

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

    Toast.makeText(context, "Hello from onUpdate", Toast.LENGTH_SHORT);
    
        5
  •  0
  •   CommonsWare    16 年前

    将小部件添加到 (有什么想法吗?)

    不要尝试发射 Toasts BroadcastReceiver .

    有没有办法测试故障在哪里

    看看LogCat,via adb logcat Intent .

    我看不出有什么明显的问题。你可能想看一眼 one of my book examples

        6
  •  0
  •   Steve Haley    16 年前

    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"/>
    
        7
  •  0
  •   Melinda Green    13 年前

    我知道这根线很古老,但是。。。 其他答案描述了你的烤面包问题。至于为什么您的弹出式活动不能在touch上启动,您可能需要启用“更新”操作才能启动并调用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>
    

    这似乎是一个非常不寻常的API,它要求您声明要调用的重写方法。获取父级自定义版本的常用方法是简单地重写/实现它们。也许这种奇怪的模式有一个很好的理由,但它不是我以前见过的Java模式。因此,我认为这可能会让很多应用程序小部件的作者绊倒。如果没有这种机制,应用程序小部件似乎还不够混乱。

        8
  •  0
  •   Stephan    13 年前

    另外一点:从小部件调用的活动需要在清单文件中声明。没有抛出异常,只是看起来什么都没有发生。。。

        9
  •  -1
  •   Sverrir Sigmundarson    14 年前

    我只是想在这里的某个地方注意到这一点,因为我已经(相当愚蠢地)为此奋斗了一整晚。基本上,我正确地完成了所有的意图代码,但没有启动任何东西。

    问题是我不小心接到了这样的电话

    super.onUpdate(context, appWidgetManager, appWidgetIds);
    

    在重写的onUpdate()函数的末尾。

    不要 打这个电话给super,因为它会清除你设置的所有悬而未决的意图!