Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android appwidget click not working

Gosh, there must be a thousand different tutorials on android appwidgets and even more questions here, but I just cannot figure out why mine isn't working. sigh Rhetorical question: why can't the code be the same here as just about every other object with the setOnClickListener (new new Button.OnClickListener() { // do stuff }... Anyway, my widget shows up on the screen and the labels are correct, but when I tap on the widget, nothing happens. I've put breakpoints in all the places where I think something would happen, but nothing is being executed.

Question 1: What code is executed after a widget is tapped?

My widget doesn't really update when it is tapped. Rather, it just executes some code in the rest of my program. It just makes some networking http and/or socket server commands. Also, my widget is configured with an activity before it is placed on the desktop.

Here's the manifest:

 <receiver android:name="PhcaAppWidgetProvider" >
     <intent-filter>
         <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
         <action android:name="com.skipmorrow.phca.PhcaAppWidgetProvider.WIDGET_CLICKED" />
     </intent-filter>
     <meta-data android:name="android.appwidget.provider"
                android:resource="@xml/phca_widget_info" />
 </receiver>

Here's the widget configurator activity

    private Activity act;
    private static ListView listView;
    private static ArrayAdapter<String> adapter;
    private ArrayList<String> actionList;
    private final String widgetPageName = "_widget";
    int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
     private static final String PREFS_NAME = "PHCA";
     private static final String PREF_PREFIX_KEY = "prefix_";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setTitle("Choose an action for this widget");
        actionList = GetActionList();
        if (!actionList.isEmpty()) {
            listView = getListView();
            adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1, actionList);
            setListAdapter(adapter);
        }
        else {
            // no objects on the widget page
        }

        // Find the widget id from the intent. 
         Intent intent = getIntent();
         Bundle extras = intent.getExtras();
         if (extras != null) {
             mAppWidgetId = extras.getInt(
                     AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
         }

         // If they gave us an intent without the widget id, just bail.
         if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
             finish();
         }
    }

    private ArrayList<String> GetActionList() {
        ArrayList<String> l = new ArrayList<String>();
        Page p = CommonActivity.GetPageNamed(getApplicationContext(), widgetPageName);
        if (p!=null) {
            if (p.pageObjects.size()==0) DisplayEmptyPageHelpDialog();
            for (int i = 0; i < p.pageObjects.size(); i++) {
                l.add(p.pageObjects.get(i).GetParsedMajorLabel(getApplicationContext()).toString());
            }
        }
        else {
            CreateWidgetPage();
            DisplayEmptyPageHelpDialog();
        }
        return l;
    }

    private void CreateWidgetPage() {
        Page widgetPage = new Page(getApplicationContext());
        widgetPage.setPageName(widgetPageName);
        widgetPage.SetPageType("list");
        widgetPage.setNote("Widget Page");
        widgetPage.setPageTitle("Widget Page");
        widgetPage.setImageFilename("");
        widgetPage.setTransparentImageOverlayFilename("");
        widgetPage.InsertInstanceIntoDatabase(getApplicationContext());
    }

     private void DisplayEmptyPageHelpDialog() {
        Dialog helpDialog = new Dialog(this);
        helpDialog.setContentView(R.layout.phca_help_dialog);
        helpDialog.setTitle("PHCA Widget");
        TextView helpText = (TextView) helpDialog.findViewById(R.id.tvHelpText);
        helpText.setText("Your _widget page is empty. Please add an action to the _widget page so it can be used in a widget.");
        TextView subTitle = (TextView) helpDialog.findViewById(R.id.tvSubject);
        subTitle.setText("PHCA Widget configurator");
        helpDialog.show();
    }

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
        SharedPreferences.Editor prefs = getSharedPreferences(PREFS_NAME, 0).edit();
         prefs.putInt(PREF_PREFIX_KEY + mAppWidgetId, position);
         prefs.commit();

         // Push widget update to surface with newly set prefix
         String majorLabel = CommonActivity.GetPageObjectAtIndex(getApplicationContext(), widgetPageName, position).GetParsedMajorLabel(getApplicationContext()).toString();
         String minorLabel = CommonActivity.GetPageObjectAtIndex(getApplicationContext(), widgetPageName, position).GetParsedMinorLabel(getApplicationContext()).toString();
         AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getApplicationContext());
         PhcaAppWidgetProvider.updateAppWidget(getApplicationContext(), appWidgetManager,
                 mAppWidgetId, majorLabel, minorLabel);

         Intent resultValue = new Intent();
         resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
         setResult(RESULT_OK, resultValue);
         finish();
    }

