Find home screen widget id - android

I wrote a widget that sits on my home screen.
There is also a configuration activity which can be started from the widget or from the launcher.
When started from launcher, I don't have the widget id.
Is it possible to find it somehow?
The reason is that I want to send an update message from the activity to the widget.

Something like this seems to work for me:
Context context = getApplicationContext();
ComponentName name = new ComponentName(context, MyWidgetProvider.class);
int [] ids = AppWidgetManager.getInstance(context).getAppWidgetIds(name);

Related

How to open launcher's widget picker?

I want to open the launcher's widget picker (for example, the one we get when we long press on home screen) from my Activity. What I want to achieve is, I want to take the user to my widget so that there are more chances that he will consider adding it.
Programmatically adding the widget to home screen will be the best case. But, because that is not possible, I want to go as closer as possible to make user add the widget.
I tried the following but that only opens a dialog (not the launcher's) with all the widgets and by selecting one nothing happens.
Intent pickIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK);
pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 0);
startActivityForResult(pickIntent, 1234);
How to make this work? Any suggestions on this scenario are much appreciated.
It's possible to pin widget to homescreen (official doc) on API 26+:
AppWidgetManager mAppWidgetManager =
context.getSystemService(AppWidgetManager.class);
AppWidgetProviderInfo myWidgetProviderInfo = new AppWidgetProviderInfo();
ComponentName myProvider = myWidgetProviderInfo.provider;
if (mAppWidgetManager.isRequestPinAppWidgetSupported()) {
Intent pinnedWidgetCallbackIntent = new Intent( ... );
PendingIntent successCallback = PendingIntent.createBroadcast(context, 0,pinnedWidgetCallbackIntent);
mAppWidgetManager.requestPinAppWidget(myProvider, null,
successCallback.getIntentSender());
}

How to Launch an Android AppWidget's configuration Activity from another activity?

Well this is driving me crazy. I have developed an App-widget. Everything is working fine.
I have a configuration activity which launches every time a widget is added on the home screen and works beautiful. I save the user settings per widget id etc.
The widget has some buttons, one of them launches an activity with about information, the "About Activity".
The "About Activity" has a button which I want to use to launch the configuration activity for the widget id that launched the "About Activity". The reason I want to do that is because I want the user to be able to configure the contents of any instance of my widget without having it removed and added again (in order to launch the configuration activity).
The configuration activity needs the AppWidgetManager.EXTRA_APPWIDGET_ID in order to make the job (save the user settings for this specific widgetid) so I must somehow pass this extra when I 'm calling it from another activity. The obvious think to do is this:
startActivity(new Intent(context,act_configure.class).putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, ??? ));
Now my question is where is the widgetid? I found a million ways to get the widgetids (the array) but not a single clue on how to get the specific widgetid which launched the "About Activity"
Any help about this will make the hours I spent to find a solution, worth something. Thank you in advance.
p.s. Please forgive my English as they are not my native language...
Thanks to Cory Chaltron here is the solution to my problem.
In the widget provider onUpdate method I should create a "unique" intent to pass to the pending intent which handles the launch of the about activity. Because of the way Android compares Intents, passing the WidgetID in the extras IS NOT ENOUGH, you should also pass it as data to the intent in order to be unique. So here is the code:
Intent aboutIntent = new Intent(cx, act_about.class);
aboutIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetIds[i]);
// Make this unique for this appWidgetId
aboutIntent.setData(Uri.withAppendedPath(Uri.parse("customuri://widget/id/"), String.valueOf(widgetID)));
PendingIntent aboutPendingIntent = PendingIntent.getActivity(cx, 0, aboutIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK), PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.cmdabout, aboutPendingIntent)
Although I answer my own question I am not accepting it because it is based on Cory's answer. Thank you all for the help...
How are you setting your widget views? I have an app where I iterate over the active widgets and configure set the RemoteView there. You could set your widget id in the onClick you are attaching to the "About" button.
final AppWidgetManager widgetManager = AppWidgetManager.getInstance(this);
final ComponentName widgetName = new ComponentName(this, WidgetProvider.class);
final int[] widgetIds = widgetManager.getAppWidgetIds(widgetName);
for (int widgetId : widgetIds) {
final RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.widget);
// This is the important part :-D
remoteViews.findViewById(R.id.your_about_button).setOnClickListener(... a listener to start your about activity that puts the widget id in the extra like you suggest in your question ...);
widgetManager.updateAppWidget(widgetId, remoteViews);
}

