PDF文件未在nougat Android中打开

时间:2017-02-17 08:40:20

标签: android pdf android-7.0-nougat

我是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());
        }
    }

有没有人像这样面对这个问题

3 个答案:

答案 0 :(得分:0)

如果您尝试使用某些第三方应用程序打开存储在应用程序内部存储中的某些文件,则应使用 FileProvider 获取该文件的uri。 https://developer.android.com/reference/android/support/v4/content/FileProvider.html

答案 1 :(得分:0)

如果您正在使用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");

你正在创造的

答案 2 :(得分:0)

以下是在Android 7.0或更低版本中阅读pdf文件的完整方式:

<强>步骤1: 首先,将您的pdf文件放在assets文件夹中,如下面的屏幕截图所示。 Placing pdf file in assets folder

<强>步骤-2: 现在转到build.gradle文件并添加以下行:

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

}

然后在依赖项下添加以下行并同步:

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

<强>步骤-3: 现在添加一个新的java文件,该文件应该从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:"xml"文件夹下创建名为"res"的文件夹。 (如果文件夹已经存在则无需创建)。现在在providers_path.xml文件夹中添加xml文件。这是截图: Place of provider_path xml file

内部文件添加以下行:

<?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行和这两个方法:

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文件。