web-dev-qa-db-ja.com

Android PDFファイルを開く

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を開くにはどうすればよいですか?

30
Lyd

問題は、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
}   
94
Paul Burke
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();
    }
6
Sanjit Majee

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 を参照してください。

1
David Kennedy

以下の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)
}
0