Skip to main content
Version: 1.1.4

Android

All function details are mentioned detaily in mobile section. This section includes platform specific codes.

Importing WebView#

To add a WebView to your app in the layout, add the following code to your activity's layout XML file:

<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="496dp"
android:layout_marginBottom="0dp" />

On Android, you need to add some additional configurations. First create a file_paths.xml folder inside your app/src/main/res/xml then Add the following codes

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="." />
</paths>

Secondly add the following code inside the tag of your android/app/src/main/AndroidManifest.xml: and change the android:authorities with your projects name with .provider extension

<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.example.demopulpoarjava.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>

After configuration is done. We can start creating our WebView

First we initialize webView instance by id and add some settings

web = (WebView) findViewById(R.id.webview);
// setJavaScriptEnabled for execute JavaScript commands
web.getSettings().setJavaScriptEnabled(true);
// setDomStorageEnabled for display model images
web.getSettings().setDomStorageEnabled(true);
// url = 'https://devphotomakeup.pulpoar.com'
webView.loadUrl(url)
web.setWebViewClient(new WebViewClient() {
@Override
// javascript commands should be executed after page loaded
public void onPageFinished(WebView view, String url) {
web.loadUrl("javascript:initProducts('af648582-1346-45e0-bea2-f872c7a84c6d','http://127.0.0.1:8000')");
web.loadUrl("javascript:
activeProduct = {'********'};");
web.loadUrl("javascript:set_active_products(JSON.stringify(activeProduct))");
}
});

After this step we can see our WebView with with Choose Model and Take a Photo options. Choose Model should be working but Take a photo is not. We will use onShowFileChooser function for open camera createImageFile for generate image path and onActivityResult function will be executed after image selected

web.setWebChromeClient(new WebChromeClient() {
// method for choose camera or file
public boolean onShowFileChooser(
WebView webView, ValueCallback<Uri[]> filePathCallback,
WebChromeClient.FileChooserParams fileChooserParams) {
if (mFilePathCallback != null) {
mFilePathCallback.onReceiveValue(null);
}
mFilePathCallback = filePathCallback;
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
takePictureIntent.putExtra("return-data", true);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// create the file where the photo should go
File photoFile = null;
try {
String destination = Environment.getExternalStorageDirectory().getPath() + "/image.jpg";
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(destination)));
// creates the File
photoFile = createImageFile();
takePictureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
} catch (IOException ex) {
// Error occurred while creating the File
Log.e(TAG, "Unable to create Image File", ex);
}
// continue only if the file was successfully created
if (photoFile != null) {
mCameraPhotoPath = "file:" + photoFile.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
} else {
takePictureIntent = null;
}
}
Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
contentSelectionIntent.setType("image/*");
Intent[] intentArray;
if (takePictureIntent != null) {
intentArray = new Intent[]{
takePictureIntent
};
} else {
intentArray = new Intent[0];
}
Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
chooserIntent.putExtra(Intent.EXTRA_TITLE, "Select Option");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);
return true;
}
});
// return here for create image File Path
private File createImageFile() throws IOException {
// Create an image file name
@SuppressLint("SimpleDateFormat") String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, // prefix
".jpg", // suffix
storageDir // directory
);
currentPhotoPath = image.getAbsolutePath();
return image;
}
// return here after select image from camera or files
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
Uri[] results = null;
// Check that the response is a good one
if (resultCode == Activity.RESULT_OK) {
// If image selected from camera this part will be executed
if (data == null) {
results = new Uri[]{Uri.parse("file:" + currentPhotoPath)};
} else {
// if image selected from file this part will be executed
String dataString = data.getDataString();
results = new Uri[]{Uri.parse(mCameraPhotoPath)};
if (dataString != null) {
results = new Uri[]{Uri.parse(dataString)};
}
}
}
mFilePathCallback.onReceiveValue(results);
mFilePathCallback = null;
}

Apply Product#

We can apply products by product id or product name these parts are explained in detail in mobile section

// apply Product with Product uid by passing buttonMap value to productArrayList
public void applyProduct(View view){
// getting buttons id when button clicked
final int id = view.getId();
// applying product by uid
web.loadUrl("javascript:applyProductWithCode("+"'"+productArrayList.get(buttonMap.get(id)).uid+"'"+")");
}

We can pass this function inside button component in XML file

<Button
style="?android:attr/buttonBarButtonStyle"
android:id="@+id/button_1"
android:layout_margin="10sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="50sp"
android:background="@drawable/rounded_button"
android:onClick="applyProduct" />

Complete Source Code#

Our Sample App Source Code App like below

