2017-02-17 12 views
2

Я новичок в Android, и перед вами стоит проблема, связанная с тем, чтобы открыть PDF-файл ни с чем. В то время как в зефире и других версиях Android он открывается, но в нуге это не так.PDF-файл не открыт в nougat 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()); 
     } 
    } 

ли кто-нибудь сталкиваться с этой проблемой, как этот

+0

, потому что вы никогда не помещаете файл в свой FileProvider, и вы пропускаете бессмысленный uri – Selvin

+0

@Selvin Как это сделать, можете ли вы поделиться кодом? – Muju

+0

Код в примере из официальной документации андроида. Я не вижу смысла повторять его здесь на SO (особенно, когда это было достаточно долгое время) – Selvin

ответ

0

Если вы пытаетесь открыть какой-нибудь файл, хранящийся во внутренней памяти приложения с некоторым приложением третьей стороны, то вы должны использовать FileProvider для получения uri для файла. https://developer.android.com/reference/android/support/v4/content/FileProvider.html

+0

Я уже использовал это, но ничего не случилось. – Muju

+0

@Muju, но код, который вы опубликовали, не использовался FileProvider – Sanjeet

+0

PdfContentProvider является файловым провайдером. – Muju

0

Если Вы используете андроида-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(); 
} 

Вы также можете использовать ваш провайдер File

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"); 

Что Вы erliar Создано

0

Вот полный способ чтения PDF-файл в Android 7.0 или менее:

Шаг 1: Прежде всего, поместите файл в формате PDF в активах как следующий снимок экрана. 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: Теперь перейдите в класс Activity from wh прежде чем вы хотите загрузить PDF и добавьте следующие строки и 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.