我遇到一个问题,我在WebView中加载了一个页面 - 我不打算为整个应用程序发布代码,因为我的问题非常具体:我的HTML页面中的“选择文件”按钮适用于Android Studio创建的模拟器,但不在其他任何地方。
按钮运行此代码:
<input type='file' id='fileInput' accept='text/plain' onchange='openFile(event);'>
var openFile = function(event) {
var input = event.target;
var reader = new FileReader();
reader.onload = function(e){
/* various string parsing */
};
reader.readAsText(input.files[0]);
};
这在我的模拟器上工作得很好,这是API 23:点击按钮打开设备的默认文件选择器来选择文件。但是,在我的实际手机上,即API 16,单击此按钮不会执行任何操作。此外,在Genymotion模拟器(API 18)上,单击按钮不会执行任何操作。有什么我可以做的来解决这个问题吗?该按钮在我的手机和Genymotion模拟器上都不会产生任何错误消息,它只是坐在那里没有任何反应。
我需要应用程序才能使用允许语音到文本的设备,因此我不仅可以使用模拟器,而且还可以使用。
答案 0 :(得分:8)
为选择文件
设置WebChromeClient
<强> CODE 强>
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.webkit.JavascriptInterface;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;
import android.widget.Toast;
import org.apache.http.util.EncodingUtils;
public class BrowserScreen extends Activity {
private WebView webView;
private String url = "url";
private ValueCallback<Uri> mUploadMessage;
private final static int FILECHOOSER_RESULTCODE = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.browser_activity);
initFields();
setListeners();
}
public void initFields() {
// TODO Auto-generated method stub
webView = (WebView) findViewById(R.id.webView1);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setBuiltInZoomControls(true);
webView.getSettings().setAllowFileAccess(true);
}
public void setListeners() {
// TODO Auto-generated method stub
webView.setWebViewClient(new WebViewClient() {
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
webView.loadUrl("about:blank");
view.clearHistory();
}
});
webView.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress) {
}
//The undocumented magic method override
//Eclipse will swear at you if you try to put @Override here
// For Android 3.0+
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
startActivityForResult(Intent.createChooser(i, "File Chooser"), FILECHOOSER_RESULTCODE);
}
// For Android 3.0+
public void openFileChooser(ValueCallback uploadMsg, String acceptType) {
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("*/*");
startActivityForResult(
Intent.createChooser(i, "File Browser"),
FILECHOOSER_RESULTCODE);
}
//For Android 4.1
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
startActivityForResult(Intent.createChooser(i, "File Chooser"), FILECHOOSER_RESULTCODE);
}
});
webView.loadUrl(url);
final MyJavaScriptInterface myJavaScriptInterface
= new MyJavaScriptInterface(this);
webView.addJavascriptInterface(myJavaScriptInterface, "AndroidFunction");
}
@Override
public void onBackPressed() {
// TODO Auto-generated method stub
if (webView.canGoBack() == true) {
webView.goBack();
} else {
super.onBackPressed();
}
}
public class MyJavaScriptInterface {
Context mContext;
MyJavaScriptInterface(Context c) {
mContext = c;
}
@JavascriptInterface
public void showToast(String toast) {
Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
// webView.loadUrl("javascript:document.getElementById(\"Button3\").innerHTML = \"bye\";");
}
@JavascriptInterface
public void openAndroidDialog() {
AlertDialog.Builder myDialog
= new AlertDialog.Builder(BrowserScreen.this);
myDialog.setTitle("DANGER!");
myDialog.setMessage("You can do what you want!");
myDialog.setPositiveButton("ON", null);
myDialog.show();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
if (requestCode == FILECHOOSER_RESULTCODE) {
if (null == mUploadMessage) return;
Uri result = intent == null || resultCode != RESULT_OK ? null
: intent.getData();
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
}
}
}
答案 1 :(得分:0)
“接受的答案”不适用于我。我从Google Chromium Samples.
找到了新答案public class WebViewActivity extends AppCompatActivity {
ActivityWebviewBinding binding;
public static final int INPUT_FILE_REQUEST_CODE = 1;
private ProgressDialog progressDialog;
private ValueCallback<Uri[]> mFilePathCallback;
private String mCameraPhotoPath;
@SuppressLint("SetJavaScriptEnabled")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_webview);
setSupportActionBar(binding.toolbar);
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle(getString(R.string.button_register_now));
}
progressDialog = new ProgressDialog(WebViewActivity.this);
progressDialog.setMessage("Loading...");
progressDialog.show();
WebSettings webSettings = binding.webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setSupportZoom(true);
webSettings.setBuiltInZoomControls(true);
webSettings.setDisplayZoomControls(false);
webSettings.setAllowFileAccess(true);
webSettings.setLoadWithOverviewMode(true);
webSettings.setUseWideViewPort(true);
binding.webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
final Uri uri = Uri.parse(url);
return handleUri(uri);
}
@TargetApi(Build.VERSION_CODES.N)
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
final Uri uri = request.getUrl();
return handleUri(uri);
}
private boolean handleUri(final Uri uri) {
if (uri != null) {
Log.i("TAG", "Uri =" + uri);
// Based on some condition you need to determine if you are going to load the url
// in your web view itself or in a browser.
// You can use `host` or `scheme` or any part of the `uri` to decide.
if (uri.getLastPathSegment() != null) {
if (uri.getLastPathSegment().contains("p1_business_part1.php")) {
finish();
startActivity(new Intent(WebViewActivity.this, LoginActivity.class));
return false;
}
} else {
binding.webView.loadUrl(uri.toString());
return true;
}
}
return false;
}
@Override
public void onPageFinished(WebView view, String url) {
if (progressDialog.isShowing()) {
progressDialog.dismiss();
}
}
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
Toast.makeText(WebViewActivity.this, "Error:" + description, Toast.LENGTH_SHORT).show();
view.loadUrl("about:blank");
}
});
binding.webView.setWebChromeClient(new WebChromeClient() {
public boolean onShowFileChooser(
WebView webView, ValueCallback<Uri[]> filePathCallback,
WebChromeClient.FileChooserParams fileChooserParams) {
if (mFilePathCallback != null) {
mFilePathCallback.onReceiveValue(null);
}
mFilePathCallback = filePathCallback;
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
} catch (IOException ex) {
// Error occurred while creating the File
Log.e("TAG", "Unable to create Image File", ex);
}
// Continue only if the File was successfully created
if (photoFile != null) {
mCameraPhotoPath = "file:" + photoFile.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
} else {
takePictureIntent = null;
}
}
Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
contentSelectionIntent.setType("image/*");
Intent[] intentArray;
if (takePictureIntent != null) {
intentArray = new Intent[]{takePictureIntent};
} else {
intentArray = new Intent[0];
}
Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivityForResult(chooserIntent, INPUT_FILE_REQUEST_CODE);
return true;
}
});
binding.webView.loadUrl("your_url");
}
/**
* More info this method can be found at
* http://developer.android.com/training/camera/photobasics.html
*
* @return
* @throws IOException
*/
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
return File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode != INPUT_FILE_REQUEST_CODE || mFilePathCallback == null) {
super.onActivityResult(requestCode, resultCode, data);
return;
}
Uri[] results = null;
// Check that the response is a good one
if (resultCode == Activity.RESULT_OK) {
if (data == null) {
// If there is not data, then we may have taken a photo
if (mCameraPhotoPath != null) {
results = new Uri[]{Uri.parse(mCameraPhotoPath)};
}
} else {
String dataString = data.getDataString();
if (dataString != null) {
results = new Uri[]{Uri.parse(dataString)};
}
}
}
mFilePathCallback.onReceiveValue(results);
mFilePathCallback = null;
}
@Override
public void onBackPressed() {
// TODO Auto-generated method stub
if (binding.webView.canGoBack()) {
binding.webView.goBack();
} else {
super.onBackPressed();
}
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
finish();
return super.onOptionsItemSelected(item);
}
}
希望对其他人有帮助。
谢谢。