Cordova implements custom download plug-ins and WPS online preview
Brief description
Click the download link and request the URL to determine whether the mobile phone has WPS installed. If WPS is installed, call WPS online editing. If it is not installed, download the file and notify it in the notification bar to display the download progress (do not call the download manager in Android system).
Using AsyncTask asynchronous task implementation, call the publishProgress() method to refresh the progress
Download request
Control WebView can easily embed web pages into app s, and more powerful, it can also be called directly with js.
WebChromeClient is a dialog box that assists WebView in processing JavaScript, including website icon, website title, loading progress, etc.
When clicking the download link, the setWebChromeClient method in WebView will be requested and the URL of the download request will be passed
Call setDownloadListener in the setWebChromeClient method
Then call the custom plug-in in setDownloadListener.
@Override public void setWebChromeClient(WebChromeClient client) { chromeClient = (SystemWebChromeClient)client; super.setWebChromeClient(client); Context context = super.getContext(); super.setDownloadListener(new DownloadListener() { @Override public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimeType, long contentLength) { String fileName = URLUtil.guessFileName(url, contentDisposition, mimeType); String destPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) .getAbsolutePath() + File.separator + fileName; //destPath is the obtained mobile phone storage path, which is / storage/emulated/0 //Call the SystemDownloadFile class to complete the file download new SystemDownloadFile(context).execute(url, destPath); } }); }
Reference learning: understanding WebView https://www.jianshu.com/p/3e0136c9e748
Download implementation
Asynchronous task implementation using AsyncTask
Common methods of AsyncTask
onPreExecute method:
1. When an asynchronous task starts executing, the system calls this method first.
2. This method runs in the main thread and can initialize the control.
dolnBackground method:
1. After the onPreExecute method is executed, the system executes this method
2. This method runs in the sub thread, and more time-consuming operations are executed in this method.
onProgressUpdate method:
1. Display the current progress, which is applicable to the demand for real-time display of progress such as downloading or scanning.
2. This method runs in the main thread and can modify the control state, such as displaying percentage.
3. To trigger this method, you need to use the publishProgress method in dolnBackground.
publishProgress method:
1. Used in doInBackground.
2. Used to trigger onProgressUpdate method.
on PostExecute method:
1. The system will call this method after the asynchronous task is completed.
2. This method runs in the main thread and can modify the control state, for example, the download is complete.
Reference learning: https://blog.csdn.net/yixingling/article/details/79517048
The download Plug-in mainly uses the doInBackground() and onProgressUpdate() methods
In the doInBackground() method
The download file mainly uses the while loop, input / output stream and byte array, and writes the byte array to the output stream
while(pro1!=100){ while((len = is.read(buf))!=-1){ total_length += len; if(file_length>=0) { pro1 = (int) ((total_length / (float) file_length) * 100);//Delivery progress (pay attention to sequence) } os.write(buf, 0, len);//Write output stream if(pro1!=pro2) { // Call onProgressUpdate function to update the progress publishProgress(pro2=pro1);//Trigger onProgressUpdate() method } } }
In the onProgressUpdate() method,
It mainly uses NotificationChannel and notificationcompat Builder to set the download progress
@Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); if(!checkWps()){ NotificationManager notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE); //Judge whether the current system is above 8.0 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "My Notifications", NotificationManager.IMPORTANCE_DEFAULT); //Do not start vibration notificationChannel.enableVibration(false); //Do not start sound notificationChannel.setSound(null,null); notificationManager.createNotificationChannel(notificationChannel); } //Style the notification bar NotificationCompat.Builder builder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID) .setSmallIcon(R.drawable.control) .setContentTitle(fileName) .setContentText("Downloading,Please wait...") .setWhen(System.currentTimeMillis()) .setAutoCancel(true) .setSound(null) .setOnlyAlertOnce(true) .setProgress(100, values[0], false); notificationManager.notify(NOTIFICATION_ID, builder.build()); if(values[0]>=100) { //After the download is completed, set not to open the file automatically //builder.setContentText("download completed"); Intent intent = new Intent(); File file = new File(destPath); Uri fileURI = GenericFileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".provider", file); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//set mark intent.setAction(Intent.ACTION_VIEW);//Actions, viewing intent.setDataAndType(fileURI, getMIMEType(file));//Set type //Auto open //context.startActivity(intent); //Call PendingIntent, add a click event to the notification bar, and click to open the downloaded file PendingIntent pi = PendingIntent.getActivity(context, 0, intent, 0); builder.setContentTitle("Download complete") .setContentText("Click open") // .setContentIntent(pi) .setContentInfo(fileName+"Download complete") .setContentIntent(pi); notificationManager.notify(NOTIFICATION_ID, builder.build()); } } }
Using tutorials http://developer.android.com/training/notify-user/index.html
Online preview implementation (using WPS)
1. Judge whether wps is installed on the mobile phone
//Determine whether wps is installed private boolean checkWps(){ Intent intent = context.getPackageManager().getLaunchIntentForPackage("cn.wps.moffice_eng");//Package name for WPS Personal Edition if (intent == null) { return false; } else { return true; } }
2. Call WPS to open the file
public void openDocument() { try { wpsCloseListener = new WpsCloseListener(); IntentFilter filter = new IntentFilter(); filter.addAction("com.kingsoft.writer.back.key.down");//Press the return key filter.addAction("com.kingsoft.writer.home.key.down");//Press the home key filter.addAction("cn.wps.moffice.file.save");//preservation filter.addAction("cn.wps.moffice.file.close");//close context.registerReceiver(wpsCloseListener,filter);//Register broadcast openDocFile(); } catch (Exception e) { e.printStackTrace(); } }
3. Open the document
// open documents boolean openDocFile() { try { Intent intent = context.getPackageManager().getLaunchIntentForPackage("cn.wps.moffice_eng"); Bundle bundle = new Bundle(); if (canWrite) { bundle.putString(Define.OPEN_MODE, Define.NORMAL); bundle.putBoolean(Define.ENTER_REVISE_MODE, true);//Open in revision mode } else { bundle.putString(Define.OPEN_MODE, Define.READ_ONLY); } //Open mode bundle.putBoolean(Define.SEND_SAVE_BROAD, true); bundle.putBoolean(Define.SEND_CLOSE_BROAD, true); bundle.putBoolean(Define.HOME_KEY_DOWN, true); bundle.putBoolean(Define.BACK_KEY_DOWN, true); bundle.putBoolean(Define.ENTER_REVISE_MODE, true); bundle.putBoolean(Define.IS_SHOW_VIEW, false); bundle.putBoolean(Define.AUTO_JUMP, true); //Set broadcast bundle.putString(Define.THIRD_PACKAGE, context.getPackageName()); //The package name of the third-party application, which is used to verify the legitimacy of the modified application // bundle.putBoolean(Define.CLEAR_FILE, true); //Delete open files after closing intent.setAction(Intent.ACTION_VIEW); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.setData(Uri.parse(url)); intent.putExtras(bundle); context.startActivity(intent); return true; } catch (ActivityNotFoundException e) { e.printStackTrace(); return false; } }
4. Set the broadcast receiver to judge whether the user exits wps. If so, call back the app
// After opening the document and browsing, call back the internal control app and return to the internal control app page private class WpsCloseListener extends BroadcastReceiver { @Override public void onReceive(Context context1, Intent intent1) { try { if (intent1.getAction().equals("cn.wps.moffice.file.close")|| intent1.getAction().equals("com.kingsoft.writer.back.key.down")) { appBack(); context.unregisterReceiver(wpsCloseListener);//Log off broadcast } }catch (Exception e) { e.printStackTrace(); } } } //After exiting wps, return to the app page public void appBack() { //Get ActivityManager ActivityManager mAm = (ActivityManager) context.getSystemService(ACTIVITY_SERVICE); //Get the currently running task List<ActivityManager.RunningTaskInfo> taskList = mAm.getRunningTasks(100); for (ActivityManager.RunningTaskInfo rti : taskList) { //Find the task of the current application and start the activity at the top of the stack of the task to switch the program to the foreground if (rti.topActivity.getPackageName().equals(context.getPackageName())) { mAm.moveTaskToFront(rti.id, 0); } } }