Cordova实现自定义下载插件和WPS在线预览
简要描述
点击下载链接,请求URL,判断手机是否安装WPS,如果安装则调用wps在线编辑,没有安装则对文件进行下载,并在通知栏进行通知,显示下载进度(不调用安卓系统内的下载管理器)。
使用AsyncTask异步任务实现,调用publishProgress()方法刷新进度
下载请求
控件WebView,可以使得网页轻松的内嵌到app里,并且比较强大的是,还可以直接跟js相互调用。
WebChromeClient是辅助WebView处理JavaScript的对话框,网站图标,网站title,加载进度等。
当点击下载链接的时候会请求WebView中的setWebChromeClient方法,传递了下载请求的URL
调用setWebChromeClient方法中的setDownloadListener
然后在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是获取的手机存储路径是/storage/emulated/0
//调用SystemDownloadFile类,完成文件的下载
new SystemDownloadFile(context).execute(url, destPath);
}
});
}
参考学习:了解WebView https://www.jianshu.com/p/3e0136c9e748
下载实现
使用AsyncTask异步任务实现
AsyncTask常用方法
onPreExecute方法:
1.异步任务开始执行时,系统最先调用此方法。
2.此方法运行在主线程中,可以对控件进行初始化等操作。
dolnBackground方法:
1.执行完onPreExecute方法后,系统执行此方法
2.此方法运行在子线程中,比较耗时的操作放在此方法中执行。
onProgressUpdate方法:
1.显示当前进度,适用于下载或扫描这类需要实时显示进度的需求。
2.此方法运行在主线程中,可以修改控件状态,例如: 显示百分比。
3.触发此方法,需要在dolnBackground中使用publishProgress方法。
publishProgress方法:
1.在doInBackground中使用。
2.用于触发onProgressUpdate方法。
on PostExecute方法:
1.当异步任务执行完成后,系统会调用此方法。
2.此方法运行在主线程中,可以修改控件状态,例如: 下载完成。
参考学习:https://blog.youkuaiyun.com/yixingling/article/details/79517048
下载插件中主要使用了doInBackground()和onProgressUpdate()方法
在doInBackground()方法中
下载文件主要是使用了while循环、输入输出流,byte数组,将byte数组写入到输出流中
while(pro1!=100){
while((len = is.read(buf))!=-1){
total_length += len;
if(file_length>=0) {
pro1 = (int) ((total_length / (float) file_length) * 100);//传递进度(注意顺序)
}
os.write(buf, 0, len);//写入输出流
if(pro1!=pro2) {
// 调用onProgressUpdate函数,更新进度
publishProgress(pro2=pro1);//触发onProgressUpdate()方法
}
}
}
在onProgressUpdate()方法中,
主要使用了NotificationChannel,NotificationCompat.Builder来对下载进度进行了设置
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
if(!checkWps()){
NotificationManager notificationManager = (NotificationManager) context.getSystemService(NOTIFICATION_SERVICE);
//判断当前是否为8.0以上系统
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "My Notifications", NotificationManager.IMPORTANCE_DEFAULT);
//不启动震动
notificationChannel.enableVibration(false);
//不启动声音
notificationChannel.setSound(null,null);
notificationManager.createNotificationChannel(notificationChannel);
}
//设置通知栏的样式
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
.setSmallIcon(R.drawable.control)
.setContentTitle(fileName)
.setContentText("正在下载,请等待...")
.setWhen(System.currentTimeMillis())
.setAutoCancel(true)
.setSound(null)
.setOnlyAlertOnce(true)
.setProgress(100, values[0], false);
notificationManager.notify(NOTIFICATION_ID, builder.build());
if(values[0]>=100) {
//下载完成后,设置不自动打开文件
//builder.setContentText("下载完成");
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);//设置标记
intent.setAction(Intent.ACTION_VIEW);//动作,查看
intent.setDataAndType(fileURI, getMIMEType(file));//设置类型
//自动打开
//context.startActivity(intent);
//调用PendingIntent,给通知栏加点击事件,点击后打开下载的文件
PendingIntent pi = PendingIntent.getActivity(context, 0, intent, 0);
builder.setContentTitle("下载完成")
.setContentText("点击打开")
// .setContentIntent(pi)
.setContentInfo(fileName+"下载完成")
.setContentIntent(pi);
notificationManager.notify(NOTIFICATION_ID, builder.build());
}
}
}
使用教程 http://developer.android.com/training/notify-user/index.html
在线预览实现(使用WPS)
1.判断手机是否安装wps
//判断wps是否安装
private boolean checkWps(){
Intent intent = context.getPackageManager().getLaunchIntentForPackage("cn.wps.moffice_eng");//WPS个人版的包名
if (intent == null) {
return false;
} else {
return true;
}
}
2.调用WPS对文件进行打开
public void openDocument() {
try {
wpsCloseListener = new WpsCloseListener();
IntentFilter filter = new IntentFilter();
filter.addAction("com.kingsoft.writer.back.key.down");//按下返回键
filter.addAction("com.kingsoft.writer.home.key.down");//按下home键
filter.addAction("cn.wps.moffice.file.save");//保存
filter.addAction("cn.wps.moffice.file.close");//关闭
context.registerReceiver(wpsCloseListener,filter);//注册广播
openDocFile();
} catch (Exception e) {
e.printStackTrace();
}
}
3.打开文档
// 打开文档
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);//以修订模式打开
} else {
bundle.putString(Define.OPEN_MODE, Define.READ_ONLY);
}
//打开模式
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);
//设置广播
bundle.putString(Define.THIRD_PACKAGE, context.getPackageName());
//第三方应用的包名,用于对改应用合法性的验证
// bundle.putBoolean(Define.CLEAR_FILE, true);
//关闭后删除打开文件
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.设置广播接收器,判断用户是否退出wps,退出的话,回调app
// 打开文档浏览完毕后,回调内控app,回到内控app页面
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);//注销广播
}
}catch (Exception e) {
e.printStackTrace();
}
}
}
//退出wps后,返回到app页面
public void appBack() {
//获取ActivityManager
ActivityManager mAm = (ActivityManager) context.getSystemService(ACTIVITY_SERVICE);
//获得当前运行的task
List<ActivityManager.RunningTaskInfo> taskList = mAm.getRunningTasks(100);
for (ActivityManager.RunningTaskInfo rti : taskList) {
//找到当前应用的task,并启动task的栈顶activity,达到程序切换到前台
if (rti.topActivity.getPackageName().equals(context.getPackageName())) {
mAm.moveTaskToFront(rti.id, 0);
}
}
}