Question

I am making an android app that has 2 widgets. I have 1 widget set up and working, and the second widget is recognized in the widget list & loads correctly, but:

If I already have widget 1 on the screen when I add widget 2, both widgets change to widget 2. If I have a widget 2 and a widget 1, and add a widget 2, they all change to widget 2. The same happens if I add widget 1 - they all change to widget 1.

Also, nothing happens when widget 2 is clicked, even though I have used pretty much the same code from widget 1.

Below are the relevant files:

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.liamwli.reboot_widget"
    android:installLocation="internalOnly"
    android:versionCode="3"
    android:versionName="1.1" >

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

    <uses-permission android:name="android.permission.REBOOT" />
    <uses-permission android:name="com.android.vending.CHECK_LICENSE" />

    <application
        android:allowClearUserData="false"
        android:icon="@drawable/icon"
        android:label="@string/app_name" >
        <activity
            android:name=".reboot_widget_activeity"
            android:excludeFromRecents="true"
            android:icon="@drawable/icon"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver
            android:name=".Reboot_rec"
            android:icon="@drawable/icon"
            android:label="Reboot Recovery Widget" >
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
                <action android:name="com.liamwli.reboot_widget.Reboot_rec.ACTION_WIDGET_CLICK_RECEIVER" />
            </intent-filter>

            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/rebr_widget" />
        </receiver>

        <service android:name=".Reboot_rec$ToggleService" />

        <receiver
            android:name=".Widget"
            android:icon="@drawable/icon"
            android:label="Reboot Widget" >
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
                <action android:name="com.liamwli.reboot_widget.Widget.ACTION_WIDGET_CLICK_RECEIVER" />
            </intent-filter>

            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/widgetstuff" />
        </receiver>

        <service android:name=".Widget$ToggleService" />

        <activity
            android:name=".Reboot"
            android:excludeFromRecents="true"
            android:icon="@drawable/icon"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="com.liamwli.reboot_widget.REBOOT" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity
            android:name=".Reboot_rec"
            android:excludeFromRecents="true"
            android:icon="@drawable/icon"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="com.liamwli.reboot_widget.REBOOT_REC" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity
            android:name=".hidprefs"
            android:excludeFromRecents="true"
            android:icon="@drawable/icon"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="com.liamwli.reboot_widget.HIDPREFS" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Widget.java (For widget 1):

package com.liamwli.reboot_widget;

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

public class Widget extends AppWidgetProvider {
    public static String ACTION_WIDGET_CLICK_RECEIVER = "ActionReceiverWidget";

    public static int appid[];
    public static RemoteViews rview;

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
            int[] appWidgetIds) {
        updateWidgetState(context, "");
    }

    @Override
    public void onReceive(Context paramContext, Intent paramIntent) {
        String str = paramIntent.getAction();
        if (paramIntent.getAction().equals(ACTION_WIDGET_CLICK_RECEIVER)) {
            updateWidgetState(paramContext, str);
        } else {
            if ("android.appwidget.action.APPWIDGET_DELETED".equals(str)) {
                int i = paramIntent.getExtras().getInt("appWidgetId", 0);
                if (i == 0) {

                } else {
                    int[] arrayOfInt = new int[1];
                    arrayOfInt[0] = i;
                    onDeleted(paramContext, arrayOfInt);
                }
            }
            super.onReceive(paramContext, paramIntent);
        }
    }

    static void updateWidgetState(Context paramContext, String paramString) {
        RemoteViews localRemoteViews = buildUpdate(paramContext, paramString);
        ComponentName localComponentName = new ComponentName(paramContext,
                Widget.class);
        AppWidgetManager.getInstance(paramContext).updateAppWidget(
                localComponentName, localRemoteViews);
    }

    private static RemoteViews buildUpdate(Context paramContext, String paramString)
       {
         // Toast.makeText(paramContext, "buildUpdate() ::"+paramString, Toast.LENGTH_SHORT).show();
         rview = new RemoteViews(paramContext.getPackageName(), R.layout.widget_layout);
         Intent active = new Intent(paramContext, Widget.class);
         active.setAction(ACTION_WIDGET_CLICK_RECEIVER);

         PendingIntent configPendingIntent = PendingIntent.getActivity(paramContext, 0, active, 0);

// upadte this R.id.buttonus1 with your layout or image id on which click you want to start Activity

Intent configIntent = new Intent(paramContext,  Reboot.class);
configIntent.setAction((ACTION_WIDGET_CLICK_RECEIVER));
PendingIntent configPendingIntent1 = PendingIntent.getActivity(paramContext, 0, configIntent, 0);
rview.setOnClickPendingIntent(R.id.bRB, configPendingIntent1);
         if(paramString.equals(ACTION_WIDGET_CLICK_RECEIVER))
         {



         }  
          return rview; 
       }

    @Override
    public void onEnabled(Context context) {
        super.onEnabled(context);
        // Toast.makeText(context, "onEnabled()  ", Toast.LENGTH_SHORT).show();
    }

    // Called each time an instance of the App Widget is removed from the host
    @Override
    public void onDeleted(Context context, int[] appWidgetId) {
        super.onDeleted(context, appWidgetId);
        // Toast.makeText(context, "onDeleted()  ", Toast.LENGTH_SHORT).show();
    }

    // Called when last instance of App Widget is deleted from the App Widget
    // host.
    @Override
    public void onDisabled(Context context) {
        super.onDisabled(context);
        // Toast.makeText(context, "onDisabled()  ", Toast.LENGTH_SHORT).show();
    }

}

