I am opening the camera and file chooser in my application. It's working fine in all versions including android 11. But in google pixel 5 with android 11, it's breaking while trying to open the camera. App not breaking but camera keep closing alert is showing and below exception is happening.
java.lang.IllegalStateException: GCA not granted write permission to file:///storage/emulated/0/Pictures/JPEG_20210727_095347_634440296695227002.jpg
Java code :
/***Camera or file chooser ***/
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
if ( Build.VERSION.SDK_INT <= 29) {
file_path = filePathCallback;
Intent takePictureIntent = null;
boolean includePhoto = true;
if (includePhoto)
{
takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null)
{
File photoFile = null;
try {
photoFile = create_image();
takePictureIntent.putExtra("PhotoPath", cam_file_data);
} catch (IOException ex) {
Log.e(TAG, "Image file creation failed", ex);
}
if (photoFile != null) {
cam_file_data = "file:" + photoFile.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
} else {
cam_file_data = null;
takePictureIntent = null;
}
}
}
Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
contentSelectionIntent.setType(file_type);
if (multiple_files) {
contentSelectionIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
}
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, "File chooser");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivityForResult(chooserIntent, file_req_code);
return true;
} else if ( Build.VERSION.SDK_INT >= 30) {
if (mFilePathCallback != null) {
mFilePathCallback.onReceiveValue(null);
}
mFilePathCallback = filePathCallback;
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile();
takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
} catch (IOException ex) {
}
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;
} else {
return false;
}
}
private File create_image() throws IOException {
#SuppressLint("SimpleDateFormat")
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "img_" + timeStamp + "_";
File storageDir = getApplicationContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES); //getCacheDir();
return File.createTempFile(imageFileName, ".jpg", storageDir);
}
Call back
/*******Camera Request Callback******/
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
if (requestCode != INPUT_FILE_REQUEST_CODE || mFilePathCallback == null)
{
super.onActivityResult(requestCode, resultCode, intent);
return;
}
Uri[] results = null;
if (resultCode == Activity.RESULT_OK) {
if (intent == null) {
if (mCameraPhotoPath != null) {
results = new Uri[]{Uri.parse(mCameraPhotoPath)};
}
} else {
String dataString = intent.getDataString();
if (dataString != null)
{
results = new Uri[]{Uri.parse(dataString)};
}
}
}
mFilePathCallback.onReceiveValue(results);
mFilePathCallback = null;
} else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q) {
Uri[] results = null;
if (resultCode == Activity.RESULT_CANCELED) {
if (requestCode == file_req_code) {
file_path.onReceiveValue(null);
return;
}
}
if (resultCode == Activity.RESULT_OK) {
if (requestCode == file_req_code) {
if (null == file_path) {
return;
}
ClipData clipData;
String stringData;
try {
clipData = intent.getClipData();
stringData = intent.getDataString();
} catch (Exception e) {
clipData = null;
stringData = null;
}
if (clipData == null && stringData == null && cam_file_data != null) {
results = new Uri[]{
Uri.parse(cam_file_data)
};
} else {
if (clipData != null) {
final int numSelectedFiles = clipData.getItemCount();
results = new Uri[numSelectedFiles];
for (int i = 0; i < clipData.getItemCount(); i++) {
results[i] = clipData.getItemAt(i).getUri();
}
} else {
results = new Uri[]{
Uri.parse(stringData)
};
}
}
}
}
file_path.onReceiveValue(results);
file_path = null;
} else {
if (requestCode == file_req_code) {
if (null == file_data)
return;
Uri result = intent == null || resultCode != Activity.RESULT_OK ? null : intent.getData();
file_data.onReceiveValue(result);
file_data = null;
}
}
}
Android manifest file :
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.CAMERA2" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29"
/>
Related
I have a WebView app that allows users to select and upload a file using an <input type="file">.
However, when I close the file selection dialog (either by selecting a file, or cancelling), my WebView app resets: it refreshes to the homepage.
#SuppressLint("InlinedApi")
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
if (Config.requireStorage && Config.requireCamera) {
String[] perms = {Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.CAMERA};
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, perms, FCR);
} else if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, FCR);
} else if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, FCR);
} else if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.RECORD_AUDIO)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.RECORD_AUDIO}, FCR);
}
if (mUMA != null) {
mUMA.onReceiveValue(null);
}
mUMA = filePathCallback;
if (Arrays.asList(fileChooserParams.getAcceptTypes()).contains("audio/*")) {
Intent chooserIntent = fileChooserParams.createIntent();
startActivityForResult(chooserIntent, CODE_AUDIO_CHOOSER);
return true;
}
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(MainActivity.this.getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile();
takePictureIntent.putExtra("PhotoPath", mCM);
} catch (IOException ex) {
Log.e(TAG, "Image file creation failed", ex);
}
if (photoFile != null) {
mCM = "file:" + photoFile.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
FileProvider.getUriForFile(MainActivity.this, getPackageName() + ".provider", photoFile));
} else {
takePictureIntent = null;
}
}
Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
if (takeVideoIntent.resolveActivity(MainActivity.this.getPackageManager()) != null) {
File videoFile = null;
try {
videoFile = createVideoFile();
takeVideoIntent.putExtra("PhotoPath", mVM);
} catch (IOException ex) {
Log.e(TAG, "Video file creation failed", ex);
}
if (videoFile != null) {
mVM = "file:" + videoFile.getAbsolutePath();
takeVideoIntent.putExtra(MediaStore.EXTRA_OUTPUT,
FileProvider.getUriForFile(MainActivity.this, getPackageName() + ".provider", videoFile));
} else {
takeVideoIntent = null;
}
}
Intent contentSelectionIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
contentSelectionIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
contentSelectionIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/* video/*");
contentSelectionIntent.putExtra(Intent.EXTRA_MIME_TYPES, new String[]{"image/*", "video/*"});
Intent[] intentArray;
if (takePictureIntent != null && takeVideoIntent != null) {
intentArray = new Intent[]{takePictureIntent, takeVideoIntent};
} else if (takePictureIntent != null) {
intentArray = new Intent[]{takePictureIntent};
} else if (takeVideoIntent != null) {
intentArray = new Intent[]{takeVideoIntent};
} else {
intentArray = new Intent[0];
}
Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
chooserIntent.putExtra(Intent.EXTRA_TITLE, "Upload");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivityForResult(chooserIntent, FCR);
}
return true;
}
Does anyone know how I can just make the <input type="file"> work, so that it holds the file and when I submit the form I can handle this file?
I developed website and converted it into Android app using WebView. Saw few implementation and tried FILE upload, where I can upload image from gallery but I am not allowed to upload image which is taken from Camera. I was thrown net::ERR_ACCESS_DENIED error. Please help me to get this fixed.
MAINACTIVITY.java
public class MainActivity extends AppCompatActivity {
private WebView web;
String webUrl = "https://mywebsite.com/";
public Context context;
private static final String TAG = MainActivity.class.getSimpleName();
private static final int FILECHOOSER_RESULTCODE = 1;
private ValueCallback<uri> mUploadMessage;
private Uri mCapturedImageURI = null;
private ValueCallback<Uri[]> mFilePathCallback;
private String mCameraPhotoPath;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
web = (WebView) findViewById(R.id.myweb);
web.loadUrl(webUrl);
WebSettings mywebsettings = web.getSettings();
mywebsettings.setJavaScriptEnabled(true);
web.setWebViewClient(new WebViewClient());
web.getSettings().setLoadsImagesAutomatically(true);
web.getSettings().setRenderPriority(WebSettings.RenderPriority.HIGH);
web.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
web.getSettings().setAppCacheEnabled(true);
web.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
mywebsettings.setDomStorageEnabled(true);
mywebsettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
mywebsettings.setUseWideViewPort(true);
mywebsettings.setSavePassword(true);
mywebsettings.setSaveFormData(true);
mywebsettings.setEnableSmoothTransition(true);
web.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) {
File photoFile = null;
try {
photoFile = createImageFile();
takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
} catch (IOException ex) {
Log.e(TAG, "Unable to create Image File", ex);
}
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, getString(R.string.image_chooser));
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);
return true;
}
private File createImageFile() throws IOException {
File imageStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "DirectoryNameHere");
if (!imageStorageDir.exists()) {
imageStorageDir.mkdirs();
}
imageStorageDir = new File(imageStorageDir + File.separator + "IMG_" + String.valueOf(System.currentTimeMillis()) + ".jpg");
return imageStorageDir;
}
public void openFileChooser(ValueCallback<uri> uploadMsg, String acceptType) {
mUploadMessage = uploadMsg;
try {
File imageStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "DirectoryNameHere");
if (!imageStorageDir.exists()) {
imageStorageDir.mkdirs();
}
File file = new File(imageStorageDir + File.separator + "IMG_" + String.valueOf(System.currentTimeMillis()) + ".jpg");
mCapturedImageURI = Uri.fromFile(file); // save to the private variable
final Intent captureIntent = new Intent(android.provider.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, getString(R.string.image_chooser));
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Parcelable[]{captureIntent});
startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);
} catch (Exception e) {
Toast.makeText(getBaseContext(), "Camera Exception:" + e, Toast.LENGTH_LONG).show();
}
}
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
openFileChooser(uploadMsg, "");
}
public void openFileChooser(ValueCallback<uri> uploadMsg, String acceptType, String capture) {
openFileChooser(uploadMsg, acceptType);
}
});
}
verride
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
if (requestCode == FILECHOOSER_RESULTCODE) {
if (null == this.mUploadMessage) {
return;
}
Uri result = null;
try {
if (resultCode != RESULT_OK) {
result = null;
} else {
// retrieve from the private variable if the intent is null
result = data == null ? mCapturedImageURI : data.getData();
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "activity :" + e, Toast.LENGTH_LONG).show();
}
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (requestCode != FILECHOOSER_RESULTCODE || mFilePathCallback == null) {
super.onActivityResult(requestCode, resultCode, data);
return;
}
Uri[] results = null;
if (resultCode == Activity.RESULT_OK) {
if (data == null || data.getData() == 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() {
if(web.canGoBack()){
web.goBack();
}
else {
super.onBackPressed();
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<WebView
android:id="#+id/web"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
using following app permissions:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.CAMERA2"/>
strings.xml
<string name="image_chooser">File Chooser</string>
I wrote a hybrid app and I want to use file upload HTML (file and camera) page. I use the below code and it works well.
When the user clicks on FileUploader input, the native window opens (to choose between File or Camera) and everything works just fine.
My only problem is that, when user click out of the window, this one will be closed and after no more opened, maybe something to reinitialise or restart.
If someone has some ideas...
On MainActivity:
var chrome = new SmarterWebChromeClient((uploadMsg) =>
{
mUploadMessage = uploadMsg;
mCameraPhotoPath = null;
Intent takePictureIntent = new Intent(Android.Provider.MediaStore.ActionImageCapture);
//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
writeEx(ex.ToString());
}
// Continue only if the File was successfully created
if (photoFile != null)
{
mCameraPhotoPath = "file:" + photoFile.AbsolutePath;
takePictureIntent.PutExtra(Android.Provider.MediaStore.ExtraOutput,
Android.Net.Uri.FromFile(photoFile));
}
else
{
takePictureIntent = null;
}
Intent contentSelectionIntent = new Intent(Intent.ActionGetContent);
contentSelectionIntent.AddCategory(Intent.CategoryOpenable);
contentSelectionIntent.SetType("image/*");
Intent[] intentArray;
if (takePictureIntent != null)
{
intentArray = new Intent[] { takePictureIntent };
}
else
{
intentArray = new Intent[0];
}
Intent chooserIntent = new Intent(Intent.ActionChooser);
chooserIntent.PutExtra(Intent.ExtraIntent, contentSelectionIntent);
chooserIntent.PutExtra(Intent.ExtraTitle, "Choisir une photo");
chooserIntent.PutExtra(Intent.ExtraInitialIntents, intentArray);
StartActivityForResult(chooserIntent, MainActivity.FILECHOOSER_RESULTCODE);
});
mWebView.SetWebViewClient(new MyWebViewClient());
mWebView.SetWebChromeClient(chrome);
...
protected override void OnActivityResult(int requestCode, Result resultCode, Intent intent)
{
if (requestCode == FILECHOOSER_RESULTCODE)
{
if (null == mUploadMessage)
return;
// Check that the response is a good one
if (resultCode == Result.Ok)
{
Android.Net.Uri[] results = null;
if (intent == null)
{
// If there is not data, then we may have taken a photo
if (mCameraPhotoPath != null)
{
results = new Android.Net.Uri[] { Android.Net.Uri.Parse(mCameraPhotoPath) };
}
else
{
}
}
else
{
if (intent.DataString != null)
{
results = new Android.Net.Uri[] { Android.Net.Uri.Parse(intent.DataString) };
}
}
mUploadMessage.OnReceiveValue(results);
mUploadMessage = null;
}
}
}
And my WebChromeClient Class :
partial class SmarterWebChromeClient : WebChromeClient
{
Action<IValueCallback> callback;
public SmarterWebChromeClient(Action<IValueCallback> callback)
{
this.callback = callback;
}
public override bool OnShowFileChooser(WebView webView, IValueCallback filePathCallback, FileChooserParams fileChooserParams)
{
callback(filePathCallback);
return true;
}
}
I solve your problem like below code
Put an else part for result NOT OK
// Check that the response is a good one
if (resultCode == Result.Ok)
{
//...
}
else
{
mUploadMessage.OnReceiveValue(null);
mUploadMessage = null;
}
I am working on android webview. I am facing problem while uploading the image from Camera action in Nexus 5. Here, Camera get open, I click the image but then nothing happens,image is not get upload. But it works fine with like Document or Gallery. There are a lot solution and this. But I am unable to solve my problem. What can be done to solve this issue?
In my menifest file, I include :
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
In my activity, i include :
private static final int INPUT_FILE_REQUEST_CODE = 1;
private static final int FILECHOOSER_RESULTCODE = 1;
private static final String TAG = MainActivity.class.getSimpleName();
private WebView webView;
private ValueCallback<Uri> mUploadMessage;
private Uri mCapturedImageURI = null;
private ValueCallback<Uri[]> mFilePathCallback;
private String mCameraPhotoPath;
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
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;
} else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
if (requestCode != FILECHOOSER_RESULTCODE || mUploadMessage == null) {
super.onActivityResult(requestCode, resultCode, data);
return;
}
if (requestCode == FILECHOOSER_RESULTCODE) {
if (null == this.mUploadMessage) {
return;
}
Uri result = null;
try {
if (resultCode != RESULT_OK) {
result = null;
} else {
// retrieve from the private variable if the intent is null
result = data == null ? mCapturedImageURI : data.getData();
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "activity :" + e,
Toast.LENGTH_LONG).show();
}
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
}
}
return;
}
For my WebChromeClient, I include :
public class MyWebChromeClient extends WebChromeClient{
// For Android 5.0
public boolean onShowFileChooser(WebView view, ValueCallback<Uri[]> filePath, WebChromeClient.FileChooserParams fileChooserParams) {
// Double check that we don't have any existing callbacks
if (mFilePathCallback != null) {
mFilePathCallback.onReceiveValue(null);
}
mFilePathCallback = filePath;
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;
}
// openFileChooser for Android 3.0+
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
mUploadMessage = uploadMsg;
// Create AndroidExampleFolder at sdcard
// Create AndroidExampleFolder at sdcard
File imageStorageDir = new File(
Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES)
, "Photo Folder");
if (!imageStorageDir.exists()) {
// Create AndroidExampleFolder at sdcard
imageStorageDir.mkdirs();
}
// Create camera captured image file path and name
File file = new File(
imageStorageDir + File.separator + "IMG_"
+ String.valueOf(System.currentTimeMillis())
+ ".jpg");
Log.d("File", "File: " + file);
mCapturedImageURI = Uri.fromFile(file);
// Camera capture image intent
final Intent captureIntent = new Intent(
android.provider.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/*");
// Create file chooser intent
Intent chooserIntent = Intent.createChooser(i, "Image Chooser");
// Set camera intent to file chooser
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS
, new Parcelable[] { captureIntent });
// On select image call onActivityResult method of activity
startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);
}
// 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);
}
}
What can be done here, so that image get uploaded via Camera action ?
I solve my issue for Camera by changing following line of code in onActivityResult method :
if (resultCode == Activity.RESULT_OK) {
if (data == null || data.getDataString() == 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)};
}
}
}
I add this : if (data == null || data.getDataString() == null) {...}
Add android:requestLegacyExternalStorage="true" to the application tag in manifest
I had "upload file success" with WebView which loaded the html5 page. But I have a problem in the code. My code as follows:
mWebView = (WebView) findViewById(R.id.wv_card);
WebSettings webSettings = mWebView.getSettings();
webSettings.setAllowFileAccess(true); // 设置允许访问文件数据
webSettings.setJavaScriptEnabled(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
webSettings.setSupportZoom(false);
webSettings.setUseWideViewPort(true);
webSettings.setLoadWithOverviewMode(true);
mWebView.setWebChromeClient(new XHSWebChromeClient());
/**
* 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.CHINESE).format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
String sdcard = Environment.getExternalStorageDirectory().toString();
File storageDir = new File(sdcard + "/WeiJuMei/Download");
return File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Uri uri = null;
try {
if (requestCode == FILE_CHOOSER_RESULT_CODE) {
if (null == mUploadMessage) return;
Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();
if (result == null) {
mUploadMessage.onReceiveValue(null);
mUploadMessage = null;
return;
}
Log.i(TAG, "onActivityResult" + result.toString());
String path = FileUtils.getPath(this, result);
if (TextUtils.isEmpty(path)) {
mUploadMessage.onReceiveValue(null);
mUploadMessage = null;
return;
}
uri = Uri.fromFile(new File(path));
Log.i(TAG, "onActivityResult after parser uri:" + uri.toString());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// mUploadMessage.onReceiveValue(new Uri[]{uri});
if (/*requestCode != INPUT_FILE_REQUEST_CODE ||*/ mUploadMessage == 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)};
}
}
}
mUploadMessage.onReceiveValue(results);
// mUploadMessage = null;
// return;
} else {
mUploadMessage.onReceiveValue(uri);
}
mUploadMessage = null;
}
} catch (Exception e) {
try {
mUploadMessage.onReceiveValue(uri);
mUploadMessage = null;
} catch (Exception e1) {
mUploadMessage.onReceiveValue(null);
mUploadMessage = null;
return;
}
}
}
public class XHSWebChromeClient extends WebChromeClient {
#Override
public void onProgressChanged(WebView webView, int newProgress) {
progressBar.setProgress(newProgress);
if (newProgress == 100) {
progressBar.setVisibility(View.GONE);
}
super.onProgressChanged(webView, newProgress);
}
#Override
public boolean onJsAlert(WebView webView, String s, String s1, JsResult jsResult) {
return super.onJsAlert(webView, s, s1, jsResult);
}
// For Android 3.0+
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
Log.i(TAG, "in openFile Uri Callback");
if (mUploadMessage != null) {
mUploadMessage.onReceiveValue(null);
}
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("*/*");
startActivityForResult(Intent.createChooser(i, "File Chooser"), FILE_CHOOSER_RESULT_CODE);
}
// For Android 3.0+
public void openFileChooser(ValueCallback uploadMsg, String acceptType) {
Log.i(TAG, "in openFile Uri Callback has accept Type" + acceptType);
if (mUploadMessage != null) {
mUploadMessage.onReceiveValue(null);
}
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
String type = TextUtils.isEmpty(acceptType) ? "*/*" : acceptType;
i.setType(type);
startActivityForResult(Intent.createChooser(i, "File Chooser"),
FILE_CHOOSER_RESULT_CODE);
}
// For Android 4.1
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
Log.i(TAG, "in openFile Uri Callback has accept Type" + acceptType + "has capture" + capture);
if (mUploadMessage != null) {
mUploadMessage.onReceiveValue(null);
}
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
String type = TextUtils.isEmpty(acceptType) ? "*/*" : acceptType;
i.setType(type);
startActivityForResult(Intent.createChooser(i, "File Chooser"), FILE_CHOOSER_RESULT_CODE);
}
// Android 5.0+
#Override
#SuppressLint("NewApi")
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, android.webkit.WebChromeClient.FileChooserParams fileChooserParams) {
if (mUploadMessage != null) {
mUploadMessage.onReceiveValue(null);
}
mUploadMessage = 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.i(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;
}
}
When choosing native image with Chinese path I found upload image was failing, but english path is successful, Why does this happen and how can I solve this problem?