13

Code like this works well.

    Intent configIntent = new Intent (context, WidgetConfigActivity.class);
    configIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
    PendingIntent pIntent = PendingIntent.getActivity(context, 0, configIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    remoteView.setOnClickPendingIntent(R.id.btn, pIntent);

But I want to hide that button befor activity will appear, so I'm triing to send intent to the widget itself, perform hiding components in onReceive() method and then start activity. Problem is that I can't use startActivity() function in AppWidget.

Is there any solution ?

ThinkingStiff
  • 64,767
  • 30
  • 146
  • 239
oleg.semen
  • 2,901
  • 2
  • 28
  • 56

4 Answers4

19

Problem is that I can't use startActivity() function in AppWidget.

Yes, you can. You are passed in a Context object into onUpdate() (or onReceive()) of your AppWidgetProvider -- call startActivity() on that.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • 2
    nothing like a good ol' commonsware answer on a friday afternoon... telling it like it is – Alex Lockwood Jun 29 '12 at 23:10
  • oh my god, I know this is stackoverflow but I gotta say this: I spent an entire weekend working around making a class to get me a context from an activity to the widget, only becaues I did not notice the Context passed in the onUpdate, oh dear lord – Motassem Kassab Jul 26 '17 at 23:02
16

Thanks 2 CommonsWare

There is one more thing to do. context.startActivity(); throws RuntimeException in this case.

Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?

So you need to set flag

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

before.

oleg.semen
  • 2,901
  • 2
  • 28
  • 56
6
   // on receive function use this for new activity start
               Intent intent = new Intent (context, AppWdget.class);
               intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK);
               context.startActivity (intent);
spinhaxo
  • 58
  • 6
sandhu
  • 305
  • 4
  • 4
0

You can send a broadcast intent rather starting an activity! I wanted to perform an action when a widget button was pushed -- not specially to start an activity that would show up on screen. You can use this technique to execute your code in the widget itself (where the widget does not necessarily contain an Activity.)

Intent intt = new Intent(ctx, RWidg.class);
intt.setAction("myActionName");
PendingIntent bcInt = PendingIntent.getBroadcast(ctx, 0, intt, 0);

RemoteViews views = new RemoteViews(ctx.getPackageName(), R.layout.widg_lay);
views.setOnClickPendingIntent(R.id.button, bcInt);

appWidgetManager.updateAppWidget(widgId, views);

Rather than using a PendingIntent to start an activity, using the PendingIntent.getBroadcast() creates a PendingIntent with 'secret key': ActivityManager.INTENT_SENDER_BROADCAST which causes the ActivityManager to do a sendBroadcast() rather than a startActivity()

You need to add an 'if' statement to your onRecieve() method to intercept the action name or names that you use:

public void onReceive(Context ctx, Intent intt) {
  String action = intt.getAction();
  if (action.compareTo("myActionName")) {
    // Do your myActionName work here
  } else {
    super.onReceive(ctx, intt);
  }
} // end of onReceive
Ribo
  • 3,363
  • 1
  • 29
  • 35