001package com.gigya.android.sdk.ui.plugin; 002 003import android.Manifest; 004import android.content.Intent; 005import android.content.pm.PackageManager; 006import android.net.Uri; 007import android.os.Build; 008import android.provider.MediaStore; 009import android.support.annotation.NonNull; 010import android.support.v4.app.Fragment; 011import android.support.v4.content.ContextCompat; 012import android.webkit.ValueCallback; 013import android.webkit.WebChromeClient; 014import android.webkit.WebView; 015 016import com.gigya.android.sdk.GigyaLogger; 017import com.gigya.android.sdk.utils.FileUtils; 018 019import java.io.File; 020import java.lang.ref.WeakReference; 021 022import static android.app.Activity.RESULT_OK; 023 024public class GigyaPluginFileChooser extends WebChromeClient { 025 026 private final WeakReference<Fragment> _fragmentRef; 027 028 GigyaPluginFileChooser(Fragment fragment) { 029 _fragmentRef = new WeakReference<>(fragment); 030 } 031 032 private Fragment getFragment() { 033 return _fragmentRef.get(); 034 } 035 036 private static final String LOG_TAG = "GigyaPluginFileChooser"; 037 038 static final int FIRE_ACCESS_PERMISSION_REQUEST_CODE = 14; 039 static final int FILE_CHOOSER_MEDIA_REQUEST_CODE = 15; 040 private String _cameraTempImagePath; 041 private ValueCallback<Uri[]> _imagePathCallback; 042 043 @Override 044 public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) { 045 GigyaLogger.debug(LOG_TAG, "onShowFileChooser: "); 046 if (getFragment() == null) { 047 return false; 048 } 049 050 if (_imagePathCallback != null) { 051 _imagePathCallback.onReceiveValue(null); 052 } 053 _imagePathCallback = filePathCallback; 054 055 final int externalStoragePermission = ContextCompat.checkSelfPermission(webView.getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE); 056 if (externalStoragePermission == PackageManager.PERMISSION_GRANTED) { 057 sendImageChooserIntent(); 058 } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 059 getFragment().requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, FIRE_ACCESS_PERMISSION_REQUEST_CODE); 060 } else { 061 GigyaLogger.error(LOG_TAG, "Application must include Manifest.permission.WRITE_EXTERNAL_STORAGE in order to communicate with file system"); 062 return false; 063 } 064 return true; 065 } 066 067 private void sendImageChooserIntent() { 068 if (getFragment() == null) { 069 return; 070 } 071 GigyaLogger.debug(LOG_TAG, "Sending image chooser intent."); 072 Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 073 if (takePictureIntent.resolveActivity(getFragment().getActivity().getPackageManager()) != null) { 074 File imageFile = null; 075 try { 076 imageFile = FileUtils.createImageFile(); 077 takePictureIntent.putExtra("imagePath", _cameraTempImagePath); 078 } catch (Exception ex) { 079 ex.printStackTrace(); 080 } 081 if (imageFile != null) { 082 _cameraTempImagePath = "file:" + imageFile.getAbsolutePath(); 083 takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(imageFile)); 084 } else { 085 takePictureIntent = null; 086 } 087 } 088 089 // Set up an image file chooser intent. 090 final Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT); 091 contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE); 092 contentSelectionIntent.setType("image/*"); 093 094 final Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER); 095 chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent); 096 chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser"); 097 chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, takePictureIntent != null ? 098 new Intent[]{takePictureIntent} : new Intent[0]); 099 getFragment().startActivityForResult(chooserIntent, FILE_CHOOSER_MEDIA_REQUEST_CODE); 100 } 101 102 void onActivityResult(int resultCode, Intent data) { 103 Uri[] results = null; 104 if (resultCode == RESULT_OK) { 105 if (data != null && data.getDataString() != null) { 106 String dataString = data.getDataString(); 107 results = new Uri[]{Uri.parse(dataString)}; 108 } 109 // If there is not data, then we may have taken a photo 110 else if (_cameraTempImagePath != null) { 111 results = new Uri[]{Uri.parse(_cameraTempImagePath)}; 112 } 113 } 114 _imagePathCallback.onReceiveValue(results); 115 _imagePathCallback = null; 116 } 117 118 void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 119 GigyaLogger.debug(LOG_TAG, "onRequestPermissionsResult:"); 120 if (requestCode == FIRE_ACCESS_PERMISSION_REQUEST_CODE) { 121 if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 122 GigyaLogger.debug(LOG_TAG, "External storage permission explicitly granted."); 123 if (_imagePathCallback != null) { 124 sendImageChooserIntent(); 125 } 126 } else { 127 // Permission denied by the user. 128 GigyaLogger.debug(LOG_TAG, "External storage permission explicitly denied."); 129 } 130 } 131 } 132}