开发者

Pass data from app widget to activity depending on textview clicked

I'm getting my feet wet regarding android programming so sorry if this is very simple.

My app widget consists of several dynamically added textviews, each of which launch the same activity with a varying index based on which one was clicked. Getting the correct index is what i'm having trouble with currently.

Below is the code i use to create the widget:

public static String ListItemIndex = "com.georgeduckett.helloworld.ScrollWidgetProvider.ListItemIndex";

@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];


        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.scroll_widget_layout);

        // Create several views that will contain the content
        for (int newviewindex = 1; newviewindex<5; newviewindex++) {
            // Create an Intent to launch WidgetActivity for when we're clicked on
            Intent intent = new Intent(context, WidgetActivity.class);
            Bundle bundle = new Bundle();

            bundle.putInt(com.georgeduckett.helloworld.ScrollWidgetProvider.ListItemIndex, newviewindex);
            intent.putExtras(bundle);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);

            RemoteViews SubItemView = new RemoteViews(context.getPackageName(), R.layout.scroll_widget_item_layout);
            SubItemView.setTextViewText(R.id.textbox1, "testing " + newviewindex);
            SubItemView.setOnClickPendingIntent(R.id.textbox1, pendingIntent);
            views.addView(R.id.items_container, SubItemVie开发者_Go百科w);
        }

        // Tell the AppWidgetManager to perform an update on the current App Widget
        appWidgetManager.updateAppWidget(appWidgetId, views);
    }
}

And here is the activity code:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Bundle bundle = getIntent().getExtras();

    if(bundle != null) {
        int Index = bundle.getInt(com.georgeduckett.helloworld.ScrollWidgetProvider.ListItemIndex);
        Toast.makeText(this, Integer.toString(Index), Toast.LENGTH_LONG).show();
    }
    else
    {
        Toast.makeText(this, "Boo!", Toast.LENGTH_LONG).show();
    }

    setContentView(R.layout.main);
}

Currently what happens is no matter which one i click on i always get '1' popup, which either implies i'm always clicking on the first one, or it implies the wrong data is getting passed through.

I've looked all over the place for this one, but can't find any information other than a generic 'how to pass data' type tutorials/problems.


I think you are falling for a 'trap' in PendingIntent - it is not cleared out by default. You need to give it a flag to do so.


The comment by @george-duckett deserves a separate answer entry, since it was, what really solved my problem.

I've figured out a solution to my problem. It seems if i have several pending intents for the same action, it'll just get the most recent one, effectively ignoring previous ones. The solution is to pass in a unique identifier as the 'requestCode' parameter of the PendingIntent.getActivity method.

I had similar code with a similar problem. It also put extras into intent and later created a pendingIntent:

PendingIntent pendingIntent = PendingIntent.getBroadcast(
    context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

The usage of PendingIntent.FLAG_UPDATE_CURRENT instead of 0 was good and ensured, the broadcast recieves a fresh intent with correct data we can get from "extra" like getIntExtra.

Using 0 for requestCode caused problems though. Only after I changed it to some value, unique accross my TextView elements, I was able to get different data for different touched text views. My elements show notification, so the notificationId was a natural fit:

int notificationId = reminder.notificationId /* specific to my application, 
                                             find something for yours! */;
PendingIntent pendingIntent = PendingIntent.getBroadcast(
    context, notificationId, intent, PendingIntent.FLAG_UPDATE_CURRENT);


Try this. Add data to intent

intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));


Here is a method in Kotlin to get pending intent to open your activity

fun getPendingIntentMyActivity(context: Context, message: String = "Hello World"): PendingIntent {
    val intent = Intent(context, MyActivity::class.java)
    intent.action = APPWIDGET_OPEN_APP_INTENT
    intent.data = Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))
    val extras = Bundle().apply {
        putString(APPWIDGET_OPEN_APP_INTENT, APPWIDGET_OPEN_APP_DATA)
        putString(APPWIDGET_OPEN_APP_DATA_MESSAGE, message)
    }
    intent.putExtras(extras)
    return PendingIntent.getActivity(context, 0, intent, FLAG_UPDATE_CURRENT or FLAG_IMMUTABLE)
}

Then set it in the Widget

remoteViews.setOnClickPendingIntent(R.id.rootView, getPendingIntentMyActivity(context, "Hello")
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