package com.example.demopulpoarjava;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;
//import class for Uploading part start
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.webkit.ValueCallback;
import android.widget.Button;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import android.webkit.WebChromeClient;
//import class for Uploading part End
public class MainActivity extends AppCompatActivity {
Product p1 = new Product("Pulpoar Lipstick 01", "Lipstick","l01", "#8d2152", "product_code");
Product p2 = new Product("Pulpoar Lipstick 02", "Lipstick","l02", "#A4585E", "product_code");
Product p3 = new Product("Pulpoar Lipstick 3","Lipstick","l03","#7f081d","product_code");
Product p4 = new Product("Pulpoar Blusher 01","Blusher","b01","#f27a51","product_code");
Product p5 = new Product("Pulpoar Eyeliner 01","Eyeliner","e01", "#000000", "product_code");
Product p6 = new Product("Pulpoar Foundation 01", "Foundation", "f01", "#DFBBA1", "product_code");
private WebView web;
String webUrl = "https://devphotomakeup.pulpoar.com"; // WebView Url
private static final String TAG = MainActivity.class.getSimpleName();
private static final int FILECHOOSER_RESULTCODE = 1;
private ValueCallback<Uri[]> mFilePathCallback;
private String mCameraPhotoPath;
private String currentPhotoPath;
HashMap<Integer,Integer> buttonMap = new HashMap<Integer, Integer>();
ArrayList<Button> buttonArrayList= new ArrayList<>();
ArrayList<Product> productArrayList = new ArrayList<>();
@SuppressLint("SetJavaScriptEnabled")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Components from XML file
web = (WebView) findViewById(R.id.webview);
final Button button1 = findViewById(R.id.button_1);
final Button button2 = findViewById(R.id.button_2);
final Button button3 = findViewById(R.id.button_3);
final Button button4 = findViewById(R.id.button_4);
final Button button5 = findViewById(R.id.button_5);
final Button button6 = findViewById(R.id.button_6);
buttonArrayList.add(button1);
buttonArrayList.add(button2);
buttonArrayList.add(button3);
buttonArrayList.add(button4);
buttonArrayList.add(button5);
buttonArrayList.add(button6);
productArrayList.add(p1);
productArrayList.add(p2);
productArrayList.add(p3);
productArrayList.add(p4);
productArrayList.add(p5);
productArrayList.add(p6);
// Fill the Button Map with id and index --> (2131165253 , 0)
// For apply selected buttons color
for(int i = 0; i<buttonArrayList.size();i++){
buttonMap.put(buttonArrayList.get(i).getId(),i);
}
// setting buttons color
for(int i= 0;i<productArrayList.size() ;i++){
buttonArrayList.get(i).setBackgroundColor(Color.parseColor(productArrayList.get(i).colorCode));
}
// loads the WebView
web.loadUrl(webUrl);
web.setWebViewClient(new WebViewClient() {
@Override
// javascript commands should be executed after page loaded
public void onPageFinished(WebView view, String url) {
web.loadUrl("javascript:initProducts('af648582-1346-45e0-bea2-f872c7a84c6d','http://127.0.0.1:8000')");
web.loadUrl("javascript: activeProduct = {'********'}");
web.loadUrl("javascript:set_active_products(JSON.stringify(activeProduct))");
}
});
// setJavaScriptEnabled for execute JavaScript commands
web.getSettings().setJavaScriptEnabled(true);
// setDomStorageEnabled for display model images
web.getSettings().setDomStorageEnabled(true);
web.setWebChromeClient(new WebChromeClient() {
// method for choose camera or file
public boolean onShowFileChooser(
WebView webView, ValueCallback<Uri[]> filePathCallback,
WebChromeClient.FileChooserParams fileChooserParams) {
if (mFilePathCallback != null) {
mFilePathCallback.onReceiveValue(null);
}
mFilePathCallback = filePathCallback;
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// create the file where the photo should go
File photoFile = null;
try {
String destination = Environment.getExternalStorageDirectory().getPath() + "/image.jpg";
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(destination)));
// creates the File
photoFile = createImageFile();
takePictureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
} catch (IOException ex) {
// Error occurred while creating the File
Log.e(TAG, "Unable to create Image File", ex);
}
// continue only if the file was successfully created
if (photoFile != null) {
mCameraPhotoPath = "file:" + photoFile.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
} else {
takePictureIntent = null;
}
}
Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
contentSelectionIntent.setType("image/*");
Intent[] intentArray;
if (takePictureIntent != null) {
intentArray = new Intent[]{
takePictureIntent
};
} else {
intentArray = new Intent[0];
}
Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);
return true;
}
});
}
// return here for create image File Path
private File createImageFile() throws IOException {
// Create an image file name
@SuppressLint("SimpleDateFormat") String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
currentPhotoPath = image.getAbsolutePath();
return image;
}
// return here when file selected from camera or from SD Card
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Uri[] results = null;
// Check that the response is a good one
if (resultCode == Activity.RESULT_OK) {
// If there is not data, then we may have taken a photo
if (data == null) {
results = new Uri[]{Uri.parse("file:" + currentPhotoPath)};
} else {
// if image selected from file this part will be executed
String dataString = data.getDataString();
results = new Uri[]{Uri.parse(mCameraPhotoPath)};
if (dataString != null) {
results = new Uri[]{Uri.parse(dataString)};
}
}
}
mFilePathCallback.onReceiveValue(results);
mFilePathCallback = null;
}
// apply Product with Product uid by passing buttonMap value to productArrayList
public void applyProduct(View view){
// getting buttons id when button clicked
final int id = view.getId();
// applying product by uid
web.loadUrl("javascript:applyProductWithCode("+"'"+productArrayList.get(buttonMap.get(id)).uid+"'"+")");
}
@Override
// You can add webView commands if you need
public void onBackPressed() {
if (web.canGoBack()) {
web.goBack();
} else {
super.onBackPressed();
}
}
}
caution

Provide camera permission to capture photo

Result:

Screenshot

You can request sample project from here