Passing data from widget to app

2019-07-13 11:24发布

I'm developing a widget for my app and I'd like to pass specific data from the widget to the app. The user can add multiple versions of the widget and I need to detect which widget it is coming from so I can show specific information in the app.

What I have works so far, but only if I exit my app completely (repeatedly pressing the back button), otherwise it doesn't seem to be detecting the data being passed in.

This the code I have to pass the data from the widget to the app:

public class WidgetProvider extends AppWidgetProvider  {

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

        final int N = appWidgetIds.length;

        for (int i=0; i<N; i++) 
            UpdateWidget(context, appWidgetManager, appWidgetIds[i]);
    }

    public static void UpdateWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId)
    {
        Intent intent = new Intent(context, Main.class);
        final Bundle bun = new Bundle();
        bun.putInt("widgetId", appWidgetId);
        intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.putExtras(bun);

        PendingIntent pendingIntent = PendingIntent.getActivity(context, appWidgetId, intent, PendingIntent.FLAG_UPDATE_CURRENT);

        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
        views.setOnClickPendingIntent(R.id.widgetText, pendingIntent);

        appWidgetManager.updateAppWidget(appWidgetId, views);
    }
}

UPDATE

Getting close to getting this working, thanks to Tal Kanel. I have an ActionBar in my app and following Google's guidelines, I have this code in onOptionsItemSelected:

if (item.getItemId() == android.R.id.home) {
          final Intent intent = new Intent(activity, Main.class);
          intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
          startActivity(intent);
          return true;
    } 

If I click on the "back" button in the ActionBar, then minimize my app and click on the widget this code is always null:

    if (getIntent().getExtras() != null)
    {

    }

UPDATE 2

Actually, just going back to the main activity in my app causes getExtras() to be null. I have this code in my app widget, that does not pass any extras to the app:

    PendingIntent piMain = PendingIntent.getActivity(context, appWidgetId, new Intent(context, Main.class), PendingIntent.FLAG_UPDATE_CURRENT);

    rv.setOnClickPendingIntent(R.id.widgetTitle, piMain);

If I click on that part in my widget, then go back and click on the part of my widget that is supposed to pass the extras, getExtras() is always null.

1条回答
Melony?
2楼-- · 2019-07-13 11:50

first of all - your application not really close when you pressing back until returning to home screen. it's just that no activities from your application exists in this stage.
I think it's very important to know that, in case you didn't...

about your problem:
you are trying to launch activity from the widget with the FLAG_ACTIVITY_CLEAR_TOP, that it definition:

If set, and the activity being launched is already running in the current task, then instead of launching a new instance of that activity, all of the other activities on top of it will be closed and this Intent will be delivered to the (now on top) old activity as a new Intent.

that means that if your Main activity already running in forground, then when you start the activity from the widget - all other activities on top of this Main activity will be removed from stack, and Main will resume and get into to Activity.onNewIntent(intent) callback.

that's why you don't see the data - because the activity don't restart with the new intent, but only get into the onNewIntent(intent) with the new intent you sent.

I'm sure that if you'll put a break point in the onNewIntent(intent) method - you'll see that the intent you sent is delivered there, with all the extra's data.

another problem with your code: check the definition of the Intent.putExtras(boundle) method:

Add a set of extended data to the intent. The keys must include a package prefix, for example the app com.android.contacts would use names like "com.android.contacts.ShowAll".

it seems like you don't call your key prefix according to the rules. that's why it's null.

hope it helped you.

查看更多
登录 后发表回答