In my android application, I have registered for intent filter android.intent.action.SEND in one of my activities to receive data from other applications.
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
<data android:mimeType="application/pdf" />
<data android:mimeType="text/x-vcard" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
<data android:mimeType="application/pdf" />
</intent-filter>
When data is shared from other apps with my app using share intent, this activity receives the intent. I would like to know the package name of app which shared the data with my app.
I tried following code but it always returns null.
final String packageName = this.getCallingPackage()
Is there any way I can get the package name of app that shared data with my app using intent that i am receiving?
If the share intent was created using ShareCompat.IntentBuilder it will contain the extra EXTRA_CALLING_PACKAGE.
But most apps don't provide this information. And if the extra is present you should not use it for any security-critical functionality because senders are free to provide any value they like.
To use getCallingPackage(), the caller should use startActivityForResult(Intent, int) instead of startActivity(). Otherwise, it will return null. Straight from the doc:
Note: if the calling activity is not expecting a result (that is it
did not use the startActivityForResult(Intent, int) form that includes
a request code), then the calling package will be null.
https://developer.android.com/reference/android/app/Activity.html#getCallingPackage%28%29
Related
I'm creating a messaging app with Air for Android. I would like to enable other apps to share text to my app via the share menu option.
How do I get my app listed in there?
(This is the menu I would like to get listed in:)
Add an appropriate intent filter in your Activity tag in manifest file.
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
Your Activity will show up, when Android searches for such Share Intent handlers.
To an Activity that will handle any shared content, add an Intent Filter to your Manifest. For example:
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
<data android:mimeType="image/*" />
</intent-filter>
The web and stackoverflow contain several examples how to get a file from another Android app (e.g., to use it as email attachment) using an ACTION_GET_CONTENT intent. But what kind of class do I have to implement to create an application providing content for the ACTION_GET_CONTENT event such as I can choose this app (e.g., for selecting an email attachment).
Is a ContentProvider the right solution? And what do I have to add to my AndroidManifest.xml?
After some hours of web search I found the following solution.
Implement an Activity handling intents. Within, use the following or more specific code:
Uri resultUri = // the thing to return
Intent result = new Intent();
result.setData(resultUri);
setResult(Activity.RESULT_OK, result);
finish();
Add the following to the Manifest:
<activity
android:name="ActivityName"
android:label="Some label" >
<intent-filter>
<action android:name="android.intent.action.GET_CONTENT" />
<category android:name="android.intent.category.OPENABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.PICK" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>
</activity>
starting from api level 18 incoming intent can also have EXTRA_ALLOW_MULTIPLE set to true and in this case you can send back in result more than one file. To do so you need to set it as ClipData:
resultIntent.setClipData(clipData)
Using Android, when I click on an e-mail address in my default browser, a menu list pops up with Gmail, (an built-in email client), and K-9 (another e-mail application).
I would like to add my android application to appear in this list. Is this possible and how do I do this?
add this intent-filter to your activity in manifiest:
<intent-filter>
<action android:name="android.intent.action.SENDTO" />
<data android:scheme="mailto" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND" />
<data android:mimeType="*/*" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE" />
<data android:mimeType="*/*" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="mailto" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
You need to create an IntentFilter this requires both Java code, where you create an Activity that is triggered when the system notifies someone is trying to send an email, and changes to your AndroidManifest where you subscribe to the Intent action. Here is an SO Post that explains which intent filters you need: android intent-filter to listen for sent email addresses?
You add these to your Activity entry in your AndroidManifest and then when someone clicks an email it'll show your app. when someone clicks it, it'll open that specific Activity you are going to want to read about pulling data out of intents. Specifically you'll want to pull out: http://developer.android.com/reference/android/content/Intent.html#EXTRA_EMAIL from the extras.
Read about intent-filter here:
https://developer.android.com/training/sharing/receive.html
I'm using the intent filter below to associate an activity with three types of custom extensions for a "file" scheme: .smmx, .smmstyle and .mm
<activity blablabla>
<intent-filter>
<action android:name="android.intent.action.EDIT" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data
android:host="*"
android:mimeType="application/octet-stream"
android:pathPattern=".*\\.smmx"
android:scheme="file" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.EDIT" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data
android:host="*"
android:mimeType="application/octet-stream"
android:pathPattern=".*\\.mm"
android:scheme="file" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.EDIT" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data
android:host="*"
android:mimeType="application/octet-stream"
android:pathPattern=".*\\.smmstyle"
android:scheme="file" />
</intent-filter>
</activity>
Problem is, that when used with the dropbox app, this intent filter associates the activity with virtually any extension. For example: when opening files with extensions *.mpb, *.adu - and a lot more - the dropbox app starts the associated activity although there is no match in the filename for any of the above pathPatterns in the intent filter.
It seems the intent filter wrongly evaluates true.
Any idea what might be causing this and how to avoid getting associated with files not intended for my activity?
After adding android:host="*" to each data section, the behaviour changes indeed.
The activity is no longer associated with all extensions. However, now it not always evaluates as matching.
For example this Uri is not matched
file:///mnt/sdcard/Android/data/com.dropbox.android/files/scratch/Bright%20Orange%20Levels.smmstyle
Although another file with the same extension opened from the same drobox app was matched OK.
This is happening on both a Galaxy GT-I9000 running android 2.2 and Archos 80 G9 running android 3.2
So: much better but not yet perfect. Will research further.
When Android perform matching test between intent and intent-filter, the test for only compares the URI and the data type in the Intent object to a URI and data type specified in the filter.
You can see the detail explanation here.
I'm writing an Android app that accompanies a website and I wanted to make the app intercept certain URLs. I found multiple examples through Google and on SO but none of them work. I create my Intent:
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://xgn.nl/article/" + String.valueOf(id)));
and then launch it from another Activity (where i is the intent from above)
startActivity(i);
The intent filter for the activity that should receive this is:
<activity android:name=".ArticleActivity" android:theme="#style/XGN.Red">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="http" android:host="xgn.nl" android:pathPrefix="/article/" android:mimeType="text/*" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
</activity>
I also tried it without the mimeType in the filter. The intent resolver sees the filter but complains that the data does not match with the data in the intent and launches the browser instead.
What am I doing wrong?
I actually solved it 5s after I posted it, the problem was that you need to specify the fully qualified class name for this to work :)
<activity android:name="nl.xgn.ArticleActivity" android:theme="#style/XGN.Red">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="http" android:host="xgn.nl" android:pathPrefix="/article/" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
</activity>
EDIT: To be more precise, the error I was seeing in logcat was wrong. The data type did match, but it chose the more visible browser class over my lazily defined activity. Specifying the full class name and removing the mimeType made this work.