2017-12-05 35 views
0

내 안드로이드 앱의 자산 폴더에 저장된 "NEFT.pdf"파일을 표시하려고합니다.
다음 코드는이 코드는 API 25 이상에서 작동하지 않는 API 25fileProvider를 사용하여 assets 폴더에서 PDF 파일을 열려고했지만 FileNotFoundException이 발생합니다. 해당 파일 또는 디렉토리가 없습니다.

private void CopyReadAssets(String filename) { 
    AssetManager assetManager = getAssets(); 
    InputStream in = null; 
    OutputStream out = null; 
    File file = new File(getFilesDir(), filename); 

    try { 
     in = assetManager.open(filename); 
     out = openFileOutput(file.getName(), Context.MODE_WORLD_READABLE); 

     copyFile(in, out); 
     in.close(); 
     in = null; 
     out.flush(); 
     out.close(); 
     out = null; 


     Intent intent = new Intent(Intent.ACTION_VIEW); 
     intent.setDataAndType(
       Uri.parse("file://" + getFilesDir() + "/"+filename), "application/pdf"); 

     startActivity(intent); 
    } catch (Exception e) 
    { 
     Toast.makeText(PdfFilesList.this, "cra: "+e.toString(), Toast.LENGTH_SHORT).show(); 
    } 
} 

까지 절대적으로 잘 작동합니다. MODE_WORLD_READABLE 오류가 더 이상 지원되지 않습니다.
나는 MODE_PRIVATE로 변경하지만 그건 나에게

android.os.fileuriexposedexception가 intent.getdata를 통해 응용 프로그램을 넘어 노출 다른 오류()을 제공합니다.
그래서 나는 Developer.Android.com에 설명 된 개념을 적용했다.

E/DisplayData : openFd : java.io.FileNotFoundException :
이 내가 오류 로그에 무엇을 얻을 아니오 같은 파일 또는 디렉터리

E/PdfLoader : 파일을로드 할 수 없습니다 (열리지 않습니다) 데이터 표시 [PDF : NEFT.pdf] + ContentOpenable, uri : content : //com.user.plansmart.provider/pdf_files/NEFT.pdf

uri가 올바르게 보입니다. 누구든지 여기서 오류를 찾는데 도와 줄 수 있습니까?

여기 공급자 요소가 매니페스트 파일에 있습니다. 당신이 PDF를 표시 싶어요 원인

<provider 
     android:name="android.support.v4.content.FileProvider" 
     android:authorities="${applicationId}.provider" 
     android:exported="false" 
     android:grantUriPermissions="true"> 
     <meta-data 
      android:name="android.support.FILE_PROVIDER_PATHS" 
      android:resource="@xml/provider_paths"/> 
    </provider> 

이 PDF 파일

private void displayFile(String filename) { 
    try { 
     File filePath = new File(getApplicationContext().getFilesDir(), "pdf"); 
     File newFile = new File(filePath, filename); 

     //new version 
     Uri fileUri = FileProvider.getUriForFile(PdfFilesList.this, 
       BuildConfig.APPLICATION_ID + ".provider", newFile); 

     getApplicationContext().grantUriPermission(PACKAGE_NAME, 
          fileUri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 

     Intent intent = new Intent(Intent.ACTION_VIEW); 
     intent.setDataAndType(fileUri, "application/pdf"); 
     intent.setFlags(FLAG_GRANT_READ_URI_PERMISSION | FLAG_GRANT_WRITE_URI_PERMISSION); 
     startActivity(intent); 
    }catch (Exception e){ 
     e.printStackTrace(); 
     Toast.makeText(PdfFilesList.this, "df "+e.toString(), Toast.LENGTH_SHORT).show(); 
    } 
} 
+0

다음은 사용할 수 없습니다 자민련이 (가) 다음을 수행 선호 FileProvider 클래스를 제공합니다. 재고. Recode. – greenapps

+0

'getFilesDir(), "pdf");'. 뭐라 했니? 자산? 아닙니다. 자산이 아닙니다. getFilesDir()은 비공개 내부 저장소입니다. 게시물을 수정하십시오. 제목으로 시작합니다. – greenapps

+0

파일이 자산입니까? 그런 다음 getFilesDir()을 사용할 수 없습니다. 당신이 가지고있는 것을 말하십시오. – greenapps

답변

0

를 표시 할 수있는 안드로이드 코드입니다 provider_paths.xml 파일

<?xml version="1.0" encoding="utf-8"?> 
<paths xmlns:android="http://schemas.android.com/apk/res/android"> 
<external-path name="external_files" path="."/> 
<files-path name="pdf_files" path="pdf/"/> 

입니다 별도의 응용 프로그램 (예 : Adobe Reader)의 파일 장치 메모리에 파일 복사

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

      InputStream in = null; 
      OutputStream out = null; 
      String state = Environment.getExternalStorageState(); 
      if (!Environment.MEDIA_MOUNTED.equals(state)) { 
       Toast.makeText(getActivity(), "External Storage is not Available", Toast.LENGTH_SHORT).show(); 
      } 
      File pdfDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/PDFs"); 
      if (!pdfDir.exists()) { 
       pdfDir.mkdir(); 
      } 
      File file = new File(pdfDir + "/abc.pdf"); 

      try 
      { 
       in = assetManager.open("abc.pdf"); 
       out = new BufferedOutputStream(new FileOutputStream(file)); 
       copyFile(in, out); 
       in.close(); 
       in = null; 
       out.flush(); 
       out.close(); 
       out = null; 
      } catch (Exception e) 
      { 
       Log.e("tag", e.getMessage()); 
      } 
      if (file.exists()) //Checking for the file is exist or not 
      { 
       Uri path = Uri.fromFile(file); 
       Intent objIntent = new Intent(Intent.ACTION_VIEW); 
       objIntent.setDataAndType(path, "application/pdf"); 
       objIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
       Intent intent1 = Intent.createChooser(objIntent, "Open PDF with.."); 
       try { 
        startActivity(intent1); 
       } catch (ActivityNotFoundException e) { 
        Toast.makeText(getActivity(), "Activity Not Found Exception ", Toast.LENGTH_SHORT).show(); 
       } 
      } else { 
       Toast.makeText(getActivity(), "The file not exists! ", Toast.LENGTH_SHORT).show(); 
      } 
     } 

: - - :

private void copyFile(InputStream in, OutputStream out) throws IOException 
    { 
     byte[] buffer = new byte[1024]; 
     int read; 
     while ((read = in.read(buffer)) != -1) 
     { 
      out.write(buffer, 0, read); 
     } 
    } 

사용하면 자산 파일이있는 경우 아래의 권한

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
+0

"파일이 없습니다". Uri 경로를이 Uri 경로 = Uri.parse ("content : //com.user.plansmart.provider/pdf_files/"+ filename)로 변경하려고했습니다. – pamo

+0

또한 Uri 경로 = Uri.parse ("file : /// android_asset /"+ filename)로 시도했습니다. do'nt work – pamo

+0

이 답변에 시간을 보내지 마십시오. 그것의 말도 안돼. – greenapps