I am facing issue in opening Email in MYApp when I made its launch mode to "singleInstance".
I have attached sample Android project which reads file name from email attachment and displays it on screen. Works fine in case of onCreate but throws error in onNewIntent when apps launch mode is singleInstance.
Launchmode.java
package your.namespace.launchmode;
public class LaunchModeActivity extends Activity {
private static final int OPEN_ACT = 2;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String name = getAttachmetName(getIntent());
if(null != name)
{
TextView textv = (TextView) findViewById(R.id.attachmentnm);
textv.setText(name);
}
}
@Override
protected void onNewIntent(Intent savedInstanceState)
{
super.onNewIntent(savedInstanceState);
String name = getAttachmetName(savedInstanceState);
if(null != name)
{
TextView textv = (TextView) findViewById(R.id.attachmentnm);
textv.setText(name);
}
}
private String getAttachmetName(Intent intent) {
final Uri documentUri = intent.getData();
if(null != documentUri){
final String uriString = documentUri.toString();
String documentFilename = null;
final int mailIndexPos = uriString.lastIndexOf("/attachments");
if (mailIndexPos != -1) {
final Uri curi = documentUri;
final String [] projection = new String[] {OpenableColumns.DISPLAY_NAME};
final Cursor cursor = getApplicationContext().getContentResolver().query(curi, projection, null, null, null);
if (cursor != null) {
final int attIdx = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
if (attIdx != -1) {
cursor.moveToFirst();
documentFilename = cursor.getString(attIdx);
}
cursor.close();
}
}
return documentFilename;
}
return null;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if((resultCode == RESULT_OK) && (requestCode == OPEN_ACT))
{
Log.d("LaunchMode", "Second activity returned");
}
}
}
AndroidManifest
<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="your.namespace.launchmode"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="com.google.android.gm.permission.READ_GMAIL"/>
<uses-permission android:name="com.google.android.gm.permission.WRITE_GMAIL"/>
<uses-permission android:name="com.google.android.providers.gmail.permission.READ_GMAIL"/>
<uses-permission android:name="com.google.android.providers.gmail.permission.WRITE_GMAIL"/>
<uses-sdk android:minSdkVersion="8" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:label="@string/app_name"
android:launchMode="singleInstance"
android:name=".LaunchModeActivity" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter >
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<!-- docx -->
<data android:mimeType="application/vnd.openxmlformats-officedocument.wordprocessingml.document" />
<!-- xlsx -->
<data android:mimeType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" />
<!-- pptx -->
<data android:mimeType="application/vnd.openxmlformats-officedocument.presentationml.presentation" />
<data android:mimeType="application/vnd.ms-excel" />
<data android:mimeType="application/msword" />
<data android:mimeType="application/vnd.ms-powerpoint" />
<data android:mimeType="text/plain" />
</intent-filter>
</activity>
</application>
</manifest>
Steps to reproduce 1)Install apk on device. 2)Go to gmail native app on device, open any attachment(office document) to view. 3)Choose LaunchMode app to complete action. 4)LaunchMode app will display file name on screen.
This works fine for first time (onCreate flow) but when this app is switch in background and again I try 2,3,4 steps.. app crashes with error
E/DatabaseUtils(30615): java.lang.SecurityException: Permission Denial: reading com.google.android.gm.provider.MailProvider uri content://gmail-ls/[email protected]/messages/5/attachments/0.2/BEST/false from pid=32657, uid=10058 requires com.google.android.gm.permission.READ_GMAIL
E/DatabaseUtils(30615): at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:309)
E/DatabaseUtils(30615): at android.content.ContentProvider$Transport.bulkQuery(ContentProvider.java:178)
E/DatabaseUtils(30615): at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:111)
E/DatabaseUtils(30615): at android.os.Binder.execTransact(Binder.java:339)
E/DatabaseUtils(30615): at dalvik.system.NativeStart.run(Native Method)
D/AndroidRuntime(32657): Shutting down VM
I need to fix this as, I need to have single instance of Application and should get email attachment name too. Please let me know If I am missing something here.
My question here is why it work in flow of onCreate and it wont work in case of onNewIntent
Note: 1)Works fine with 2.x phones 2) Works fine with Single top launch mode. 3) Some updates on Gmail app.link here:
You likely got a URI permission to read the file name when you received the intent and aren't using the permissions that you requested (READ_GMAIL
and WRITE_GMAIL
). The URI permission is valid only until your application finish()
es, so you won't have it when you try to resume.
That's consistent with your experiences - it works when the intent is fresh, but not old ones. I think that WRITE_GMAIL
is a signature permission and I am guessing that READ_GMAIL
is as well. In that case, there is not much you can do. READ_ATTACHMENT
might be a more appropriate permission for you to request.
More on URI permissions: http://developer.android.com/guide/topics/security/permissions.html#uri
Try removing the uses-permission
tags from your manifest and see if you have the same experience. You can also try to examine the intent
when you receive it by checking its flags.
checkCallingOrSelfUriPermission(documentUri , Intent.FLAG_GRANT_READ_URI_PERMISSION)
If you get 0 returned, you have been using URI permissions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With