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")
精彩评论