繁体   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