Android-приложение Gmail - проблема с URI вложения почты - PullRequest
5 голосов
/ 30 июня 2011

Мне нужно открыть файл вложения из приложения gmail через мое приложение.

Я получаю ссылку в шаблоне, например content: //gmail-ls/messages/mailid%40gmail.com/4/attachments/0.1/BEST/false

Моя проблема заключается в том, что ссылка не является уникальной для каждого файла в почтовом клиенте. Один или несколько файлов имеют одинаковые Uri .

Можно ли получить имя файла или дату отправки электронного письма, чтобы я мог решить эту проблему.

Заранее спасибо.

Ответы [ 4 ]

7 голосов
/ 28 мая 2014

Как показано ниже, вы можете сделать локальную копию того же вложения и работать с этим файлом. Непосредственно вы не сможете получить доступ к тому файлу, который находится на сервере Gmail.

    Uri uri = getIntent().getData();
    if (uri != null) {
    try {
        InputStream attachment = getContentResolver().openInputStream(uri);
        if (attachment == null)
            Log.e("GMAIL ATTACHMENT", "Mail attachment failed to resolve");
        else {

            FileOutputStream tmp = new FileOutputStream(getCacheDir().getPath() + "/temp.myfile");
            byte[] buffer = new byte[1024];
            while (attachment.read(buffer) > 0)
                tmp.write(buffer);
            tmp.close();
            attachment.close();
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    }
    return getCacheDir().getPath() + "/temp.myfile";

Запомните, чтобы добавить это в манифест.

    <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <action android:name="android.intent.action.EDIT" />

            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />

            <data
                android:host="*"
                android:mimeType="application/octet-stream"
                android:pathPattern=".*\\.tsconfig" />
            <!-- To handle gmail attachments -->
    </intent-filter>
2 голосов
/ 04 августа 2011

Я решил эту проблему косвенным путем.

Я определил уникальность, используя размер файла.

В случае, если вам нужен код, это

InputStream is = getContentResolver().openInputStream(uri);
FILE_SIZE=is.available();
0 голосов
/ 26 сентября 2015

Спасибо, Локеш Кумар, ваш код очень помог!Тем не менее, мне нравится выделять проблему с вашим решением.

При попытке использовать ваш код:

    FileOutputStream tmp = new FileOutputStream(getCacheDir().getPath() + "/temp.myfile");
        byte[] buffer = new byte[1024];
        while (attachment.read(buffer) > 0)
            tmp.write(buffer);
        tmp.close();
        attachment.close();

он скопирован во весь файл, но я думаю, что естьпроблема.Делая attachment.read(buffer), вы каждый раз читаете 1024 байта и, скажем, у вас есть файл размером 2000 байтов.

При первом чтении вы получите первые 1024, затем при следующем и последнем чтении вы получите последние 976 байт, и из того, что я видел, в этом случае буфер не очищаетпоследние байты из прочитанного предварительного просмотра, конец файла будет 976 байт от последнего чтения, а остальные 48 от чтения до самого последнего. Это сделает неверный конец файла.

В моем случае, вложение - это файл kml (файл данных о местоположении в формате xml), который мне пришлось скопировать.Пытаясь использовать этот код, я всегда получал неверный конец kml.после закрывающего тега я получил некоторый текст, который был от чтения до самого последнего.

Примерно так:

  </Document>
</kml>
278
34.81186031,31.96118044
34.81184437,31.96122622
34.81181701,31.96127052
34.81182701,31.9612875

Конечно, это недопустимый kml, и он будет вызывать ошибки при попытке его анализа.

Поэтому я использовал другой код для чтения из входного потока, который сделал работу лучше.

Это мой код для копирования файла:

InputStream attachment = getContentResolver().openInputStream(container.uri);
            FileOutputStream tmp = new FileOutputStream(container.fileName);

            BufferedInputStream bis = new BufferedInputStream(attachment);
            StringBuffer b = new StringBuffer();

            while (bis.available() != 0) {
                char c = (char) bis.read();
                b.append(c);
            }

            bis.close();
            attachment.close();
            tmp.write(String.valueOf(b).getBytes());
            tmp.close();
0 голосов
/ 06 января 2013

Недавно я столкнулся с той же проблемой и нашел способ получить имя файла:

public static String getContentName(ContentResolver resolver, Uri uri){
    Cursor cursor = resolver.query(uri, new String[]{MediaStore.MediaColumns.DISPLAY_NAME}, null, null, null);
    cursor.moveToFirst();
    int nameIndex = cursor.getColumnIndex(cursor.getColumnNames()[0]);
    if (nameIndex >= 0) {
        return cursor.getString(nameIndex);
    } else {
        return null;
    }
}

Для использования:

String fileName = getContentName(getContentResolver(), getIntent().getData());

С уважением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...