And here's my appwidget provider

 public class PhcaAppWidgetProvider extends AppWidgetProvider {
    private static final String ACTION_CLICK = "WIDGET_CLICKED";
    private final String widgetPageName = "_widget";
     private static final String PREFS_NAME = "PHCA";
     private static final String PREF_PREFIX_KEY = "prefix_";

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

        // Get all ids
        ComponentName thisWidget = new ComponentName(context,
                PhcaAppWidgetProvider.class);
        //int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
        final int N = appWidgetIds.length;
         for (int i=0; i<N; i++) {
            int appWidgetId = appWidgetIds[i];

            SharedPreferences myPrefs = context.getSharedPreferences(PREFS_NAME, context.MODE_WORLD_WRITEABLE);
            Integer objNum = myPrefs.getInt(PREF_PREFIX_KEY + appWidgetId, -1);
            if (objNum > -1) {
                PageAction pa = (PageAction) CommonActivity.GetPageObjectAtIndex(context, widgetPageName, objNum);
                String majorLabel = pa.GetUnparsedMajorLabel(context).toString();
                String minorLabel = pa.GetUnparsedMinorLabel(context).toString();
                updateAppWidget(context, appWidgetManager, appWidgetId, majorLabel, minorLabel);
            }
        }
    }

    @Override
    public void onEnabled(Context context) {
        Log.d("Widget", "onEnabled");
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        String intentAction = intent.getAction();
        updateWidgetState(context, intentAction);
        if (intentAction.equals(ACTION_CLICK)) {
            Bundle extras = intent.getExtras();
            Integer appWidgetId = extras.getInt("appwidgetid");
            SharedPreferences myPrefs = context.getSharedPreferences(PREFS_NAME, context.MODE_WORLD_WRITEABLE);
            Integer objNum = myPrefs.getInt(PREF_PREFIX_KEY + appWidgetId, -1);
            if (objNum > -1) {
                PageAction pa = (PageAction) CommonActivity.GetPageObjectAtIndex(context, widgetPageName, objNum);
                pa.ExecuteActionFromWidgetClick(context);
            }
        } else {
            super.onReceive(context, intent);
        }
    }

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

    private static RemoteViews buildUpdate(Context ctx, String paramString)
     {
        RemoteViews views = new RemoteViews(ctx.getPackageName(), R.layout.phca_appwidget);
        views.setTextViewText(R.id.majorlabel, "majorLabel");
        views.setTextViewText(R.id.minorlabel, "minorLabel");
        Intent intent = new Intent(ctx, PhcaAppWidgetProvider.class);
        intent.setAction(ACTION_CLICK);
        intent.putExtra("appwidgetid", 0);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(ctx, 0, intent , 0);
        views.setOnClickPendingIntent(R.layout.phca_appwidget, pendingIntent);
        if(paramString.equals(ACTION_CLICK))
        {
              Toast.makeText(ctx, "ACTION_CLICK", Toast.LENGTH_LONG).show();

        }            
        return views; 
     }
 }

When I add the widget and remove it, different intents are passed into the onReceive, so that is working, but nothing when a click happens.

Question 2: Can someone please be so kind as to point out what I did wrong? I pretty followed the tutorials here: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/appwidget/ExampleAppWidgetProvider.html

