我想用我的应用程序打开pdfs附件。
我已经设置了intent-filter
<intent-filter android:label="@string/label" >
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:mimeType="application/pdf" />
<data android:mimeType="image/*" />
</intent-filter>
<intent-filter android:label="@string/label" >
<action android:name="android.intent.action.SHARE" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:mimeType="application/pdf" />
<data android:mimeType="image/*" />
</intent-filter>
它在Android 4.4设备上运行良好但在4.2.2上我得到以下异常:
java.lang.SecurityException: Permission Denial: opening provider com.google.android.gm.provider.MailProvider from ProcessRecord{2120ac60 21661:com.some.app.package/u0a10113} (pid=21661, uid=10113) requires com.google.android.gm.permission.READ_GMAIL or com.google.android.gm.permission.WRITE_GMAIL
我尝试添加所有这些权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="com.android.email.permission.READ_ATTACHMENT"/>
<uses-permission android:name="com.google.android.gm.permission.READ_GMAIL"/>
<uses-permission android:name="com.google.android.gm.permission.READ_CONTENT_PROVIDER"/>
奇怪的是,如果我尝试加载相同的附件而不是使用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"/>
仍然没有运气
EDIT2:
这就是我触发异常的方式:
public static byte[] getBytesFromUri(Uri uri, Context appCtx) {
ByteArrayOutputStream byteBuffer = null;
InputStream inputStream = null;
try {
inputStream = appCtx.getContentResolver().openInputStream(uri); //crash here
byteBuffer = new ByteArrayOutputStream();
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
byteBuffer.write(buffer, 0, len);
}
inputStream.close();
inputStream=null;
return byteBuffer.toByteArray();
} catch (IOException e) {
log.e(TAG, "error retrieving bytearray from uri "+uri);
e.printStackTrace();
}
return null;
}
EDIT3:
以下是我如何获取文件uri:
Uri fileUri = null;
if (Intent.ACTION_VIEW.equals(intent.getAction())) {
fileUri = intent.getData();
intent.setData(null);
} else if (Intent.ACTION_SEND.equals(intent.getAction())) {
fileUri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
intent.removeExtra(Intent.EXTRA_STREAM);
}
编辑4 对于greenapps: 这是uris:
的Gmail
content://gmail-ls/gmail.account@gmail.com/messages/76/attachments/0.1/BEST/false
电子邮件
file:///storage/emulated/0/Android/data/com.android.email/cache/test_file.pdf
所以uris是不同的,但它们也在4.4设备上,它仍然有效
答案 0 :(得分:0)
使用以下代码: 意图过滤器
<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" />
<data android:host="*" />
<data android:scheme="smb" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:pathPattern=".*\\.pdf" />
</intent-filter>
<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" />
<data android:host="*" />
<data android:scheme="smb" />
<data android:scheme="http" />
<data android:scheme="https" />
<data android:mimeType="application/pdf" />
</intent-filter>
<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" />
<data android:host="*" />
<data android:scheme="file" />
<data android:scheme="content" />
<!-- Workaround to match files in paths with dots in them, like /sdcard/my.folder/test.pdf -->
<data android:pathPattern=".*\\.pdf" />
<data android:pathPattern=".*\\..*\\.pdf" />
<data android:pathPattern=".*\\..*\\..*\\.pdf" />
</intent-filter>
<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" />
<data android:host="*" />
<data android:scheme="file" />
<data android:scheme="content" />
<data android:mimeType="application/pdf" />
</intent-filter>
在活动类中使用CONTENT RESOLVER
将URI转换为数据 TextView fileNameTextView;
private File file;
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 */;
String filenm = fileName + fileExt;
file = new File(getCacheDir(), filenm);
is = getContentResolver().openInputStream(uri);
os = new FileOutputStream(file.getPath());
byte[] buffer = new byte[4096];
int count;
while ((count = is.read(buffer)) > 0) {
os.write(buffer, 0, count);
}
os.close();
is.close();
fileNameTextView.setText(fullPath);
pdfView.fromFile(file)
.enableSwipe(true) // allows to block changing pages using swipe
.swipeHorizontal(false)
.enableDoubletap(true)
.password("123456")
.defaultPage(0)
.load();
Log.e("TAG", "===onfile path: "+file.getAbsolutePath() );
Log.e("TAG", "===onFile name: "+file.getName() );
} 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();
}
}