use of android.webkit.JavascriptInterface in project Bolts-Android by BoltsFramework.
the class WebViewAppLinkResolver method getAppLinkFromUrlInBackground.
@Override
public Task<AppLink> getAppLinkFromUrlInBackground(final Uri url) {
final Capture<String> content = new Capture<String>();
final Capture<String> contentType = new Capture<String>();
return Task.callInBackground(new Callable<Void>() {
@Override
public Void call() throws Exception {
URL currentURL = new URL(url.toString());
URLConnection connection = null;
while (currentURL != null) {
// Fetch the content at the given URL.
connection = currentURL.openConnection();
if (connection instanceof HttpURLConnection) {
// Unfortunately, this doesn't actually follow redirects if they go from http->https,
// so we have to do that manually.
((HttpURLConnection) connection).setInstanceFollowRedirects(true);
}
connection.setRequestProperty(PREFER_HEADER, META_TAG_PREFIX);
connection.connect();
if (connection instanceof HttpURLConnection) {
HttpURLConnection httpConnection = (HttpURLConnection) connection;
if (httpConnection.getResponseCode() >= 300 && httpConnection.getResponseCode() < 400) {
currentURL = new URL(httpConnection.getHeaderField("Location"));
httpConnection.disconnect();
} else {
currentURL = null;
}
} else {
currentURL = null;
}
}
try {
content.set(readFromConnection(connection));
contentType.set(connection.getContentType());
} finally {
if (connection instanceof HttpURLConnection) {
((HttpURLConnection) connection).disconnect();
}
}
return null;
}
}).onSuccessTask(new Continuation<Void, Task<JSONArray>>() {
@Override
public Task<JSONArray> then(Task<Void> task) throws Exception {
// Load the content in a WebView and use JavaScript to extract the meta tags.
final TaskCompletionSource<JSONArray> tcs = new TaskCompletionSource<>();
final WebView webView = new WebView(context);
webView.getSettings().setJavaScriptEnabled(true);
webView.setNetworkAvailable(false);
webView.setWebViewClient(new WebViewClient() {
private boolean loaded = false;
private void runJavaScript(WebView view) {
if (!loaded) {
// After the first resource has been loaded (which will be the pre-populated data)
// run the JavaScript meta tag extraction script
loaded = true;
view.loadUrl(TAG_EXTRACTION_JAVASCRIPT);
}
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
runJavaScript(view);
}
@Override
public void onLoadResource(WebView view, String url) {
super.onLoadResource(view, url);
runJavaScript(view);
}
});
// Inject an object that will receive the JSON for the extracted JavaScript tags
webView.addJavascriptInterface(new Object() {
@JavascriptInterface
public void setValue(String value) {
try {
tcs.trySetResult(new JSONArray(value));
} catch (JSONException e) {
tcs.trySetError(e);
}
}
}, "boltsWebViewAppLinkResolverResult");
String inferredContentType = null;
if (contentType.get() != null) {
inferredContentType = contentType.get().split(";")[0];
}
webView.loadDataWithBaseURL(url.toString(), content.get(), inferredContentType, null, null);
return tcs.getTask();
}
}, Task.UI_THREAD_EXECUTOR).onSuccess(new Continuation<JSONArray, AppLink>() {
@Override
public AppLink then(Task<JSONArray> task) throws Exception {
Map<String, Object> alData = parseAlData(task.getResult());
AppLink appLink = makeAppLinkFromAlData(alData, url);
return appLink;
}
});
}
use of android.webkit.JavascriptInterface in project WordPress-Android by wordpress-mobile.
the class JsCallbackReceiver method executeCallback.
@JavascriptInterface
public void executeCallback(String callbackId, String params) {
switch(callbackId) {
case CALLBACK_DOM_LOADED:
mListener.onDomLoaded();
break;
case CALLBACK_SELECTION_STYLE:
// Compare the new styles to the previous ones, and notify the JsCallbackListener of the changeset
Set<String> rawStyleSet = Utils.splitDelimitedString(params, JS_CALLBACK_DELIMITER);
// Strip link details from active style set
Set<String> newStyleSet = new HashSet<>();
for (String element : rawStyleSet) {
if (element.matches("link:(.*)")) {
newStyleSet.add("link");
} else if (!element.matches("link-title:(.*)")) {
newStyleSet.add(element);
}
}
mListener.onSelectionStyleChanged(Utils.getChangeMapFromSets(mPreviousStyleSet, newStyleSet));
mPreviousStyleSet = newStyleSet;
break;
case CALLBACK_SELECTION_CHANGED:
// Called for changes to the field in current focus and for changes made to selection
// (includes moving the caret without selecting text)
// TODO: Possibly needed for handling WebView scrolling when caret moves (from iOS)
Set<String> selectionKeyValueSet = Utils.splitDelimitedString(params, JS_CALLBACK_DELIMITER);
mListener.onSelectionChanged(Utils.buildMapFromKeyValuePairs(selectionKeyValueSet));
break;
case CALLBACK_INPUT:
// TODO: Possibly needed for handling WebView scrolling when caret moves (from iOS)
break;
case CALLBACK_FOCUS_IN:
// TODO: Needed to handle displaying/graying the format bar when focus changes between the title and content
AppLog.d(AppLog.T.EDITOR, "Focus in callback received");
break;
case CALLBACK_FOCUS_OUT:
// TODO: Needed to handle displaying/graying the format bar when focus changes between the title and content
AppLog.d(AppLog.T.EDITOR, "Focus out callback received");
break;
case CALLBACK_NEW_FIELD:
// TODO: Used for logging/testing purposes on iOS
AppLog.d(AppLog.T.EDITOR, "New field created, " + params);
break;
case CALLBACK_IMAGE_REPLACED:
AppLog.d(AppLog.T.EDITOR, "Image replaced, " + params);
// Extract the local media id from the callback string (stripping the 'id=' part)
if (params.length() > 3) {
mListener.onMediaReplaced(params.substring(3));
}
break;
case CALLBACK_VIDEO_REPLACED:
AppLog.d(AppLog.T.EDITOR, "Video replaced, " + params);
// Extract the local media id from the callback string (stripping the 'id=' part)
if (params.length() > 3) {
mListener.onMediaReplaced(params.substring(3));
}
break;
case CALLBACK_IMAGE_TAP:
AppLog.d(AppLog.T.EDITOR, "Image tapped, " + params);
String uploadStatus = "";
List<String> mediaIds = new ArrayList<>();
mediaIds.add("id");
mediaIds.add("url");
mediaIds.add("meta");
mediaIds.add("type");
Set<String> mediaDataSet = Utils.splitValuePairDelimitedString(params, JS_CALLBACK_DELIMITER, mediaIds);
Map<String, String> mediaDataMap = Utils.buildMapFromKeyValuePairs(mediaDataSet);
String mediaId = mediaDataMap.get("id");
String mediaUrl = mediaDataMap.get("url");
if (mediaUrl != null) {
mediaUrl = Utils.decodeHtml(mediaUrl);
}
MediaType mediaType = MediaType.fromString(mediaDataMap.get("type"));
String mediaMeta = mediaDataMap.get("meta");
JSONObject mediaMetaJson = new JSONObject();
if (mediaMeta != null) {
mediaMeta = Utils.decodeHtml(mediaMeta);
try {
mediaMetaJson = new JSONObject(mediaMeta);
String classes = JSONUtils.getString(mediaMetaJson, "classes");
Set<String> classesSet = Utils.splitDelimitedString(classes, ", ");
if (classesSet.contains("uploading")) {
uploadStatus = "uploading";
} else if (classesSet.contains("failed")) {
uploadStatus = "failed";
}
} catch (JSONException e) {
e.printStackTrace();
AppLog.d(AppLog.T.EDITOR, "Media meta data from callback-image-tap was not JSON-formatted");
}
}
mListener.onMediaTapped(mediaId, mediaType, mediaMetaJson, uploadStatus);
break;
case CALLBACK_LINK_TAP:
// Extract and HTML-decode the link data from the callback params
AppLog.d(AppLog.T.EDITOR, "Link tapped, " + params);
List<String> linkIds = new ArrayList<>();
linkIds.add("url");
linkIds.add("title");
Set<String> linkDataSet = Utils.splitValuePairDelimitedString(params, JS_CALLBACK_DELIMITER, linkIds);
Map<String, String> linkDataMap = Utils.buildMapFromKeyValuePairs(linkDataSet);
String url = linkDataMap.get("url");
if (url != null) {
url = Utils.decodeHtml(url);
}
String title = linkDataMap.get("title");
if (title != null) {
title = Utils.decodeHtml(title);
}
mListener.onLinkTapped(url, title);
break;
case CALLBACK_MEDIA_REMOVED:
AppLog.d(AppLog.T.EDITOR, "Media removed, " + params);
// Extract the media id from the callback string (stripping the 'id=' part of the callback string)
if (params.length() > 3) {
mListener.onMediaRemoved(params.substring(3));
}
break;
case CALLBACK_VIDEOPRESS_INFO_REQUEST:
// Extract the VideoPress id from the callback string (stripping the 'id=' part of the callback string)
if (params.length() > 3) {
mListener.onVideoPressInfoRequested(params.substring(3));
}
break;
case CALLBACK_LOG:
// Strip 'msg=' from beginning of string
if (params.length() > 4) {
AppLog.d(AppLog.T.EDITOR, callbackId + ": " + params.substring(4));
}
break;
case CALLBACK_RESPONSE_STRING:
AppLog.d(AppLog.T.EDITOR, callbackId + ": " + params);
Set<String> responseDataSet;
if (params.startsWith("function=") && params.contains(JS_CALLBACK_DELIMITER)) {
String functionName = params.substring("function=".length(), params.indexOf(JS_CALLBACK_DELIMITER));
List<String> responseIds = new ArrayList<>();
switch(functionName) {
case "getHTMLForCallback":
responseIds.add("id");
responseIds.add("contents");
break;
case "getSelectedTextToLinkify":
responseIds.add("result");
break;
case "getFailedMedia":
responseIds.add("ids");
}
responseDataSet = Utils.splitValuePairDelimitedString(params, JS_CALLBACK_DELIMITER, responseIds);
} else {
responseDataSet = Utils.splitDelimitedString(params, JS_CALLBACK_DELIMITER);
}
mListener.onGetHtmlResponse(Utils.buildMapFromKeyValuePairs(responseDataSet));
break;
case CALLBACK_ACTION_FINISHED:
mListener.onActionFinished();
break;
default:
AppLog.d(AppLog.T.EDITOR, "Unhandled callback: " + callbackId + ":" + params);
}
}
use of android.webkit.JavascriptInterface in project AgentWeb by Justson.
the class JsBaseInterfaceHolder method checkObject.
@Override
public boolean checkObject(Object v) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)
return true;
boolean tag = false;
Class clazz = v.getClass();
Method[] mMethods = clazz.getMethods();
for (Method mMethod : mMethods) {
Annotation[] mAnnotations = mMethod.getAnnotations();
for (Annotation mAnnotation : mAnnotations) {
if (mAnnotation instanceof JavascriptInterface) {
tag = true;
break;
}
}
if (tag)
break;
}
return tag;
}
use of android.webkit.JavascriptInterface in project ForPDA by RadiationX.
the class QmsChatFragment method showMoreMess.
@JavascriptInterface
public void showMoreMess() {
if (getContext() == null)
return;
MiniTemplator t = App.get().getTemplate(App.TEMPLATE_QMS_CHAT_MESS);
App.setTemplateResStrings(t);
int endIndex = currentChat.getShowedMessIndex();
int startIndex = Math.max(endIndex - 30, 0);
currentChat.setShowedMessIndex(startIndex);
QmsRx.generateMess(t, currentChat.getMessages(), startIndex, endIndex);
String messagesSrc = t.generateOutput();
t.reset();
messagesSrc = QmsRx.transformMessageSrc(messagesSrc);
webView.evalJs("showMoreMess('" + messagesSrc + "')");
}
use of android.webkit.JavascriptInterface in project ForPDA by RadiationX.
the class ThemeFragmentWeb method copySpoilerLink.
@JavascriptInterface
public void copySpoilerLink(String postId, String spoilNumber) {
if (getContext() == null)
return;
runInUiThread(() -> {
new AlertDialog.Builder(getContext()).setMessage(R.string.spoiler_link_copy_ask).setPositiveButton(R.string.ok, (dialog, which) -> {
IBaseForumPost post = getPostById(Integer.parseInt(postId));
String s = "https://4pda.ru/forum/index.php?act=findpost&pid=" + post.getId() + "&anchor=Spoil-" + post.getId() + "-" + spoilNumber;
Utils.copyToClipBoard(s);
}).setNegativeButton(R.string.cancel, null).show();
});
}
Aggregations