2017-06-08 11 views
0

私はアンドロイドアプリケーションからPDFを開くためのカスタムクラスを使用しています。 PDFが既にダウンロードされているかどうかをチェックし、既存のPDFビューアアプリケーションを使用してPDFを開きます。 PDFビューアアプリケーションがない場合は、Googleドキュメントを使用してpdfを開こうとします。アンドロイドからPDFを開くアプリケーション

Android Studio 2.2.3から2.3.2へのアップグレードと24から25へのビルドツールのバージョンまで、クラスは正常に動作していました。ターゲットSDKは引き続きAPI 24です。問題の正確な根本原因を特定できません。

PDFクラス

public class PDFTools { 
private static final String GOOGLE_DRIVE_PDF_READER_PREFIX = "http://docs.google.com/viewer?url="; 
private static final String PDF_MIME_TYPE = "application/pdf"; 
private static final String HTML_MIME_TYPE = "text/html"; 

/** 
* If a PDF reader is installed, download the PDF file and open it in a reader. 
* Otherwise ask the user if he/she wants to view it in the Google Drive online PDF reader.<br /> 
* <br /> 
* <b>BEWARE:</b> This method 
* @param context 
* @param pdfUrl 
* @return 
*/ 
public static void showPDFUrl(final Context context, final String pdfUrl) { 
    if (isPDFSupported(context)) { 
     downloadAndOpenPDF(context, pdfUrl); 
    } else { 
     askToOpenPDFThroughGoogleDrive(context, pdfUrl); 
    } 
} 

/** 
* Downloads a PDF with the Android DownloadManager and opens it with an installed PDF reader app. 
* @param context 
* @param pdfUrl 
*/ 

public static void downloadAndOpenPDF(final Context context, final String pdfUrl) { 
    // Get filename 
    final String filename = pdfUrl.substring(pdfUrl.lastIndexOf("/") + 1); 
    // The place where the downloaded PDF file will be put 
    final File tempFile = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), filename); 
    if (tempFile.exists()) { 
     // If we have downloaded the file before, just go ahead and show it. 
     Uri uri = null; 
     File docPath = new File(context.getExternalFilesDir(null), "Download"); 
     File newFile = new File(docPath, filename); 

     uri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", newFile); 

     openPDF(context, uri); 
     return; 
    } 

    // Show progress dialog while downloading 
    final ProgressDialog progress = ProgressDialog.show(context, context.getString(R.string.pdf_show_local_progress_title), 
      context.getString(R.string.message_please_wait), true); 

    // Create the download request 
    DownloadManager.Request r = new DownloadManager.Request(Uri.parse(pdfUrl)); 
    r.setDestinationInExternalFilesDir(context, Environment.DIRECTORY_DOWNLOADS, filename); 
    final DownloadManager dm = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); 
    BroadcastReceiver onComplete = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      if (!progress.isShowing()) { 
       return; 
      } 
      context.unregisterReceiver(this); 

      progress.dismiss(); 
      long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); 
      Cursor c = dm.query(new DownloadManager.Query().setFilterById(downloadId)); 

      if (c.moveToFirst()) { 
       int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS)); 
       if (status == DownloadManager.STATUS_SUCCESSFUL) { 
        Uri uri = null; 
        try { 
         uri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", tempFile); 

        }catch (IllegalArgumentException iae) { 
         iae.printStackTrace(); 
        } 
        if (uri !=null) { 
         openPDF(context, uri); 
        } 
       } 
      } 
      c.close(); 
     } 
    }; 
    context.registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); 

    // Enqueue the request 
    dm.enqueue(r); 
} 

/** 
* Show a dialog asking the user if he wants to open the PDF through Google Drive 
* @param context 
* @param pdfUrl 
*/ 
public static void askToOpenPDFThroughGoogleDrive(final Context context, final String pdfUrl) { 
    new AlertDialog.Builder(context) 
      .setTitle(R.string.pdf_show_online_dialog_title) 
      .setMessage(R.string.pdf_show_online_dialog_question) 
      .setNegativeButton(R.string.pdf_show_online_dialog_button_no, null) 
      .setPositiveButton(R.string.pdf_show_online_dialog_button_yes, new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        openPDFThroughGoogleDrive(context, pdfUrl); 
       } 
      }) 
      .show(); 
} 

