Android Studio / SDK 30 I need to upload into a input file in webview.
There is TONS of 6,7 to 8 years ago answers that don't work anymore :(
I have a working webview that can use .getUserMedia (webrtc), can use GPS, but is unable to upload in a regular <input type="file" >
This code does ask (when start the app) permissions for camera, storage, gps...
I want to trigger a prompt that ask the user take photo, take video or choose from gallery and that actually uploads it.
here my Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.apptheway.wexview">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_GPS" />
<uses-permission android:name="android.permission.ACCESS_ASSISTED_GPS" />
<uses-permission android:name="android.permission.ACCESS_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="28" />
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" android:maxSdkVersion="28" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.CAMERA2" />
<uses-permission android:name="android.webkit.PermissionRequest" />
<uses-permission android:name="com.android.vending.BILLING" />
<uses-permission android:name="com.android.vending.CHECK_LICENSE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera2" />
<uses-feature android:name="android.hardware.location.gps" />
<uses-feature android:name="android.hardware.location.network" />
<application
android:allowBackup="true"
android:fullBackupContent="true"
android:hardwareAccelerated="true"
android:requestLegacyExternalStorage="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.AppCompat.NoActionBar">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Here MainActivity
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Window;
import android.webkit.GeolocationPermissions;
import android.webkit.PermissionRequest;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceRequest;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import java.util.Random;
@SuppressLint("SetJavaScriptEnabled")
public class MainActivity extends AppCompatActivity {
private WebView mWebView;
private ValueCallback<Uri> mUploadMessage;
private final static int FILECHOOSER_RESULTCODE = 1;
@Override
protected void onStart() {
super.onStart();
String[] permissions = {
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.CAMERA,
Manifest.permission.RECORD_AUDIO,
Manifest.permission.MODIFY_AUDIO_SETTINGS,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
requestPermissions(permissions, 0);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
for (int i = 0; i < permissions.length; i++) {
String permission = permissions[i];
boolean isGranted = grantResults[i] >= 0;
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().requestFeature(Window.FEATURE_NO_TITLE);
mWebView = new WebView(this);
WebSettings webSettings = mWebView.getSettings();
webSettings.setLoadWithOverviewMode(true);
webSettings.setUseWideViewPort(true);
webSettings.setDomStorageEnabled(true);
webSettings.setGeolocationEnabled(true);
webSettings.setBuiltInZoomControls(true);
webSettings.setDisplayZoomControls(false);
webSettings.setSupportZoom(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
webSettings.setJavaScriptEnabled(true);
webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
webSettings.setAllowFileAccess(true);
webSettings.setAllowContentAccess(true);
webSettings.setDatabaseEnabled(true);
webSettings.setMediaPlaybackRequiresUserGesture(false);
webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
mWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
String url = request.getUrl().toString();
int opensInWexView = 1;
// DOMAINS
// if ( !url.contains("stubfee.com") && !url.contains("stubfee.com") && !url.contains("stubfeedevent.com") ) {
// opensInWexView = 0;
// }
// IF FILE
if ( url.contains(".pdf") || url.contains(".mov") || url.contains(".mp") ||
url.contains(".hv") || url.contains(".aif") || url.contains(".wav") ||
url.contains(".xls") || url.contains(".doc") || url.contains(".txt")
) {
opensInWexView = 0;
}
// URL SCHEME
if ( url.startsWith("tel:") || url.startsWith("sms:") ||
url.startsWith("mms:") || url.startsWith("mailto:") ||
url.startsWith("fax:")
) {
opensInWexView = 0;
}
switch (opensInWexView) {
case 0:
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
break;
default:
view.loadUrl(url);
break;
}
return true;
}
});
mWebView.setWebChromeClient(new WebChromeClient() {
// CAMERA
public void onPermissionRequest(final PermissionRequest request) {
request.grant(request.getResources());
}
// GPS
public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
callback.invoke(origin, true, false);
}
// FILE INPUT
});
mWebView.loadUrl("https://www.stubfee.com/account/" + (new Random().nextInt((1000000 - 1) + 1) + 1) + "/");
this.setContentView(mWebView);
}
@Override
public boolean onKeyDown(final int keyCode, final KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
mWebView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
}
In many answers they talk about adding code inside
mWebView.setWebChromeClient(new WebChromeClient() {}
But any answer from the web I try; it does work :(
in one of the answers, I get the gallery to open, but when select a file, nothing happens :(
is there a more recent approach ?
what I'm I missing ?
Tried those without success
Upload an Image from camera or gallery in WebView
Android Webview Upload Image from gallery or camera
Saving photos and videos using Android FileProvider to the gallery
File Upload in WebView Android Studio
How to Upload Files with WebView in Android Studio?
How to make upload button work in android app?
Thanks