package com.onespan.orchestrationclientsample.registration; import android.app.Activity; import android.app.ProgressDialog; import android.content.Intent; import android.content.res.Resources; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.util.Base64; import android.util.Log; import android.view.Window; import android.webkit.CookieManager; import android.webkit.PermissionRequest; import android.webkit.ValueCallback; import android.webkit.WebChromeClient; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import com.android.volley.NetworkResponse; import com.android.volley.Request; import com.android.volley.RequestQueue; import com.android.volley.Response; import com.android.volley.VolleyError; import com.android.volley.toolbox.JsonObjectRequest; import com.android.volley.toolbox.StringRequest; import com.android.volley.toolbox.Volley; import com.onespan.orchestrationclientsample.R; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.Map; import androidx.appcompat.app.AppCompatActivity; public class idvLaunchActivity extends AppCompatActivity { //Layout items private static final String TAG = idvLaunchActivity.class.getName(); //error logging private static final int FILECHOOSER_RESULTCODE = 2888; public static final int INPUT_FILE_REQUEST_CODE = 1; private WebView mWebview ; private ProgressDialog progress; String link = "https://gs.onespan.cloud/idv-rpoc/";// global variable Resources res;// global variable private ValueCallback mUploadMessage; private ValueCallback mFilePathCallback; private String mCameraPhotoPath; private HashMap preRegisteredUserDetails; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); Intent intent = getIntent(); preRegisteredUserDetails = (HashMap)intent.getSerializableExtra("userdetails"); final RequestQueue queue = Volley.newRequestQueue(this); String tokenRequestUrl = link + "/oauth/token"; StringRequest idvTokenRequest = new StringRequest(Request.Method.POST, tokenRequestUrl, new Response.Listener() { @Override public void onResponse(Object response) { Log.d(TAG, response.toString()); try { JSONObject authTokenResponse = new JSONObject(response.toString()); String authToken = authTokenResponse.getString("access_token"); GetIDVRequest(queue, authToken); } catch (JSONException e) { Log.e(TAG, e.getMessage(), e); } } }, new Response.ErrorListener() { public void onErrorResponse(VolleyError error) { Log.e(TAG, error.getMessage(), error); } }) { @Override public Map getHeaders() { Map params = new HashMap<>(); params.put("contentType", "multipart/form-data;"); final String USERNAME = "myjwtuser"; final String PASSWORD = "myjwtpassword"; String creds = String.format("%s:%s",USERNAME,PASSWORD); String auth = "Basic " + Base64.encodeToString(creds.getBytes(), Base64.DEFAULT); params.put("Authorization", auth); return params; } @Override public Map getParams(){ Map params = new HashMap(); params.put("grant_type","client_credentials"); params.put("scope","tenant_access"); return params; } }; queue.add(idvTokenRequest); } private void GetIDVRequest(RequestQueue queue, final String authToken) { JSONObject transactionData = null; transactionData = buildJSONRequest(); String idvTransactionRequestUrl = link + "/api/transaction/"; JsonObjectRequest idvPackageRequest = new JsonObjectRequest(Request.Method.PUT,idvTransactionRequestUrl,transactionData, new Response.Listener() { @Override public void onResponse(JSONObject response) { Log.d(TAG, response.toString()); try { JSONArray tokens = response.getJSONArray("tokens"); JSONObject token = tokens.getJSONObject(0); showWebView(response.getString("id"), token.getString("token")); } catch (JSONException e) { e.printStackTrace(); } } }, new Response.ErrorListener() { public void onErrorResponse(VolleyError error) { Log.e(TAG, error.networkResponse.toString(), error); NetworkResponse response = error.networkResponse; int statusCode = response.statusCode; /* Get the response data */ String json = ""; if (response.data != null) { json = new String(response.data); } String log = String.format("%1$s\nResponse code: %2$s\nResponse body: %3$s", link, statusCode, json); Log.d(TAG, log); } }) { @Override public Map getHeaders() { Map params = new HashMap<>(); params.put("contentType", "application/json;"); params.put("Authorization", "Bearer" + authToken); params.put("X-Tenant", "salesdemo"); return params; } }; queue.add(idvPackageRequest); } private class ChromeClient extends WebChromeClient { @Override public void onProgressChanged(WebView view, int newProgress) { if(newProgress >= 85) { progress.dismiss(); } super.onProgressChanged(view, newProgress); } @Override public boolean onShowFileChooser(WebView webView, ValueCallback filePathCallback, FileChooserParams fileChooserParams) { Log.d(TAG, "showing file chooser"); 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 { photoFile = createImageFile(); takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath); } 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, "Image Chooser"); chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray); startActivityForResult(chooserIntent, INPUT_FILE_REQUEST_CODE); return true; } // Need to accept permissions to use the camera @Override public void onPermissionRequest(final PermissionRequest request) { Log.d(TAG, "onPermissionRequest"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { request.grant(request.getResources()); Log.d(TAG, "permission Request granted: "+ Arrays.toString(request.getResources())); } } } public String loadJSONFromAsset() { String json = null; try { InputStream is = this.getAssets().open("idvTransactionData.json"); int size = is.available(); byte[] buffer = new byte[size]; is.read(buffer); is.close(); json = new String(buffer, "UTF-8"); } catch (IOException ex) { ex.printStackTrace(); return null; } return json; } private JSONObject buildJSONRequest(){ JSONObject transactionData = null; try { transactionData = new JSONObject(//String.format( "{"+ " \"workflow_id\": \"00000000-0000-0000-0000-200000000007\"," + " \"language\":\"english\"," + " \"brand_id\":\"sales\"," + " \"opaque_id\":\"WorkflowExternalMitAt\"," + " \"skip_camera\":"+true+"," + " \"users\":[{" + " \"role\": \"Customer\"," + " \"first_name\": \""+preRegisteredUserDetails.get("first_name")+"\"," + //Will " \"last_name\": \""+preRegisteredUserDetails.get("last_name")+"\"," + //LaSala " \"phone_number\": \""+preRegisteredUserDetails.get("mobile_number")+"\"," + //+19999999999 " \"dob\": \""+preRegisteredUserDetails.get("date_of_birth")+"\"," + //1976-11-30T00:00:00.000Z " \"address\": {"+ " \"post_code\": \""+preRegisteredUserDetails.get("zip_code")+"\"," + //01752 " \"country_code\": \""+preRegisteredUserDetails.get("country")+"\"," + //US " \"county_or_province\": \""+preRegisteredUserDetails.get("state")+"\"," + //New Hampshire " \"city\": \""+preRegisteredUserDetails.get("city")+"\"," + //Marlborough " \"street\": \""+preRegisteredUserDetails.get("street_name")+"\"," + //Mount Royal Ave " \"po_box\": \""+preRegisteredUserDetails.get("street_number")+"\"" + //2 "}" + " }]," + " \"tokens\": [{" + " \"role\": \"Customer\"" + " }]," + " \"documents\": [{" + " \"id\": \"Consent\"," + " \"document_template_id\": \"babdf419-6144-4e01-b8fb-98c863c9a2b1\""+ " }," + " {" + " \"id\": \"Documentforsignature\","+ " \"document_template_id\": \"babdf419-6144-4e01-b8fb-98c863c9a2b2\""+ " }]"+ "}" );//,inputFirstName,inputLastName,inputMobileNumber,inputDateOfBirth,inputPostCode,inputCountryCode,inputState,inputCity,inputStreet,inputPOBox)); Log.d(TAG, "JSON Transaction Data:" + transactionData.toString()); } catch (JSONException e) { e.printStackTrace(); } return transactionData; } private void showWebView(String transactionID, String transactionToken){ setContentView(R.layout.activity_idvnewaccount); mWebview = findViewById(R.id.chromeWebView); WebSettings webSettings = mWebview.getSettings(); webSettings.setJavaScriptEnabled(true); webSettings.setUseWideViewPort(true); webSettings.setLoadWithOverviewMode(true); webSettings.setDomStorageEnabled(true); webSettings.setAllowFileAccess(true); webSettings.setAllowFileAccessFromFileURLs(true); webSettings.setAllowUniversalAccessFromFileURLs(true); webSettings.setPluginState(WebSettings.PluginState.ON); webSettings.setMediaPlaybackRequiresUserGesture(false); // AppRTC requires third party cookies to work CookieManager cookieManager = CookieManager.getInstance(); cookieManager.setAcceptThirdPartyCookies(mWebview, true); mWebview.setWebContentsDebuggingEnabled(true); mWebview.setWebViewClient(new WebViewClient()); mWebview.setWebChromeClient(new ChromeClient()); progress= ProgressDialog.show(this, "", "Loading..."); Log.d(TAG, "loading URL: " + link + "/sales/#/esign/" + transactionID + "?access_token="+transactionToken); mWebview.loadUrl(link + "/sales/#/esign/" + transactionID + "?access_token="+transactionToken); mWebview.measure(100, 100); mWebview.requestFocus(); } private File createImageFile() throws IOException { // Create an image file name String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); String imageFileName = "JPEG_" + timeStamp + "_"; File storageDir = Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES); File imageFile = File.createTempFile( imageFileName, /* prefix */ ".jpg", /* suffix */ storageDir /* directory */ ); return imageFile; } // Return here when file selected from camera or from SDcard @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if(requestCode != INPUT_FILE_REQUEST_CODE || mFilePathCallback == null) { super.onActivityResult(requestCode, resultCode, data); return; } Uri[] results = null; // Check that the response is a good one if(resultCode == Activity.RESULT_OK) { if(data != null) { String dataString = data.getDataString(); if (dataString != null) { results = new Uri[]{Uri.parse(dataString)}; } else { // If there is not data, then we may have taken a photo if (mCameraPhotoPath != null) { results = new Uri[]{Uri.parse(mCameraPhotoPath)}; } } } } mFilePathCallback.onReceiveValue(results); mFilePathCallback = null; return; } }