/** 
* Launches a browser to view the PDF through Google Drive 
* @param context 
* @param pdfUrl 
*/ 
public static void openPDFThroughGoogleDrive(final Context context, final String pdfUrl) { 
    Intent i = new Intent(Intent.ACTION_VIEW); 
    i.setDataAndType(Uri.parse(GOOGLE_DRIVE_PDF_READER_PREFIX + pdfUrl), HTML_MIME_TYPE); 
    context.startActivity(i); 
} 
/** 
* Open a local PDF file with an installed reader 
* @param context 
* @param localUri 
*/ 
public static final void openPDF(Context context, Uri localUri) { 
    Intent i = new Intent(Intent.ACTION_VIEW); 
    i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 
    i.setDataAndType(localUri, PDF_MIME_TYPE); 
    context.startActivity(i); 
} 
/** 
* Checks if any apps are installed that supports reading of PDF files. 
* @param context 
* @return 
*/ 
public static boolean isPDFSupported(Context context) { 
    Intent i = new Intent(Intent.ACTION_VIEW); 
    final File tempFile = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "test.pdf"); 
    i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 
    i.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 
    try { 
     i.setDataAndType(FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider" ,tempFile), PDF_MIME_TYPE); 
    }catch (IllegalArgumentException iae) { 
    } 
    return context.getPackageManager().queryIntentActivities(i, PackageManager.MATCH_DEFAULT_ONLY).size() > 0; 
} 

}

それは私がスタックオーバーフロー自体からこのサンプルをとっている

java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Android/data/<PACKAGE>/files/Download/javascript_pdf_version.pdf 

としてエラーがスローされます。これについてあなたの助けを感謝します。

+0

質問を編集し、 'FileProvider'設定XMLリソースを投稿してください。このエラーに基づいて、正しく設定されていないようです。 – CommonsWare

+0

Androidマニフェストで上記のように設定されたFileProviderパスXMLは、<?xml version = "1.0" encoding = "utf-8"?> <外部ファイル・パス名=" 外部」パス= "ダウンロード" /> user8133044

+0

マニフェスト<プロバイダ アンドロイド:名= "android.support.v4.content.FileProvider" アンドロイド:当局= "$ {} APPLICATIONID .provider" アンドロイド:エクスポート= "false" を アンドロイド:grantUriPermissions = "真"> <メタデータ アンドロイド:名= "android.support.FILE_PROVIDER_PATHS" アンドロイド:リソース= "@ xml/provider_paths" /> <?xml version = "1.0" encoding = "utf-8"?> user8133044

答えて

0

ダウンロードするには、このような何かを試してみてください:RestTemplateを使用して

のWebService:(ファイル変換&ストレージ用)

public PdfByteArrayObject getPrintjob(String empId) { 
    PdfByteArrayObject pdfByteArrayObject = null; 
    try { 
     getUrl(); 
     RestTemplate restTemplate = new RestTemplate();    
     restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter()); 

     pdfByteArrayObject = restTemplate.getForObject("pdfURL" + empId, PdfByteArrayObject.class); 


    } catch (Exception e) { 
     e.printStackTrace();    
     Log.e("webser======", e.toString()); 
    } 
    return pdfByteArrayObject; 
} 

getUrl方法:

public void getUrl() { 
    StringBuffer stringBuffer = new StringBuffer(); 
    String aDataRow = ""; 
    String aBuffer = ""; 
    try { 
     File serverPath = new File(Environment.getExternalStorageDirectory(), "ServerUrl"); 

     if (serverPath.exists()) { 
      FileInputStream fIn = new FileInputStream(serverPath); 
      BufferedReader myReader = new BufferedReader(
        new InputStreamReader(fIn)); 

      while ((aDataRow = myReader.readLine()) != null) { 
       aBuffer += aDataRow; 
      } 
      RestUrl = aBuffer; 
      Log.e("RestUrl", RestUrl + "--"); 
      myReader.close(); 
     } else { 
      Log.e("RestUrl", "File not found"); 
     } 

    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    // Toast.makeText(getApplicationContext(),aBuffer,Toast.LENGTH_LONG).show(); 
} 

とオブジェクト:

public class PdfByteArrayObject { 

private byte[] pdffile; 

public byte[] getPdffile() { 
    return pdffile; 
} 

public void setPdffile(byte[] pdffile) { 
    this.pdffile = pdffile; 
} 
} 

これは役に立ちます。

+0

以前のソリューションでは、PDFが正しくダウンロードされています。ただし、モバイルアプリで表示することはできません。 – user8133044

関連する問題