Reboot_rec.java (for widget 2):

package com.liamwli.reboot_widget;

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

public class Reboot_rec extends AppWidgetProvider {


    public static String ACTION_WIDGET_CLICK_RECEIVER = "ActionReceiverWidget";

    public static int appid[];
    public static RemoteViews rview;

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
            int[] appWidgetIds) {
        updateWidgetState(context, "");
    }

    @Override
    public void onReceive(Context paramContext, Intent paramIntent) {
        String str = paramIntent.getAction();
        if (paramIntent.getAction().equals(ACTION_WIDGET_CLICK_RECEIVER)) {
            updateWidgetState(paramContext, str);
        } else {
            if ("android.appwidget.action.APPWIDGET_DELETED".equals(str)) {
                int i = paramIntent.getExtras().getInt("appWidgetId", 0);
                if (i == 0) {

                } else {
                    int[] arrayOfInt = new int[1];
                    arrayOfInt[0] = i;
                    onDeleted(paramContext, arrayOfInt);
                }
            }
            super.onReceive(paramContext, paramIntent);
        }
    }

    static void updateWidgetState(Context paramContext, String paramString) {
        RemoteViews localRemoteViews = buildUpdate(paramContext, paramString);
        ComponentName localComponentName = new ComponentName(paramContext,
                Widget.class);
        AppWidgetManager.getInstance(paramContext).updateAppWidget(
                localComponentName, localRemoteViews);
    }

    private static RemoteViews buildUpdate(Context paramContext, String paramString)
       {
         // Toast.makeText(paramContext, "buildUpdate() ::"+paramString, Toast.LENGTH_SHORT).show();
         rview = new RemoteViews(paramContext.getPackageName(), R.layout.widget_layout_rec);
         Intent active = new Intent(paramContext, Reboot_rec.class);
         active.setAction(ACTION_WIDGET_CLICK_RECEIVER);

         PendingIntent configPendingIntent = PendingIntent.getActivity(paramContext, 0, active, 0);

// upadte this R.id.buttonus1 with your layout or image id on which click you want to start Activity

Intent configIntent = new Intent(paramContext,  Reboot_rec_ac.class);
configIntent.setAction((ACTION_WIDGET_CLICK_RECEIVER));
PendingIntent configPendingIntent1 = PendingIntent.getActivity(paramContext, 0, configIntent, 0);
rview.setOnClickPendingIntent(R.id.bRBR, configPendingIntent1);
         if(paramString.equals(ACTION_WIDGET_CLICK_RECEIVER))
         {



         }  
          return rview; 
       }

    @Override
    public void onEnabled(Context context) {
        super.onEnabled(context);
        // Toast.makeText(context, "onEnabled()  ", Toast.LENGTH_SHORT).show();
    }

    // Called each time an instance of the App Widget is removed from the host
    @Override
    public void onDeleted(Context context, int[] appWidgetId) {
        super.onDeleted(context, appWidgetId);
        // Toast.makeText(context, "onDeleted()  ", Toast.LENGTH_SHORT).show();
    }

    // Called when last instance of App Widget is deleted from the App Widget
    // host.
    @Override
    public void onDisabled(Context context) {
        super.onDisabled(context);
        // Toast.makeText(context, "onDisabled()  ", Toast.LENGTH_SHORT).show();
    }





}

Rebr_widget.xml (for widget 2):

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


</appwidget-provider>

widgetstuff.xml (for widget 1):

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


</appwidget-provider>

Can ANYONE tell me what the problem is? I am doing my nut in trying to figure it out :(

Was it helpful?

Solution

You havent made use of the onUpdate param int[] appWidgetIds.

You should loop through this, and apply any code to each one. At the moment you are not telling it which widget to update. Nor do you try and update more than the one widget.

Example below, note the loop on N. And the sub method also uses the id of the widget, which is passed from the loop on onUpdate.

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

        Log.d(LOG_TAG, "Updating Example Widgets.");

        // 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, WidgetExampleActivity.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);

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


            // Update The clock label using a shared method
            updateAppWidget(context, appWidgetManager, appWidgetId);
        }
    }

    public static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
        String currentTime =  df.format(new Date());

        RemoteViews updateViews = new RemoteViews(context.getPackageName(), R.layout.widget1);
        updateViews.setTextViewText(R.id.widget1label, currentTime);
        appWidgetManager.updateAppWidget(appWidgetId, updateViews);
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top