在 webview 中从相机上传图像不起作用
Posted
技术标签:
【中文标题】在 webview 中从相机上传图像不起作用【英文标题】:upload image from camera in webview does not work 【发布时间】:2018-08-08 18:02:59 【问题描述】:我一直在尝试通过来自画廊和相机的 webview 从 facebook 上传 Workplace 中的图像。
从图库中它可以正常工作,但从相机中,图像不会出现在上传中。
我已经看到类似this 和this 这样的问题的帖子,但我看不出有什么问题。
这是我的课:
public class WorkplaceActivity extends BaseActivity implements WorkplaceContract.View
private WorkplacePresenter workplacePresenter;
private Tracker trackerGA;
private MyApplicaton appGA;
private Toolbar toolbar;
private WebView ctWebView;
private ValueCallback<Uri[]> mUploadMessage;
private final static int FILECHOOSER_RESULTCODE = 1;
private Uri mCameraURI;
@Override
public void setupWorkplace()
WebViewClient webclient = new WebViewClient();
ctWebView = (WebView) findViewById(R.id.ctWebView);
ctWebView.getSettings().setAppCacheEnabled(true);
ctWebView.getSettings().setjavascriptEnabled(true);
ctWebView.getSettings().setLoadWithOverviewMode(true);
ctWebView.getSettings().setAllowFileAccess(true);
ctWebView.setWebViewClient(webclient);
ctWebView.loadUrl(ConstantsStrings.WORKPLACE_URL);
@Override
public void setupGA()
// Google Analytics
appGA = (MyApplicaton) getApplication();
trackerGA = appGA.getDefaultTracker();
sendGA(ConstantsStrings.WORKPLACE_GA_IN);
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_workplace);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
workplacePresenter = new WorkplacePresenter();
workplacePresenter.attachView(this);
workplacePresenter.checkPermissions(WorkplaceActivity.this);
ActionBar actionBar = this.getSupportActionBar();
if (actionBar != null)
actionBar.setDisplayHomeAsUpEnabled(false);
actionBar.setDisplayShowHomeEnabled(false);
actionBar.setHomeAsUpIndicator(R.drawable.ic_arrow_left);
actionBar.setTitle("");
// add back button
ImageButton back_button = (ImageButton) findViewById(R.id.back_button);
back_button.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
if (ctWebView.canGoBack())
ctWebView.goBack();
Log.d("WORKPLACE", "click back");
);
// add close button
ImageButton close_button = (ImageButton) findViewById(R.id.close_button);
close_button.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
finish();
Log.d("WORKPLACE", "click close");
);
setupGA();
setupWorkplace();
ctWebView.setWebChromeClient(new WebChromeClient()
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams)
WorkplaceActivity.this.openFileChooser(filePathCallback);
return true;
);
@Override
public void onBackPressed()
super.onBackPressed();
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent)
if (requestCode == FILECHOOSER_RESULTCODE)
if (mUploadMessage != null)
Uri[] temp = new Uri[1];
if (intent != null && intent.getData() != null)
temp[0] = intent.getData();
else if (mCameraURI != null)
temp[0] = mCameraURI;
mUploadMessage.onReceiveValue(temp);
mUploadMessage = null;
public static Intent newInstance(Context context)
return new Intent(context, WorkplaceActivity.class);
@Override
public void onAttachedToWindow()
super.onAttachedToWindow();
workplacePresenter.attachView(this);
@Override
public void onDetachedFromWindow()
super.onDetachedFromWindow();
workplacePresenter.detachView();
@Override
public void showLoading()
@Override
public void hideLoading()
@Override
public void sendGA(String msg)
// Google Analytics
trackerGA = appGA.getDefaultTracker();
trackerGA.setScreenName(msg);
trackerGA.send(new HitBuilders.ScreenViewBuilder().build());
private void openFileChooser(ValueCallback<Uri[]> uploadMsg)
mUploadMessage = uploadMsg;
try
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
ActivityCompat.requestPermissions(WorkplaceActivity.this, new String[]Manifest.permission.CAMERA, FILECHOOSER_RESULTCODE);
ActivityCompat.requestPermissions(WorkplaceActivity.this, new String[]Manifest.permission_group.STORAGE, 6);
ActivityCompat.requestPermissions(WorkplaceActivity.this, new String[]Manifest.permission.WRITE_EXTERNAL_STORAGE, 5);
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File cameraDir = new File(storageDir.getAbsolutePath() + File.separator + "browser-photos");
cameraDir.mkdirs();
String mCameraFilePath = cameraDir.getAbsolutePath() + File.separator + ".jpg";
mCameraURI = Uri.fromFile(new File(mCameraFilePath));
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mCameraURI);
Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
contentSelectionIntent.setType("image/*");
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, new Parcelable[]takePictureIntent);
startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);
catch (Exception e)
Toast.makeText(getBaseContext(), "Camera Exception:" + e, Toast.LENGTH_LONG);
当我尝试从相机上传图像时,我的手机会保存图像,但它不会出现在上传屏幕上。
【问题讨论】:
【参考方案1】:检查一下它对我有用。
public class MainActivity extends Activity
private WebView webView;
private ValueCallback<Uri> mUploadMessage;
private ValueCallback<Uri[]> mUploadMessages;
private Uri mCapturedImageURI = null;
private static final int MY_CAMERA_REQUEST_CODE = 100;
private static final int FILECHOOSER_RESULTCODE = 1;
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = findViewById(R.id.webView);
webView.setWebViewClient(new WebViewClient());
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setPluginState(WebSettings.PluginState.ON);
webView.getSettings().setAppCacheEnabled(false);
webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
webView.getSettings().setUseWideViewPort(true);
webView.getSettings().setLoadWithOverviewMode(true);
webView.getSettings().setBuiltInZoomControls(false);
webView.getSettings().setSupportZoom(false);
webView.getSettings().setDefaultZoom(WebSettings.ZoomDensity.FAR);
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setDatabaseEnabled(true);
webView.getSettings().setDatabasePath("/data/data/" + webView.getContext().getPackageName() + "/databases/");
webView.loadUrl("url");
webView.setWebChromeClient(new WebChromeClient()
// For api level bellow 24
public boolean shouldOverrideUrlLoading(WebView view, String url)
if (url.startsWith("http"))
// Return false means, web view will handle the link
return false;
return false;
// From api level 24
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request)
/*Toast.makeText(mcontext, "New Method",Toast.LENGTH_SHORT).show();*/
// Get the tel: url
String url = request.getUrl().toString();
if (url.startsWith("http"))
// Return false means, web view will handle the link
return false;
return false;
// openFileChooser for android 3.0+
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType)
mUploadMessage = uploadMsg;
openImageChooser();
// For Lollipop 5.0+ Devices
public boolean onShowFileChooser(WebView mWebView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams)
mUploadMessages = filePathCallback;
openImageChooser();
return true;
// openFileChooser for Android < 3.0
public void openFileChooser(ValueCallback<Uri> uploadMsg)
openFileChooser(uploadMsg, "");
//openFileChooser for other Android versions
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture)
openFileChooser(uploadMsg, acceptType);
);
private void openImageChooser()
try
File imageStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "FolderName");
if (!imageStorageDir.exists())
imageStorageDir.mkdirs();
File file = new File(imageStorageDir + File.separator + "IMG_" + String.valueOf(System.currentTimeMillis()) + ".jpg");
mCapturedImageURI = Uri.fromFile(file);
final Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedImageURI);
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
Intent chooserIntent = Intent.createChooser(i, "Image Chooser");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Parcelable[]captureIntent);
startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);
catch (Exception e)
e.printStackTrace();
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent)
super.onActivityResult(requestCode, resultCode, intent);
if (requestCode == FILECHOOSER_RESULTCODE)
if (null == this.mUploadMessage && null == this.mUploadMessages)
return;
/* Uri result;
if (requestCode != RESULT_OK)
result = null;
else
result = intent == null ? this.mCapturedImageURI : intent.getData();
this.mUploadMessage.onReceiveValue(result);
this.mUploadMessage = null;*/
if (null != mUploadMessage)
handleUploadMessage(requestCode, resultCode, intent);
else if (mUploadMessages != null)
handleUploadMessages(requestCode, resultCode, intent);
private void handleUploadMessage(int requestCode, int resultCode, Intent intent)
Uri result = null;
try
if (resultCode != RESULT_OK)
result = null;
else
// retrieve from the private variable if the intent is null
result = intent == null ? mCapturedImageURI : intent.getData();
catch (Exception e)
e.printStackTrace();
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void handleUploadMessages(int requestCode, int resultCode, Intent intent)
Uri[] results = null;
try
if (resultCode != RESULT_OK)
results = null;
else
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);
else
results = new Uri[]mCapturedImageURI;
catch (Exception e)
e.printStackTrace();
mUploadMessages.onReceiveValue(results);
mUploadMessages = null;
【讨论】:
不要忘记在清单中以及以编程方式添加存储和相机权限。以上是关于在 webview 中从相机上传图像不起作用的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Android 7.0 中从相机或图库中选择要裁剪的图像?