Android appWidget多个实例

时间:2012-05-15 19:29:33

标签: android android-appwidget

这个问题几乎与Android - Multiple appWidgets playing different sounds重复,但我的代码无效。我正在使用小部件ID添加一个额外的intent,并使用日志语句来证明它,但每当我点击其中一个小部件时,只有多个实例,我才会获得最后一个appWidgetId。看起来第一个小部件的意图在添加第二个小部件后会发生变化。如果其他帖子中的代码应该有效,那么我必须忽略一些东西,因为我相信我的设置方式几乎相同。

 public class PhcaAppWidgetProvider extends AppWidgetProvider {
     private static final String ACTION_CLICK = "com.skipmorrow.phca.PhcaAppWidgetProvider.WIDGET_CLICKED";
     private final String widgetPageName = "_widget";
     private static final String PREFS_NAME = "PHCA";
     private static final String PREF_PREFIX_KEY = "prefix_";
     private static String MY_DEBUG = "PhcaAppWidget";

     @Override
     public void onUpdate(Context context, AppWidgetManager appWidgetManager,
             int[] appWidgetIds) {
        Log.d(MY_DEBUG, "Provider.onUpdate");
     }

     @Override
     public void onReceive(Context context, Intent intent) {
        String intentAction = intent.getAction();
        Log.d(MY_DEBUG, "Provider.onReceive(); action = " + intentAction);
        Bundle extras = intent.getExtras();

        // make a list of all extras, just so I can see what is in there...
        if (extras!=null) {
            Set<String> ks = extras.keySet();
            Iterator<String> iterator = ks.iterator();
            while (iterator.hasNext()) {
                String s = iterator.next();
                Log.d(MY_DEBUG, "Provider.Key found: " + s);
            }
        }
        else {
          Log.d(MY_DEBUG, "Provider.extras was null");
        }

            int[] appWidgetIds1 = intent.getIntArrayExtra("appWidgetIds");

            if (extras!=null && extras.containsKey("appWidgetIds")){
                // sometimes the intent comes back with an array of appWidgetIds, and sometimes the appWidgetId is stored
                // in the one extra "appWidgetId" Clicks never come with the array of appWidgetIds. They always come by
                // themselves
                Log.d(MY_DEBUG, "Provider.Intent extras does contain a key appWidgetIds");
                if (appWidgetIds1!=null) Log.d(MY_DEBUG, "Provider.Intent int array appWidgetIds1 size is " + appWidgetIds1.length);
                for (int i = 0; i<appWidgetIds1.length; i++) {
                    int appWidgetId = appWidgetIds1[i];
                    Log.d(MY_DEBUG, "Provider.Intent appWidgetIds1[" + i + "] = " + appWidgetId);
                    if (intentAction.equals("android.appwidget.action.APPWIDGET_UPDATE")) {
                        Log.d(MY_DEBUG, "Provider.APPWIDGET UPDATE");
                        updateWidgetState(context, intentAction, appWidgetId);
                    } else if (intentAction.equals("android.appwidget.action.APPWIDGET_DELETED")) {
                        // do nothing
                    }
                    else {
                        super.onReceive(context, intent);
                    }
                }
            } else {

            String intentData = intent.getDataString();
            Log.d(MY_DEBUG, "Provider.intent data = " + intentData);


            Integer appWidgetId = intent.getIntExtra("appWidgetId", -1);
            Log.d(MY_DEBUG, "Provider.appWidgetId = " + appWidgetId);

            if (intentAction.equals(ACTION_CLICK)) {
                Log.d(MY_DEBUG, "Provider.Clicked");
                SharedPreferences myPrefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_WORLD_WRITEABLE);
                Integer objNum = myPrefs.getInt(PREF_PREFIX_KEY + appWidgetId, -1);
                Log.d(MY_DEBUG, "Provider.ObjNum = " + objNum);
                if (objNum > -1) {
                    Log.d(MY_DEBUG, "Provider.Executing...");
                    PageAction pa = (PageAction) CommonActivity.GetPageObjectAtIndex(context, widgetPageName, objNum);
                    pa.ExecuteActionFromWidgetClick(context);
                }
            }
            else {
                super.onReceive(context, intent);
            } 
            }
     }

     public static void updateWidgetState(Context paramContext, String paramString, Integer appWidgetId)
     {
        Log.d(MY_DEBUG, "Provider.updateWidgetState; appWidgetId = " + appWidgetId + "; paramString = " + paramString);
        RemoteViews localRemoteViews = buildUpdate(paramContext, paramString, appWidgetId);
        ComponentName localComponentName = new ComponentName(paramContext, PhcaAppWidgetProvider.class);
        AppWidgetManager.getInstance(paramContext).updateAppWidget(localComponentName, localRemoteViews);
     }



     private static RemoteViews buildUpdate(Context ctx, String paramString, Integer appWidgetId)
     {
        Log.d(MY_DEBUG, "Provider.buildUpdate(); appWidgetId = " + appWidgetId + "; paramString = " + paramString);
        RemoteViews views = new RemoteViews(ctx.getPackageName(), R.layout.phca_appwidget);
        if (paramString.equals("android.appwidget.action.APPWIDGET_UPDATE")) {
            Log.d(MY_DEBUG, "Provider.buildUpdate().. APPWIDGET_UPDATE");
            Intent intent = new Intent(ctx, PhcaAppWidgetProvider.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setAction(ACTION_CLICK);
            intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
            Uri data = Uri.withAppendedPath(
                Uri.parse("ABCD" + "://widget/id/")
                ,String.valueOf(appWidgetId));
            intent.setData(data);
            Log.d(MY_DEBUG, "Provider.Added intent extra \"" +  AppWidgetManager.EXTRA_APPWIDGET_ID + "\" = " + appWidgetId);

            PendingIntent pendingIntent = PendingIntent.getBroadcast(ctx, appWidgetId, intent , PendingIntent.FLAG_UPDATE_CURRENT);
            views.setOnClickPendingIntent(R.id.phca_appwidget_layout, pendingIntent);
        }
        if(paramString.equals(ACTION_CLICK))
        {
            Log.d(MY_DEBUG, "Provider.buildUpdate().. CLICKED");
            Toast.makeText(ctx, "ACTION_CLICK", Toast.LENGTH_LONG).show();
        }
        return views; 
    }
 }

