I am new to Android application development. Been struggling since a month, and have worked on this issue since 2 weeks by now. I have done extensive research on Android WebViews across different versions. Checked most other posts related to my issue,
- someone's wordpress blog-posts related to webview
- stackoverflow: #SO1, #SO2, #SO3, #SO4, #SO5, #SO6, #SO7
- google android issue
- some more: #SO8, #SO9, #SO10
i need someone to help me with how to handle Android version 4.4 (KITKAT) to allow users to upload files via HTML forms inside of WebView.
I cannot use CrossWalk and don't want to use any of the github code made by others. i want to fix the methods that i can override for each API Level. Also, there is no chance of adding Javascript in Server side pages.
The onCreate method of my WebViewActivity contains the following code:
webView.setWebChromeClient(new WebChromeClient() {
@Override
public void onCloseWindow(WebView w) {
super.onCloseWindow(w);
finish();
}
@Override
public boolean onCreateWindow(WebView view, boolean dialog, boolean userGesture, Message resultMsg) {
WebView childView = new WebView(WebViewActivity.this);
final WebSettings settings = childView.getSettings();
settings.setDomStorageEnabled(true);
settings.setJavaScriptEnabled(true);
settings.setAllowFileAccess(true);
settings.setAllowContentAccess(true);
childView.setWebChromeClient(this);
WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
transport.setWebView(childView);
resultMsg.sendToTarget();
return false;
}
// For Android Version < 3.0
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
//System.out.println("WebViewActivity OS Version : " + Build.VERSION.SDK_INT + "\t openFC(VCU), n=1");
mUploadMessage = uploadMsg;
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType(TYPE_IMAGE);
startActivityForResult(intent, INPUT_FILE_REQUEST_CODE);
}
// For 3.0 <= Android Version < 4.1
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
//System.out.println("WebViewActivity 3<A<4.1, OS Version : " + Build.VERSION.SDK_INT + "\t openFC(VCU,aT), n=2");
openFileChooser(uploadMsg, acceptType, "");
}
// For 4.1 <= Android Version < 5.0
public void openFileChooser(ValueCallback<Uri> uploadFile, String acceptType, String capture) {
//System.out.println("WebViewActivity 4.1<A<5, OS Version : " + Build.VERSION.SDK_INT + "\t openFC(VCU,aT,c), n=3");
mUploadMessage = uploadFile;
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType(TYPE_IMAGE);
startActivityForResult(intent, INPUT_FILE_REQUEST_CODE);
}
From Here.
{
//For Android Version = 4.4.*
public void showFileChooser(ValueCallback<String[]> filePathCallback, String acceptType, boolean paramBoolean) {
//System.out.println("WebViewActivity 4.1<A<5, OS Version : " + Build.VERSION.SDK_INT + "\t showFC(VCS,aT,p), n=3");
//ToDo,not supported yet, need to find a way to convert ValueCallback<String[]> to ValuCallback<Uri[]>
}
//For Android Version = 4.4.*
public void showFileChooser(ValueCallback<String[]> uploadFileCallback, FileChooserParams fileChooserParams) {
//System.out.println("WebViewActivity 4.1<A<5, OS Version : " + Build.VERSION.SDK_INT + "\t showFC(VCS,FCP), n=2");
//ToDo,not supported yet, need to find a way to convert ValueCallback<String[]> to ValuCallback<Uri[]>
}
}
Till Here.
// For Android Version 5.0+
// Ref: https://github.com/GoogleChrome/chromium-webview-samples/blob/master/input-file-example/app/src/main/java/inputfilesample/android/chrome/google/com/inputfilesample/MainFragment.java
public boolean onShowFileChooser(WebView webView,
ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
System.out.println("WebViewActivity A>5, OS Version : " + Build.VERSION.SDK_INT + "\t onSFC(WV,VCUB,FCP), n=3");
if (mFilePathCallback != null) {
mFilePathCallback.onReceiveValue(null);
}
mFilePathCallback = filePathCallback;
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType(TYPE_IMAGE);
startActivityForResult(intent, INPUT_FILE_REQUEST_CODE);
return true;
}
});
The local variables have been initialized as follows:
private static final String TYPE_IMAGE = "image/*";
private static final int INPUT_FILE_REQUEST_CODE = 1;
private ValueCallback<Uri> mUploadMessage;
private ValueCallback<Uri[]> mFilePathCallback;
- I want someone to help me add code to the ToDo sections marked by comments and tags [noHTML like noSQL]
- I want help using TargetApi annotation correctly, and the SuppressLint one too. for the final block meant for Android OS Version 5.0.
- Additionally, am I missing any necessary Overrides?
One more thing, i would like to understand why this piece of code is needed, or whether it can be skipped, i did debug testing, my code doesn't work without it.
if (mFilePathCallback != null) { mFilePathCallback.onReceiveValue(null); }
The onActivityResult method is written like this:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == INPUT_FILE_REQUEST_CODE) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
if (mFilePathCallback == null) {
super.onActivityResult(requestCode, resultCode, data);
return;
}
Uri[] results = null;
if (resultCode == RESULT_OK) {
String dataString = data.getDataString();
if (dataString != null) {
results = new Uri[]{Uri.parse(dataString)};
}
}
mFilePathCallback.onReceiveValue(results);
mFilePathCallback = null;
} else {
if (mUploadMessage == null) {
super.onActivityResult(requestCode, resultCode, data);
return;
}
Uri result = null;
if (resultCode == RESULT_OK) {
if (data != null) {
result = data.getData();
}
}
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
}
} else {
super.onActivityResult(requestCode, resultCode, data);
}
For reference, this is my module build.gradle file (not project build.gradle file):
android {
//using 21 [Android 5.0], in order to use LOLLIPOP constant in code above
compileSdkVersion 21
//https://developer.android.com/tools/revisions/build-tools.html
buildToolsVersion "23.0.2"
defaultConfig {
applicationId "ab.cd.efghijklmo.pqrstuvwxyz"
//need to support Honeycomb [Android 3.0]
minSdkVersion 11
versionCode 16
versionName "1.0.15"
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-project.txt'
}
}
packagingOptions {
exclude 'META-INF/DEPENDENCIES.txt'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/LICENSE'
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/notice.txt'
exclude 'META-INF/license.txt'
exclude 'META-INF/dependencies.txt'
}
}