簡體   English   中英

無法在牛軋糖Android中打開PDF文件

[英]PDF file not open in nougat Android

我是Android的新手,我面臨着打開PDF文件的問題。 在棉花糖和其他Android版本中會打開,但在牛軋糖中不會打開。

我的代碼是這樣的

private void CopyReadAssets()
    {
        AssetManager assetManager = getResources().getAssets();

        InputStream in = null;
        OutputStream out = null;
        File file = new File(getFilesDir(), "Induction.pdf");
        try
        {
            copyFile(assetManager.open("Induction.pdf"), file);

        } catch (Exception e)
        {
            Log.e("tag", e.getMessage());
        }

        MimeTypeMap mime = MimeTypeMap.getSingleton();
        String ext = file.getName().substring(file.getName().lastIndexOf(".") + 1);
        String type = mime.getMimeTypeFromExtension(ext);
        try {
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_VIEW);

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                //intent.setDataAndType(getUri(file), type);

                Uri uri = Uri.parse("content://com.econnect.team.PdfContentProvider/"+"Induction.pdf");
               // Uri uri = FileProvider.getUriForFile(this, getPackageName() + ".PdfContentProvider", file);
                intent.setDataAndType(uri, type);

            } else {
                intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                intent.setDataAndType(Uri.fromFile(file), type);
                Log.e("Uri ", " "+ Uri.fromFile(file));
            }
            startActivityForResult(intent, 100);

        }catch (FileUriExposedException ex){
            Log.e("Uri ", "exception: "+ex.getMessage());
        }
        catch (ActivityNotFoundException anfe) {
            Toast.makeText(Menus.this, "No activity found to open this attachment.", Toast.LENGTH_LONG).show();

        }
    }

    private void copyFile(InputStream in, File f) throws IOException
    {
        try {
            FileOutputStream out = new FileOutputStream(f);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                out = openFileOutput(f.getName(), Context.MODE_PRIVATE);
            }
            else {
                out = openFileOutput(f.getName(), Context.MODE_WORLD_READABLE);
            }
            byte[] buffer = new byte[1024];
            int read;
            while ((read = in.read(buffer)) != -1) {
                out.write(buffer, 0, read);
            }
            in.close();
            out.close();
        }catch (Exception e){
            Log.e("copy file", e.getMessage());
        }
    }

有人這樣面對過這個問題嗎

如果您嘗試使用某些第三方應用程序打開存儲在應用程序內部存儲中的某些文件,則應使用FileProvider獲取該文件的uri。 https://developer.android.com/reference/android/support/v4/content/FileProvider.html

如果您使用的是android-N(即上述API 24),請執行以下操作:

    try {
                                Intent intent = new Intent(Intent.ACTION_VIEW);
                                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                File f = new File(yourPath);

                                Uri uri = null;

                                // Above Compile SDKversion: 25 -- Uri.fromFile Not working
                                // So you have to use Provider
                                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                                 uri = Uri.parse("content://com.econnect.team.PdfContentProvider/"+"Induction.pdf");

                                // Add in case of if We get Uri from fileProvider.
                                    intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
                                    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                                }else{
                                    uri = Uri.fromFile(f);
                                }

                                intent.setDataAndType(uri, "application/pdf");
                                startActivity(intent);
}catch(Exeption e){
    e.printstacktrace();
}

您還可以使用文件提供程序

 Uri uri = FileProvider.getUriForFile(this, getPackageName() + ".PdfContentProvider", file);

或者像這樣使用它:

 uri = FileProvider.getUriForFile(this,getApplicationContext().getPackageName() +
                                            ".provider", file);

代替

uri = Uri.parse("content://com.econnect.team.PdfContentProvider/"+"Induction.pdf");

您所創建的

這是在Android 7.0或更低版本中讀取pdf文件的完整方法:

步驟1:首先,將您的pdf文件放入資產文件夾,如以下屏幕截圖所示。 將pdf文件放置在資產文件夾中

步驟2:現在轉到build.gradle文件並添加以下行:

repositories {
maven {
    url "https://s3.amazonaws.com/repo.commonsware.com"
}

}

然后在依賴項下添加以下行並同步:

compile 'com.commonsware.cwac:provider:0.4.3'

步驟3:現在添加一個新的Java文件,該文件應從FileProvider擴展, FileProvider在我的情況下,文件名是LegacyCompatFileProvider ,其內部包含代碼。

import android.database.Cursor;
import android.net.Uri;

import android.support.v4.content.FileProvider;

import com.commonsware.cwac.provider.LegacyCompatCursorWrapper;

public class LegacyCompatFileProvider extends FileProvider {
  @Override
  public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
    return(new LegacyCompatCursorWrapper(super.query(uri, projection, selection, selectionArgs, sortOrder)));
  }
}

步驟4:"res"文件夾下創建一個名為"xml" "res"文件夾。 (如果文件夾已經存在,則無需創建)。 現在,在xml文件夾中添加一個providers_path.xml文件。 這是屏幕截圖: provider_path xml文件的位置

在文件內部添加以下行:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <files-path name="stuff" />
</paths>

步驟5:現在轉到AndroidManifest.xml文件,並在<application></application>標記中的以下行:

<provider
            android:name="LegacyCompatFileProvider"
            android:authorities="REPLACE_IT_WITH_PACKAGE_NAME"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"/>
        </provider>

步驟6:現在轉到要從其中加載pdf的Activity類,並添加以下1行和這2種方法:

private static final String AUTHORITY="REPLACE_IT_WITH_PACKAGE_NAME";

static private void copy(InputStream in, File dst) throws IOException {
        FileOutputStream out=new FileOutputStream(dst);
        byte[] buf=new byte[1024];
        int len;

        while ((len=in.read(buf)) > 0) {
            out.write(buf, 0, len);
        }

        in.close();
        out.close();
    }

    private  void LoadPdfFile(String fileName){

        File f = new File(getFilesDir(), fileName + ".pdf");

        if (!f.exists()) {
            AssetManager assets=getAssets();

            try {
                copy(assets.open(fileName + ".pdf"), f);
            }
            catch (IOException e) {
                Log.e("FileProvider", "Exception copying from assets", e);
            }
        }

        Intent i=
                new Intent(Intent.ACTION_VIEW,
                        FileProvider.getUriForFile(this, AUTHORITY, f));

        i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

        startActivity(i);
        finish();
    }

現在調用LoadPdfFile方法並傳遞不帶.pdf的文件名,例如在我的情況下為"chapter-0" ,它將在pdf閱讀器中打開pdf文件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM