网页端上传文件常用<input type='file'/>标签,放上这个标签,浏览器就会出现这个文件选择器,点击就可以弹出文件选择窗口,很是简单方便,不过,包含<input type='file'/>标签的网页要是在安卓WebView中渲染,<input type='file'/>这个标签就会失效,用户点击后毫无反应,根本原因就是安卓WebView没有实现具体的文件选择器方法,对应的方法是空的,我们要安卓WebView支持<input type='file'/>只能重写对应的方法,调用原生java代码去实现文件上传的功能,大体可以分为以下几步:
1、重载文件选择按钮被点击后的方法,即onShowFileChooser()方法。
2、在onShowFileChooser()方法中声明一个意图,打开文件选择相对应的Activity,即FILE_CHOOSER_RESULT_CODE。
3、重载onActivityResult()方法,在里面接收用户选择的文件的Uri,传给input标签
下面还是直接上代码:
package com.test.sdxjwkq;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.ClipData;
import android.os.Build;
import android.os.Bundle;
import android.webkit.WebView;
import android.webkit.WebChromeClient;
import android.net.Uri;
import android.webkit.ValueCallback;
import android.content.Intent;
import android.text.TextUtils;
import android.webkit.WebViewClient;
import android.os.Environment;
public class MainActivity extends AppCompatActivity {
private ValueCallback<Uri> uploadMessage;
private ValueCallback<Uri[]> uploadMessageAboveL;
private final static int FILE_CHOOSER_RESULT_CODE = 10000;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView=findViewById(R.id.webView1);
webView.getSettings().setJavaScriptEnabled(true);//支持javascript
webView.getSettings().setAllowContentAccess(true);
webView.getSettings().setAllowFileAccess(true);
// 开启DOM缓存,开启LocalStorage存储(html5的本地存储方式)
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setDatabaseEnabled(true);
webView.getSettings().setDatabasePath(MainActivity.this.getApplicationContext().getCacheDir().getAbsolutePath());
//javascript接口映射
//webView.addJavascriptInterface(new Utils(), "Utils");
//webView.addJavascriptInterface(new Sql(), "Sql");
webView.setWebChromeClient(new WebChromeClient() {
// For Android >= 5.0
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) {
uploadMessageAboveL = filePathCallback;
openImageChooserActivity();
return true;
}
});
webView.loadUrl("file:///android_asset/main.html");
//webView.loadUrl("file:///"+Environment.getExternalStorageDirectory()+"/Enen/main.html");
}
private void openImageChooserActivity() {
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
startActivityForResult(Intent.createChooser(i, "Image Chooser"), FILE_CHOOSER_RESULT_CODE);
}
private static WebView webView;
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == FILE_CHOOSER_RESULT_CODE) {
if (null == uploadMessage && null == uploadMessageAboveL) return;
Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();
if (uploadMessageAboveL != null) {
onActivityResultAboveL(requestCode, resultCode, data);
} else if (uploadMessage != null) {
uploadMessage.onReceiveValue(result);
uploadMessage = null;
}
}
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void onActivityResultAboveL(int requestCode, int resultCode, Intent intent) {
if (requestCode != FILE_CHOOSER_RESULT_CODE || uploadMessageAboveL == null)
return;
Uri[] results = null;
if (resultCode == Activity.RESULT_OK) {
if (intent != null) {
String dataString = intent.getDataString();
ClipData clipData = intent.getClipData();
if (clipData != null) {
results = new Uri[clipData.getItemCount()];
for (int i = 0; i < clipData.getItemCount(); i++) {
ClipData.Item item = clipData.getItemAt(i);
results[i] = item.getUri();
}
}
if (dataString != null)
results = new Uri[]{Uri.parse(dataString)};
}
}
uploadMessageAboveL.onReceiveValue(results);
uploadMessageAboveL = null;
}
}
|