Android: Adding data to Intent fails to load Activity - android

I have a widget that supposed to call an Activity of the main app when the user clicks on widget body. My setup works for a single widget instance but for a second instance of the same widget the PendingIntent gets reused and as result the vital information that I'm sending as extra gets overwritten for the 1st instance. So I figured that I should pass widget ID as Intent data however as soon as I add Intent#setData I would see in the log that 2 separate Intents are appropriately fired but the Activity fails to pick it up so basically Activity will not come up and nothing happens (no error or warning ether)
Here's how the activity is setup in the Manifest:
<activity android:name=".SearchResultsView"
android:label="#string/search_results"
<intent-filter>
<action android:name="bostone.android.search.RESULTS" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
And here's code that is setup for handling the click
Intent di = new Intent("bostone.android.search.RESULTS");
di.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// if line below is commented out - the Activity will start
di.setData(ContentUris.withAppendedId(Uri.EMPTY, widgetId));
di.putExtra("URL", url);
views.setOnClickPendingIntent(R.id.widgetContent,
PendingIntent.getActivity(this, 0, di, 0));
The main app and the widget are packaged as 2 separate APK each in its own package and Manifest

I think you need a <data> tag in your <intent-filter> in order for the intent you are firing to match the intent-filter you have registered.
https://developer.android.com/guide/topics/manifest/data-element.html
Also using Uri.EMPTY may be a problem. I'd create your own Uri scheme, so that your setData() call looks something like:
di.setData(Uri.withAppendedPath(Uri.parse("droidln://widget/id/"), String.valueOf(appWidgetId)));
and your intent-filter would look like:
<intent-filter>
<action android:name="bostone.android.search.RESULTS" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="droidln"/>
</intent-filter>

Related

<activity> without <intent-filter> in AndroidManifest.xml

I know I need to use to enable an activity to receive an Intent like this (not main activity).
<activity android:name=".MyApp_2ndActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
However, I found it can be triggered too if "intent-filter" is removed, like this.
<activity android:name=".MyApp_2ndActivity">
</activity>
I am wondering what difference is in these 2 formats?
See here: http://developer.android.com/guide/components/intents-filters.html
The difference is the second one can only be started using an explicit Intent -- one which names the component it wants to start. The first one can be started by an implicit Intent -- one which does not specify the exact component but contains information for the system to find an appropriate match for. The intent filters are used by the system for resolving such intents.
Difference is the when we use this code:
<activity android:name=".MyApp_2ndActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
This will be the first activity triggered when you starts your application.It doesnot need any explicit intents
and when we use this code:
<activity android:name=".MyApp_2ndActivity">
</activity>
the activity will be started with the use of Explicit intent
Intent filters are used, for example, when the activity starts from a specific event on the device. Your main activity has specific intent filters. If you want your application start when NFC tag is scanned, you can specify that via intent filters.
You can read more here for example.
http://developer.android.com/guide/components/intents-filters.html

Start Activity with NFC in a specific task

My app contains a number of activities. One of these activities responds to an NFC intent filter, as well as standard intents, however, this activity is launching in it's own task, and not in the same task as the app. The app is not necessarily running when the NFC intent is initiated but if it is, I want the activity to launch in the same task to ensure a seamless user experience. At the moment, the app is behaving as though there are 2 of them running.
Here is the manifest for my NFC activity:
<activity
android:name="name.subname.app.activity.ItemSummaryActivity"
android:label="#string/title_activity_item_summary" >
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<data android:mimeType="application/vnd.name.nfcdemo" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
Is it possible to launch the activity in the existing task, if it exists?
I see two options here:
1) Add android:launchMode="singleTask" to activity tag in the manifest:
<activity
android:name="name.subname.app.activity.ItemSummaryActivity"
android:label="#string/title_activity_item_summary"
android:launchMode="singleTask" >
"singleTask":
The system creates the activity at the root of a new task and routes the intent to it. However, if an instance of the activity already exists, the system routes the intent to existing instance through a call to its onNewIntent() method, rather than creating a new one.
2) Supply Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT flag to startActivity() intent. But, if the activity is triggered by NFC (and using this option is not feasible) consider what #NFC guy has to say here.

Child Activity gets killed after parent activity is finished

I have 2 apps, one of them is calling an activity from the second one through an intent filter like so:
Call in App1 (Parent app)
Intent openApp = new Intent("com.app.intent.Activity2");
startActivity(openApp );
Intent filter in App2 (child app)
<activity
android:name=".app.activity.Activity2"
android:label="#string/app_name"
android:launchMode="singleInstance"
>
<intent-filter>
<action android:name="com.app.intent.Activity2" />
<category android:name="android.intent.category.BROWSABLE"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
At one point the Parent application has to close but the problem is the Activity2 from the second application gets killed as well. I can see that Activity2 is actually running under the same package, is there any way to have the Activity2 persist and run even after the parent applicaiton is closed ?
Thank you
This discussion seems to have what you need. Seems like you need to get the launch intent from the package you want to launch and use that in your intent.
Launch an application from another application on Android
Android will generally run all components from the same APK in a single process, so if one of those crashes the process then they will all be gone.
You can however tell it to put an activity or service in its own process.
<activity
android:name=".app.activity.Activity2"
android:label="#string/app_name"
android:launchMode="singleInstance"
android:process=":my_unique_process">
Of course if your process is dieing unexpectedly, that's a problem that needs to be understood and fixed - this would just be a temporary workaround.

How can I start the next matching activity if my app is the default one

I have an activity that works as a hook for various intents. Specifically, the VOICE_COMMAND and CALL_PRIVILEGED. (It is a requirement to use these.)
<activity android:name=".MyActivity"
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.VOICE_COMMAND" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.CALL_PRIVILEGED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="tel" />
</intent-filter>
</activity>
I ask the user to set my app as the default action for these intents so they don't have to select it every time. This is also a requirement.
The problem is that in certain cases I want my activity to work transparently and pass the intent to the dialer or other app. This should be selectable by the user. I achieved this by using getPackageManager().setComponentEnabledSetting(myCompName, isEnabled, PackageManager.DONT_KILL_APP) on my activity in certain places of the code.
Is there a more elegant way to do this? I tried startNextMatchingActivity(getIntent()) but that does not start anything (returns false). Does this mean that if there is a default action, then everything else is ignored from the intent resolution?
Currently (on Android 2.3) there seems to be no other way of forwarding the intent than doing it manually. Additionally, to send CALL_PRIVILEGED intent the app must have special permissions that only system apps have. (The app will receive not allowed exceptions otherwise.)
All in all, the intent must be converted to some other intent that my app can send and start the next activity manually by retrieving the list of applicable activities from the PackageManager.queryIntentActivities() API.

What is the Intent action gets raised when the user starts/opens an Application in Android

What is the Intent action gets raised when the user starts/opens an Application? Basically I want to execute some code on receiving the above Intent.
Thanks,
poddroid
The Intent that triggers the first Activity of an application to run is Intent.ACTION_MAIN, with category Intent.CATEGORY_LAUNCHER.
This is why in the manifest file of any application, the Activity that will be the first screen features the intent filter:
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
I don't know what code you would need to execute before your Activity's onCreate(Bundle) method, but you can also extend the Application class and override its onCreate() method to execute code before any Activity is created.

Categories

Resources