原創(chuàng)文章,轉(zhuǎn)載請注明本文出處http://www.reibang.com/p/841bfa47b45c
這篇文章的已知bug窿侈,我已經(jīng)改好了念秧,在我另一篇博文里,地址:http://www.reibang.com/p/62f3750f72a8
前言
一周前做的項目中聊闯,要嵌入一個H5的頁面工猜,這個H5功能很簡單,主要就是給用戶提供預約申請菱蔬,其中需要上傳本人身份證篷帅。
在這里推薦一下github上面開源的小型AgentWeb
還有就是騰訊的TBS騰訊瀏覽服務
這兩個我都在項目中嘗試過,效果都還不錯拴泌,關于這兩個庫的具體使用方法魏身,我上面給出的github地址或官方技術接入指南講的都比較詳細,就不綴述了弛针,您要是有疑問可以在評論區(qū)留言叠骑,咱們可以互相探討。
正題
這是H5頁面中需要上傳圖片的截圖
通過webview.loadUrl(“你要加載的地址”)加載網(wǎng)頁時削茁,在手持設備上點擊圖中上傳圖片時宙枷,用以上兩個庫不做任何處理的情況下,有以下問題:
- AgentWeb會出現(xiàn)彈出圖片選擇器掉房,本以為接下來點擊相冊會進入相冊,但是實際情況是(不同手機會有不同表現(xiàn))點擊相冊之后慰丛,閃退卓囚。
- 集成TBS騰訊瀏覽服務,不給webView設置一個webview.webviewClient()诅病,會從手機上已安裝的一個瀏覽器正常打開相冊哪亿,但是這樣就像是從你的應用進入到了其他應用,所以一般還是要webView.setWebViewClient()贤笆,寫上這個方法之后蝇棉,點擊上傳圖片會沒有任何響應。
解決
這個時候我們需要H5跟Android互調(diào)(js跟java互調(diào))
思路:在H5頁面上點擊這個上傳圖片時芥永,調(diào)用的是Android原生方法來打開相冊或者攝像頭篡殷,下面以打開相冊為例。
代碼片段:
// js 調(diào)android 方法
webView.addJavascriptInterface(new DemoJavaScriptInterface(), "demo");
這里的DemoJavaScriptInterface是你要定義給JS調(diào)用的方法的所屬類名埋涧,
下圖中的demo.chickOnAndroid就是js中要拼接而成的方法
/**
* 定義的給js調(diào)的方法
*/
final class DemoJavaScriptInterface{
DemoJavaScriptInterface(){
}
@JavascriptInterface
public void clickOnAndroid(String s){
//這里執(zhí)行你用Android原生方法打開相冊或攝像頭的操作
//用intent打開即可
startActivityForResult(把intent傳進來)板辽;
}```
**clickOnAndroid(String s)中的String類型的參數(shù)s,
就是js中window.demo.clickOnAndroid(getJson())方法中棘催,getJson()返回的值**
要打開手機中的文件還需要
//用來接收下面ValueCallback<Uri> 回調(diào)
private ValueCallback<Uri> mUploadMessage;
private ValueCallback<Uri[]> uploadMessageAboveL;
..........................................................................................................................
webView.setWebChromeClient(new WebChromeClient(){
//Android 3.0 以下
public void openFileChooser(ValueCallback<Uri> valueCallback) {
mUploadMessage = valueCallback;
selectImage();//就是上面
}
// Android 3~4.1
public void openFileChooser(ValueCallback valueCallback, String acceptType) {
mUploadMessage = valueCallback;
selectImage();
}
// Android 4.1以上
public void openFileChooser(ValueCallback<Uri> valueCallback, String acceptType, String capture) {
mUploadMessage = valueCallback;
selectImage();
}
// Android 5.0以上
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback,
WebChromeClient.FileChooserParams fileChooserParams ) {
uploadMessageAboveL = filePathCallback;
selectImage();
return true;
}
})劲弦;
openFileChooser是WebChromeClient中的隱藏方法需要你手動去寫
5.0之后就變成了onShowFileChooser
selectImage()就是你選擇圖片的一些操作
private void selectImage() {
FileUtils.delFile(compressPath);
Intent intent;
if (Build.VERSION.SDK_INT < 19) {
intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
} else {
intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
Intent wrapperIntent = Intent.createChooser(intent, null);
//REQ_CHOOSE是定義的一個常量
startActivityForResult(wrapperIntent, REQ_CHOOSE);
}
在Activity中還要重寫onActivityResult()來處理你選擇圖片之后的操作
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if(null == intent){
//為了避免 彈出 相冊選擇器 之后 點擊取消 閃退
mUploadMessage.onReceiveValue(null);
return;
}
if (null== mUploadMessage){
mUploadMessage.onReceiveValue(null);
return;
}
Uri uri = null;
if (requestCode ==REQ_CHOOSE){
uri = afterChosePic(intent);
//afterChosePic()這是選擇照片之后要處理的
}
mUploadMessage.onReceiveValue(uri);
mUploadMessage = null;
}```
afterChosePic()方法代碼
private Uri afterChosePic(Intent data) {
// 獲取圖片的路徑:
String[] proj = { MediaStore.Images.Media.DATA };
// 好像是android多媒體數(shù)據(jù)庫的封裝接口,具體的看Android文檔
Cursor cursor = managedQuery(data.getData(), proj, null, null, null);
if(cursor == null ){
Toast.makeText(this, "上傳的圖片僅支持png或jpg格式",Toast.LENGTH_SHORT).show();
return null;
}
// 按我個人理解 這個是獲得用戶選擇的圖片的索引值
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
// 將光標移至開頭 醇坝,這個很重要邑跪,不小心很容易引起越界
cursor.moveToFirst();
// 最后根據(jù)索引值獲取圖片路徑
String path = cursor.getString(column_index);
if(path != null && (path.endsWith(".png")||path.endsWith(".PNG")||path.endsWith(".jpg")||path.endsWith(".JPG"))){
File newFile = FileUtils.compressFile(path, compressPath);
return Uri.fromFile(newFile);
}else{
Toast.makeText(this, "上傳的圖片僅支持png或jpg格式",Toast.LENGTH_SHORT).show();
}
return null;
}
#####到此,webview加載h5頁面(也就是js)選擇圖片的操作就基本完成了
(噓纲仍,上班期間躲著寫的呀袱,可能思路有點亂,沒看明白的可以留言郑叠,我看到了就會回)