Shortcut Can't Start Activity - android

I created some shortcut of my activities by code, most of them can't
open its related activity. I found that it only work if I added
filter CREATE_SHORTCUT to activity. Why?
<activity
android:name=".ui.Main"
android:launchMode="singleTop"
android:screenOrientation="portrait"
android:theme="#android:style/Theme.NoTitleBar" >
<intent-filter>
<action android:name="android.intent.action.CREATE_SHORTCUT" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
(test in Go Launcher & MIUI 2.3.7)
I got logs below, should I add MAIN filter?
09-27 13:34:44.075: E/Launcher(7893): Launcher does not have the
permission to launch Intent { act=android.intent.action.VIEW
flg=0x10000000 cmp=/.ui.Activity2 bnds=[349,76][469,211] }. Make
sure to create a MAIN intent-filter for the corresponding activity
or use the exported attribute for this activity.

As the error message suggests, you could add
android:exported="true"
to your activity.
Although this should be the default value if I read the android documentation right:
android:exported
Whether or not the activity can be launched by
components of other applications — "true" if it can be, and "false" if
not. If "false", the activity can be launched only by components of
the same application or applications with the same user ID. The
default value depends on whether the activity contains intent filters.
The absence of any filters means that the activity can be invoked only
by specifying its exact class name. This implies that the activity is
intended only for application-internal use (since others would not
know the class name). So in this case, the default value is "false".
On the other hand, the presence of at least one filter implies that
the activity is intended for external use, so the default value is
"true".
Maybe someone else can clarify this.

Related

Avoid Activity resuming when app goes in background

