我正在开发一个Android应用程序,我必须打开一些文件。
这是我的代码使用意图:
public class FacturaActivity extends Activity {
(...)
public void downloadInvoice(View view) {
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() +"/"+ filename);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file),"application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
}
}
文件位于SD卡的根目录中,我可以手动打开它。
问题
应用程序在到达startActivity(intent)时关闭。我认为问题出在AndroidManifest.xml文件中,但我不知道如何正确使用它。
的AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="8" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:name="###.MyApplication" > <!--cant show complete name-->
<activity
android:name="###.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".FacturaActivity" >
</activity>
</application>
logcat的
07-03 15:49:13.094: E/AndroidRuntime(1032): FATAL EXCEPTION: main
07-03 15:49:13.094: E/AndroidRuntime(1032): java.lang.IllegalStateException: Could not execute method of the activity
(...)
07-03 15:49:13.094: E/AndroidRuntime(1032): Caused by: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=file:///mnt/sdcard/201209_F2012212782.PDF typ=application/pdf flg=0x40000000 }
07-03 15:49:13.094: E/AndroidRuntime(1032): at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1408)
07-03 15:49:13.094: E/AndroidRuntime(1032): at android.app.Instrumentation.execStartActivity(Instrumentation.java:1378)
07-03 15:49:13.094: E/AndroidRuntime(1032): at android.app.Activity.startActivityForResult(Activity.java:2817)
07-03 15:49:13.094: E/AndroidRuntime(1032): at android.app.Activity.startActivity(Activity.java:2923)
你能帮我完成AndroidManifest吗?或者我该如何打开pdf?
答案 0 :(得分:89)
问题是没有安装应用程序来处理打开PDF。您应该使用Intent Chooser,如下所示:
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() +"/"+ filename);
Intent target = new Intent(Intent.ACTION_VIEW);
target.setDataAndType(Uri.fromFile(file),"application/pdf");
target.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
Intent intent = Intent.createChooser(target, "Open File");
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
// Instruct the user to install a PDF reader here, or something
}
答案 1 :(得分:6)
String dir="/Attendancesystem";
public void displaypdf() {
File file = null;
file = new File(Environment.getExternalStorageDirectory()+dir+ "/sample.pdf");
Toast.makeText(getApplicationContext(), file.toString() , Toast.LENGTH_LONG).show();
if(file.exists()) {
Intent target = new Intent(Intent.ACTION_VIEW);
target.setDataAndType(Uri.fromFile(file), "application/pdf");
target.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
Intent intent = Intent.createChooser(target, "Open File");
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
// Instruct the user to install a PDF reader here, or something
}
}
else
Toast.makeText(getApplicationContext(), "File path is incorrect." , Toast.LENGTH_LONG).show();
}
答案 2 :(得分:5)
从API 24开始,将file://
URI发送到另一个应用程序将抛出FileUriExposedException。而是使用FileProvider发送content://
URI:
public File getFile(Context context, String fileName) {
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
return null;
}
File storageDir = context.getExternalFilesDir(null);
return new File(storageDir, fileName);
}
public Uri getFileUri(Context context, String fileName) {
File file = getFile(context, fileName);
return FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", file);
}
还必须在清单中定义FileProvider:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.mydomain.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
示例file_paths.xml:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files-path name="name" path="path" />
</paths>
适当替换“名称”和“路径”。
要授予PDF查看器访问文件的权限,您还必须向意图添加FLAG_GRANT_READ_URI_PERMISSION
标志:
private void displayPdf(String fileName) {
Uri uri = getFileUri(this, fileName);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, "application/pdf");
// FLAG_GRANT_READ_URI_PERMISSION is needed on API 24+ so the activity opening the file can read it
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_GRANT_READ_URI_PERMISSION);
if (intent.resolveActivity(getPackageManager()) == null) {
// Show an error
} else {
startActivity(intent);
}
}
有关更多详细信息,请参见FileProvider documentation。
答案 3 :(得分:1)
您没有打开文件的权限是因为您没有按照您的意图授予其他应用打开或查看文件的权限。要允许其他应用打开下载的文件,请包含标志(如下所示):FLAG_GRANT_READ_URI_PERMISSION
Intent browserIntent = new Intent(Intent.ACTION_VIEW);
browserIntent.setDataAndType(getUriFromFile(localFile), "application/pdf");
browserIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION|
Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(browserIntent);
对于函数:
getUriFromFile(localFile)
private Uri getUriFromFile(File file){
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
return Uri.fromFile(file);
}else {
return FileProvider.getUriForFile(itemView.getContext(), itemView.getContext().getApplicationContext().getPackageName() + ".provider", file);
}
}
答案 4 :(得分:0)
以下Kotlin版本(@ paul-burke响应的更新版本:
fun openPDFDocument(context: Context, filename: String) {
//Create PDF Intent
val pdfFile = File(Environment.getExternalStorageDirectory().absolutePath + "/" + filename)
val pdfIntent = Intent(Intent.ACTION_VIEW)
pdfIntent.setDataAndType(Uri.fromFile(pdfFile), "application/pdf")
pdfIntent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
//Create Viewer Intent
val viewerIntent = Intent.createChooser(pdfIntent, "Open PDF")
context.startActivity(viewerIntent)
}