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. */
Related
I have a problem regarding Android task and intent management.
Scenario
User gets a push with a deep-link into the app.
We show a notification putting the URI into the Intent Data.
User clicks the notification and is taken into the app and redirected to some Feature1Activity described by the deep-link.
User looks around, and backs out of the app.
Later, user opens the app from history (long-press home or multitasking button).
Now the same intent that were used from the notification (with the deep-link in the Intent Data) is used to start the app.
Hence, user is taken into the Feature1Activity again.
Problem:
Starting the app from history (long-press home or multitasking button) does not reset the Task (which it does when launching from app icon).
I understand that starting an app from history is not supposed to reset the task since it is intended to be used as "get-right-back-where-you-were". However, in my case this is an issue since the launch of the app from a notification is a one time thing.
Anyone else encountered this problem? Anyone know any solution?
More in-depth
The intent inside the PendingIntent is built like this:
Intent intent = new Intent (Intent.ActionView);
intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags (Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags (Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
intent.setData (Uri.Parse (DEEP_LINK_URL));
I found out about the FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET just this day and really thought that it would git rid of my problem but it made no difference.
There are three activities of interest:
SplashActivity (main launcher & listener of the deep-linking schema -- this activity just redirects either to login or OverviewActivity)
OverviewActivity (authorized user's main activity)
Feature1Activity (any feature that the deep-link is pointing to)
What happens when the user clicks the notification is that the SplashActivity acts as a listener for the schema and converts the deep-link url to two intents to start up OverviewActivity and Feature1Activity using Activity.startActivities (Intent[]).
When I look at the intent from the notification inside SplashActivity it always contain the deep-link in the Data.
One work around
There is a work around, setting some booleanExtra field to the notification intent (for instance "ignoreWhenLaunchedFromHistory" = true) and then check in SplashActivity before redirecting
boolean fromHistory = (getIntent().getFlags() & FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) == FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY;
if (fromHistory && getIntent().getBooleanExtra ("ignoreWhenLaunchedFromHistory", false))
// Don't follow deep-link even if it exists
else
// Follow deep-link
Except that it hackish and ugly, can you see any problems with this work around?
EDIT: The work around only works when I am responsible for sending the Intent with the deep-link. Since no external source can know about the "ignoreWhenLaunchedFromHistory" extra.
From what I get, maybe using android:excludeFromRecents="true"on your manifest (as a property for the Activity declaration) might ameliorate the issue?
Iam new to android. I could understand the concept of Broadcast Receivers, but i couldn't understand the concept of sendBroadcast(Intent i).. My main doubt is who will listen to this sendBroadcast.
public class OOVOOActivity extends Activity {
/** Called when the activity is first created. */
public static int count = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
addShortcut();
}
private void addShortcut(){
Intent shortcut = new Intent("com.android.launcher.action.INSTALL_SHORTCUT");
// Shortcut name
shortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME, getString(R.string.app_name));
shortcut.putExtra("duplicate", false); // Just create once
// Setup current activity shoud be shortcut object
ComponentName comp = new ComponentName(this.getPackageName(), "."+this.getLocalClassName());
shortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, new Intent(Intent.ACTION_MAIN).setComponent(comp));
// Set shortcut icon
ShortcutIconResource iconRes = Intent.ShortcutIconResource.fromContext(this, R.drawable.search);
shortcut.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconRes);
sendBroadcast(shortcut);
}
I have few questions to ask,
In the above code there is no toast message is used, But if i
run the app i could see the toast msg.. Plz explain how it is coming
and also tell me how to hide those toast msg.
U could see sendBroadcast(shortcut); , basically who will listen to this broadcast.
Plz clear my doubt. Thank U
U could see sendBroadcast(shortcut); , basically who will listen to this broadcast.
Some other app or apps. No app might receive this broadcast. 999 apps might receive this broadcast. That is up to the user and the developers of those other apps.
In this case, you are assuming that there are one or more apps on the device that will respond to a com.android.launcher.action.INSTALL_SHORTCUT broadcast. Please note the com.android. This means that this Intent action is not part of the Android SDK. com.android is used for pieces of the Android environment. As it turns out, this Intent action is not documented, meaning that it may or may not work on all devices and Android OS versions.
Plz explain how it is coming
Other developers, besides you, can write code that displays Toast messages. They can even write code that displays Toast messages in response to a broadcast Intent. It turns out that your test environment contains such code, possibly in the com.android.launcher application.
also tell me how to hide those toast msg
You don't.
My boss asked me to prove that my application behaves properly when summoned by another application (dunno why he asked that).
So I have two apps here, one launches a second one. How I launch the specific app I want? Using Intent launch seemly any generic app that reaches a certain goal, not the app I really want.
Give this a try.
Intent secondIntent = new Intent();
secondIntent.setAction(Intent.ACTION_MAIN);
secondIntent.setClassName("com.example", "com.example.YourSecondApp");
startActivity(secondIntent);
I should point out that com.example should be the package of your second application (the one you want to call) and com.example.YourSecondapp is the class name where you have your onCreate() method.
Intent secondApp = new Intent("com.test.SecondApp");
startActivity(secondApp);
Check out for more examples
http://developer.android.com/resources/faq/commontasks.html#opennewscreen
Create one Intent using the following code
Explicit Intent
When you know the particular component(activity/service) to be loaded
Intent intent = new Intent();
intent.setClass("className/package name");
start<Activity/Service>(intent);
Imlicit Intent
When we do not have the idea which class to load and we know the Action to be perform by the launched application we can go with this intent.
Action needs to set, and the Android run time fallows the intent Resolution technique and list out(one or more components) the components to perform the action. from the list out components (if more than one), user will get the chance to launch his chosen application
I wish to have an app that targets Android 2.1, API level 7, launch multiple activities at once when a user clicks on a C2DM notification that has come in. This is the method I currently use to launch my activity:
public static PendingIntent getActivity (Context context, int requestCode, Intent intent, int flags)
This method only allows me to put one activity on the stack. What I really want to do is use this method:
public static PendingIntent getActivities (Context context, int requestCode, Intent[] intents, int flags)
This method reports that it is only available for API level 11, which is Android 3.0. I do not wish to break backward compatibility with 2.1. Can anyone suggest how I might be able to achieve this effect without taking a dependency on Android 3.0? I tried looking for the source to this new method, but it does not appear to be available yet.
What you do is have a separate activity that is the target of the alarm, and build the intent stack from there, as below. This could probably be generalised into something very like 'getactivities' quite easily - it's a pity it isn't in the compat libraries.
public class AlarmActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
intent = new Intent(this, ChildActivity.class);
startActivity(intent);
finish();
}
}
As MisterSquonk says in the comments, only one Activity can be active at any one time (even in 3.0), so launching "multiple activities at once" is not going to be possible. Even if it were, what will the user experience be like with multiple activities starting in quick succession, and no guarantee of which will be launched last, and so be the one left for the user to interact with.
I suspect that you actually want to wake up different parts of your app simultaneously without each one having its own UI. If so, then I would suggest having one or more Services which implement multiple BroadcastReceivers against a common Intent filter. When you fire a Broadcast of that event, then multiple things will get woken up at once.
I'm having the hardest time figuring out how to remove home screen AppWidget's programmatically (i.e. without the user actually dragging one into the trash). As an example, consider an app that can have multiple accounts, with any number of widgets for each account - once an account is removed, widget should be deleted as well.
I've tried following an obscure example from http://www.netmite.com/android/mydroid/cupcake/frameworks/base/services/java/com/android/server/AppWidgetService.java, but that doesn't seem to even trigger OnDeleted, much less remove the AppWidget from the home screen.
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_DELETED);
intent.setComponent(info.componentName); // references AppWidgetProvider's class
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
sendBroadcast(intent);
Does anyone have any advice on how this can be accomplished? An example would be the bee's knees. Thanks.
You cannot add or remove app widgets from the home screen. Only the user can do that.
Any app widgets tied to a deleted account could show a different account, or adopt some "(account deleted)" look that would trigger the user to get rid of the app widget or reconfigure it.
I'm pretty sure this should work:
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName("com.example",
"com.example.Widget"));
AppWidgetHost host = new AppWidgetHost(ctx, 0);
host.deleteAppWidgetId(appWidgetIds[0]);