Search in sources :

Example 16 with JavascriptInterface

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;
        }
    });
}
Also used : JavascriptInterface(android.webkit.JavascriptInterface) URL(java.net.URL) HttpURLConnection(java.net.HttpURLConnection) WebView(android.webkit.WebView) WebViewClient(android.webkit.WebViewClient) JSONArray(org.json.JSONArray) JSONException(org.json.JSONException) IOException(java.io.IOException) JSONException(org.json.JSONException) HttpURLConnection(java.net.HttpURLConnection) URLConnection(java.net.URLConnection) JSONObject(org.json.JSONObject) HashMap(java.util.HashMap) Map(java.util.Map)

Example 17 with JavascriptInterface

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);
    }
}
Also used : JSONObject(org.json.JSONObject) ArrayList(java.util.ArrayList) MediaType(org.wordpress.android.editor.EditorFragmentAbstract.MediaType) JSONException(org.json.JSONException) HashSet(java.util.HashSet) JavascriptInterface(android.webkit.JavascriptInterface)

Example 18 with JavascriptInterface

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;
}
Also used : Method(java.lang.reflect.Method) JavascriptInterface(android.webkit.JavascriptInterface) Annotation(java.lang.annotation.Annotation)

Example 19 with JavascriptInterface

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 + "')");
}
Also used : MiniTemplator(biz.source_code.miniTemplator.MiniTemplator) SuppressLint(android.annotation.SuppressLint) JavascriptInterface(android.webkit.JavascriptInterface)

Example 20 with JavascriptInterface

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();
    });
}
Also used : IBaseForumPost(forpdateam.ru.forpda.api.IBaseForumPost) JavascriptInterface(android.webkit.JavascriptInterface)

Aggregations

JavascriptInterface (android.webkit.JavascriptInterface)32 JSONObject (org.json.JSONObject)9 JSONException (org.json.JSONException)7 Intent (android.content.Intent)4 WebView (android.webkit.WebView)4 WebViewClient (android.webkit.WebViewClient)4 IOException (java.io.IOException)4 Annotation (java.lang.annotation.Annotation)4 Method (java.lang.reflect.Method)4 File (java.io.File)3 SharedPreferences (android.content.SharedPreferences)2 IBaseForumPost (forpdateam.ru.forpda.api.IBaseForumPost)2 HashMap (java.util.HashMap)2 SuppressLint (android.annotation.SuppressLint)1 Bitmap (android.graphics.Bitmap)1 Uri (android.net.Uri)1 SslError (android.net.http.SslError)1 Bundle (android.os.Bundle)1 AlertDialog (android.support.v7.app.AlertDialog)1 JsPromptResult (android.webkit.JsPromptResult)1