How to access gmail attachment data in my app

2020-02-06 02:25发布

I have an app that uses a specifically created binary (.gcsb) file type. These files are kept in a folder on the sdcard.

At the moment they are moved on and off using ES file explorer or the phone manufacturer 'behave like a USB drive' transfer utilities. Clunky. What I want to to is be able to email the files to the phone, then to open the files as attachments from within gmail, which should fire up the app, which will then save them to the appropriate SD card folder.

I've found some stuff about setting up intents to - hopefully - start the app in clicking 'preview' within gmail (specifically Open custom Gmail attachment in my Android app), but what I'm not at all sure of is how to access the file data! I guess it must be with one of the Intent.get...Extra() functions, but which, and how to use it?

2条回答
不美不萌又怎样
2楼-- · 2020-02-06 02:54

nwm01223' answer is correct! A small addendum: His answer only works for ACTION_VIEW. if you add

Uri uri = null;
if(Intent.ACTION_VIEW.equals(action)){
    uri = intent.getData();
} else if(Intent.ACTION_SEND.equals(action)){
    uri = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
}

it will also work for ACTION_SEND

查看更多
We Are One
3楼-- · 2020-02-06 03:09

Found out how to do it. Hopefully this may help someone else. Party mine, partly from other posts. It is aiming to handle .gcsb file attachments.

The intent-filter is

<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:mimeType="application/octet-stream" />
</intent-filter>

and the code in the activity onCreate() / onRestart() is

Intent intent = getIntent();
InputStream is = null;
FileOutputStream os = null;
String fullPath = null;

try {
    String action = intent.getAction();
    if (!Intent.ACTION_VIEW.equals(action)) {
        return;
    }

    Uri uri = intent.getData();
    String scheme = uri.getScheme();
    String name = null;

    if (scheme.equals("file")) {
        List<String> pathSegments = uri.getPathSegments();
        if (pathSegments.size() > 0) {
            name = pathSegments.get(pathSegments.size() - 1);
        }
    } else if (scheme.equals("content")) {
        Cursor cursor = getContentResolver().query(uri, new String[] {
            MediaStore.MediaColumns.DISPLAY_NAME
        }, null, null, null);
        cursor.moveToFirst();
        int nameIndex = cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME);
        if (nameIndex >= 0) {
            name = cursor.getString(nameIndex);
        }
    } else {
        return;
    }

    if (name == null) {
        return;
    }

    int n = name.lastIndexOf(".");
    String fileName, fileExt;

    if (n == -1) {
        return;
    } else {
        fileName = name.substring(0, n);
        fileExt = name.substring(n);
        if (!fileExt.equals(".gcsb")) {
            return;
        }
    }

    fullPath = ""/* create full path to where the file is to go, including name/ext */;

    is = getContentResolver().openInputStream(uri);
    os = new FileOutputStream(fullPath);

    byte[] buffer = new byte[4096];
    int count;
    while ((count = is.read(buffer)) > 0) {
        os.write(buffer, 0, count);
    }
    os.close();
    is.close();
} catch (Exception e) {
    if (is != null) {
        try {
            is.close();
        } catch (Exception e1) {
        }
    }
    if (os != null) {
        try {
            os.close();
        } catch (Exception e1) {
        }
    }
    if (fullPath != null) {
        File f = new File(fullPath);
        f.delete();
    }
}

It appears to work in the standard Android gmail and mail applications. The file name is obtained two different ways depending if 'download' (scheme file) or 'preview' (scheme content) was pressed in gmail.

Note that it is extremely important that the activity is not set to be single instance.

查看更多
登录 后发表回答