In my application I have three activities:
<activity
android:name="com.example.myapp.SplashScreenActivity"
android:exported="true"
android:launchMode="singleInstance"
android:noHistory="true"
android:screenOrientation="sensorLandscape" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.example.myapp.MainActivity"
android:exported="false"
android:launchMode="singleInstance"
android:screenOrientation="sensorLandscape" >
</activity>
<activity
android:name="com.example.myapp.ListActivity"
android:exported="false"
android:launchMode="singleTop"
android:screenOrientation="sensorLandscape" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.myapp.MainActivity" />
</activity>
The first one is the LAUNCHER, SplashScreenActivity, which is a splash screen that disappears quite soon and it's not shown in recent activities, it starts MainActivity. In MainActivity users can select a category and ListActivity shows the items belonging to the given category. This is done with the following code:
Intent i = new Intent(getActivity(),ListActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
i.putExtra("category",mCategory);
startActivity(i);
In ListActivity the onResume method checks for the "category" extra and shows data accordingly. Since Activity launchMode is singleTop, I've also overridden the onNewIntent method to set the new Intent of the Activity.
This works properly if the app doesn't go in background: in this case, when I restart MainActivity and select a category, ListActivity resumes the old Activity showing data belonging to the previously chosen category.
How should I fix flags/launchMode in such way that my app doesn't resume ListActivity with the old data loaded?
You should not use the special launch modes. These are rarely required and only in very specific circumstances. Remove all the launchMode specifiers from your manifest. You also don't need to use these flags when launching ListActivity from MainActivity:
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
Your use of singleInstance launch mode is causing you all these problems.
Assuming you would ditch all the launchModes and Flags, then activity lifecycle gives you all the information needed to implement application as you have described - maybe there is somethings you have not added?
Once application goes to background, then ListActivity will be allowed to save its state, even if system will kill your process (lack of memory etc.), then still - launching back your app will first bring back ListActivity with previously saved instance state. So you will not have behaviour as you describe : when I restart MainActivity and select a category, ListActivity resumes the old Activity showing data belonging to the previously chosen category.
Still, if you need to keep to your current design, then you should somehow inform ListActivity of new data changes, question is if ListActivity.onNewIntent is being called at all in the case your describe? Have you tried adding Intent.FLAG_ACTIVITY_SINGLE_TOP : as per this blog entry: http://www.acnenomor.com/1094151p2/bug-onnewintent-not-called-for-singletop-activity-with-intentflagactivitynewtask ?

Implicit intent within same application

How do I build an intent and the Manifest so that I can invoke an activity with my application as an implicit intent.
The idea is that I am writing some general code that I wish to use in a number of applications.
This code is held in an Android library and is linked to the using application.
This general code opens an activity and does some work.
Once it is done (user clicks a button) it needs to transfer to an activity that is specific to this application.
As per my understanding on your questions,
You can declare your activity with specified implicit intent in your application's manifest file..
For example: If you want to make a application for view Image with your application and you have to use that application on your device which can allow other activity to view image using implicit intent action.VIEW so ,just
<activity android:label="#string/app_name" android:name=".MyImageViewerActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN">
<category android:name="android.intent.category.LAUNCHER">
</category></action></intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW">
<category android:name="android.intent.category.DEFAULT">
<data android:mimetype="image/*">
</data></category></action></intent-filter>
</activity>
In the above code we can see that intent-filter has following properties.
a. action: type for which this activity will respond for.Like this activity will respond for view action.
b. category: implicit intents are divided in categories.Like this activity is in default category.
c. data: Specify more information about intent-filter. Like this activity will handle file of mimeType “image/*”.
And when you install this application in your device and click on any image file, you will see a choice dialog that offer you to select between default application and your application. Just select your application to see the image.
For more info with example look at this What is intent filter in android?
Tutorial: Registering via Intentfilter
I think you can use intent-filters. I didn't use it for such things, but I hope that will help you.
Idea is that you can call your activity not by name, but by it's action (that is setted in intent-filter in your Manifest)

Start Activity with action, but no category

I am trying to start an activity defined in another apk, in its AndroidManifest.xml, it defines an activity and with an action, but no category defined.
The format is like
<activity name="...">
<intent-filter>
<action android:name="action name">
<intent-filter>
</activity>
My code is following
Intent i = new Intent("action name");
startActivity(i);
However my apk crashed with uncaught ActivityNotFound exception, the logs read
No Activity found to handle intent ... "
Any thoughts?
Thanx a lot.
Looking at the Intent documentation, it says Note also the DEFAULT category supplied here: this is required for the Context.startActivity method to resolve your activity when its component name is not explicitly specified. If the activity's IntentFilter definition does not include that category then you can't start it with startActivity. Try using the setClassName method, and pass it the package class and the activity class you're trying to launch.
you cannot have empty category when you use startActivity(...).
add a default category and this will do the job:
<intent-filter>
<action android:name="action name" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
You need to define the activity you are starting in your Manifest. Make sure you have provided same <intent-action (and name of the activity) that has the activity in the other apk you want to start.
android: how do i open another app from my app?

Android: Why is the name of the android app taken as the name of the starting activity?

In my manifest file, I have given the application name as MyApp and the name of the starting activity as Main Menu.
<application android:theme="#style/theme" android:icon="#drawable/myicon" android:label="#string/app_name">
<activity android:name=".MainMenu"
android:label="#string/mainmenu_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
When I see the app icon in the default menu screen of android, the name shown is Main Menu. Why is MyApp not the name shown for the app?
Because your app can define more than one activity that shows up in the launcher. All activities that have this type of intent filter:
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
Will appear in the launcher, each with its own label. The fact that if you don't define a label on your activity, it's inherited from the application is basically a commodity.
Also, every activity has its own android:icon (which, again, is inherited from <application> for commodity). With this property your two launcher entries can have not only different labels, but different icons as well.
On a more general note, even "non-main" activities can handle certain types of events, and in these cases their labels and icons are relevant. For example, if one of your activities (doesn't matter which one) handles ACTION_SEND intents (like most sharing apps do -- see Facebook, Twitter, ...), then whenever the user presses a "Share" button in any application, a list of applications that can complete that certain activity is displayed to the user (in this case these applications could be Facebook, Twitter and your app). This list will contain an icon and a label (i.e. Facebook). Your entry's display will be dictated by the android:icon and android:label attributes defined by your receiving <activity>, and only if it doesn't define them they'll be taken from your <application>.
This allows you to have an entry such as "Share via MyApp" without modifying your application's name. Or, if your application also has an activity that handles ACTION_VIEW, that activity could have, for example, the label "View in MyApp".
Digging even deeper, <intent-filter> elements can have their own label and icon. Basically, Android chooses the icon and label to display like this:
If the <intent-filter> has it, pick that, stop.
If the <activity> has it, pick that, stop.
Pick the one in <application>.
This is helpful in two situations:
You don't want to change your activity's label / icon: maybe you want to use those in other places such as the title bar (and you don't want your title bar to say "Share via MyApp")
You have activities with multiple intent filters. For example, you could handle both ACTION_SEND and ACTION_VIEW intents in the same activity. In this case, you'd have two intent filters set for that activity with the labels "Share via MyApp" and "View in MyApp".
I hope I've made myself clear, these are very basic things that can be pretty hard to grasp at first, but that provide great flexibility in building apps and integrating them with the Android system and/or other apps.
Another thing to note is that you can easily have an application that doesn't have any entries in the launcher (by not having any activity with the intent filter mentioned above). These are perfectly valid apps and it's good practice when creating Service-only apps (such as widgets).
If android:label is set for activity then its value is taken. It it is omitted for activity then the android:label attribute set on application is taken instead.
You simply cannot have different labels for activity and for application as your application has one launcher for your activity with the label you set it to have. I'm not quite sure I totally understand what you are trying to achieve tho.
In the manifest, remove the android:label attribute on the launch activity. Then the activity will inherit the name specified in the application's android:label.

intent-filter with android:priority setting

I test the intent-filter android:priority="0" and intent-filter android:priority="20" by android.intent.category.HOME. I list the information below,
<activity android:name=".TestHomeActivity"
android:label="#string/app_name">
<intent-filter android:priority="0">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
When finishing system booting, it always pops up a dialog (ResolveActiivty) for choose preferred activity for this intent...
Can anyone can help this? is it error usage for android:priority?
Thanks!
I haven't actually seen android:priority being taken into account when the system is resolving intents. I just tried setting a priority on an intent-filter that I use, but the system still gave me the resolution popup dialog, no matter what value I set my intent-filter's priority to.
I guess you'll just have to select the home screen activity you want to use (i.e. yours) and select the "Use by default..." checkbox.
android:priority is only used on OrderedBroadcast intents, not the order of resolution for non-ordered broadcasts. Users select the default activity for a given action, which is why the dialog pops up. So, yes, you are using priority incorrectly.
From your snippet, it seems that You are trying to launch your application. Priority is the one that should be given to the parent component w.r.t handling intents of the type described by the filter.
It provides information about the ability of an activity to respond to an intent that matches the filter, relative to other activities.It also controls the order in which broadcast receivers are executed to receive broadcast messages.
Use this attribute only if you really need to impose a specific order in which the broadcasts are received, or want to force Android to prefer one activity over others.
The value must be an integer, such as
"100". Higher numbers have a higher
priority.
// non-privileged applications can never define a priority > 0 (PKMS)

Categories

Resources