Question 3: It would seem that I could put an android:onclick="WidgetClicked" in the layout xml for the widget, but I couldn't figure out where to put the WidgetClicked method. The WidgetProvider seemed logical, but that didn't work for me either. Is there a way to do this in the xml?

DISCLAIMER: the code above is the current state after a day and a half of troubleshooting. It just one iteration of many different tries.

like image 845
MrGibbage Avatar asked May 11 '12 13:05

MrGibbage


1 Answers

you need to rigister a reciver for widget click as in manifest :

  <receiver android:name="MyAppWidgetProvider" >
     <intent-filter>
         <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
         <action android:name="com.myname.myapp.MyAppWidgetProvider.ACTION_CLICK" />
     </intent-filter>
     <meta-data android:name="android.appwidget.provider"
     android:resource="@xml/my_widget_info" />
 </receiver>

AppWidgetProvider.java

public class MyAppWidgetProvider extends AppWidgetProvider {
    private static final String ACTION_CLICK = "ACTION_CLICK_WIDGET";
    private final String widgetPageName = "_widget";
    private static final String PREFS_NAME = "MYAPP";
    private static final String PREF_PREFIX_KEY = "prefix_";
    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
            int[] appWidgetIds) {

        ComponentName thisWidget = new ComponentName(context,
                MyAppWidgetProvider.class);
        final int N = appWidgetIds.length;
        for (int i=0; i<N; i++) {
            int appWidgetId = appWidgetIds[i];

            SharedPreferences myPrefs = 
                context.getSharedPreferences(PREFS_NAME, context.MODE_WORLD_WRITEABLE);
            Integer objNum = myPrefs.getInt(PREF_PREFIX_KEY + appWidgetId, -1);
            if (objNum > -1) {
                PageAction pa = (PageAction) CommonActivity
                    .GetPageObjectAtIndex(context, widgetPageName, objNum);
                String majorLabel = pa.GetUnparsedMajorLabel(context).toString();
                String minorLabel = pa.GetUnparsedMinorLabel(context).toString();
                updateAppWidget(context, appWidgetManager, 
                    appWidgetId, majorLabel, minorLabel);
            }
        }
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        String intentAction = intent.getAction();
        if (intentAction.equals(ACTION_CLICK)) {
        updateWidgetState(paramContext, str);
            Bundle extras = intent.getExtras();
            Integer appWidgetId = extras.getInt("appwidgetid");
            SharedPreferences myPrefs = 
            context.getSharedPreferences(PREFS_NAME, context.MODE_WORLD_WRITEABLE);
            Integer objNum = myPrefs.getInt(PREF_PREFIX_KEY + appWidgetId, -1);
            if (objNum > -1) {
                PageAction pa = (PageAction) CommonActivity
                .GetPageObjectAtIndex(context, widgetPageName, objNum);
                pa.ExecuteActionFromWidgetClick(context);
            }
        } else {
            super.onReceive(context, intent);
        }
    } 

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

    private static RemoteViews buildUpdate(Context ctx, String paramString)
          {
         RemoteViews views = 
         new RemoteViews(ctx.getPackageName(), R.layout.my_appwidget);
        views.setTextViewText(R.id.majorlabel, majorLabel);
        views.setTextViewText(R.id.minorlabel, minorLabel);
        Intent intent = new Intent(ctx, MyAppWidgetProvider.class);
        intent.setAction(ACTION_CLICK);
        intent.putExtra("appwidgetid", mAppWidgetId);
        PendingIntent configPendingIntentprev = PendingIntent.getBroadcast(ctx, 0, intent , 0);
        views.setOnClickPendingIntent(R.layout.my_appwidget, pendingIntent);
            if(parmString.equals(ACTION_CLICK))
            {
             //Toast.maketext("").show();
             //

            }            
             return rview; 
          }
 }

see my answer in this post for full example.

like image 54
ρяσѕρєя K Avatar answered Sep 20 '22 03:09

ρяσѕρєя K