package net.alhazmy13.mediapicker.Image; import android.Manifest; import android.annotation.TargetApi; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.provider.MediaStore; import android.support.annotation.NonNull; import android.support.v4.app.ActivityCompat; import android.support.v4.content.FileProvider; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.widget.Toast; import net.alhazmy13.camerapicker.R; import net.alhazmy13.mediapicker.FileProcessing; import net.alhazmy13.mediapicker.Utility; import java.io.File; import java.io.IOException; import java.io.Serializable; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Created by Alhazmy13 on 10/26/15. * MediaPicker */ public class ImageActivity extends AppCompatActivity { private static final String TAG = "ImageActivity"; private File destination; private Uri mImageUri; private ImageConfig mImgConfig; private List<String> listOfImgs; public static Intent getCallingIntent(Context activity, ImageConfig imageConfig) { Intent intent = new Intent(activity, ImageActivity.class); intent.putExtra(ImageTags.Tags.IMG_CONFIG, imageConfig); return intent; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Intent intent = getIntent(); if (intent != null) { mImgConfig = (ImageConfig) intent.getSerializableExtra(ImageTags.Tags.IMG_CONFIG); } if (savedInstanceState == null) { pickImageWrapper(); listOfImgs = new ArrayList<>(); } if (mImgConfig.debug) Log.d(ImageTags.Tags.TAG, mImgConfig.toString()); } private void pickImage() { Utility.createFolder(mImgConfig.directory); destination = new File(mImgConfig.directory, Utility.getRandomString() + mImgConfig.extension.getValue()); switch (mImgConfig.mode) { case CAMERA: startActivityFromCamera(); break; case GALLERY: if (mImgConfig.allowMultiple) startActivityFromGalleryMultiImg(); else startActivityFromGallery(); break; case CAMERA_AND_GALLERY: showFromCameraOrGalleryAlert(); break; default: break; } } private void showFromCameraOrGalleryAlert() { new AlertDialog.Builder(this) .setTitle(getString(R.string.media_picker_select_from)) .setPositiveButton(getString(R.string.media_picker_camera), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { if (mImgConfig.debug) Log.d(ImageTags.Tags.TAG, "Alert Dialog - Start From Camera"); startActivityFromCamera(); } }) .setNegativeButton(getString(R.string.media_picker_gallery), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { if (mImgConfig.debug) Log.d(ImageTags.Tags.TAG, "Alert Dialog - Start From Gallery"); if (mImgConfig.allowMultiple) startActivityFromGalleryMultiImg(); else startActivityFromGallery(); } }) .setOnCancelListener(new DialogInterface.OnCancelListener() { @Override public void onCancel(DialogInterface dialogInterface) { if (mImgConfig.debug) Log.d(ImageTags.Tags.TAG, "Alert Dialog - Canceled"); finish(); } }) .show(); } private void startActivityFromGallery() { mImgConfig.isImgFromCamera = false; Intent photoPickerIntent = new Intent(Intent.ACTION_PICK); // photoPickerIntent.putExtra(Intent.EXTRA_LOCAL_ONLY, true); photoPickerIntent.setType("image/*"); startActivityForResult(photoPickerIntent, ImageTags.IntentCode.REQUEST_CODE_SELECT_PHOTO); if (mImgConfig.debug) Log.d(ImageTags.Tags.TAG, "Gallery Start with Single Image mode"); } @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) private void startActivityFromGalleryMultiImg() { mImgConfig.isImgFromCamera = false; Intent photoPickerIntent = new Intent(); photoPickerIntent.putExtra(Intent.EXTRA_LOCAL_ONLY, true); photoPickerIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); photoPickerIntent.setAction(Intent.ACTION_GET_CONTENT); photoPickerIntent.setType("image/*"); startActivityForResult(Intent.createChooser(photoPickerIntent, "Select Picture"), ImageTags.IntentCode.REQUEST_CODE_SELECT_MULTI_PHOTO); if (mImgConfig.debug) Log.d(ImageTags.Tags.TAG, "Gallery Start with Multiple Images mode"); } private void startActivityFromCamera() { mImgConfig.isImgFromCamera = true; Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); mImageUri = FileProvider.getUriForFile(this, this.getApplicationContext().getPackageName() + ".provider", destination); intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri); startActivityForResult(Intent.createChooser(intent, "Select Picture"), ImageTags.IntentCode.CAMERA_REQUEST); if (mImgConfig.debug) Log.d(ImageTags.Tags.TAG, "Camera Start"); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); if (mImageUri != null) { outState.putString(ImageTags.Tags.CAMERA_IMAGE_URI, mImageUri.toString()); outState.putSerializable(ImageTags.Tags.IMG_CONFIG, mImgConfig); } } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); if (savedInstanceState.containsKey(ImageTags.Tags.CAMERA_IMAGE_URI)) { mImageUri = Uri.parse(savedInstanceState.getString(ImageTags.Tags.CAMERA_IMAGE_URI)); destination = new File(mImageUri.getPath()); mImgConfig = (ImageConfig) savedInstanceState.getSerializable(ImageTags.Tags.IMG_CONFIG); } } @TargetApi(Build.VERSION_CODES.JELLY_BEAN) @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { Log.d(ImageTags.Tags.TAG, "onActivityResult() called with: " + "requestCode = [" + requestCode + "], resultCode = [" + resultCode + "], data = [" + data + "]"); if (resultCode == RESULT_OK) { switch (requestCode) { case ImageTags.IntentCode.CAMERA_REQUEST: new CompressImageTask(destination.getAbsolutePath(), mImgConfig , ImageActivity.this).execute(); break; case ImageTags.IntentCode.REQUEST_CODE_SELECT_PHOTO: processOneImage(data); break; case ImageTags.IntentCode.REQUEST_CODE_SELECT_MULTI_PHOTO: //Check if the intent contain only one image if (data.getClipData() == null) { processOneImage(data); } else { //intent has multi images listOfImgs = ImageProcessing.processMultiImage(this, data); new CompressImageTask(listOfImgs, mImgConfig, ImageActivity.this).execute(); } break; default: break; } } else { Intent intent = new Intent(); intent.setAction("net.alhazmy13.mediapicker.rxjava.image.service"); intent.putExtra(ImageTags.Tags.PICK_ERROR, "user did not select any image"); sendBroadcast(intent); finish(); } } private void processOneImage(Intent data) { try { Uri selectedImage = data.getData(); String selectedImagePath = FileProcessing.getPath(this, selectedImage); new CompressImageTask(selectedImagePath, mImgConfig, ImageActivity.this).execute(); } catch (Exception ex) { ex.printStackTrace(); } } private void finishActivity(List<String> path) { Intent resultIntent = new Intent(); resultIntent.putExtra(ImagePicker.EXTRA_IMAGE_PATH, (Serializable) path); setResult(RESULT_OK, resultIntent); finish(); } private void pickImageWrapper() { if (Build.VERSION.SDK_INT >= 23) { List<String> permissionsNeeded = new ArrayList<String>(); final List<String> permissionsList = new ArrayList<String>(); if((mImgConfig.mode == ImagePicker.Mode.CAMERA || mImgConfig.mode == ImagePicker.Mode.CAMERA_AND_GALLERY) && !addPermission(permissionsList, Manifest.permission.CAMERA)) permissionsNeeded.add(getString(R.string.media_picker_camera)); if (!addPermission(permissionsList, Manifest.permission.WRITE_EXTERNAL_STORAGE)) permissionsNeeded.add(getString(R.string.media_picker_read_Write_external_storage)); if (permissionsList.size() > 0) { if (permissionsNeeded.size() > 0) { // Need Rationale String message = getString(R.string.media_picker_you_need_to_grant_access_to) + permissionsNeeded.get(0); for (int i = 1; i < permissionsNeeded.size(); i++) message = message + ", " + permissionsNeeded.get(i); showMessageOKCancel(message, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { ActivityCompat.requestPermissions(ImageActivity.this, permissionsList.toArray(new String[permissionsList.size()]), ImageTags.IntentCode.REQUEST_CODE_ASK_PERMISSIONS); } }); return; } ActivityCompat.requestPermissions(ImageActivity.this, permissionsList.toArray(new String[permissionsList.size()]), ImageTags.IntentCode.REQUEST_CODE_ASK_PERMISSIONS); return; } pickImage(); } else { pickImage(); } } private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) { new AlertDialog.Builder(ImageActivity.this) .setMessage(message) .setPositiveButton(getString(R.string.media_picker_ok), okListener) .setNegativeButton(getString(R.string.media_picker_cancel), null) .create() .show(); } private boolean addPermission(List<String> permissionsList, String permission) { if (ActivityCompat.checkSelfPermission(ImageActivity.this, permission) != PackageManager.PERMISSION_GRANTED) { permissionsList.add(permission); // Check for Rationale Option if (!ActivityCompat.shouldShowRequestPermissionRationale(ImageActivity.this, permission)) return false; } return true; } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { switch (requestCode) { case ImageTags.IntentCode.REQUEST_CODE_ASK_PERMISSIONS: Map<String, Integer> perms = new HashMap<String, Integer>(); // Initial perms.put(Manifest.permission.CAMERA, PackageManager.PERMISSION_GRANTED); perms.put(Manifest.permission.WRITE_EXTERNAL_STORAGE, PackageManager.PERMISSION_GRANTED); // Fill with results for (int i = 0; i < permissions.length; i++) perms.put(permissions[i], grantResults[i]); // Check for ACCESS_FINE_LOCATION if (perms.get(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED && perms.get(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { // All Permissions Granted pickImage(); } else { // Permission Denied Toast.makeText(ImageActivity.this, getString(R.string.media_picker_some_permission_is_denied), Toast.LENGTH_SHORT) .show(); } break; default: super.onRequestPermissionsResult(requestCode, permissions, grantResults); } } private static class CompressImageTask extends AsyncTask<Void, Void, Void> { private final ImageConfig mImgConfig; private final List<String> listOfImgs; private List<String> destinationPaths; private WeakReference<ImageActivity> mContext; public CompressImageTask(List<String> listOfImgs, ImageConfig imageConfig, ImageActivity context) { this.listOfImgs = listOfImgs; this.mContext = new WeakReference<>(context); this.mImgConfig = imageConfig; this.destinationPaths = new ArrayList<>(); } public CompressImageTask(String absolutePath, ImageConfig imageConfig, ImageActivity context) { List<String> list = new ArrayList<>(); list.add(absolutePath); this.listOfImgs = list; this.mContext = new WeakReference<>(context); this.destinationPaths = new ArrayList<>(); this.mImgConfig = imageConfig; } @Override protected Void doInBackground(Void... params) { for (String mPath : listOfImgs) { File file = new File(mPath); File destinationFile = null; if (mImgConfig.isImgFromCamera) { destinationFile = file; } else { destinationFile = new File(mImgConfig.directory, Utility.getRandomString() + mImgConfig.extension.getValue()); } destinationPaths.add(destinationFile.getAbsolutePath()); try { Utility.compressAndRotateIfNeeded(file, destinationFile, mImgConfig.compressLevel.getValue(), mImgConfig.reqWidth, mImgConfig.reqHeight); } catch (IOException e) { e.printStackTrace(); } } return null; } @Override protected void onPostExecute(Void aVoid) { super.onPostExecute(aVoid); ImageActivity context = mContext.get(); if (context != null) { context.finishActivity(destinationPaths); Intent intent = new Intent(); intent.setAction("net.alhazmy13.mediapicker.rxjava.image.service"); intent.putExtra(ImageTags.Tags.IMAGE_PATH, (Serializable) destinationPaths); context.sendBroadcast(intent); } } } }