Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(android): update WebView to support <a download> and camera/gallery picker for input fields #14167

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,23 @@
*/
package ti.modules.titanium.ui.widget.webview;

import android.app.DownloadManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.FeatureInfo;
import android.graphics.Color;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Environment;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewParent;
import android.webkit.CookieManager;
import android.webkit.DownloadListener;
import android.webkit.URLUtil;
import android.webkit.WebSettings;
import android.webkit.WebView;
import androidx.annotation.RequiresApi;
Expand All @@ -28,6 +33,7 @@
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
Expand Down Expand Up @@ -378,6 +384,39 @@ public TiUIWebView(TiViewProxy proxy)
params.height = TiCompositeLayout.LayoutParams.MATCH_PARENT;
params.width = TiCompositeLayout.LayoutParams.MATCH_PARENT;

/*
enable file download from <a href download> tag
it starts download automatically in the background and
shows a notification
*/
webView.setDownloadListener(new DownloadListener() {
@Override
public void onDownloadStart(String url, String userAgent,
String contentDisposition,
String mimeType, long contentLength)
{
String guessedMimeType = URLConnection.guessContentTypeFromName(url);
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setMimeType(guessedMimeType);
String cookies = CookieManager.getInstance().getCookie(url);
request.addRequestHeader("cookie", cookies);
request.addRequestHeader("User-Agent", userAgent);
request.setDescription("Downloading...");
request.setTitle(URLUtil.guessFileName(url, contentDisposition, guessedMimeType));
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, URLUtil.guessFileName(url,
contentDisposition, guessedMimeType));
Context context = TiApplication.getInstance().getApplicationContext();
DownloadManager dm = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
dm.enqueue(request);
KrollDict kd = new KrollDict();
kd.put("status", "started");
kd.put("url", url);
kd.put("target", Environment.DIRECTORY_DOWNLOADS);
fireEvent("download", kd);
}
});

setNativeView(webView);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -623,17 +623,14 @@ private Intent createFileChooserIntentFrom(WebChromeClient.FileChooserParams cho
}

// If capturing a photo/video, create a file for it in the gallery and get a "content://" URI to it.
switch (actionName) {
case MediaStore.ACTION_IMAGE_CAPTURE:
mCaptureFileUri = MediaModule.createExternalPictureContentUri(true);
break;
case MediaStore.ACTION_VIDEO_CAPTURE:
mCaptureFileUri = MediaModule.createExternalVideoContentUri(true);
break;
default:
mCaptureFileUri = null;
break;
if (hasImageMimeType) {
mCaptureFileUri = MediaModule.createExternalPictureContentUri(true);
} else if (hasVideoMimeType) {
mCaptureFileUri = MediaModule.createExternalVideoContentUri(true);
} else {
mCaptureFileUri = null;
}

if (mCaptureFileUri != null) {
intent.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setClipData(ClipData.newRawUri("", mCaptureFileUri));
Expand All @@ -646,10 +643,17 @@ private Intent createFileChooserIntentFrom(WebChromeClient.FileChooserParams cho
}

// If multiple apps can handle the intent, then let the end-user choose which one to use.
intent = Intent.createChooser(intent, chooserParams.getTitle());

Intent chooser = new Intent(Intent.ACTION_CHOOSER);
chooser.putExtra(Intent.EXTRA_INTENT, intent);
chooser.putExtra(Intent.EXTRA_TITLE, chooserParams.getTitle());

Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
Intent[] intentArray = { cameraIntent };
chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);

// Return the final intent for file selection or image/video capturing.
return intent;
return chooser;
}

/**
Expand Down
Loading