我有配置活动(ListActivity)这是我的onListItemClick:

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);
    Toast.makeText(getApplicationContext(), "onListItemClick", Toast.LENGTH_SHORT);
    Log.d(MY_DEBUG, "Configurator.onListItemClick");
    SharedPreferences.Editor prefs = getSharedPreferences(PREFS_NAME, 0).edit();
    prefs.putInt(PREF_PREFIX_KEY + mAppWidgetId, position);
    prefs.commit();
    Log.d(MY_DEBUG, "Configurator.Prefs.commit()");

    // Push widget update to surface with newly set prefix
    Log.d(MY_DEBUG, "Configurator.calling updateWidgetState with appWidgetId = " + mAppWidgetId);
    PhcaAppWidgetProvider.updateWidgetState(getApplicationContext(), "android.appwidget.action.APPWIDGET_UPDATE", mAppWidgetId);
    Log.d(MY_DEBUG, "Configurator.updateWidgetState complete");
    Intent resultValue = new Intent();
    Uri data = Uri.withAppendedPath(
            Uri.parse("ABCD" + "://widget/id/")
            ,String.valueOf(mAppWidgetId));
    resultValue.setData(data);
    resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
    Log.d(MY_DEBUG, "Configurator.Creating widget with id = " + mAppWidgetId);
    setResult(RESULT_OK, resultValue);
    finish();
}

我已经在这方面工作了两天,我希望有人可以指出我的方式错误。虚拟电子啤酒等待着能够解决这个问题的人:)

2 个答案:

答案 0 :(得分:4)

我试图查看你的代码,但没有找到它为什么它不适合你,除了我在你的代码中发现了一些其他的错误。无论如何,我已经构建了一个可以尝试的快速工作代码。

<强> WidgetProvider.java

package com.example.helloclickablewidget;

import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.widget.RemoteViews;
import android.widget.Toast;

public class WidgetProvider extends AppWidgetProvider {

    public static final String WIDGET_CLICKED = "com.example.helloclickablewidget.WIDGET_CLICKED";

    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();

        if (action != null && action.equals(WIDGET_CLICKED)) {
            int widgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
            Toast.makeText(context, "Widget clicked. ID: " + widgetId, Toast.LENGTH_LONG).show();
        } else {
            super.onReceive(context, intent);
        }
    }

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        final int N = appWidgetIds.length;

        // Perform this loop procedure for each App Widget that belongs to this provider
        for (int i = 0; i < N; i++) {
            int appWidgetId = appWidgetIds[i];

            // Create an Intent to launch ExampleActivity
            Intent intent = new Intent(context, WidgetProvider.class);
            intent.setAction(WIDGET_CLICKED);
            intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
            PendingIntent pendingIntent = PendingIntent.getBroadcast(context, appWidgetId, intent,
                    PendingIntent.FLAG_UPDATE_CURRENT);

            // Get the layout for the App Widget and attach an on-click listener
            // to the button
            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
            views.setOnClickPendingIntent(R.id.text, pendingIntent);
            // Tell the AppWidgetManager to perform an update on the current app widget
            appWidgetManager.updateAppWidget(appWidgetId, views);
        }
    }

}

<强>布局/ widget.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/text"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:text="@string/app_name" >
</TextView>

<强> XML / widget.xml

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialLayout="@layout/widget"
    android:minHeight="50dp"
    android:minWidth="50dp"
    android:updatePeriodMillis="86400000" >
</appwidget-provider>

<强>的AndroidManifest.xml

<manifest package="com.example.helloclickablewidget"
    android:versionCode="1"
    android:versionName="1.0" xmlns:android="http://schemas.android.com/apk/res/android">

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <receiver android:name="WidgetProvider" android:exported="false">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
                <action android:name="com.example.helloclickablewidget.WIDGET_CLICKED"/>
            </intent-filter>
            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/widget" />
        </receiver>
    </application>

</manifest>

答案 1 :(得分:1)

尝试替换这些行:

Uri data = Uri.withAppendedPath(
            Uri.parse("ABCD" + "://widget/id/")
            ,String.valueOf(appWidgetId));
        intent.setData(data);

使用:

intent.setData(ContentUris.withAppendedId(Uri.EMPTY, appWidgetId));