@@ -83,6 +83,16 @@ Licensed to the Apache Software Foundation (ASF) under one
8383import java .util .HashMap ;
8484import java .util .StringTokenizer ;
8585
86+ import android .Manifest ;
87+ import android .os .Environment ;
88+ import android .provider .MediaStore ;
89+ import android .util .Log ;
90+ import androidx .core .content .FileProvider ;
91+ import java .io .File ;
92+ import java .io .IOException ;
93+ import java .text .SimpleDateFormat ;
94+ import java .util .Date ;
95+
8696@ SuppressLint ("SetJavaScriptEnabled" )
8797public class InAppBrowser extends CordovaPlugin {
8898
@@ -147,6 +157,8 @@ public class InAppBrowser extends CordovaPlugin {
147157 private boolean fullscreen = true ;
148158 private String [] allowedSchemes ;
149159 private InAppBrowserClient currentClient ;
160+ private String photoFilePath ;
161+ private Uri photoFileUri ;
150162
151163 /**
152164 * Executes the request and returns PluginResult.
@@ -921,19 +933,61 @@ public boolean onKey(View v, int keyCode, KeyEvent event) {
921933 public boolean onShowFileChooser (WebView webView , ValueCallback <Uri []> filePathCallback , WebChromeClient .FileChooserParams fileChooserParams )
922934 {
923935 LOG .d (LOG_TAG , "File Chooser 5.0+" );
936+ if (Build .VERSION .SDK_INT >= 23 && (cordova .getActivity ().checkSelfPermission (
937+ Manifest .permission .WRITE_EXTERNAL_STORAGE ) != PackageManager .PERMISSION_GRANTED
938+ || cordova .getActivity ().checkSelfPermission (
939+ Manifest .permission .CAMERA ) != PackageManager .PERMISSION_GRANTED )) {
940+ cordova .getActivity ().requestPermissions (new String [] {
941+ Manifest .permission .WRITE_EXTERNAL_STORAGE , Manifest .permission .CAMERA }, 1 );
942+ }
943+
924944 // If callback exists, finish it.
925- if (mUploadCallback != null ) {
945+ if (mUploadCallback != null ) {
926946 mUploadCallback .onReceiveValue (null );
927947 }
928948 mUploadCallback = filePathCallback ;
929949
950+ Intent takePictureIntent = new Intent (MediaStore .ACTION_IMAGE_CAPTURE );
951+
952+ if (takePictureIntent .resolveActivity (cordova .getActivity ().getPackageManager ()) != null ) {
953+
954+ File photoFile = null ;
955+ try {
956+ photoFile = createImageFile ();
957+ takePictureIntent .putExtra ("PhotoPath" , photoFilePath );
958+ } catch (IOException ex ) {
959+ Log .e (LOG_TAG , "Image file creation failed" , ex );
960+ }
961+ if (photoFile != null ) {
962+ photoFilePath = "file:/" + photoFile .getAbsolutePath ();
963+ photoFileUri = FileProvider .getUriForFile (
964+ cordova .getActivity ().getApplicationContext (),
965+ cordova .getActivity ().getPackageName () + ".fileprovider" ,
966+ photoFile
967+ );
968+ takePictureIntent .putExtra (MediaStore .EXTRA_OUTPUT , photoFileUri );
969+ } else {
970+ takePictureIntent = null ;
971+ }
972+ }
930973 // Create File Chooser Intent
931- Intent content = new Intent (Intent .ACTION_GET_CONTENT );
932- content .addCategory (Intent .CATEGORY_OPENABLE );
933- content .setType ("*/*" );
974+ Intent contentSelectionIntent = new Intent (Intent .ACTION_GET_CONTENT );
975+ contentSelectionIntent .addCategory (Intent .CATEGORY_OPENABLE );
976+ contentSelectionIntent .setType ("*/*" );
977+ Intent [] intentArray ;
978+ if (takePictureIntent != null ) {
979+ intentArray = new Intent [] { takePictureIntent };
980+ } else {
981+ intentArray = new Intent [0 ];
982+ }
983+
984+ Intent chooserIntent = new Intent (Intent .ACTION_CHOOSER );
985+ chooserIntent .putExtra (Intent .EXTRA_INTENT , contentSelectionIntent );
986+ chooserIntent .putExtra (Intent .EXTRA_INITIAL_INTENTS , intentArray );
934987
935988 // Run cordova startActivityForResult
936- cordova .startActivityForResult (InAppBrowser .this , Intent .createChooser (content , "Select File" ), FILECHOOSER_REQUESTCODE );
989+ cordova .startActivityForResult (InAppBrowser .this , chooserIntent , FILECHOOSER_REQUESTCODE );
990+
937991 return true ;
938992 }
939993 });
@@ -1047,6 +1101,22 @@ public void postMessage(String data) {
10471101 return "" ;
10481102 }
10491103
1104+ private File createImageFile () throws IOException {
1105+ @ SuppressLint ("SimpleDateFormat" ) String timeStamp = new SimpleDateFormat ("yyyyMMdd_HHmmss" ).format (new Date ());
1106+ String imageFileName = "img_" +timeStamp +"_" ;
1107+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .P ) {
1108+ // let's use the new api for accessing external storage on 29 onwards
1109+ File storageDir = this .cordova .getActivity ().getExternalFilesDir (Environment .DIRECTORY_PICTURES );
1110+ File file = new File (storageDir , imageFileName + ".jpg" );
1111+ return file ;
1112+ } else {
1113+ // was working well on older droids so let's leave it as is.
1114+ File storageDir = Environment .getExternalStoragePublicDirectory (Environment .DIRECTORY_PICTURES );
1115+ File file = File .createTempFile (imageFileName ,".jpg" ,storageDir );
1116+ return file ;
1117+ }
1118+ }
1119+
10501120 /**
10511121 * Create a new plugin success result and send it back to JavaScript
10521122 *
@@ -1087,6 +1157,10 @@ public void onActivityResult(int requestCode, int resultCode, Intent intent) {
10871157 super .onActivityResult (requestCode , resultCode , intent );
10881158 return ;
10891159 }
1160+ // Intent data are empty when using camera
1161+ if (intent != null && intent .getData () == null ) {
1162+ intent .setData (photoFileUri );
1163+ }
10901164 mUploadCallback .onReceiveValue (WebChromeClient .FileChooserParams .parseResult (resultCode , intent ));
10911165 mUploadCallback = null ;
10921166 }
0 commit comments