Android Gmail app-Mail Attachment URI issue
I have to open attachment file from gmail app thru my app.
I get link in pattern like content://gmail-ls/messages/mailid%40gmail.com/4/attachments/0.1/BEST/false
My problem is the link is not unique for each file in the mail client.. One or more file has same Uri.
Is开发者_如何学JAVA there any way to get the file name or email sent date so that I can come over this issue.
Thanks in advance.
As shown below you can make a local copy of the same attachment and work on that file. Directly you wont be able to access that file which is on the gmail server.
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";
Reember to add this to your manifest.
<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>
I resolved this issue in an indirect way.
I identified the uniqueness using the file size.
In-case if you need the code here it is
InputStream is = getContentResolver().openInputStream(uri);
FILE_SIZE=is.available();
I've recently came across the same issue and found a way to get the file name:
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;
}
}
To use:
String fileName = getContentName(getContentResolver(), getIntent().getData());
Regards.
Thank you Lokesh Kumar, your code helped a lot! However, I do like to highlight an issue with your solution.
When trying to use this code of yours:
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();
it did copied to entire file, but I think there is a problem.
When doing attachment.read(buffer)
, you are reading 1024 bytes each time and lets say, that you have a file of 2000 bytes.
On the first reading, you will get the first 1024, then on the next and last reading, you will get the last 976 bytes and from what I saw, in this case, the buffer doesn't clean the last bytes from the previews read, the end of the file will be 976 byte from last reading, and the rest 48 from the the reading before the very last one.. This will make the end of the file incorrect.
In my case, The attachment is a kml file (a location data file in form of xml) which I had to copy. By trying to use this code I always got the end of the kml incorrect. after the closing tag, I got some text which was from the reading before the very last one.
Something like this:
</Document>
</kml>
278
34.81186031,31.96118044
34.81184437,31.96122622
34.81181701,31.96127052
34.81182701,31.9612875
Of course, this is not a valid kml, and it will cause errors when trying to pars it.
Therefore, I have used some different code to read from the input stream which did the job better.
This is my code for copying the file:
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();
精彩评论