{"componentChunkName":"component---src-templates-blog-post-js","path":"/how-to-integrate-vuukle-in-native-mobile-application/","result":{"data":{"site":{"siteMetadata":{"title":"Vuukle Docs","author":"Vuukle"}},"markdownRemark":{"id":"633eac3e-0597-5b8e-80be-d8c38fa1b2d6","html":"<p>We want to create the best experience possible for you. You have no need to update SDK anymore, since it’s in the web view we will handle the heavy lifting for you. You will get the latest updates and new features as soon as they are uploaded on our servers.</p>\n<p>You will be working with our <strong>iframe URL’s</strong></p>\n<p>Comment widget iframe looks like this:</p>\n<p><a href=\"https://cdn.vuukle.com/amp.html?apiKey=c7368a34-dac3-4f39-9b7c-b8ac2a2da575&#x26;host=smalltester.000webhostapp.com&#x26;id=381&#x26;img=https://smalltester.000webhostapp.com/wp-content/uploads/2017/10/wallhaven-303371-825x510.jpg&#x26;title=Newpost&#x26;url=https://smalltester.000webhostapp.com/2017/12/new-post-22#1\">https://cdn.vuukle.com/amp.html?apiKey=c7368a34-dac3-4f39-9b7c-b8ac2a2da575&#x26;host=smalltester.000webhostapp.com&#x26;id=381&#x26;img=https://smalltester.000webhostapp.com/wp-content/uploads/2017/10/wallhaven-303371-825x510.jpg&#x26;title=Newpost&#x26;url=https://smalltester.000webhostapp.com/2017/12/new-post-22#1</a></p>\n<p><strong>Required parameters (for comment widget iframe):</strong></p>\n<ol>\n<li>apiKey - Your API key (<a href=\"https://docs.vuukle.com/how-to-embed-vuukle-2.0-via-js/\">https://docs.vuukle.com/how-to-embed-vuukle-2.0-via-js/</a>)</li>\n<li>host - your site host (Exclude http:// or www.)</li>\n<li>id -unique article ID</li>\n<li>img - article image</li>\n<li>title - article title</li>\n<li>url - article URL (include http:// or www.)</li>\n</ol>\n<p>Emote widget iframe looks like this:</p>\n<p><a href=\"https://cdn.vuukle.com/widgets/emotes.html?apiKey=c7368a34-dac3-4f39-9b7c-b8ac2a2da575&#x26;host=smalltester.000webhostapp.com&#x26;articleId=381&#x26;img=https://smalltester.000webhostapp.com/wp-content/uploads/2017/10/wallhaven-303371-825x510.jpg&#x26;title=New%20post%2022&#x26;url=https://smalltester.000webhostapp.com/2017/12/new-post-22#1\">https://cdn.vuukle.com/widgets/emotes.html?apiKey=c7368a34-dac3-4f39-9b7c-b8ac2a2da575&#x26;host=smalltester.000webhostapp.com&#x26;articleId=381&#x26;img=https://smalltester.000webhostapp.com/wp-content/uploads/2017/10/wallhaven-303371-825x510.jpg&#x26;title=New%20post%2022&#x26;url=https://smalltester.000webhostapp.com/2017/12/new-post-22#1</a></p>\n<p><strong>Required parameters (for emote widget iframe):</strong></p>\n<ol>\n<li>apiKey - Your API key (<a href=\"https://docs.vuukle.com/how-to-embed-vuukle-2.0-via-js/\">https://docs.vuukle.com/how-to-embed-vuukle-2.0-via-js/</a>)</li>\n<li>host - your site host (Exclude http:// or www.)</li>\n<li>articleId -unique article ID</li>\n<li>img - article image</li>\n<li>title - article title</li>\n<li>url - article URL (include http:// or www.)</li>\n</ol>\n<p>If you have any additional options to include, please contact support@vuukle.com</p>\n<p><strong>Integration Steps</strong></p>\n<ol>\n<li><strong>Create xml resourse:</strong></li>\n</ol>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token operator\">&lt;</span><span class=\"token operator\">?</span>xml version<span class=\"token operator\">=</span><span class=\"token string\">\"1.0\"</span> encoding<span class=\"token operator\">=</span><span class=\"token string\">\"utf-8\"</span><span class=\"token operator\">?</span><span class=\"token operator\">></span>\n<span class=\"token operator\">&lt;</span><span class=\"token class-name\">FrameLayout</span> xmlns<span class=\"token operator\">:</span>android<span class=\"token operator\">=</span><span class=\"token string\">\"http://schemas.android.com/apk/res/android\"</span>\n    xmlns<span class=\"token operator\">:</span>tools<span class=\"token operator\">=</span><span class=\"token string\">\"http://schemas.android.com/tools\"</span>\n    android<span class=\"token operator\">:</span>layout_width<span class=\"token operator\">=</span><span class=\"token string\">\"match_parent\"</span>\n    android<span class=\"token operator\">:</span>id<span class=\"token operator\">=</span><span class=\"token string\">\"@+id/container\"</span>\n    android<span class=\"token operator\">:</span>layout_height<span class=\"token operator\">=</span><span class=\"token string\">\"match_parent\"</span>\n    tools<span class=\"token operator\">:</span>context<span class=\"token operator\">=</span><span class=\"token string\">\"com.vuukle.webview.MainActivity\"</span><span class=\"token operator\">></span>\n\n    <span class=\"token operator\">&lt;</span><span class=\"token class-name\">WebView</span>\n        android<span class=\"token operator\">:</span>id<span class=\"token operator\">=</span><span class=\"token string\">\"@+id/activity_main_webview_comments\"</span>\n        android<span class=\"token operator\">:</span>layout_width<span class=\"token operator\">=</span><span class=\"token string\">\"match_parent\"</span>\n        android<span class=\"token operator\">:</span>layout_height<span class=\"token operator\">=</span><span class=\"token string\">\"match_parent\"</span>\n        tools<span class=\"token operator\">:</span>layout_editor_absoluteX<span class=\"token operator\">=</span><span class=\"token string\">\"8dp\"</span>\n        tools<span class=\"token operator\">:</span>layout_editor_absoluteY<span class=\"token operator\">=</span><span class=\"token string\">\"8dp\"</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span>\n\n<span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span><span class=\"token class-name\">FrameLayout</span><span class=\"token operator\">></span></code></pre></div>\n<p><strong>Add permission to AndroidManifest.xml:</strong></p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token operator\">&lt;</span><span class=\"token keyword\">uses</span><span class=\"token operator\">-</span>permission android<span class=\"token operator\">:</span>name<span class=\"token operator\">=</span><span class=\"token string\">\"android.permission.INTERNET\"</span> <span class=\"token operator\">/</span><span class=\"token operator\">></span></code></pre></div>\n<p><strong>Getting events from javascript page.</strong></p>\n<p>You can listen to events from javascript via console logs. WebChromeClient provides a callback onConsoleMessage.</p>\n<p><em>Example</em>:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">//javascript support\n    mWebViewComments.getSettings().setJavaScriptEnabled(true);\n    mWebViewComments.getSettings().setDomStorageEnabled(true);\n    mWebViewComments.getSettings().setSupportMultipleWindows(true);\n    mWebViewComments.setWebChromeClient(webChromeClient);</code></pre></div>\n<p>The webСlientChrome looks like this</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\"> private WebChromeClient webChromeClient = new WebChromeClient() {\n        @Override\n        public boolean onConsoleMessage(ConsoleMessage consoleMessage) {\n            Log.d(&quot;consoleJs&quot;, consoleMessage.message());\n            //Listening for console message that contains &quot;Comments initialized!&quot; string\n            if (consoleMessage.message().contains(&quot;Comments initialized!&quot;)) {\n                //signInUser(name, email) - javascript function implemented on a page\n                mWebViewComments.loadUrl(&quot;javascript:signInUser(&#39;&quot; + name + &quot;&#39;, &#39;&quot; + email + &quot;&#39;)&quot;);\n            }\n            return super.onConsoleMessage(consoleMessage);\n        }\n​\n        @Override\n        public boolean onCreateWindow(final WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {\n            popup = new WebView(MainActivity.this);\n            popup.getSettings().setJavaScriptEnabled(true);\n            popup.getSettings().setPluginState(WebSettings.PluginState.ON);\n            popup.getSettings().setSupportMultipleWindows(true);\n            popup.setLayoutParams(view.getLayoutParams());\n            popup.getSettings().setUserAgentString(popup.getSettings().getUserAgentString().replace(&quot;; wv&quot;, &quot;&quot;));\n            final String[] urlLast = {&quot;&quot;};\n            popup.setWebViewClient(new WebViewClient() {\n                @Override\n                public boolean shouldOverrideUrlLoading(WebView view, String url) {\n                    if (url.contains(AUTH) || url.contains(CONSENT)) {\n                        Log.d(&quot;openWebView&quot;, &quot;open vebView 2 &quot; + url);\n                        if (popup != null)\n                            popup.loadUrl(url);\n                        checkConsent(url);\n                    } else {\n                        return selectOpenTab(url);\n                    }\n                    return true;\n                }\n               private boolean selectOpenTab(String url) {\n                    if (url.contains(&quot;msg_url&quot;)) {\n                        Log.d(&quot;openWebView&quot;, &quot;open app &quot; + url);\n                        openSite.openApp(url);\n                    } else if (url.contains(&quot;facebook&quot;) || url.contains(&quot;twitter&quot;) || url.contains(&quot;telegram&quot;)) {\n                        Log.d(&quot;openWebView&quot;, &quot;open vebView 2 &quot; + url);\n                        popup.loadUrl(url);\n                    } else {\n                        Log.d(&quot;openWebView&quot;, &quot;open vebView 1 &quot; + url);\n                        mWebViewComments.loadUrl(url);\n                        mContainer.removeView(popup);\n                        popup.destroy();\n                        return false;\n                    }\n                    return true;\n                }\n                          private void checkConsent(String url) {\n                    if (urlLast[0].equals(url)) {\n                        mContainer.removeView(popup);\n                        popup.destroy();\n                    } else {\n                        mWebViewComments.reload();\n                        urlLast[0] = url;\n                    }\n                }\n​\n            });\n            popup.setWebChromeClient(new WebChromeClient() {\n                @Override\n                public void onCloseWindow(WebView window) {\n                    super.onCloseWindow(window);\n                    mContainer.removeView(window);\n                }\n            });\n            mContainer.addView(popup);\n            WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;\n            transport.setWebView(popup);\n            resultMsg.sendToTarget();\n​\n            return true;\n        }\n        // For Lollipop 5.0+ Devices\n        public boolean onShowFileChooser(WebView mWebView, ValueCallback&lt;Uri[]&gt; filePathCallback, FileChooserParams fileChooserParams) {\n            if (uploadMessage != null) {\n                uploadMessage.onReceiveValue(null);\n                uploadMessage = null;\n            }\n            uploadMessage = filePathCallback;\n            return openPermission();\n        }\n        private boolean openPermission() {\n            if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {\n                openPhoto.selectImage(MainActivity.this);\n                return true;\n            } else {\n                ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, CAMERA_PERMISSION);\n                try {\n                    openPhoto.selectImage(MainActivity.this);\n                } catch (Exception e) {\n                    Toast.makeText(MainActivity.this, &quot;An error has occurred&quot;, Toast.LENGTH_SHORT).show();\n                }\n                if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {\n                    openPhoto.selectImage(MainActivity.this);\n                    return true;\n                } else {\n                    uploadMessage = null;\n                    return false;\n               }\n            }\n        }\n    };</code></pre></div>\n<p>Return the selected photo or snapshot</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">protected void onActivityResult(int requestCode, int resultCode, Intent intent) {\n    if (CAMERA_PERMISSION == resultCode &amp;&amp; requestCode == Activity.RESULT_OK)\n        openPhoto.selectImage(MainActivity.this);\n    if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.LOLLIPOP) {\n        if (requestCode == REQUEST_SELECT_FILE) {\n            if (uploadMessage == null)\n                return;\n            if (intent == null) {\n                Intent intent1 = new Intent();\n                intent1.setData(openPhoto.getImageUri());\n             uploadMessage.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(resultCode, intent1));\n            } else\n                uploadMessage.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(resultCode, intent));\n            uploadMessage = null;\n        }\n    } else if (requestCode == FILE_CHOOSER_RESULT_CODE) {\n        if (null == mUploadMessage)\n           return;\n        Uri result = intent == null || resultCode != MainActivity.RESULT_OK ? null : intent.getData();\n        mUploadMessage.onReceiveValue(result);\n        mUploadMessage = null;\n    }\n}</code></pre></div>\n<p><strong>Passing data to javascript page.</strong></p>\n<p>WebView lets you ability to inject your javascript code into page. We can use it for passing data.</p>\n<p><em>Example</em>:</p>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token comment\">//signInUser(name, email) - function implemented in javascript code on page</span>\nmWebViewComments<span class=\"token punctuation\">.</span><span class=\"token function\">loadUrl</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"javascript:signInUser('\"</span> <span class=\"token operator\">+</span> name <span class=\"token operator\">+</span> <span class=\"token string\">\"', '\"</span> <span class=\"token operator\">+</span> email <span class=\"token operator\">+</span> <span class=\"token string\">\"')\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p><strong>Listening on url loading.</strong></p>\n<p>We also can override url loading with WebViewClient.</p>\n<p><em>Example</em>:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\"> mWebViewComments.setWebViewClient(new WebViewClient() {\n    @Override\n    public boolean shouldOverrideUrlLoading(WebView view, final String url) {\n        //Clicked url\n        Log.d(TAG, &quot;Clicked url: &quot; + url);\n        if (url.contains(&quot;mailto:to&quot;) || url.contains(&quot;mailto:&quot;)) {\n            openSite.openEmail(url.replace(&quot;%20&quot;, &quot; &quot;));\n        } else {\n            //Lets signInUser whenever url is clicked just for sample\n            openSite.openWhatsApp(url, view);\n            openSite.openMessenger(url);\n        }\n        //if u use super() it will load url into webview\n        return true;\n    }\n});</code></pre></div>\n<p>Class for different page transitions</p>\n<p><em>Example</em>:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">public class OpenSite {\n    private Context context;\n    public OpenSite(Context context) {\n        this.context = context;\n    }\n    public void openWhatsApp(String url, WebView view) {\n        url = decodeUrl(url);\n        if (!url.contains(&quot;whatsapp://send&quot;) &amp;&amp; !url.contains(&quot;fb-messenger&quot;))\n            view.loadUrl(url);\n        else if (url.contains(&quot;whatsapp://send&quot;))\n            openApp(&quot;https://api.whatsapp.com&quot; + url.substring(url.indexOf(&quot;://&quot;) + 2));\n    }\n    public void openMessenger(String url) {\n        url = decodeUrl(url);\n        if (url.contains(&quot;fb-messenger&quot;)) {\n            Intent sendIntent = new Intent();\n            sendIntent.setAction(Intent.ACTION_SEND);\n            sendIntent\n                    .putExtra(Intent.EXTRA_TEXT,\n                            url.substring(url.indexOf(&quot;?link=&quot;) + 6));\n            sendIntent.setType(&quot;text/plain&quot;);\n            sendIntent.setPackage(&quot;com.facebook.orca&quot;);\n            try {\n                context.startActivity(sendIntent);\n            } catch (android.content.ActivityNotFoundException ex) {\n                context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(&quot;market://details?id=com.facebook.orca&quot;)));\n            }\n        }\n    }\n    public void openEmail(String url) {\n        url = decodeUrl(url);\n        Intent emailIntent = new Intent(Intent.ACTION_SENDTO, Uri.fromParts(\n                &quot;mailto&quot;, &quot;&quot;, null));\n        emailIntent.putExtra(Intent.EXTRA_SUBJECT, url.substring(url.indexOf(&quot;subject=&quot;) + 8, url.indexOf(&quot;&amp;body&quot;)));\n        emailIntent.putExtra(Intent.EXTRA_TEXT, url.substring(url.indexOf(&quot;body=&quot;) + 5));\n        try {\n            context.startActivity(Intent.createChooser(emailIntent, null));\n        } catch (android.content.ActivityNotFoundException ex) {\n            context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(&quot;market://details?id=com.google.android.gm&quot;)));\n        }\n    }\n    private String decodeUrl(String url) {\n        try {\n            url = URLDecoder.decode(url, &quot;UTF-8&quot;);\n        } catch (UnsupportedEncodingException e) {\n            e.printStackTrace();\n            return url;\n        }\n        return url;\n    }\n    public void openApp(String url) {\n        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));\n        context.startActivity(intent);\n    }\n}</code></pre></div>\n<p><strong>Open dialog</strong></p>\n<p>Lets you choose between gallery and photo.</p>\n<p><em>Example</em>:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">public class OpenPhoto {\n    private String FORMAT_TIME = &quot;yyyyMMddHHmmss&quot;;\n    private String FILE_EXTENSION = &quot;.jpg&quot;;\n    private String FILE_PROVIDER = &quot;com.vuukle.webview.android.fileprovider&quot;;\n    private Uri imageUri;\n    public Uri getImageUri() {\n        return imageUri;\n    }\n    private File getPictureFile(Context contex) throws IOException {\n        String timeStamp = new SimpleDateFormat(FORMAT_TIME).format(new Date());\n        String pictureFile = &quot;VUUKLE&quot; + timeStamp;\n        File storageDir = contex.getExternalFilesDir(Environment.DIRECTORY_PICTURES);\n        File image = File.createTempFile(pictureFile, FILE_EXTENSION, storageDir);\n        String pictureFilePath = image.getAbsolutePath();\n        return image;\n    }\n    public  void selectImage(Context context) {\n        final CharSequence[] options = {context.getString(R.string.take_photo), context.getString(R.string.choose_from_gallery), context.getString(R.string.cancel)};\n        AlertDialog.Builder builder = new AlertDialog.Builder(context);\n        builder.setTitle(context.getString(R.string.choose_your_profile_picture));\n        builder.setItems(options, (dialog, item) -&gt; {\n            if (options[item].equals(context.getString(R.string.take_photo))) {\n                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);\n                File photo = null;\n                try {\n                    photo = getPictureFile(context);\n                } catch (IOException e) {\n                    e.printStackTrace();\n                }\n                imageUri = FileProvider.getUriForFile(\n                        context,\n                        FILE_PROVIDER,\n                        photo);\n                intent.putExtra(MediaStore.EXTRA_OUTPUT,\n                        imageUri);\n                ((MainActivity) context).startActivityForResult(intent, REQUEST_SELECT_FILE);\n            } else if (options[item].equals(context.getString(R.string.choose_from_gallery))) {\n                try {\n                    Intent pickPhoto = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);\n                    ((MainActivity) context).startActivityForResult(pickPhoto, REQUEST_SELECT_FILE);\n                } catch (ActivityNotFoundException e) {\n                }\n           } else if (options[item].equals(context.getString(R.string.cancel))) {                dialog.dismiss();\n            }\n        });\n        builder.show();\n    }\n}</code></pre></div>\n<hr>\n<p><strong>Handling social login windows.</strong></p>\n<p>You need to add the property <code class=\"language-text\">.setSupportMultipleWindows(true)</code>to webview setting in order to enable the support of multiple windows.</p>\n<hr>\n<p>Implements the possibility to go back on the previous page.</p>\n<p><strong>Handling onBackPressed</strong></p>\n<div class=\"gatsby-highlight\" data-language=\"@override\"><pre class=\"language-@override\"><code class=\"language-@override\"> public void onBackPressed() {\n     if (popup != null &amp;&amp; popup.getParent() != null) {\n         mContainer.removeView(popup);\n         popup.destroy();\n     } else {\n         mWebViewComments.goBack();\n     }\n }</code></pre></div>\n<hr>\n<p>The full application example you can <a href=\"https://github.com/vuukle/webSDK\">check here</a> or download a demo APK <a href=\"https://www.dropbox.com/s/81ljpjzb0zrgong/Vuukle.apk?dl=0\">Here</a></p>","frontmatter":{"title":"How to integrate Vuukle web version into your native Android application","date":"March 03, 2020","category":"Install Vuukle","tags":["how to","install","vuukle","native","android"],"shortDescription":"We want to create the best experience possible for you. You have no need to update SDK anymore, since it's in the web view we will handle the heavy lifting for you. You will get the latest updates and new features as soon as they are uploaded on our servers"}}},"pageContext":{"id":"633eac3e-0597-5b8e-80be-d8c38fa1b2d6"}}}