我們都知道,IOS與Android在對H5頁面上的處理是有區別的,舉個例子:
最近公司要做一個在webView界面長按保存圖片到圖庫裏的一個功能。看起來,很簡單嘛,我上個廁所的功夫,H5小哥刷刷的寫完了,快啊(到底是誰快)。接着開始調試,IOS打開手機,進到這個界面,長按了下,OK,沒有問題,調試完成。我去,好快,我也試了下,好吧,有問題,於是我就戴上放大鏡似的眼鏡研究了起來。在這一點上,android的webView沒有IOS處理的好,IOS已經實現了長按保存,android苦了,得自己實現,好吧,擼起袖子幹起來!
1.攔截長按事件
通過查看源碼我們知道webView也是View的一個子類,那就好辦了,按照其他控件的一樣寫出長按事件
2,判斷是否是圖片類型
通過查看webView的源碼,我們知道,webView的getHitTestResult()函數可以獲取到點擊頁面元素的類型,哈哈,這樣我們就可以根據類型進行相應的處理了。
通過源碼我們可以看到,HitTestResult有這兩個方法:
getType() 獲取所選目標的類型,如超鏈接,電話,圖片,郵件等
getExtra() 獲取額外的信息
再接着看,HitTestResult下的枚舉類型
注意: 在H5頁面,加載的圖片有兩種情況,一種是直接放置的圖片Url,一種是Base64編碼。
通過HitTestResult的枚舉類型,我們知道判斷webView.HitTestResult.IMAGE_TYPE和webView.HitTestResult.-SRC_ANCHOR_TYPE即可,廢話不多說,開幹。
3、保存到相冊,Android6.0以上要考慮動態權限(讀寫權限)
我們都知道Android6.0以上加入了動態權限,這個時候就得判斷是否是6.0以上的手機了
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// 手機系統6.0(23)以上動態申請權限
}else{//6.0以下不需要
}
在if裏面加入權限判斷,這個我就省略不寫了,很簡單。項目裏返的是base64編碼,所以敲黑板,重點來了:
private var bitmapFile: Bitmap? = null
val hitTestResult = mBinding.bwebView.hitTestResult
if (hitTestResult.extra!=null){
if (hitTestResult.type == WebView.HitTestResult.IMAGE_TYPE || hitTestResult.type == WebView.HitTestResult.SRC_ANCHOR_TYPE) {
Thread(Runnable {
try {
val bitmapArray: ByteArray = Base64.decode(hitTestResult.extra.split(",")[1], Base64.DEFAULT)
val bitmap = BitmapFactory.decodeByteArray(bitmapArray, 0, bitmapArray.size)
[email protected] = bitmap
try {
val isSaveSuccess = FileUtils.saveImageToGallery(applicationContext, bitmapFile)
if (isSaveSuccess) {
Looper.prepare()
ToastUtils.show("圖片已保存到手機相冊!")
Looper.loop()
} else {
Looper.prepare()
ToastUtils.show("保存圖片失敗,請稍後重試!")
Looper.loop()
}
} catch (e: IOException) {
e.printStackTrace()
}
} catch (e: MalformedURLException) {
e.printStackTrace()
}
}).start()
}
}
分析:
第1點,注意判空,因爲考慮到項目裏不止這一處用到了H5頁面,如果從其它入口進入H5頁面,那麼hitTestResult.extra會返回null或者hitTestResult.type返回0
爲什麼type會返回0,如下:
第2點,注意放到子線程進行處理
第3點,注意需要去掉字符串的data:image/png;base64,
因爲返回的base64是這樣子的,所以得先處理下
第4點,轉碼保存圖片,工具類在下面:
//保存文件到指定路徑
public static boolean saveImageToGallery(Context context, Bitmap bmp) {
// 首先保存圖片
String storePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "jj";
File appDir = new File(storePath);
if (!appDir.exists()) {
appDir.mkdir();
}
String fileName = System.currentTimeMillis() + ".jpg";
File file = new File(appDir, fileName);
try {
FileOutputStream fos = new FileOutputStream(file);
//通過io流的方式來壓縮保存圖片
boolean isSuccess = bmp.compress(Bitmap.CompressFormat.JPEG, 60, fos);
fos.flush();
fos.close();
//把文件插入到系統圖庫
//MediaStore.Images.Media.insertImage(context.getContentResolver(), file.getAbsolutePath(), fileName, null);
//保存圖片後發送廣播通知更新數據庫
Uri uri = Uri.fromFile(file);
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));
if (isSuccess) {
return true;
} else {
return false;
}
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
如果解決了你的問題,煩請點個贊,點個關注再走唄