The article directories
-
- After downloading the PDF, write the responseBody locally
-
- Android10 below
- Android 10 above write
- Use Tencent TBS kernel to open local PDF files directly in webView
-
- Open the local PDF file directly
- Implicitly call a third-party application to open a PDF
After downloading the PDF, write the responseBody locally
Val responseBody = downLoadResponseBodyBean. Respone logE (" received responseBody. Length = = ${responseBody? .contentLength()}") if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { thread { responseBody? .let { writePDF(it) } }.start() } else{ GlobalScope.launch { responseBody? .let { writePDFQ(it) } } }Copy the code
Android10 below
fun writePDF(body: ResponseBody): Boolean { var length = 0L var result = 0 return try { val files = File(PDF_PATH) if (! files.exists()) { files.mkdirs() } val futureStudioIconFile = File(PDF_PATH_NAME) var inputStream: InputStream? = null var outputStream: OutputStream? = null try { val fileReader = ByteArray(1024) val fileSize: Long = body.contentLength() inputStream = body.byteStream() outputStream = FileOutputStream(futureStudioIconFile) while (true) { val read: Int = inputStream.read(fileReader) if (read == -1) { break } outputStream.write(fileReader,0,read) length += read result = (100*length/fileSize).toint () if(result>0){logE(" ${result}%") ownerDashBoardModel.downLoadPDFProgress.postValue(result) } } outputStream.flush() true } catch (e: IOException) {logE(" Network error ${e.printStackTrace()}") false} finally {try {inputStream!! .close() outputStream!! .close() } catch(e: Exception) { e.printStackTrace() } } } catch (e: IOException) { logE(e.message) false } }Copy the code
Android 10 above write
@RequiresApi(Build.VERSION_CODES.Q) private suspend fun writePDFQ(responseBody: ResponseBody) { var length = 0L withContext(Dispatchers.IO){ var result = 0 val fileSize: Long = responseBody. ContentLength () logE (" file size: $fileSize") try { val inputStream = responseBody.byteStream() val bis = BufferedInputStream(inputStream) val values = ContentValues() values.put(MediaStore.MediaColumns.DISPLAY_NAME, fileName) values.put(MediaStore.Downloads.MIME_TYPE, "application/pdf") values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS) var uri = contentResolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, values) if (uri ! = null) { val outputStream = contentResolver.openOutputStream(uri) if (outputStream ! = null) { val bos = BufferedOutputStream(outputStream) val buffer = ByteArray(1024) var bytes = bis.read(buffer) while (bytes >= 0) { bos.write(buffer, 0 , bytes) bos.flush() bytes = bis.read(buffer) length += bytes result = (101*length/fileSize).toInt() if(result in 1.. 100){logE("Q monitor PDF file writing progress: ${result}%") ownerDashBoardModel.downLoadPDFProgress.postValue(result) } } bos.close() } }else{ Toast.makeText(context, $fileName write Exception ", toast.length_short).show()} bis.close()}catch (e: Exception) {e.printStackTrace()}}Copy the code
- Android10 below write SD card root directory, you can create folder
- Android10 and above are placed in the public directory Download directory, and in the root directory. Otherwise, you will have Permission denied when you open the file using an implicit third-party APP
Use Tencent TBS kernel to open local PDF files directly in webView
- At present the latest version of the API ‘com. Tencent. TBS. TBSSDK: SDK: 43903’ support through QQ browser to open the PDF
- If aiming at 10 or higher Android platform, in the application, please list file requestLegacyExternalStorage value is set to true:
<manifest ... >
<!-- This attribute is "false" by default on apps targeting
Android 10 or higher. -->
<application android:requestLegacyExternalStorage="true" ... >
...
</application>
</manifest>
Copy the code
<! <RelativeLayout Android :id="@+id/rl_pdf" Android :layout_width="match_parent" android:layout_height="match_parent"> <com.beans.base.widget.TBSWebView android:id="@+id/webView" android:layout_width="match_parent" android:layout_height="match_parent"> </com.beans.base.widget.TBSWebView> </RelativeLayout>Copy the code
Open the local PDF file directly
var tbsReaderView:TbsReaderView? Private fun openPDF() {var bundle = bundle () if(isAndroidQ()){bundle.putString("filePath", "/storage/emulated/0/Download/wey.pdf") bundle.putString("tempPath", context.cacheDir? .path+"/wey.pdf") }else{ bundle.putString("filePath", getPdfPath()) bundle.putString("tempPath", Environment.getExternalStorageDirectory().path) } var result = tbsReaderView!! .preOpen(parseFormat(parseName()),false) if (result){ tbsReaderView!! .openFile(bundle) }else{ QbSdk.openFileReader(this,"/storage/emulated/0/Download/wey.pdf",null, ValueCallback {logE(" PDF $it")})}}Copy the code
private fun parseFormat( fileName:String):String{
return fileName.substring(fileName.lastIndexOf(".") + 1);
}
Copy the code
private fun parseName():String{
return PDF_PATH_NAME.substring(PDF_PATH_NAME.lastIndexOf("/")+1)
}
Copy the code
Implicitly call a third-party application to open a PDF
// Save path of PDF file val PDF_PATH: String = Environment.getExternalStorageDirectory().getPath().toString() + "/wey/" val PDF_PATH_NAME: String = "${PDF_PATH}wey.pdf" var file :File if(Build.VERSION.SDK_INT < Build.VERSION_CODES.Q){ file= File(PDF_PATH_NAME) }else{ file = File("/storage/emulated/0/Download/", fileName) } if(! File.exists ()) {toastutils.s (this," file not found ") return@OnClickListener} val intent = intent (intent.action_view) var URI :Uri if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ){ uri = Uri.parse(PDF_PATH_NAME) if( Build.VERSION.SDK_INT >=Build.VERSION_CODES.Q){ uri = Uri.parse(PDF_PATH_Q_NAME) } }else{ uri = Uri.fromFile(file) } intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) intent.setDataAndType(uri, "application/pdf") var componentName:ComponentName = intent.resolveActivity(packageManager) if(componentName == null){ Toastutils.s (this," $componentName") return@OnClickListener}else{logE(" componentName")} try {toastutils.s (this," $componentName") return@OnClickListener}else{logE(" componentName")} try { startActivityForResult(intent,PDF_JUMP_CODE) } catch(e: ActivityNotFoundException) { Log.e("URLSpan","Activity was not found for intent, $intent") }Copy the code
override fun onDestroy() { super.onDestroy() mBinding.webView.clearCache(true) mBinding.webView.clearFormData() mBinding.webView.destroy() tbsReaderView!! .onStop() }Copy the code