Android - Communications between a widget and its app

I have a widget that shows various images with text below, and the same UI set up in the app itself. I want the widget to not only be able to open the app, but to open the app based on which picture is showing in the widget and then show that same image in the app. However, I am having a tough time getting this to work.
Thanks.
Let's say there are several images in the ui, you can set different Intent for each image, and these intents each will target a different activity.
This post: http://rxwen.blogspot.com/2012/10/communication-between-android-widget.html may give you some hints.
Add this code in widget.java file to launch your application. instead of MainActivity.class you can call any activity
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
RemoteViews views = new RemoteViews(context.getPackageName(),R.layout.mywidget_provider);
Intent openApp = new Intent(context,MainActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(context,0,openApp,0);
views.setOnClickPendingIntent(R.id.btnOpenApp,pIntent);
appWidgetManager.updateAppWidget(appWidgetId,views);
}

Can an Activity be started from within a WidgetAppProvider?

I have a widget that I have an intent that starts an activity when I click, but I need to get saved Data into the widget, so onEnabled can I start an Activity that will look up the saved data for the activity?
Also an intent I need to set up for the click events... how do I set these up with out first having the config show up?
I still do not know if an activity can be explicitly started without doing something like an onclickevent... but saving data within the widget can be accomplished by using the
Context.getSharedPreferences( String name, int mode );
to get saved prefernces, and by using
nt[] allids = AppWidgetManager .getInstance(context) .
getAppWidgetIds(new ComponentName(context, AwarenessWidget.class));
to get all the IDS

How to programmatically disable onClick handler on Android AppWidget Button

I have a Button on appwidget, that I need to 'enable'/'disable' programmatically from a Service.
First idea was to call setBoolean(R.id.buttonid, "setClickable", false) to disable it, but apparently you can't call setClickable remotely.
Another idea was was remove the text label from it with rv.setTextViewText(R.id.buttonid, "") and then remove the click handler by rv.setOnClickPendingIntent(R.id.buttonid, null). Unfortunately passing null to it causes NullPointerException in in android.app.ActivityThread.handleServiceArgs
Is there some other way to programmatically disable/enable appwidget Button? I could just call rv.setViewVisibility(R.id.buttonid, View.GONE) to hide the button completely instead of disabling it. This would however completely break whole widget layout and I would like to avoid it.
The solution I'm using now is hiding the button with setViewVisibility and showing other blank button instead to the keep appwidget layout as it was before.
Basically I had the same problem, but wanted to do it entirely programmatic, so we just pass the boolean value to the setBoolean() function:
remoteViews.setBoolean(R.id.imageButton1, "setEnabled", false);
Don't forget to tell Android to update the home screen:
RemoteViews remoteViews = new RemoteViews(context.getResources().getText(R.string.package_name).toString(), R.layout.your_layout);
ComponentName thisWidget = new ComponentName(context, Widget.class);
AppWidgetManager manager = AppWidgetManager.getInstance(context);
manager.updateAppWidget(thisWidget, remoteViews);
When you create your RemoteViews instance, you supply a layout. When you want to disable the button, choose a layout with android:enabled="false" on that button.
Or, you could use setOnClickPendingIntent() and supply an Intent that just will not go anywhere (e.g., a broadcast Intent for an action that nobody uses).

Categories

Resources