Android - Communications between a widget and its app - android

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);
}

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());
}

Sending Intent to Home and Widget Add

I'm trying to figure out how to send an intent to the home screen to add a Widget to it if I can. Any ideas? Here is some code I've been fooling around with to at least prompt the Add Widget selection.
AppWidgetManager mAppWidgetManager;
AppWidgetHost mAppWidgetHost;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
selectWidget();
mAppWidgetManager = AppWidgetManager.getInstance(this);
mAppWidgetHost = new AppWidgetHost(this, R.id.APPWIDGET_HOST_ID);
}
void selectWidget() {
int appWidgetId = this.mAppWidgetHost.allocateAppWidgetId();
Intent pickIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK);
pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
startActivityForResult(pickIntent, R.id.REQUEST_PICK_APPWIDGET);
}
Thank you to anybody who contributes.
You can send the ACTION_APPWIDGET_PICK intent to the system, but your app cannot process it, unless what you're coding is a Home screen replacement, i.e. a launcher.
Take a look at the documentation for App Widget Host, in particular the section about Host Binding. The code you're using in the selectWidget() method is the same used in the original Launcher app (under title Binding app widgets on Android 4.0 and lower). Then comes an implementation for onActivityResult, where the intent is processed. This method is what is missing in your code, but if you include it, you will end up doing all the work the Home screen app does (see addAppWidget(Intent data) next in that page).
If you continue reading the App Widget Host doc, you will see that the binding process changed on Android 4.1 and there is also a new intent for this task that requires a permission in the manifest. And to complicate things more, keep in mind #CommonsWare's comment: there are a lot of Home screen implementations, that probably do the binding process differently :(
To summarize: there's no way to get the list of app widgets and process what the user selected, neither is a way to ask the launcher app to do this for us, unfortunately. Perhaps in a future Android version, as this comment in the latest Launcher source code reveals:
/**
We will likely flesh this out later, to handle allow external apps to place widgets, but for now,
we just want to expose the action around for checking elsewhere. */

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);
}

Widget to create Shortcut of Installed Apps

How to create shortcut for pre-installed apps from my widget?
Do you want some static shortcuts? Just pre-installed apps?
This is how I created what look like shortcuts on the home screen:
RemoteViewsWidget views = new RemoteViewsWidget(context, R.layout.your_layout);
Where RemoteViewsWidget is your subclass of RemoteViews. You'll want the context to use for actions done in the RemoteViewsWidget class.
In a method in the RemoteViewsWidget class, I set the image and text for the "shortcut":
setImageViewUri(imageResId, uri);
setTextViewText(textResId, displayName);
Where imageResId is the resource in your layout you want to be your thumnail and the uri points to the image (I used a locally saved file for the image source). Similar for the textResId and displayName.
setOnClickPendingIntent(layoutViewId, PendingIntent.getActivity(
context, requestCode, intent, flags));
Here, layoutViewId is the parent layout that your image view and text view live in. This layout is what triggers the intent when it is selected. The pending intent is what is executed when the layout is selected - just fill in your context, intent of the activity you want launched and flags, if necessary.
To find what you need from the apps to launch them, you probably want to use PackageManager:
List<ResolveInfo> appInfos = context.getPackageManager().queryIntentActivities(
new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER), 0);
to get a list of the resolve info for all apps in your launcher. You can get all you need from that list to make the intent for the setOnClickPendingIntent above. If you only want a subset of these apps, you can apply a different or more categories, different actions, etc. Or you can just use known packages or activities.
After you've created your remote views, you need to update the widget, either in a utility method or in your widget provider subclass:
views.updateWidget(); // update resources with image, text and intent as above
AppWidgetManager.getInstance(context.getApplicationContext()).updateAppWidget(
widgetId, views);

Find home screen widget id

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);

Categories

Resources