Issue
I am trying to create a webView for my web application in which i also can upload pictures using camera, i get the option to choose between camera or file manager and the file manager works perfect. With the camera option it opens the camera but when i then click on capture and send it does not return anything and does not load the img into the input field.
After doing some research i figured out that response.getData().getDataString() does not return anything when using the camera to capture a picture but does return something when using the file explorer to send a picture
Here is my MainActivity.java
package com.webview.android;
import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.webkit.PermissionRequest;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
import com.karan.churi.PermissionManager.PermissionManager;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MainActivity extends AppCompatActivity {
private WebView webView;
PermissionManager permissionManager;
private static final String TAG = MainActivity.class.getSimpleName();
private String mCM;
private ValueCallback<Uri> mUM;
private ValueCallback<Uri[]> mUMA;
private ActivityResultLauncher<Intent> imgFinished = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult response) {
if (Build.VERSION.SDK_INT >= 21) {
Uri[] results = null;
//Check if response is positive
if (response.getResultCode() == Activity.RESULT_OK) {
if (null == mUMA) {
return;
}
if (response.getData() == null) {
//Capture Photo if no image available
if (mCM != null) {
results = new Uri[]{Uri.parse(mCM)};
}
} else {
Log.e(TAG, "TEST5");
String dataString = response.getData().getDataString();
Log.e(TAG, String.valueOf(response.getData().getDataString()));
if (dataString != null) {
Log.e(TAG, "TEST6");
results = new Uri[]{Uri.parse(dataString)};
}
}
}
mUMA.onReceiveValue(results);
mUMA = null;
} else {
if (null == mUM) return;
Uri result = response == null || response.getResultCode() != RESULT_OK ? null : response.getData().getData();
mUM.onReceiveValue(result);
mUM = null;
}
}
}
);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = findViewById(R.id.webView);
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl("https://hbwfc-acc.9knots.nl/app");
WebSettings MyWebviewSettings = webView.getSettings();
MyWebviewSettings.setAllowFileAccessFromFileURLs(true);
MyWebviewSettings.setAllowUniversalAccessFromFileURLs(true);
MyWebviewSettings.setJavaScriptCanOpenWindowsAutomatically(true);
MyWebviewSettings.setJavaScriptEnabled(true);
MyWebviewSettings.setDomStorageEnabled(true);
MyWebviewSettings.setJavaScriptCanOpenWindowsAutomatically(true);
MyWebviewSettings.setBuiltInZoomControls(true);
MyWebviewSettings.setAllowFileAccess(true);
MyWebviewSettings.setSupportZoom(true);
MyWebviewSettings.setAllowContentAccess(true);
MyWebviewSettings.setMediaPlaybackRequiresUserGesture(false);
webView.setWebChromeClient(new WebChromeClient() {
@Override
public void onPermissionRequest(final PermissionRequest request) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
request.grant(request.getResources());
}
}
//For Android 3.0+
public void openFileChooser(ValueCallback<Uri> uploadMsg){
mUM = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("*/*");
imgFinished.launch(Intent.createChooser(i,"File Chooser"));
}
// For Android 3.0+, above method not supported in some android 3+ versions, in such case we use this
public void openFileChooser(ValueCallback uploadMsg, String acceptType){
mUM = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("*/*");
imgFinished.launch(Intent.createChooser(i, "File Browser"));
}
//For Android 4.1+
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture){
mUM = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("*/*");
imgFinished.launch(Intent.createChooser(i, "File Chooser"));
}
//For Android 5.0+
public boolean onShowFileChooser(
WebView webView, ValueCallback<Uri[]> filePathCallback,
WebChromeClient.FileChooserParams fileChooserParams){
if(mUMA != null){
mUMA.onReceiveValue(null);
}
mUMA = filePathCallback;
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, Uri.fromFile(photoFile));
}else{
takePictureIntent = null;
}
}
Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
contentSelectionIntent.setType("*/*");
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);
imgFinished.launch(chooserIntent);
return true;
}
});
webView.setWebViewClient(new WebViewClient());
webView.setWebContentsDebuggingEnabled(true);
permissionManager = new PermissionManager() {};
permissionManager.checkAndRequestPermissions(this);
}
public class Callback extends WebViewClient{
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl){
Toast.makeText(getApplicationContext(), "Failed loading app!", Toast.LENGTH_SHORT).show();
}
}
// Create an image file
private File createImageFile() throws IOException{
@SuppressLint("SimpleDateFormat") String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "img_"+timeStamp+"_";
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File tempFile = File.createTempFile(imageFileName,".jpg",storageDir);
return tempFile;
}
here is my manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.webview.android">
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO"/>
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO"/>
<queries>
<intent>
<action android:name="android.media.action.IMAGE_CAPTURE" />
</intent>
</queries>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true">
<activity android:name=".MainActivity"
android:exported="true"
android:theme="@style/Theme.AppCompat.DayNight">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
</application>
</manifest>
I expect it loads a img file into the input field
Solution
I solved the problem by replacing
Uri.fromfile(photoFile)
with
FileProvider.getUriForFile(MainActivity.this, BuildConfig.APPLICATION_ID, photoFile)
this creates a url tot he taken image in the same way as when you open a image from the file explorer
Answered By - Gerben Mol
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.