diff --git a/multipleimageselect/.gitignore b/multipleimageselect/.gitignore
new file mode 100644
index 00000000..796b96d1
--- /dev/null
+++ b/multipleimageselect/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/multipleimageselect/build.gradle b/multipleimageselect/build.gradle
new file mode 100644
index 00000000..e1b17a81
--- /dev/null
+++ b/multipleimageselect/build.gradle
@@ -0,0 +1,28 @@
+apply plugin: 'com.android.library'
+
+android {
+ compileSdkVersion 25
+ buildToolsVersion "25.0.2"
+
+ defaultConfig {
+ minSdkVersion 15
+ targetSdkVersion 25
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ compile fileTree(dir: 'libs', include: ['*.jar'])
+ compile 'com.android.support:appcompat-v7:25.1.1'
+ compile 'com.github.bumptech.glide:glide:3.7.0'
+ compile 'com.android.support:design:25.1.1'
+}
diff --git a/multipleimageselect/proguard-rules.pro b/multipleimageselect/proguard-rules.pro
new file mode 100644
index 00000000..85237996
--- /dev/null
+++ b/multipleimageselect/proguard-rules.pro
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/zhouxiaodong/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/multipleimageselect/src/main/AndroidManifest.xml b/multipleimageselect/src/main/AndroidManifest.xml
new file mode 100644
index 00000000..cdd2930b
--- /dev/null
+++ b/multipleimageselect/src/main/AndroidManifest.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/multipleimageselect/src/main/java/darsh/multipleimageselect/activities/AlbumSelectActivity.java b/multipleimageselect/src/main/java/darsh/multipleimageselect/activities/AlbumSelectActivity.java
new file mode 100644
index 00000000..9037b95f
--- /dev/null
+++ b/multipleimageselect/src/main/java/darsh/multipleimageselect/activities/AlbumSelectActivity.java
@@ -0,0 +1,334 @@
+package darsh.multipleimageselect.activities;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Process;
+import android.provider.MediaStore;
+import android.support.v7.app.ActionBar;
+import android.support.v7.widget.Toolbar;
+import android.util.DisplayMetrics;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.GridView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+import darsh.multipleimageselect.R;
+import darsh.multipleimageselect.adapters.CustomAlbumSelectAdapter;
+import darsh.multipleimageselect.helpers.Constants;
+import darsh.multipleimageselect.models.Album;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashSet;
+
+/**
+ * Created by Darshan on 4/14/2015.
+ */
+public class AlbumSelectActivity extends HelperActivity
+ implements CustomAlbumSelectAdapter.OnItemClick {
+ private ArrayList albums;
+
+ private TextView errorDisplay, txtTitle;
+
+ private ProgressBar progressBar;
+ private GridView gridView;
+ private CustomAlbumSelectAdapter adapter;
+
+ private ActionBar actionBar;
+
+ private ContentObserver observer;
+ private Handler handler;
+ private Thread thread;
+
+ private final String[] projection = new String[] {
+ MediaStore.Images.Media.BUCKET_ID, MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
+ MediaStore.Images.Media.DATA
+ };
+
+ @Override protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_album_select);
+ setView(findViewById(R.id.layout_album_select));
+
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ txtTitle = (TextView) findViewById(R.id.txt_title);
+ setSupportActionBar(toolbar);
+ //SystemBarHelper.immersiveStatusBar(this);
+ //SystemBarHelper.setHeightAndPadding(this, toolbar);
+ actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setHomeAsUpIndicator(R.drawable.ic_arrow_back);
+ actionBar.setDisplayShowTitleEnabled(false);
+ txtTitle.setText(getString(R.string.album_view));
+ }
+
+ Intent intent = getIntent();
+ if (intent == null) {
+ finish();
+ }
+ Constants.limit = intent.getIntExtra(Constants.INTENT_EXTRA_LIMIT, Constants.DEFAULT_LIMIT);
+ Constants.cameraEnable = intent.getBooleanExtra(Constants.EXTRA_CAMERA_ENABLE, false);
+
+ errorDisplay = (TextView) findViewById(R.id.text_view_error);
+ errorDisplay.setVisibility(View.INVISIBLE);
+
+ progressBar = (ProgressBar) findViewById(R.id.progress_bar_album_select);
+ gridView = (GridView) findViewById(R.id.grid_view_album_select);
+ }
+
+ @Override protected void onStart() {
+ super.onStart();
+
+ handler = new Handler() {
+ @Override public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case Constants.PERMISSION_GRANTED: {
+ loadAlbums();
+ break;
+ }
+
+ case Constants.FETCH_STARTED: {
+ progressBar.setVisibility(View.VISIBLE);
+ gridView.setVisibility(View.INVISIBLE);
+ break;
+ }
+
+ case Constants.FETCH_COMPLETED: {
+ if (adapter == null) {
+ adapter = new CustomAlbumSelectAdapter(getApplicationContext(), albums,
+ Constants.cameraEnable);
+ gridView.setAdapter(adapter);
+ adapter.setOnItemClick(AlbumSelectActivity.this);
+
+ progressBar.setVisibility(View.INVISIBLE);
+ gridView.setVisibility(View.VISIBLE);
+ orientationBasedUI(getResources().getConfiguration().orientation);
+ } else {
+ adapter.notifyDataSetChanged();
+ }
+ break;
+ }
+
+ case Constants.ERROR: {
+ progressBar.setVisibility(View.INVISIBLE);
+ errorDisplay.setVisibility(View.VISIBLE);
+ break;
+ }
+
+ default: {
+ super.handleMessage(msg);
+ }
+ }
+ }
+ };
+ observer = new ContentObserver(handler) {
+ @Override public void onChange(boolean selfChange, Uri uri) {
+ loadAlbums();
+ }
+ };
+ getContentResolver().registerContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
+ false, observer);
+
+ checkPermission();
+ }
+
+ @Override protected void onStop() {
+ super.onStop();
+
+ stopThread();
+
+ getContentResolver().unregisterContentObserver(observer);
+ observer = null;
+
+ if (handler != null) {
+ handler.removeCallbacksAndMessages(null);
+ handler = null;
+ }
+ }
+
+ @Override protected void onDestroy() {
+ super.onDestroy();
+
+ if (actionBar != null) {
+ actionBar.setHomeAsUpIndicator(null);
+ }
+ albums = null;
+ if (adapter != null) {
+ adapter.setOnItemClick(null);
+ adapter.releaseResources();
+ }
+ }
+
+ @Override public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ orientationBasedUI(newConfig.orientation);
+ }
+
+ private void orientationBasedUI(int orientation) {
+ final WindowManager windowManager =
+ (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
+ final DisplayMetrics metrics = new DisplayMetrics();
+ windowManager.getDefaultDisplay().getMetrics(metrics);
+
+ if (adapter != null) {
+ int size = orientation == Configuration.ORIENTATION_PORTRAIT ? metrics.widthPixels / 2
+ : metrics.widthPixels / 4;
+ adapter.setLayoutParams(size);
+ }
+ gridView.setNumColumns(orientation == Configuration.ORIENTATION_PORTRAIT ? 2 : 4);
+ }
+
+ @Override public void onBackPressed() {
+ super.onBackPressed();
+ setResult(RESULT_CANCELED);
+ finish();
+ }
+
+ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ if (requestCode == Constants.REQUEST_CODE && resultCode == RESULT_OK && data != null) {
+ setResult(RESULT_OK, data);
+ finish();
+ }
+ }
+
+ @Override public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home: {
+ onBackPressed();
+ return true;
+ }
+
+ default: {
+ return false;
+ }
+ }
+ }
+
+ private void loadAlbums() {
+ startThread(new AlbumLoaderRunnable());
+ }
+
+ /**
+ * 选择图片
+ */
+ @Override public void select(int position) {
+ Intent intent = new Intent(getApplicationContext(), ImageSelectActivity.class);
+ intent.putExtra(Constants.INTENT_EXTRA_ALBUM, albums.get(position).name);
+ startActivityForResult(intent, Constants.REQUEST_CODE);
+ }
+
+ /**
+ * 拍照
+ */
+ @Override public void takePhoto() {
+ Intent intent = new Intent();
+ intent.putExtra(Constants.INTENT_EXTRA_START_CAMERA, true);
+ setResult(RESULT_OK, intent);
+ finish();
+ }
+
+ private class AlbumLoaderRunnable implements Runnable {
+ @Override public void run() {
+ Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+
+ if (adapter == null) {
+ sendMessage(Constants.FETCH_STARTED);
+ }
+
+ Cursor cursor = getApplicationContext().getContentResolver()
+ .query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, null, null,
+ MediaStore.Images.Media.DATE_ADDED);
+ if (cursor == null) {
+ sendMessage(Constants.ERROR);
+ return;
+ }
+
+ ArrayList temp = new ArrayList<>(cursor.getCount());
+ HashSet albumSet = new HashSet<>();
+ File file;
+ if (cursor.moveToLast()) {
+ do {
+ if (Thread.interrupted()) {
+ return;
+ }
+
+ long albumId = cursor.getLong(cursor.getColumnIndex(projection[0]));
+ String album = cursor.getString(cursor.getColumnIndex(projection[1]));
+ String image = cursor.getString(cursor.getColumnIndex(projection[2]));
+
+ if (!albumSet.contains(albumId)) {
+ /*
+ It may happen that some image file paths are still present in cache,
+ though image file does not exist. These last as long as media
+ scanner is not run again. To avoid get such image file paths, check
+ if image file exists.
+ */
+ file = new File(image);
+ if (file.exists()) {
+ temp.add(new Album(album, image));
+ albumSet.add(albumId);
+ }
+ }
+ } while (cursor.moveToPrevious());
+ }
+ cursor.close();
+
+ if (albums == null) {
+ albums = new ArrayList<>();
+ }
+ albums.clear();
+ albums.addAll(temp);
+
+ sendMessage(Constants.FETCH_COMPLETED);
+ }
+ }
+
+ private void startThread(Runnable runnable) {
+ stopThread();
+ thread = new Thread(runnable);
+ thread.start();
+ }
+
+ private void stopThread() {
+ if (thread == null || !thread.isAlive()) {
+ return;
+ }
+
+ thread.interrupt();
+ try {
+ thread.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void sendMessage(int what) {
+ if (handler == null) {
+ return;
+ }
+
+ Message message = handler.obtainMessage();
+ message.what = what;
+ message.sendToTarget();
+ }
+
+ @Override protected void permissionGranted() {
+ Message message = handler.obtainMessage();
+ message.what = Constants.PERMISSION_GRANTED;
+ message.sendToTarget();
+ }
+
+ @Override protected void hideViews() {
+ progressBar.setVisibility(View.INVISIBLE);
+ gridView.setVisibility(View.INVISIBLE);
+ }
+}
diff --git a/multipleimageselect/src/main/java/darsh/multipleimageselect/activities/HelperActivity.java b/multipleimageselect/src/main/java/darsh/multipleimageselect/activities/HelperActivity.java
new file mode 100644
index 00000000..c3ec1eaa
--- /dev/null
+++ b/multipleimageselect/src/main/java/darsh/multipleimageselect/activities/HelperActivity.java
@@ -0,0 +1,117 @@
+package darsh.multipleimageselect.activities;
+
+import android.Manifest;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.provider.Settings;
+import android.support.annotation.NonNull;
+import android.support.design.widget.Snackbar;
+import android.support.v4.app.ActivityCompat;
+import android.support.v4.content.ContextCompat;
+import android.support.v7.app.AppCompatActivity;
+import android.view.View;
+import darsh.multipleimageselect.R;
+import darsh.multipleimageselect.helpers.Constants;
+
+/**
+ * Created by darshan on 26/9/16.
+ */
+public class HelperActivity extends AppCompatActivity {
+ protected View view;
+
+ private final int maxLines = 4;
+ private final String[] permissions = new String[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE };
+
+ protected void checkPermission() {
+ if (ContextCompat.checkSelfPermission(this,
+ Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
+ permissionGranted();
+
+ } else {
+ ActivityCompat.requestPermissions(this, permissions, Constants.PERMISSION_REQUEST_CODE);
+ }
+ }
+
+ private void requestPermission() {
+ if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
+ showRequestPermissionRationale();
+
+ } else {
+ showAppPermissionSettings();
+ }
+ }
+
+ private void showRequestPermissionRationale() {
+ Snackbar snackbar = Snackbar.make(
+ view,
+ getString(R.string.permission_info),
+ Snackbar.LENGTH_INDEFINITE)
+ .setAction(getString(R.string.permission_ok), new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ ActivityCompat.requestPermissions(
+ HelperActivity.this,
+ permissions,
+ Constants.PERMISSION_REQUEST_CODE);
+ }
+ });
+
+ /*((TextView) snackbar.getView()
+ .findViewById(android.support.design.R.id.snackbar_text)).setMaxLines(maxLines);*/
+ snackbar.show();
+ }
+
+ private void showAppPermissionSettings() {
+ Snackbar snackbar = Snackbar.make(
+ view,
+ getString(R.string.permission_force),
+ Snackbar.LENGTH_INDEFINITE)
+ .setAction(getString(R.string.permission_settings), new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Uri uri = Uri.fromParts(
+ getString(R.string.permission_package),
+ HelperActivity.this.getPackageName(),
+ null);
+
+ Intent intent = new Intent();
+ intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
+ intent.setData(uri);
+ startActivityForResult(intent, Constants.PERMISSION_REQUEST_CODE);
+ }
+ });
+
+ /*((TextView) snackbar.getView()
+ .findViewById(android.support.design.R.id.snackbar_text)).setMaxLines(maxLines);*/
+ snackbar.show();
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull
+ int[] grantResults) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+ if (requestCode != Constants.PERMISSION_REQUEST_CODE
+ || grantResults.length == 0
+ || grantResults[0] == PackageManager.PERMISSION_DENIED) {
+ permissionDenied();
+
+ } else {
+ permissionGranted();
+ }
+ }
+
+ protected void permissionGranted() {}
+
+ private void permissionDenied() {
+ hideViews();
+ requestPermission();
+ }
+
+ protected void hideViews() {}
+
+ protected void setView(View view) {
+ this.view = view;
+ }
+}
diff --git a/multipleimageselect/src/main/java/darsh/multipleimageselect/activities/ImageSelectActivity.java b/multipleimageselect/src/main/java/darsh/multipleimageselect/activities/ImageSelectActivity.java
new file mode 100644
index 00000000..22eda201
--- /dev/null
+++ b/multipleimageselect/src/main/java/darsh/multipleimageselect/activities/ImageSelectActivity.java
@@ -0,0 +1,386 @@
+package darsh.multipleimageselect.activities;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Process;
+import android.provider.MediaStore;
+import android.support.v7.app.ActionBar;
+import android.support.v7.widget.Toolbar;
+import android.text.TextUtils;
+import android.util.DisplayMetrics;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.AdapterView;
+import android.widget.GridView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+import android.widget.Toast;
+import darsh.multipleimageselect.R;
+import darsh.multipleimageselect.adapters.CustomImageSelectAdapter;
+import darsh.multipleimageselect.helpers.Constants;
+import darsh.multipleimageselect.models.Image;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashSet;
+
+/**
+ * Created by Darshan on 4/18/2015.
+ */
+public class ImageSelectActivity extends HelperActivity {
+ private ArrayList images;
+ private String album;
+
+ private TextView errorDisplay, txtFinish, txtTitle;
+
+ private ProgressBar progressBar;
+ private GridView gridView;
+ private CustomImageSelectAdapter adapter;
+
+ private ActionBar actionBar;
+
+ private int countSelected;
+
+ private ContentObserver observer;
+ private Handler handler;
+ private Thread thread;
+
+ private final String[] projection = new String[] {
+ MediaStore.Images.Media._ID, MediaStore.Images.Media.DISPLAY_NAME,
+ MediaStore.Images.Media.DATA
+ };
+
+ @Override protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_image_select);
+ setView(findViewById(R.id.layout_image_select));
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ txtFinish = (TextView) findViewById(R.id.txt_finish);
+ txtTitle = (TextView) findViewById(R.id.txt_title);
+ setSupportActionBar(toolbar);
+ //SystemBarHelper.immersiveStatusBar(this);
+ //SystemBarHelper.setHeightAndPadding(this, toolbar);
+ actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setHomeAsUpIndicator(R.drawable.ic_arrow_back);
+ actionBar.setDisplayShowTitleEnabled(false);
+ setTitle(getString(R.string.image_view));
+ }
+ toolbar.setNavigationOnClickListener(new View.OnClickListener() {
+ @Override public void onClick(View view) {
+ onBackPressed();
+ }
+ });
+ txtFinish.setOnClickListener(new View.OnClickListener() {
+ @Override public void onClick(View v) {
+ if (countSelected > 0) sendIntent();
+ }
+ });
+ Intent intent = getIntent();
+ if (intent == null) {
+ finish();
+ }
+ album = intent.getStringExtra(Constants.INTENT_EXTRA_ALBUM);
+
+ errorDisplay = (TextView) findViewById(R.id.text_view_error);
+ errorDisplay.setVisibility(View.INVISIBLE);
+
+ progressBar = (ProgressBar) findViewById(R.id.progress_bar_image_select);
+ gridView = (GridView) findViewById(R.id.grid_view_image_select);
+ gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ toggleSelection(position);
+ String selectFormat = getString(R.string.selected);
+ setTitle(String.format(selectFormat, Constants.limit - countSelected + "张"));
+ txtFinish.setVisibility(View.VISIBLE);
+ if (countSelected == 0) {
+ setTitle(getString(R.string.image_view));
+ txtFinish.setVisibility(View.INVISIBLE);
+ }
+ }
+ });
+ }
+
+ @Override protected void onStart() {
+ super.onStart();
+
+ handler = new Handler() {
+ @Override public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case Constants.PERMISSION_GRANTED: {
+ loadImages();
+ break;
+ }
+
+ case Constants.FETCH_STARTED: {
+ progressBar.setVisibility(View.VISIBLE);
+ gridView.setVisibility(View.INVISIBLE);
+ break;
+ }
+
+ case Constants.FETCH_COMPLETED: {
+ /*
+ If adapter is null, this implies that the loaded images will be shown
+ for the first time, hence send FETCH_COMPLETED message.
+ However, if adapter has been initialised, this thread was run either
+ due to the activity being restarted or content being changed.
+ */
+ if (adapter == null) {
+ adapter = new CustomImageSelectAdapter(getApplicationContext(), images);
+ gridView.setAdapter(adapter);
+
+ progressBar.setVisibility(View.INVISIBLE);
+ gridView.setVisibility(View.VISIBLE);
+ orientationBasedUI(getResources().getConfiguration().orientation);
+ } else {
+ adapter.notifyDataSetChanged();
+ /*
+ Some selected images may have been deleted
+ hence update action mode title
+ */
+ //if (actionMode != null) {
+ // countSelected = msg.arg1;
+ // actionMode.setTitle(countSelected + " 已选");
+ //}
+ }
+ break;
+ }
+
+ case Constants.ERROR: {
+ progressBar.setVisibility(View.INVISIBLE);
+ errorDisplay.setVisibility(View.VISIBLE);
+ break;
+ }
+
+ default: {
+ super.handleMessage(msg);
+ }
+ }
+ }
+ };
+ observer = new ContentObserver(handler) {
+ @Override public void onChange(boolean selfChange) {
+ loadImages();
+ }
+ };
+ getContentResolver().registerContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
+ false, observer);
+
+ checkPermission();
+ }
+
+ @Override protected void onStop() {
+ super.onStop();
+
+ stopThread();
+
+ getContentResolver().unregisterContentObserver(observer);
+ observer = null;
+
+ if (handler != null) {
+ handler.removeCallbacksAndMessages(null);
+ handler = null;
+ }
+ }
+
+ @Override protected void onDestroy() {
+ super.onDestroy();
+
+ if (actionBar != null) {
+ actionBar.setHomeAsUpIndicator(null);
+ }
+ images = null;
+ if (adapter != null) {
+ adapter.releaseResources();
+ }
+ gridView.setOnItemClickListener(null);
+ }
+
+ @Override public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ orientationBasedUI(newConfig.orientation);
+ }
+
+ private void orientationBasedUI(int orientation) {
+ final WindowManager windowManager =
+ (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
+ final DisplayMetrics metrics = new DisplayMetrics();
+ windowManager.getDefaultDisplay().getMetrics(metrics);
+
+ if (adapter != null) {
+ int size = orientation == Configuration.ORIENTATION_PORTRAIT ? metrics.widthPixels / 3
+ : metrics.widthPixels / 5;
+ adapter.setLayoutParams(size);
+ }
+ gridView.setNumColumns(orientation == Configuration.ORIENTATION_PORTRAIT ? 3 : 5);
+ }
+
+ private void toggleSelection(int position) {
+ if (!images.get(position).isSelected && countSelected >= Constants.limit) {
+ Toast.makeText(getApplicationContext(), "照片已经达到上限", Toast.LENGTH_SHORT).show();
+ //Toast.makeText(getApplicationContext(),
+ // String.format(getString(R.string.limit_exceeded), Constants.limit), Toast.LENGTH_SHORT)
+ // .show();
+ return;
+ }
+
+ images.get(position).isSelected = !images.get(position).isSelected;
+ if (images.get(position).isSelected) {
+ countSelected++;
+ } else {
+ countSelected--;
+ }
+ adapter.notifyDataSetChanged();
+ }
+
+ private ArrayList getSelected() {
+ ArrayList selectedImages = new ArrayList<>();
+ for (int i = 0, l = images.size(); i < l; i++) {
+ if (images.get(i).isSelected) {
+ selectedImages.add(images.get(i));
+ }
+ }
+ return selectedImages;
+ }
+
+ private void sendIntent() {
+ Intent intent = new Intent();
+ intent.putParcelableArrayListExtra(Constants.INTENT_EXTRA_IMAGES, getSelected());
+ intent.putExtra(Constants.INTENT_EXTRA_START_CAMERA, false);
+ setResult(RESULT_OK, intent);
+ finish();
+ }
+
+ private void loadImages() {
+ startThread(new ImageLoaderRunnable());
+ }
+
+ private class ImageLoaderRunnable implements Runnable {
+ @Override public void run() {
+ Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+ /*
+ If the adapter is null, this is first time this activity's view is
+ being shown, hence send FETCH_STARTED message to show progress bar
+ while images are loaded from phone
+ */
+ if (adapter == null) {
+ sendMessage(Constants.FETCH_STARTED);
+ }
+
+ File file;
+ HashSet selectedImages = new HashSet<>();
+ if (images != null) {
+ Image image;
+ for (int i = 0, l = images.size(); i < l; i++) {
+ image = images.get(i);
+ file = new File(image.path);
+ if (file.exists() && image.isSelected) {
+ selectedImages.add(image.id);
+ }
+ }
+ }
+
+ Cursor cursor =
+ getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection,
+ MediaStore.Images.Media.BUCKET_DISPLAY_NAME + " =?", new String[] { album },
+ MediaStore.Images.Media.DATE_ADDED);
+ if (cursor == null) {
+ sendMessage(Constants.ERROR);
+ return;
+ }
+
+ /*
+ In case this runnable is executed to onChange calling loadImages,
+ using countSelected variable can result in a race condition. To avoid that,
+ tempCountSelected keeps track of number of selected images. On handling
+ FETCH_COMPLETED message, countSelected is assigned value of tempCountSelected.
+ */
+ int tempCountSelected = 0;
+ ArrayList temp = new ArrayList<>(cursor.getCount());
+ if (cursor.moveToLast()) {
+ do {
+ if (Thread.interrupted()) {
+ return;
+ }
+
+ long id = cursor.getLong(cursor.getColumnIndex(projection[0]));
+ String name = cursor.getString(cursor.getColumnIndex(projection[1]));
+ String path = cursor.getString(cursor.getColumnIndex(projection[2]));
+ boolean isSelected = selectedImages.contains(id);
+ if (isSelected) {
+ tempCountSelected++;
+ }
+
+ file = new File(path);
+ if (file.exists()) {
+ temp.add(new Image(id, name, path, isSelected));
+ }
+ } while (cursor.moveToPrevious());
+ }
+ cursor.close();
+
+ if (images == null) {
+ images = new ArrayList<>();
+ }
+ images.clear();
+ images.addAll(temp);
+
+ sendMessage(Constants.FETCH_COMPLETED, tempCountSelected);
+ }
+ }
+
+ private void startThread(Runnable runnable) {
+ stopThread();
+ thread = new Thread(runnable);
+ thread.start();
+ }
+
+ private void stopThread() {
+ if (thread == null || !thread.isAlive()) {
+ return;
+ }
+
+ thread.interrupt();
+ try {
+ thread.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void sendMessage(int what) {
+ sendMessage(what, 0);
+ }
+
+ private void sendMessage(int what, int arg1) {
+ if (handler == null) {
+ return;
+ }
+
+ Message message = handler.obtainMessage();
+ message.what = what;
+ message.arg1 = arg1;
+ message.sendToTarget();
+ }
+
+ @Override protected void permissionGranted() {
+ sendMessage(Constants.PERMISSION_GRANTED);
+ }
+
+ @Override protected void hideViews() {
+ progressBar.setVisibility(View.INVISIBLE);
+ gridView.setVisibility(View.INVISIBLE);
+ }
+
+ private void setTitle(String title) {
+ if (!TextUtils.isEmpty(title)) {
+ txtTitle.setText(title);
+ }
+ }
+}
diff --git a/multipleimageselect/src/main/java/darsh/multipleimageselect/adapters/CustomAlbumSelectAdapter.java b/multipleimageselect/src/main/java/darsh/multipleimageselect/adapters/CustomAlbumSelectAdapter.java
new file mode 100644
index 00000000..5e35acaf
--- /dev/null
+++ b/multipleimageselect/src/main/java/darsh/multipleimageselect/adapters/CustomAlbumSelectAdapter.java
@@ -0,0 +1,113 @@
+package darsh.multipleimageselect.adapters;
+
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.TextView;
+import com.bumptech.glide.Glide;
+import darsh.multipleimageselect.R;
+import darsh.multipleimageselect.models.Album;
+import java.util.ArrayList;
+
+/**
+ * Created by Darshan on 4/14/2015.
+ */
+public class CustomAlbumSelectAdapter extends CustomGenericAdapter {
+ private boolean enableCamera;
+ private OnItemClick onItemClick;
+
+ public CustomAlbumSelectAdapter(Context context, ArrayList albums, boolean enableCamera) {
+ super(context, albums);
+ this.enableCamera = enableCamera;
+ }
+
+ public void setOnItemClick(OnItemClick onItemClick) {
+ this.onItemClick = onItemClick;
+ }
+
+ @Override public int getCount() {
+ if (enableCamera) {
+ return super.getCount() + 1;
+ }
+ return super.getCount();
+ }
+
+ @Override public View getView(final int position, View convertView, ViewGroup parent) {
+ ViewHolder viewHolder;
+
+ if (convertView == null) {
+ convertView = layoutInflater.inflate(R.layout.grid_view_item_album_select, null);
+
+ viewHolder = new ViewHolder();
+ viewHolder.imageView = (ImageView) convertView.findViewById(R.id.image_view_album_image);
+ viewHolder.textView = (TextView) convertView.findViewById(R.id.text_view_album_name);
+ viewHolder.frameLayout = (FrameLayout) convertView.findViewById(R.id.frame_album_item);
+
+ convertView.setTag(viewHolder);
+ } else {
+ viewHolder = (ViewHolder) convertView.getTag();
+ }
+
+ viewHolder.imageView.getLayoutParams().width = size;
+ viewHolder.imageView.getLayoutParams().height = size;
+ //启用拍照
+ if (enableCamera) {
+ if (0 == position) {
+ if (null != onItemClick) {
+ viewHolder.frameLayout.setOnClickListener(new View.OnClickListener() {
+ @Override public void onClick(View v) {
+ onItemClick.takePhoto();
+ }
+ });
+ }
+ viewHolder.textView.setText("拍照");
+ Glide.with(context).load(R.drawable.ic_camera).centerCrop().into(viewHolder.imageView);
+ } else {
+ if (null != onItemClick) {
+ viewHolder.frameLayout.setOnClickListener(new View.OnClickListener() {
+ @Override public void onClick(View v) {
+ onItemClick.select(position-1);
+ }
+ });
+ }
+ viewHolder.textView.setText(arrayList.get(position - 1).name);
+ Glide.with(context)
+ .load(arrayList.get(position - 1).cover)
+ .placeholder(R.drawable.image_placeholder)
+ .centerCrop()
+ .into(viewHolder.imageView);
+ }
+ } else {
+ //不启用拍照
+ if (null != onItemClick) {
+ viewHolder.frameLayout.setOnClickListener(new View.OnClickListener() {
+ @Override public void onClick(View v) {
+ onItemClick.select(position);
+ }
+ });
+ }
+ viewHolder.textView.setText(arrayList.get(position).name);
+ Glide.with(context)
+ .load(arrayList.get(position).cover)
+ .placeholder(R.drawable.image_placeholder)
+ .centerCrop()
+ .into(viewHolder.imageView);
+ }
+
+ return convertView;
+ }
+
+ private static class ViewHolder {
+ public FrameLayout frameLayout;
+ public ImageView imageView;
+ public TextView textView;
+ }
+
+ public interface OnItemClick {
+ void select(int pos);
+
+ void takePhoto();
+ }
+}
diff --git a/multipleimageselect/src/main/java/darsh/multipleimageselect/adapters/CustomGenericAdapter.java b/multipleimageselect/src/main/java/darsh/multipleimageselect/adapters/CustomGenericAdapter.java
new file mode 100644
index 00000000..768eecda
--- /dev/null
+++ b/multipleimageselect/src/main/java/darsh/multipleimageselect/adapters/CustomGenericAdapter.java
@@ -0,0 +1,46 @@
+package darsh.multipleimageselect.adapters;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.widget.BaseAdapter;
+import java.util.ArrayList;
+
+/**
+ * Created by Darshan on 4/24/2015.
+ */
+public abstract class CustomGenericAdapter extends BaseAdapter {
+ protected ArrayList arrayList;
+ protected Context context;
+ protected LayoutInflater layoutInflater;
+
+ protected int size;
+
+ public CustomGenericAdapter(Context context, ArrayList arrayList) {
+ this.arrayList = arrayList;
+ this.context = context;
+ this.layoutInflater = LayoutInflater.from(this.context);
+ }
+
+ @Override
+ public int getCount() {
+ return arrayList.size();
+ }
+
+ public T getItem(int position) {
+ return arrayList.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ public void setLayoutParams(int size) {
+ this.size = size;
+ }
+
+ public void releaseResources() {
+ arrayList = null;
+ context = null;
+ }
+}
diff --git a/multipleimageselect/src/main/java/darsh/multipleimageselect/adapters/CustomImageSelectAdapter.java b/multipleimageselect/src/main/java/darsh/multipleimageselect/adapters/CustomImageSelectAdapter.java
new file mode 100644
index 00000000..a19cb910
--- /dev/null
+++ b/multipleimageselect/src/main/java/darsh/multipleimageselect/adapters/CustomImageSelectAdapter.java
@@ -0,0 +1,65 @@
+package darsh.multipleimageselect.adapters;
+
+import android.content.Context;
+import android.support.v4.content.ContextCompat;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import com.bumptech.glide.Glide;
+import darsh.multipleimageselect.R;
+import darsh.multipleimageselect.models.Image;
+import java.util.ArrayList;
+
+/**
+ * Created by Darshan on 4/18/2015.
+ */
+public class CustomImageSelectAdapter extends CustomGenericAdapter {
+ public CustomImageSelectAdapter(Context context, ArrayList images) {
+ super(context, images);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ ViewHolder viewHolder;
+
+ if (convertView == null) {
+ convertView = layoutInflater.inflate(R.layout.grid_view_item_image_select, null);
+
+ viewHolder = new ViewHolder();
+ viewHolder.imageView = (ImageView) convertView.findViewById(R.id.image_view_image_select);
+ viewHolder.view = convertView.findViewById(R.id.view_alpha);
+
+ convertView.setTag(viewHolder);
+
+ } else {
+ viewHolder = (ViewHolder) convertView.getTag();
+ }
+
+ viewHolder.imageView.getLayoutParams().width = size;
+ viewHolder.imageView.getLayoutParams().height = size;
+
+ viewHolder.view.getLayoutParams().width = size;
+ viewHolder.view.getLayoutParams().height = size;
+
+ if (arrayList.get(position).isSelected) {
+ viewHolder.view.setAlpha(0.5f);
+ ((FrameLayout) convertView).setForeground(ContextCompat.getDrawable(context,R.drawable.ic_done_white));
+
+ } else {
+ viewHolder.view.setAlpha(0.0f);
+ ((FrameLayout) convertView).setForeground(null);
+ }
+
+ Glide.with(context)
+ .load(arrayList.get(position).path)
+ .placeholder(R.drawable.image_placeholder).into(viewHolder.imageView);
+
+ return convertView;
+ }
+
+ private static class ViewHolder {
+ public ImageView imageView;
+ public View view;
+ }
+}
diff --git a/multipleimageselect/src/main/java/darsh/multipleimageselect/helpers/Constants.java b/multipleimageselect/src/main/java/darsh/multipleimageselect/helpers/Constants.java
new file mode 100644
index 00000000..add4b650
--- /dev/null
+++ b/multipleimageselect/src/main/java/darsh/multipleimageselect/helpers/Constants.java
@@ -0,0 +1,33 @@
+package darsh.multipleimageselect.helpers;
+
+/**
+ * Created by Darshan on 5/26/2015.
+ */
+public class Constants {
+ public static final int PERMISSION_REQUEST_CODE = 1000;
+ public static final int PERMISSION_GRANTED = 1001;
+ public static final int PERMISSION_DENIED = 1002;
+
+ public static final int REQUEST_CODE = 2000;
+
+ public static final int FETCH_STARTED = 2001;
+ public static final int FETCH_COMPLETED = 2002;
+ public static final int ERROR = 2005;
+
+ /**
+ * Request code for permission has to be < (1 << 8)
+ * Otherwise throws java.lang.IllegalArgumentException: Can only use lower 8 bits for requestCode
+ */
+ public static final int PERMISSION_REQUEST_READ_EXTERNAL_STORAGE = 23;
+
+ public static final String INTENT_EXTRA_ALBUM = "album";
+ public static final String INTENT_EXTRA_IMAGES = "images";
+ public static final String INTENT_EXTRA_LIMIT = "limit";
+ public static final String INTENT_EXTRA_START_CAMERA = "start_camera";
+ public static final String EXTRA_CAMERA_ENABLE = "camera_enable";
+ public static final int DEFAULT_LIMIT = 10;
+
+ //Maximum number of images that can be selected at a time
+ public static int limit;
+ public static boolean cameraEnable;
+}
diff --git a/multipleimageselect/src/main/java/darsh/multipleimageselect/models/Album.java b/multipleimageselect/src/main/java/darsh/multipleimageselect/models/Album.java
new file mode 100644
index 00000000..76e75804
--- /dev/null
+++ b/multipleimageselect/src/main/java/darsh/multipleimageselect/models/Album.java
@@ -0,0 +1,14 @@
+package darsh.multipleimageselect.models;
+
+/**
+ * Created by Darshan on 4/14/2015.
+ */
+public class Album {
+ public String name;
+ public String cover;
+
+ public Album(String name, String cover) {
+ this.name = name;
+ this.cover = cover;
+ }
+}
diff --git a/multipleimageselect/src/main/java/darsh/multipleimageselect/models/Image.java b/multipleimageselect/src/main/java/darsh/multipleimageselect/models/Image.java
new file mode 100644
index 00000000..d99217c8
--- /dev/null
+++ b/multipleimageselect/src/main/java/darsh/multipleimageselect/models/Image.java
@@ -0,0 +1,51 @@
+package darsh.multipleimageselect.models;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Created by Darshan on 4/18/2015.
+ */
+public class Image implements Parcelable {
+ public long id;
+ public String name;
+ public String path;
+ public boolean isSelected;
+
+ public Image(long id, String name, String path, boolean isSelected) {
+ this.id = id;
+ this.name = name;
+ this.path = path;
+ this.isSelected = isSelected;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeLong(id);
+ dest.writeString(name);
+ dest.writeString(path);
+ }
+
+ public static final Creator CREATOR = new Creator() {
+ @Override
+ public Image createFromParcel(Parcel source) {
+ return new Image(source);
+ }
+
+ @Override
+ public Image[] newArray(int size) {
+ return new Image[size];
+ }
+ };
+
+ private Image(Parcel in) {
+ id = in.readLong();
+ name = in.readString();
+ path = in.readString();
+ }
+}
diff --git a/multipleimageselect/src/main/res/drawable-xhdpi/ic_arrow_back.png b/multipleimageselect/src/main/res/drawable-xhdpi/ic_arrow_back.png
new file mode 100644
index 00000000..ce5b878b
Binary files /dev/null and b/multipleimageselect/src/main/res/drawable-xhdpi/ic_arrow_back.png differ
diff --git a/multipleimageselect/src/main/res/drawable-xhdpi/ic_camera.png b/multipleimageselect/src/main/res/drawable-xhdpi/ic_camera.png
new file mode 100644
index 00000000..17aa3be0
Binary files /dev/null and b/multipleimageselect/src/main/res/drawable-xhdpi/ic_camera.png differ
diff --git a/multipleimageselect/src/main/res/drawable-xhdpi/ic_done_white.png b/multipleimageselect/src/main/res/drawable-xhdpi/ic_done_white.png
new file mode 100644
index 00000000..0ebb5555
Binary files /dev/null and b/multipleimageselect/src/main/res/drawable-xhdpi/ic_done_white.png differ
diff --git a/multipleimageselect/src/main/res/drawable-xxhdpi/ic_arrow_back.png b/multipleimageselect/src/main/res/drawable-xxhdpi/ic_arrow_back.png
new file mode 100644
index 00000000..746d7757
Binary files /dev/null and b/multipleimageselect/src/main/res/drawable-xxhdpi/ic_arrow_back.png differ
diff --git a/multipleimageselect/src/main/res/drawable-xxhdpi/ic_camera.png b/multipleimageselect/src/main/res/drawable-xxhdpi/ic_camera.png
new file mode 100644
index 00000000..8d9c05e3
Binary files /dev/null and b/multipleimageselect/src/main/res/drawable-xxhdpi/ic_camera.png differ
diff --git a/multipleimageselect/src/main/res/drawable-xxhdpi/ic_done_white.png b/multipleimageselect/src/main/res/drawable-xxhdpi/ic_done_white.png
new file mode 100644
index 00000000..200dc733
Binary files /dev/null and b/multipleimageselect/src/main/res/drawable-xxhdpi/ic_done_white.png differ
diff --git a/multipleimageselect/src/main/res/drawable/image_placeholder.xml b/multipleimageselect/src/main/res/drawable/image_placeholder.xml
new file mode 100644
index 00000000..43ad7823
--- /dev/null
+++ b/multipleimageselect/src/main/res/drawable/image_placeholder.xml
@@ -0,0 +1,5 @@
+
+
+
+
\ No newline at end of file
diff --git a/multipleimageselect/src/main/res/layout/activity_album_select.xml b/multipleimageselect/src/main/res/layout/activity_album_select.xml
new file mode 100644
index 00000000..16c8e360
--- /dev/null
+++ b/multipleimageselect/src/main/res/layout/activity_album_select.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/multipleimageselect/src/main/res/layout/activity_image_select.xml b/multipleimageselect/src/main/res/layout/activity_image_select.xml
new file mode 100644
index 00000000..9903c168
--- /dev/null
+++ b/multipleimageselect/src/main/res/layout/activity_image_select.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/multipleimageselect/src/main/res/layout/grid_view_item_album_select.xml b/multipleimageselect/src/main/res/layout/grid_view_item_album_select.xml
new file mode 100644
index 00000000..3b1a49ea
--- /dev/null
+++ b/multipleimageselect/src/main/res/layout/grid_view_item_album_select.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/multipleimageselect/src/main/res/layout/grid_view_item_image_select.xml b/multipleimageselect/src/main/res/layout/grid_view_item_image_select.xml
new file mode 100644
index 00000000..19a32a91
--- /dev/null
+++ b/multipleimageselect/src/main/res/layout/grid_view_item_image_select.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/multipleimageselect/src/main/res/layout/toolbar.xml b/multipleimageselect/src/main/res/layout/toolbar.xml
new file mode 100644
index 00000000..a2cce928
--- /dev/null
+++ b/multipleimageselect/src/main/res/layout/toolbar.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/multipleimageselect/src/main/res/values/colors.xml b/multipleimageselect/src/main/res/values/colors.xml
new file mode 100644
index 00000000..30605ab4
--- /dev/null
+++ b/multipleimageselect/src/main/res/values/colors.xml
@@ -0,0 +1,17 @@
+
+
+ #FFFFFF
+
+ #2E7D32
+ #1B5E20
+ #C8E6C9
+ #4CAF50
+
+ #212121
+ #727272
+ #B6B6B6
+ #FFFFFF
+
+ #99FFFFFF
+ #000000
+
\ No newline at end of file
diff --git a/multipleimageselect/src/main/res/values/strings.xml b/multipleimageselect/src/main/res/values/strings.xml
new file mode 100644
index 00000000..6934db08
--- /dev/null
+++ b/multipleimageselect/src/main/res/values/strings.xml
@@ -0,0 +1,18 @@
+
+ MultipleImageSelect
+
+ OK
+ Settings
+ package
+ App requires permission to Storage to view images.
+ App requires permission to Storage to view images. Tap Settings
+ and go to Permissions to grant permission.
+
+ Oops, something went wrong!
+ 选择图片
+ 单击选择
+
+ 确定
+ 还能选%1$s
+ 最多能选 %d 张
+
diff --git a/multipleimageselect/src/main/res/values/style.xml b/multipleimageselect/src/main/res/values/style.xml
new file mode 100644
index 00000000..d5241770
--- /dev/null
+++ b/multipleimageselect/src/main/res/values/style.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/simple/build.gradle b/simple/build.gradle
index 09ff929b..84a64c2b 100644
--- a/simple/build.gradle
+++ b/simple/build.gradle
@@ -22,4 +22,7 @@ android {
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile project(':takephoto_library')
+ compile 'com.android.support:support-v4:25.3.0'
+ compile 'com.android.support:appcompat-v7:25.3.0'
+ compile 'com.android.support:design:25.3.0'
}
diff --git a/simple/src/main/AndroidManifest.xml b/simple/src/main/AndroidManifest.xml
index 8908ec7c..8f1f2d93 100644
--- a/simple/src/main/AndroidManifest.xml
+++ b/simple/src/main/AndroidManifest.xml
@@ -5,7 +5,7 @@
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
- android:theme="@style/AppTheme" >
+ android:theme="@style/Theme.AppCompat.NoActionBar" >
1){
- if(rgCrop.getCheckedRadioButtonId()==R.id.rbCropYes){
- takePhoto.onPickMultipleWithCrop(limit,getCropOptions());
- }else {
- takePhoto.onPickMultiple(limit);
- }
- return;
- }
- if(rgFrom.getCheckedRadioButtonId()==R.id.rbFile){
- if(rgCrop.getCheckedRadioButtonId()==R.id.rbCropYes){
- takePhoto.onPickFromDocumentsWithCrop(imageUri,getCropOptions());
- }else {
- takePhoto.onPickFromDocuments();
- }
- return;
- }else {
- if(rgCrop.getCheckedRadioButtonId()==R.id.rbCropYes){
- takePhoto.onPickFromGalleryWithCrop(imageUri,getCropOptions());
- }else {
- takePhoto.onPickFromGallery();
- }
- }
- break;
- case R.id.btnPickByTake:
- if(rgCrop.getCheckedRadioButtonId()==R.id.rbCropYes){
- takePhoto.onPickFromCaptureWithCrop(imageUri,getCropOptions());
- }else {
- takePhoto.onPickFromCapture(imageUri);
- }
- break;
- default:
- break;
+ configCompress(takePhoto);
+ configTakePhotoOption(takePhoto);
+ switch (view.getId()) {
+ case R.id.btnPickBySelect:
+ int limit = Integer.parseInt(etLimit.getText().toString());
+ if (limit > 1) {
+ boolean isEnableCamera = rgCameraSet.getCheckedRadioButtonId() == R.id.rbCameraEnable;
+ if (rgCrop.getCheckedRadioButtonId() == R.id.rbCropYes) {
+ takePhoto.onPickMultipleWithCrop(isEnableCamera, limit, getCropOptions());
+ } else {
+ takePhoto.onPickMultiple(isEnableCamera, limit);
+ }
+ return;
}
- }
- private void configTakePhotoOption(TakePhoto takePhoto){
- TakePhotoOptions.Builder builder=new TakePhotoOptions.Builder();
- if(rgPickTool.getCheckedRadioButtonId()==R.id.rbPickWithOwn){
- builder.setWithOwnGallery(true);
+ if (rgFrom.getCheckedRadioButtonId() == R.id.rbFile) {
+ if (rgCrop.getCheckedRadioButtonId() == R.id.rbCropYes) {
+ takePhoto.onPickFromDocumentsWithCrop(imageUri, getCropOptions());
+ } else {
+ takePhoto.onPickFromDocuments();
+ }
+ return;
+ } else {
+ if (rgCrop.getCheckedRadioButtonId() == R.id.rbCropYes) {
+ takePhoto.onPickFromGalleryWithCrop(imageUri, getCropOptions());
+ } else {
+ takePhoto.onPickFromGallery();
+ }
}
- if(rgCorrectTool.getCheckedRadioButtonId()==R.id.rbCorrectYes){
- builder.setCorrectImage(true);
+ break;
+ case R.id.btnPickByTake:
+ if (rgCrop.getCheckedRadioButtonId() == R.id.rbCropYes) {
+ takePhoto.onPickFromCaptureWithCrop(imageUri, getCropOptions());
+ } else {
+ takePhoto.onPickFromCapture(imageUri);
}
- takePhoto.setTakePhotoOptions(builder.create());
-
+ break;
+ default:
+ break;
}
- private void configCompress(TakePhoto takePhoto){
- if(rgCompress.getCheckedRadioButtonId()!=R.id.rbCompressYes){
- takePhoto.onEnableCompress(null,false);
- return ;
- }
- int maxSize= Integer.parseInt(etSize.getText().toString());
- int width= Integer.parseInt(etCropWidth.getText().toString());
- int height= Integer.parseInt(etHeightPx.getText().toString());
- boolean showProgressBar=rgShowProgressBar.getCheckedRadioButtonId()==R.id.rbShowYes? true:false;
- boolean enableRawFile = rgRawFile.getCheckedRadioButtonId() == R.id.rbRawYes ? true : false;
- CompressConfig config;
- if(rgCompressTool.getCheckedRadioButtonId()==R.id.rbCompressWithOwn){
- config=new CompressConfig.Builder()
- .setMaxSize(maxSize)
- .setMaxPixel(width>=height? width:height)
- .enableReserveRaw(enableRawFile)
- .create();
- }else {
- LubanOptions option=new LubanOptions.Builder()
- .setMaxHeight(height)
- .setMaxWidth(width)
- .setMaxSize(maxSize)
- .create();
- config=CompressConfig.ofLuban(option);
- config.enableReserveRaw(enableRawFile);
- }
- takePhoto.onEnableCompress(config,showProgressBar);
+ }
+ private void configTakePhotoOption(TakePhoto takePhoto) {
+ TakePhotoOptions.Builder builder = new TakePhotoOptions.Builder();
+ if (rgPickTool.getCheckedRadioButtonId() == R.id.rbPickWithOwn) {
+ builder.setWithOwnGallery(true);
+ }
+ if (rgCorrectTool.getCheckedRadioButtonId() == R.id.rbCorrectYes) {
+ builder.setCorrectImage(true);
+ }
+ takePhoto.setTakePhotoOptions(builder.create());
+ }
+ private void configCompress(TakePhoto takePhoto) {
+ if (rgCompress.getCheckedRadioButtonId() != R.id.rbCompressYes) {
+ takePhoto.onEnableCompress(null, false);
+ return;
+ }
+ int maxSize = Integer.parseInt(etSize.getText().toString());
+ int width = Integer.parseInt(etCropWidth.getText().toString());
+ int height = Integer.parseInt(etHeightPx.getText().toString());
+ boolean showProgressBar =
+ rgShowProgressBar.getCheckedRadioButtonId() == R.id.rbShowYes ? true : false;
+ boolean enableRawFile = rgRawFile.getCheckedRadioButtonId() == R.id.rbRawYes ? true : false;
+ CompressConfig config;
+ if (rgCompressTool.getCheckedRadioButtonId() == R.id.rbCompressWithOwn) {
+ config = new CompressConfig.Builder().setMaxSize(maxSize)
+ .setMaxPixel(width >= height ? width : height)
+ .enableReserveRaw(enableRawFile)
+ .create();
+ } else {
+ LubanOptions option = new LubanOptions.Builder().setMaxHeight(height)
+ .setMaxWidth(width)
+ .setMaxSize(maxSize)
+ .create();
+ config = CompressConfig.ofLuban(option);
+ config.enableReserveRaw(enableRawFile);
}
- private CropOptions getCropOptions(){
- if(rgCrop.getCheckedRadioButtonId()!=R.id.rbCropYes)return null;
- int height= Integer.parseInt(etCropHeight.getText().toString());
- int width= Integer.parseInt(etCropWidth.getText().toString());
- boolean withWonCrop=rgCropTool.getCheckedRadioButtonId()==R.id.rbCropOwn? true:false;
+ takePhoto.onEnableCompress(config, showProgressBar);
+ }
- CropOptions.Builder builder=new CropOptions.Builder();
+ private CropOptions getCropOptions() {
+ if (rgCrop.getCheckedRadioButtonId() != R.id.rbCropYes) return null;
+ int height = Integer.parseInt(etCropHeight.getText().toString());
+ int width = Integer.parseInt(etCropWidth.getText().toString());
+ boolean withWonCrop = rgCropTool.getCheckedRadioButtonId() == R.id.rbCropOwn ? true : false;
- if(rgCropSize.getCheckedRadioButtonId()==R.id.rbAspect){
- builder.setAspectX(width).setAspectY(height);
- }else {
- builder.setOutputX(width).setOutputY(height);
- }
- builder.setWithOwnCrop(withWonCrop);
- return builder.create();
- }
+ CropOptions.Builder builder = new CropOptions.Builder();
+ if (rgCropSize.getCheckedRadioButtonId() == R.id.rbAspect) {
+ builder.setAspectX(width).setAspectY(height);
+ } else {
+ builder.setOutputX(width).setOutputY(height);
+ }
+ builder.setWithOwnCrop(withWonCrop);
+ return builder.create();
+ }
}
diff --git a/simple/src/main/java/com/jph/simple/ResultActivity.java b/simple/src/main/java/com/jph/simple/ResultActivity.java
index 9d3ad1f9..a8f886cb 100644
--- a/simple/src/main/java/com/jph/simple/ResultActivity.java
+++ b/simple/src/main/java/com/jph/simple/ResultActivity.java
@@ -49,14 +49,14 @@ private void showImg() {
View view = LayoutInflater.from(this).inflate(R.layout.image_show, null);
ImageView imageView1 = (ImageView) view.findViewById(R.id.imgShow1);
ImageView imageView2 = (ImageView) view.findViewById(R.id.imgShow2);
- Glide.with(this).load(new File(images.get(i).getCompressPath())).into(imageView1);
- Glide.with(this).load(new File(images.get(i + 1).getCompressPath())).into(imageView2);
+ Glide.with(this).load(new File(images.get(i).getPath())).into(imageView1);
+ Glide.with(this).load(new File(images.get(i + 1).getPath())).into(imageView2);
linearLayout.addView(view);
}
if (images.size() % 2 == 1) {
View view = LayoutInflater.from(this).inflate(R.layout.image_show, null);
ImageView imageView1 = (ImageView) view.findViewById(R.id.imgShow1);
- Glide.with(this).load(new File(images.get(images.size() - 1).getCompressPath())).into(imageView1);
+ Glide.with(this).load(new File(images.get(images.size() - 1).getPath())).into(imageView1);
linearLayout.addView(view);
}
diff --git a/simple/src/main/res/layout/common_layout.xml b/simple/src/main/res/layout/common_layout.xml
index 6caa3756..f4ca4bac 100644
--- a/simple/src/main/res/layout/common_layout.xml
+++ b/simple/src/main/res/layout/common_layout.xml
@@ -452,6 +452,40 @@
android:text="从文件" />
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/simple/src/main/res/values/styles.xml b/simple/src/main/res/values/styles.xml
index 766ab993..0ac0de1d 100644
--- a/simple/src/main/res/values/styles.xml
+++ b/simple/src/main/res/values/styles.xml
@@ -1,8 +1,5 @@
-
-
+
diff --git a/takephoto_library/build.gradle b/takephoto_library/build.gradle
index 712dafe8..50572b74 100644
--- a/takephoto_library/build.gradle
+++ b/takephoto_library/build.gradle
@@ -1,28 +1,29 @@
apply plugin: 'com.android.library'
android {
- compileSdkVersion 25
- buildToolsVersion "25.0.0"
+ compileSdkVersion 25
+ buildToolsVersion "25.0.0"
- defaultConfig {
- minSdkVersion 14
- targetSdkVersion 25
- versionCode 42
- versionName "4.0.2"
- }
- buildTypes {
- release {
- minifyEnabled false
- proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
- }
+ defaultConfig {
+ minSdkVersion 14
+ targetSdkVersion 25
+ versionCode 42
+ versionName "4.0.2"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
+ }
}
dependencies {
- compile fileTree(include: ['*.jar'], dir: 'libs')
- compile 'com.android.support:support-v4:25.0.0'
- compile 'com.soundcloud.android.crop:lib_crop:1.0.0'
- compile 'com.darsh.multipleimageselect:multipleimageselect:1.0.4'
- compile 'me.shaohui.advancedluban:library:1.3.2'
-}
-//apply from: "bintrayUpload.gradle"
\ No newline at end of file
+ compile fileTree(include: ['*.jar'], dir: 'libs')
+ compile 'com.android.support:support-v4:25.3.0'
+ compile 'com.android.support:appcompat-v7:25.3.0'
+ compile 'com.android.support:design:25.3.0'
+ compile 'com.soundcloud.android.crop:lib_crop:1.0.0'
+ compile 'me.shaohui.advancedluban:library:1.3.2'
+ compile 'com.github.bumptech.glide:glide:3.7.0'
+}
\ No newline at end of file
diff --git a/takephoto_library/src/androidTest/java/com/jph/takephoto/ApplicationTest.java b/takephoto_library/src/androidTest/java/com/jph/takephoto/ApplicationTest.java
deleted file mode 100644
index 48550d48..00000000
--- a/takephoto_library/src/androidTest/java/com/jph/takephoto/ApplicationTest.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.jph.takephoto;
-
-import android.app.Application;
-import android.test.ApplicationTestCase;
-
-/**
- * Testing Fundamentals
- */
-public class ApplicationTest extends ApplicationTestCase {
- public ApplicationTest() {
- super(Application.class);
- }
-}
\ No newline at end of file
diff --git a/takephoto_library/src/main/AndroidManifest.xml b/takephoto_library/src/main/AndroidManifest.xml
index 4697527a..13913459 100644
--- a/takephoto_library/src/main/AndroidManifest.xml
+++ b/takephoto_library/src/main/AndroidManifest.xml
@@ -15,5 +15,21 @@
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
+
+
+
+
+
+
+
+
+
+
diff --git a/takephoto_library/src/main/java/com/jph/takephoto/app/TakePhoto.java b/takephoto_library/src/main/java/com/jph/takephoto/app/TakePhoto.java
index da94ade0..bdb6b108 100644
--- a/takephoto_library/src/main/java/com/jph/takephoto/app/TakePhoto.java
+++ b/takephoto_library/src/main/java/com/jph/takephoto/app/TakePhoto.java
@@ -37,13 +37,13 @@ public interface TakePhoto {
* 图片多选
* @param limit 最多选择图片张数的限制
* */
- void onPickMultiple(int limit);
+ void onPickMultiple(boolean cameraEnable,int limit);
/**
* 图片多选,并裁切
* @param limit 最多选择图片张数的限制
* @param options 裁剪配置
* */
- void onPickMultipleWithCrop(int limit, CropOptions options);
+ void onPickMultipleWithCrop(boolean cameraEnable,int limit, CropOptions options);
/**
* 从文件中获取图片(不裁剪)
*/
diff --git a/takephoto_library/src/main/java/com/jph/takephoto/app/TakePhotoActivity.java b/takephoto_library/src/main/java/com/jph/takephoto/app/TakePhotoActivity.java
index 782c9923..4e033ca6 100644
--- a/takephoto_library/src/main/java/com/jph/takephoto/app/TakePhotoActivity.java
+++ b/takephoto_library/src/main/java/com/jph/takephoto/app/TakePhotoActivity.java
@@ -62,7 +62,7 @@ public TakePhoto getTakePhoto(){
}
@Override
public void takeSuccess(TResult result) {
- Log.i(TAG,"takeSuccess:" + result.getImage().getCompressPath());
+ //Log.i(TAG,"takeSuccess:" + result.getImage().getCompressPath());
}
@Override
public void takeFail(TResult result,String msg) {
diff --git a/takephoto_library/src/main/java/com/jph/takephoto/app/TakePhotoFragment.java b/takephoto_library/src/main/java/com/jph/takephoto/app/TakePhotoFragment.java
index 8d054a62..ea622214 100644
--- a/takephoto_library/src/main/java/com/jph/takephoto/app/TakePhotoFragment.java
+++ b/takephoto_library/src/main/java/com/jph/takephoto/app/TakePhotoFragment.java
@@ -60,7 +60,7 @@ public TakePhoto getTakePhoto(){
}
@Override
public void takeSuccess(TResult result) {
- Log.i(TAG,"takeSuccess:" + result.getImage().getCompressPath());
+ //Log.i(TAG,"takeSuccess:" + result.getImage().getCompressPath());
}
@Override
public void takeFail(TResult result,String msg) {
diff --git a/takephoto_library/src/main/java/com/jph/takephoto/app/TakePhotoFragmentActivity.java b/takephoto_library/src/main/java/com/jph/takephoto/app/TakePhotoFragmentActivity.java
index 95756679..9af8d87a 100644
--- a/takephoto_library/src/main/java/com/jph/takephoto/app/TakePhotoFragmentActivity.java
+++ b/takephoto_library/src/main/java/com/jph/takephoto/app/TakePhotoFragmentActivity.java
@@ -59,7 +59,7 @@ public TakePhoto getTakePhoto(){
}
@Override
public void takeSuccess(TResult result) {
- Log.i(TAG,"takeSuccess:" + result.getImage().getCompressPath());
+ //Log.i(TAG,"takeSuccess:" + result.getImage().getCompressPath());
}
@Override
public void takeFail(TResult result,String msg) {
diff --git a/takephoto_library/src/main/java/com/jph/takephoto/app/TakePhotoImpl.java b/takephoto_library/src/main/java/com/jph/takephoto/app/TakePhotoImpl.java
index c9f712ab..0dcf3780 100644
--- a/takephoto_library/src/main/java/com/jph/takephoto/app/TakePhotoImpl.java
+++ b/takephoto_library/src/main/java/com/jph/takephoto/app/TakePhotoImpl.java
@@ -7,11 +7,9 @@
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
+import android.os.Environment;
import android.support.v4.app.Fragment;
import android.widget.Toast;
-
-import com.darsh.multipleimageselect.helpers.Constants;
-import com.darsh.multipleimageselect.models.Image;
import com.jph.takephoto.R;
import com.jph.takephoto.compress.CompressConfig;
import com.jph.takephoto.compress.CompressImage;
@@ -19,6 +17,7 @@
import com.jph.takephoto.model.CropOptions;
import com.jph.takephoto.model.MultipleCrop;
import com.jph.takephoto.model.TContextWrap;
+import com.jph.takephoto.model.TException;
import com.jph.takephoto.model.TExceptionType;
import com.jph.takephoto.model.TImage;
import com.jph.takephoto.model.TIntentWap;
@@ -28,16 +27,14 @@
import com.jph.takephoto.uitl.ImageRotateUtil;
import com.jph.takephoto.uitl.IntentUtils;
import com.jph.takephoto.uitl.TConstant;
-import com.jph.takephoto.model.TException;
-import com.jph.takephoto.uitl.TFileUtils;
import com.jph.takephoto.uitl.TImageFiles;
import com.jph.takephoto.uitl.TUriParse;
import com.jph.takephoto.uitl.TUtils;
-import com.soundcloud.android.crop.Crop;
-
import java.io.File;
import java.util.ArrayList;
import java.util.Map;
+import multipleimageselect.helpers.Constants;
+import multipleimageselect.models.Image;
/**
* - 支持通过相机拍照获取图片
@@ -53,7 +50,7 @@
* - 支持智能选取及裁剪异常处理
* - 支持因拍照Activity被回收后的自动恢复
* Date: 2016/9/21 0007 20:10
- * Version:4.0.0
+ * Version:3.0.0
* 技术博文:http://www.cboy.me
* GitHub:https://github.com/crazycodeboy
* Eamil:crazycodeboy@gmail.com
@@ -69,7 +66,6 @@ public class TakePhotoImpl implements TakePhoto {
private CompressConfig compressConfig;
private MultipleCrop multipleCrop;
private PermissionManager.TPermissionType permissionType;
- private TImage.FromType fromType; //CAMERA图片来源相机,OTHER图片来源其他
/**
* 是否显示压缩对话框
*/
@@ -86,8 +82,7 @@ public TakePhotoImpl(Fragment fragment, TakeResultListener listener) {
this.listener = listener;
}
- @Override
- public void onCreate(Bundle savedInstanceState) {
+ @Override public void onCreate(Bundle savedInstanceState) {
if (savedInstanceState != null) {
cropOptions = (CropOptions) savedInstanceState.getSerializable("cropOptions");
takePhotoOptions = (TakePhotoOptions) savedInstanceState.getSerializable("takePhotoOptions");
@@ -98,8 +93,7 @@ public void onCreate(Bundle savedInstanceState) {
}
}
- @Override
- public void onSaveInstanceState(Bundle outState) {
+ @Override public void onSaveInstanceState(Bundle outState) {
outState.putSerializable("cropOptions", cropOptions);
outState.putSerializable("takePhotoOptions", takePhotoOptions);
outState.putBoolean("showCompressDialog", showCompressDialog);
@@ -108,15 +102,14 @@ public void onSaveInstanceState(Bundle outState) {
outState.putSerializable("compressConfig", compressConfig);
}
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ @Override public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case TConstant.RC_PICK_PICTURE_FROM_GALLERY_CROP:
if (resultCode == Activity.RESULT_OK && data != null) {//从相册选择照片并裁剪
try {
onCrop(data.getData(), outPutUri, cropOptions);
} catch (TException e) {
- takeResult(TResult.of(TImage.of(outPutUri, fromType)), e.getDetailMessage());
+ takeResult(TResult.of(TImage.of(outPutUri)), e.getDetailMessage());
e.printStackTrace();
}
} else {
@@ -126,9 +119,10 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
case TConstant.RC_PICK_PICTURE_FROM_GALLERY_ORIGINAL://从相册选择照片不裁剪
if (resultCode == Activity.RESULT_OK) {
try {
- takeResult(TResult.of(TImage.of(TUriParse.getFilePathWithUri(data.getData(), contextWrap.getActivity()), fromType)));
+ takeResult(TResult.of(TImage.of(
+ TUriParse.getFilePathWithUri(data.getData(), contextWrap.getActivity()))));
} catch (TException e) {
- takeResult(TResult.of(TImage.of(data.getData(), fromType)), e.getDetailMessage());
+ takeResult(TResult.of(TImage.of(data.getData())), e.getDetailMessage());
e.printStackTrace();
}
} else {
@@ -138,9 +132,10 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
case TConstant.RC_PICK_PICTURE_FROM_DOCUMENTS_ORIGINAL://从文件选择照片不裁剪
if (resultCode == Activity.RESULT_OK) {
try {
- takeResult(TResult.of(TImage.of(TUriParse.getFilePathWithDocumentsUri(data.getData(), contextWrap.getActivity()), fromType)));
+ takeResult(TResult.of(TImage.of(
+ TUriParse.getFilePathWithDocumentsUri(data.getData(), contextWrap.getActivity()))));
} catch (TException e) {
- takeResult(TResult.of(TImage.of(outPutUri, fromType)), e.getDetailMessage());
+ takeResult(TResult.of(TImage.of(outPutUri)), e.getDetailMessage());
e.printStackTrace();
}
} else {
@@ -152,7 +147,7 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
try {
onCrop(data.getData(), outPutUri, cropOptions);
} catch (TException e) {
- takeResult(TResult.of(TImage.of(outPutUri, fromType)), e.getDetailMessage());
+ takeResult(TResult.of(TImage.of(outPutUri)), e.getDetailMessage());
e.printStackTrace();
}
} else {
@@ -161,24 +156,28 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
break;
case TConstant.RC_PICK_PICTURE_FROM_CAPTURE_CROP://拍取照片,并裁剪
if (resultCode == Activity.RESULT_OK) {
- if(takePhotoOptions!=null&&takePhotoOptions.isCorrectImage())ImageRotateUtil.of().correctImage(contextWrap.getActivity(), tempUri);
- try {
- onCrop(tempUri, Uri.fromFile(new File(TUriParse.parseOwnUri(contextWrap.getActivity(), outPutUri))), cropOptions);
- } catch (TException e) {
- takeResult(TResult.of(TImage.of(outPutUri, fromType)), e.getDetailMessage());
- e.printStackTrace();
- }
+ ImageRotateUtil.of().correctImage(contextWrap.getActivity(), tempUri);
+ takeResult(TResult.of(TImage.of(outPutUri)));
+ //try {
+ // onCrop(tempUri,
+ // Uri.fromFile(new File(TUriParse.parseOwnUri(contextWrap.getActivity(), outPutUri))),
+ // cropOptions);
+ //} catch (TException e) {
+ // takeResult(TResult.of(TImage.of(outPutUri)), e.getDetailMessage());
+ // e.printStackTrace();
+ //}
} else {
listener.takeCancel();
}
break;
case TConstant.RC_PICK_PICTURE_FROM_CAPTURE://拍取照片
if (resultCode == Activity.RESULT_OK) {
- if(takePhotoOptions!=null&&takePhotoOptions.isCorrectImage())ImageRotateUtil.of().correctImage(contextWrap.getActivity(), outPutUri);
+ ImageRotateUtil.of().correctImage(contextWrap.getActivity(), outPutUri);
try {
- takeResult(TResult.of(TImage.of(TUriParse.getFilePathWithUri(outPutUri, contextWrap.getActivity()), fromType)));
+ takeResult(TResult.of(
+ TImage.of(TUriParse.getFilePathWithUri(outPutUri, contextWrap.getActivity()))));
} catch (TException e) {
- takeResult(TResult.of(TImage.of(outPutUri, fromType)), e.getDetailMessage());
+ takeResult(TResult.of(TImage.of(outPutUri)), e.getDetailMessage());
e.printStackTrace();
}
} else {
@@ -186,17 +185,18 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
}
break;
case TConstant.RC_CROP://裁剪照片返回结果
- case Crop.REQUEST_CROP://裁剪照片返回结果
+ //case Crop.REQUEST_CROP://裁剪照片返回结果
if (resultCode == Activity.RESULT_OK) {
if (multipleCrop != null) {
cropContinue(true);
} else {
try {
- TImage image = TImage.of(TUriParse.getFilePathWithUri(outPutUri, contextWrap.getActivity()), fromType);
+ TImage image =
+ TImage.of(TUriParse.getFilePathWithUri(outPutUri, contextWrap.getActivity()));
image.setCropped(true);
takeResult(TResult.of(image));
} catch (TException e) {
- takeResult(TResult.of(TImage.of(outPutUri.getPath(), fromType)), e.getDetailMessage());
+ takeResult(TResult.of(TImage.of(outPutUri.getPath())), e.getDetailMessage());
e.printStackTrace();
}
}
@@ -214,7 +214,7 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
Bitmap bitmap = data.getParcelableExtra("data");//获取裁剪的结果数据
TImageFiles.writeToFile(bitmap, outPutUri);//将裁剪的结果写入到文件
- TImage image = TImage.of(outPutUri.getPath(), fromType);
+ TImage image = TImage.of(outPutUri.getPath());
image.setCropped(true);
takeResult(TResult.of(image));
} else {
@@ -231,18 +231,29 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
break;
case TConstant.RC_PICK_MULTIPLE://多选图片返回结果
if (resultCode == Activity.RESULT_OK && data != null) {
- ArrayList images = data.getParcelableArrayListExtra(Constants.INTENT_EXTRA_IMAGES);
- if (cropOptions != null) {
- try {
- onCrop(MultipleCrop.of(TUtils.convertImageToUri(contextWrap.getActivity(), images), contextWrap.getActivity(), fromType), cropOptions);
- } catch (TException e) {
- cropContinue(false);
- e.printStackTrace();
- }
+ boolean startCamera = data.getBooleanExtra(Constants.INTENT_EXTRA_START_CAMERA, false);
+ if (startCamera) {
+ File file = new File(Environment.getExternalStorageDirectory(),
+ "/temp/" + System.currentTimeMillis() + ".jpg");
+ if (!file.getParentFile().exists()) file.getParentFile().mkdirs();
+ Uri imageUri = Uri.fromFile(file);
+ onPickFromCaptureWithCrop(imageUri, null);
} else {
- takeResult(TResult.of(TUtils.getTImagesWithImages(images, fromType)));
+ ArrayList images =
+ data.getParcelableArrayListExtra(Constants.INTENT_EXTRA_IMAGES);
+ if (cropOptions != null) {
+ try {
+ onCrop(MultipleCrop.of(
+ TUtils.convertImageToUri(contextWrap.getActivity(), images),
+ contextWrap.getActivity()), cropOptions);
+ } catch (TException e) {
+ cropContinue(false);
+ e.printStackTrace();
+ }
+ } else {
+ takeResult(TResult.of(TUtils.getTImagesWithImages(images)));
+ }
}
-
} else {
listener.takeCancel();
}
@@ -252,35 +263,36 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
}
}
- @Override
- public void onPickMultiple(int limit) {
+ @Override public void onPickMultiple(boolean cameraEnable, int limit) {
if (PermissionManager.TPermissionType.WAIT.equals(permissionType)) return;
- TUtils.startActivityForResult(contextWrap, new TIntentWap(IntentUtils.getPickMultipleIntent(contextWrap, limit), TConstant.RC_PICK_MULTIPLE));
+ TUtils.startActivityForResult(contextWrap,
+ new TIntentWap(IntentUtils.getPickMultipleIntent(contextWrap, cameraEnable, limit),
+ TConstant.RC_PICK_MULTIPLE));
}
@Override
- public void onPickMultipleWithCrop(int limit, CropOptions options) {
- this.fromType = TImage.FromType.OTHER;
- onPickMultiple(limit);
+ public void onPickMultipleWithCrop(boolean cameraEnable, int limit, CropOptions options) {
+ onPickMultiple(cameraEnable, limit);
this.cropOptions = options;
}
/**
* -----crop------
**/
- @Override
- public void onCrop(Uri imageUri, Uri outPutUri, CropOptions options) throws TException {
+ @Override public void onCrop(Uri imageUri, Uri outPutUri, CropOptions options) throws TException {
if (PermissionManager.TPermissionType.WAIT.equals(permissionType)) return;
this.outPutUri = outPutUri;
- if (!TImageFiles.checkMimeType(contextWrap.getActivity(), TImageFiles.getMimeType(contextWrap.getActivity(), imageUri))) {
- Toast.makeText(contextWrap.getActivity(), contextWrap.getActivity().getResources().getText(R.string.tip_type_not_image), Toast.LENGTH_SHORT).show();
+ if (!TImageFiles.checkMimeType(contextWrap.getActivity(),
+ TImageFiles.getMimeType(contextWrap.getActivity(), imageUri))) {
+ Toast.makeText(contextWrap.getActivity(),
+ contextWrap.getActivity().getResources().getText(R.string.tip_type_not_image),
+ Toast.LENGTH_SHORT).show();
throw new TException(TExceptionType.TYPE_NOT_IMAGE);
}
cropWithNonException(imageUri, outPutUri, options);
}
- @Override
- public void onCrop(MultipleCrop multipleCrop, CropOptions options) throws TException {
+ @Override public void onCrop(MultipleCrop multipleCrop, CropOptions options) throws TException {
this.multipleCrop = multipleCrop;
onCrop(multipleCrop.getUris().get(0), multipleCrop.getOutUris().get(0), options);
}
@@ -288,7 +300,7 @@ public void onCrop(MultipleCrop multipleCrop, CropOptions options) throws TExcep
private void cropWithNonException(Uri imageUri, Uri outPutUri, CropOptions options) {
this.outPutUri = outPutUri;
if (options.isWithOwnCrop()) {
- TUtils.cropWithOwnApp(contextWrap, imageUri, outPutUri, options);
+ //TUtils.cropWithOwnApp(contextWrap, imageUri, outPutUri, options);
} else {
TUtils.cropWithOtherAppBySafely(contextWrap, imageUri, outPutUri, options);
}
@@ -303,76 +315,78 @@ private void cropContinue(boolean preSuccess) {
if (preSuccess) {
takeResult(TResult.of(multipleCrop.gettImages()));
} else {
- takeResult(TResult.of(multipleCrop.gettImages()), outPutUri.getPath() + contextWrap.getActivity().getResources().getString(R.string.msg_crop_canceled));
+ takeResult(TResult.of(multipleCrop.gettImages()),
+ outPutUri.getPath() + contextWrap.getActivity()
+ .getResources()
+ .getString(R.string.msg_crop_canceled));
}
} else {
- cropWithNonException(multipleCrop.getUris().get(index + 1), multipleCrop.getOutUris().get(index + 1), cropOptions);
+ cropWithNonException(multipleCrop.getUris().get(index + 1),
+ multipleCrop.getOutUris().get(index + 1), cropOptions);
}
}
- @Override
- public void onPickFromDocuments() {
+ @Override public void onPickFromDocuments() {
selectPicture(0, false);
}
- @Override
- public void onPickFromGallery() {
+ @Override public void onPickFromGallery() {
selectPicture(1, false);
}
private void selectPicture(int defaultIndex, boolean isCrop) {
- this.fromType = TImage.FromType.OTHER;
if (takePhotoOptions != null && takePhotoOptions.isWithOwnGallery()) {
- onPickMultiple(1);
+ onPickMultiple(false, 1);
return;
}
if (PermissionManager.TPermissionType.WAIT.equals(permissionType)) return;
ArrayList intentWapList = new ArrayList<>();
- intentWapList.add(new TIntentWap(IntentUtils.getPickIntentWithDocuments(), isCrop ? TConstant.RC_PICK_PICTURE_FROM_DOCUMENTS_CROP : TConstant.RC_PICK_PICTURE_FROM_DOCUMENTS_ORIGINAL));
- intentWapList.add(new TIntentWap(IntentUtils.getPickIntentWithGallery(), isCrop ? TConstant.RC_PICK_PICTURE_FROM_GALLERY_CROP : TConstant.RC_PICK_PICTURE_FROM_GALLERY_ORIGINAL));
+ intentWapList.add(new TIntentWap(IntentUtils.getPickIntentWithDocuments(),
+ isCrop ? TConstant.RC_PICK_PICTURE_FROM_DOCUMENTS_CROP
+ : TConstant.RC_PICK_PICTURE_FROM_DOCUMENTS_ORIGINAL));
+ intentWapList.add(new TIntentWap(IntentUtils.getPickIntentWithGallery(),
+ isCrop ? TConstant.RC_PICK_PICTURE_FROM_GALLERY_CROP
+ : TConstant.RC_PICK_PICTURE_FROM_GALLERY_ORIGINAL));
try {
TUtils.sendIntentBySafely(contextWrap, intentWapList, defaultIndex, isCrop);
} catch (TException e) {
- takeResult(TResult.of(TImage.of("", fromType)), e.getDetailMessage());
+ takeResult(TResult.of(TImage.of("")), e.getDetailMessage());
e.printStackTrace();
}
}
- @Override
- public void onPickFromGalleryWithCrop(Uri outPutUri, CropOptions options) {
+ @Override public void onPickFromGalleryWithCrop(Uri outPutUri, CropOptions options) {
this.cropOptions = options;
this.outPutUri = outPutUri;
selectPicture(1, true);
}
- @Override
- public void onPickFromDocumentsWithCrop(Uri outPutUri, CropOptions options) {
+ @Override public void onPickFromDocumentsWithCrop(Uri outPutUri, CropOptions options) {
this.cropOptions = options;
this.outPutUri = outPutUri;
selectPicture(0, true);
}
- @Override
- public void onPickFromCapture(Uri outPutUri) {
- this.fromType = TImage.FromType.CAMERA;
+ @Override public void onPickFromCapture(Uri outPutUri) {
if (PermissionManager.TPermissionType.WAIT.equals(permissionType)) return;
if (Build.VERSION.SDK_INT >= 23) {
- this.outPutUri = TUriParse.convertFileUriToFileProviderUri(contextWrap.getActivity(), outPutUri);
+ this.outPutUri =
+ TUriParse.convertFileUriToFileProviderUri(contextWrap.getActivity(), outPutUri);
} else {
this.outPutUri = outPutUri;
}
try {
- TUtils.captureBySafely(contextWrap, new TIntentWap(IntentUtils.getCaptureIntent(this.outPutUri), TConstant.RC_PICK_PICTURE_FROM_CAPTURE));
+ TUtils.captureBySafely(contextWrap,
+ new TIntentWap(IntentUtils.getCaptureIntent(this.outPutUri),
+ TConstant.RC_PICK_PICTURE_FROM_CAPTURE));
} catch (TException e) {
- takeResult(TResult.of(TImage.of("", fromType)), e.getDetailMessage());
+ takeResult(TResult.of(TImage.of("")), e.getDetailMessage());
e.printStackTrace();
}
}
- @Override
- public void onPickFromCaptureWithCrop(Uri outPutUri, CropOptions options) {
- this.fromType = TImage.FromType.CAMERA;
+ @Override public void onPickFromCaptureWithCrop(Uri outPutUri, CropOptions options) {
if (PermissionManager.TPermissionType.WAIT.equals(permissionType)) return;
this.cropOptions = options;
this.outPutUri = outPutUri;
@@ -383,26 +397,24 @@ public void onPickFromCaptureWithCrop(Uri outPutUri, CropOptions options) {
}
try {
- TUtils.captureBySafely(contextWrap, new TIntentWap(IntentUtils.getCaptureIntent(this.tempUri), TConstant.RC_PICK_PICTURE_FROM_CAPTURE_CROP));
+ TUtils.captureBySafely(contextWrap, new TIntentWap(IntentUtils.getCaptureIntent(this.tempUri),
+ TConstant.RC_PICK_PICTURE_FROM_CAPTURE_CROP));
} catch (TException e) {
- takeResult(TResult.of(TImage.of("", fromType)), e.getDetailMessage());
+ takeResult(TResult.of(TImage.of("")), e.getDetailMessage());
e.printStackTrace();
}
}
- @Override
- public void onEnableCompress(CompressConfig config, boolean showCompressDialog) {
+ @Override public void onEnableCompress(CompressConfig config, boolean showCompressDialog) {
this.compressConfig = config;
this.showCompressDialog = showCompressDialog;
}
- @Override
- public void setTakePhotoOptions(TakePhotoOptions options) {
+ @Override public void setTakePhotoOptions(TakePhotoOptions options) {
this.takePhotoOptions = options;
}
- @Override
- public void permissionNotify(PermissionManager.TPermissionType type) {
+ @Override public void permissionNotify(PermissionManager.TPermissionType type) {
this.permissionType = type;
}
@@ -410,39 +422,29 @@ private void takeResult(final TResult result, final String... message) {
if (null == compressConfig) {
handleTakeCallBack(result, message);
} else {
- if (showCompressDialog)
- wailLoadDialog = TUtils.showProgressDialog(contextWrap.getActivity(), contextWrap.getActivity().getResources().getString(R.string.tip_compress));
-
- CompressImageImpl.of(contextWrap.getActivity(), compressConfig, result.getImages(), new CompressImage.CompressListener() {
- @Override
- public void onCompressSuccess(ArrayList images) {
- if(!compressConfig.isEnableReserveRaw()) {
- deleteRawFile(images);
- }
- handleTakeCallBack(result);
- if (wailLoadDialog != null && !contextWrap.getActivity().isFinishing())
- wailLoadDialog.dismiss();
- }
+ if (showCompressDialog) {
+ wailLoadDialog = TUtils.showProgressDialog(contextWrap.getActivity(),
+ contextWrap.getActivity().getResources().getString(R.string.tip_compress));
+ }
- @Override
- public void onCompressFailed(ArrayList images, String msg) {
- if(!compressConfig.isEnableReserveRaw()) {
- deleteRawFile(images);
+ CompressImageImpl.of(contextWrap.getActivity(), compressConfig, result.getImages(),
+ new CompressImage.CompressListener() {
+ @Override public void onCompressSuccess(ArrayList images) {
+ handleTakeCallBack(result);
+ if (wailLoadDialog != null && !contextWrap.getActivity().isFinishing()) {
+ wailLoadDialog.dismiss();
+ }
}
- handleTakeCallBack(TResult.of(images), String.format(contextWrap.getActivity().getResources().getString(R.string.tip_compress_failed), message.length > 0 ? message[0] : "", msg, result.getImage().getCompressPath()));
- if (wailLoadDialog != null && !contextWrap.getActivity().isFinishing())
- wailLoadDialog.dismiss();
- }
- }).compress();
- }
- }
- private void deleteRawFile(ArrayList images) {
- for(TImage image : images) {
- if(TImage.FromType.CAMERA == fromType) {
- TFileUtils.delete(image.getOriginalPath());
- image.setOriginalPath("");
- }
+ @Override public void onCompressFailed(ArrayList images, String msg) {
+ handleTakeCallBack(TResult.of(images), String.format(
+ contextWrap.getActivity().getResources().getString(R.string.tip_compress_failed),
+ message.length > 0 ? message[0] : "", msg, result.getImage().getPath()));
+ if (wailLoadDialog != null && !contextWrap.getActivity().isFinishing()) {
+ wailLoadDialog.dismiss();
+ }
+ }
+ }).compress();
}
}
@@ -450,7 +452,8 @@ private void handleTakeCallBack(final TResult result, String... message) {
if (message.length > 0) {
listener.takeFail(result, message[0]);
} else if (multipleCrop != null && multipleCrop.hasFailed) {
- listener.takeFail(result, contextWrap.getActivity().getResources().getString(R.string.msg_crop_failed));
+ listener.takeFail(result,
+ contextWrap.getActivity().getResources().getString(R.string.msg_crop_failed));
} else if (compressConfig != null) {
boolean hasFailed = false;
for (TImage image : result.getImages()) {
@@ -460,7 +463,8 @@ private void handleTakeCallBack(final TResult result, String... message) {
}
}
if (hasFailed) {
- listener.takeFail(result, contextWrap.getActivity().getString(R.string.msg_compress_failed));
+ listener.takeFail(result,
+ contextWrap.getActivity().getString(R.string.msg_compress_failed));
} else {
listener.takeSuccess(result);
}
diff --git a/takephoto_library/src/main/java/com/jph/takephoto/compress/CompressImageImpl.java b/takephoto_library/src/main/java/com/jph/takephoto/compress/CompressImageImpl.java
index 461d31ca..9573702a 100644
--- a/takephoto_library/src/main/java/com/jph/takephoto/compress/CompressImageImpl.java
+++ b/takephoto_library/src/main/java/com/jph/takephoto/compress/CompressImageImpl.java
@@ -46,21 +46,21 @@ public void compress() {
}
private void compress(final TImage image) {
- if (TextUtils.isEmpty(image.getOriginalPath())){
+ if (TextUtils.isEmpty(image.getPath())){
continueCompress(image,false);
return;
}
- File file = new File(image.getOriginalPath());
+ File file = new File(image.getPath());
if (file == null || !file.exists() || !file.isFile()){
continueCompress(image,false);
return;
}
- compressImageUtil.compress(image.getOriginalPath(), new CompressImageUtil.CompressListener() {
+ compressImageUtil.compress(image.getPath(), new CompressImageUtil.CompressListener() {
@Override
public void onCompressSuccess(String imgPath) {
- image.setCompressPath(imgPath);
+ image.setPath(imgPath);
continueCompress(image,true);
}
@@ -89,7 +89,7 @@ private void handleCompressCallBack(String...message){
for(TImage image:images){
if(!image.isCompressed()){
- listener.onCompressFailed(images,image.getCompressPath()+" is compress failures");
+ listener.onCompressFailed(images,image.getPath()+" is compress failures");
return;
}
}
diff --git a/takephoto_library/src/main/java/com/jph/takephoto/compress/CompressWithLuBan.java b/takephoto_library/src/main/java/com/jph/takephoto/compress/CompressWithLuBan.java
index 2503fad3..a38ec0e0 100644
--- a/takephoto_library/src/main/java/com/jph/takephoto/compress/CompressWithLuBan.java
+++ b/takephoto_library/src/main/java/com/jph/takephoto/compress/CompressWithLuBan.java
@@ -46,7 +46,7 @@ public CompressWithLuBan(Context context, CompressConfig config, ArrayList files) {
for (int i = 0, j = images.size(); i < j; i++) {
TImage image = images.get(i);
image.setCompressed(true);
- image.setCompressPath(files.get(i).getPath());
+ image.setPath(files.get(i).getPath());
}
listener.onCompressSuccess(images);
}
-}
+}
\ No newline at end of file
diff --git a/takephoto_library/src/main/java/com/jph/takephoto/model/MultipleCrop.java b/takephoto_library/src/main/java/com/jph/takephoto/model/MultipleCrop.java
index fd94276d..d5c25c03 100644
--- a/takephoto_library/src/main/java/com/jph/takephoto/model/MultipleCrop.java
+++ b/takephoto_library/src/main/java/com/jph/takephoto/model/MultipleCrop.java
@@ -15,30 +15,31 @@
public class MultipleCrop {
private ArrayList uris;
private ArrayList outUris;
- private ArrayListtImages;
- private TImage.FromType fromType;
+ private ArrayList tImages;
public boolean hasFailed;//是否有裁切失败的标识
- public static MultipleCrop of(ArrayList uris,Activity activity, TImage.FromType fromType) throws TException {
- return new MultipleCrop(uris,activity, fromType);
+
+ public static MultipleCrop of(ArrayList uris, Activity activity) throws TException {
+ return new MultipleCrop(uris, activity);
}
- public static MultipleCrop of(ArrayList uris,ArrayListoutUris, TImage.FromType fromType){
- return new MultipleCrop(uris,outUris, fromType);
+
+ public static MultipleCrop of(ArrayList uris, ArrayList outUris) {
+ return new MultipleCrop(uris, outUris);
}
- private MultipleCrop(ArrayList uris,Activity activity, TImage.FromType fromType) throws TException {
- this.uris=uris;
- ArrayListoutUris=new ArrayList<>();
- for (Uri uri:uris){
- outUris.add(Uri.fromFile(TImageFiles.getTempFile(activity,uri)));//生成临时裁切输出路径
+
+ private MultipleCrop(ArrayList uris, Activity activity) throws TException {
+ this.uris = uris;
+ ArrayList outUris = new ArrayList<>();
+ for (Uri uri : uris) {
+ outUris.add(Uri.fromFile(TImageFiles.getTempFile(activity, uri)));//生成临时裁切输出路径
}
- this.outUris=outUris;
- this.tImages= TUtils.getTImagesWithUris(outUris, fromType);
- this.fromType = fromType;
+ this.outUris = outUris;
+ this.tImages = TUtils.getTImagesWithUris(outUris);
}
- private MultipleCrop(ArrayList uris,ArrayListoutUris, TImage.FromType fromType) {
- this.uris=uris;
- this.outUris=outUris;
- this.tImages= TUtils.getTImagesWithUris(outUris, fromType);
- this.fromType = fromType;
+
+ private MultipleCrop(ArrayList uris, ArrayList outUris) {
+ this.uris = uris;
+ this.outUris = outUris;
+ this.tImages = TUtils.getTImagesWithUris(outUris);
}
public ArrayList getUris() {
@@ -67,16 +68,17 @@ public void settImages(ArrayList tImages) {
/**
* 为被裁切的图片设置已被裁切的标识
+ *
* @param uri 被裁切的图片
* @return 该图片是否是最后一张
*/
- public Map setCropWithUri(Uri uri,boolean cropped){
- if(!cropped)hasFailed=true;
- int index=outUris.indexOf(uri);
+ public Map setCropWithUri(Uri uri, boolean cropped) {
+ if (!cropped) hasFailed = true;
+ int index = outUris.indexOf(uri);
tImages.get(index).setCropped(cropped);
- Map result=new HashMap();
- result.put("index",index);
- result.put("isLast",index==outUris.size()-1? true:false);
+ Map result = new HashMap();
+ result.put("index", index);
+ result.put("isLast", index == outUris.size() - 1 ? true : false);
return result;
}
}
diff --git a/takephoto_library/src/main/java/com/jph/takephoto/model/TImage.java b/takephoto_library/src/main/java/com/jph/takephoto/model/TImage.java
index af661498..0f7d5c68 100644
--- a/takephoto_library/src/main/java/com/jph/takephoto/model/TImage.java
+++ b/takephoto_library/src/main/java/com/jph/takephoto/model/TImage.java
@@ -10,49 +10,33 @@
* Author: JPH
* Date: 2016/8/11 17:01
*/
-public class TImage implements Serializable{
- private String originalPath;
- private String compressPath;
- private FromType fromType;
+public class TImage implements Serializable {
+ private String path;
private boolean cropped;
private boolean compressed;
- public static TImage of(String path, FromType fromType){
- return new TImage(path, fromType);
- }
- public static TImage of(Uri uri, FromType fromType){
- return new TImage(uri, fromType);
- }
- private TImage(String path, FromType fromType) {
- this.originalPath = path;
- this.fromType = fromType;
- }
- private TImage(Uri uri, FromType fromType) {
- this.originalPath = uri.getPath();
- this.fromType = fromType;
- }
- public String getOriginalPath() {
- return originalPath;
+ public static TImage of(String path) {
+ return new TImage(path);
}
- public void setOriginalPath(String originalPath) {
- this.originalPath = originalPath;
+ public static TImage of(Uri uri) {
+ return new TImage(uri);
}
- public String getCompressPath() {
- return compressPath;
+ private TImage(String path) {
+ this.path = path;
}
- public void setCompressPath(String compressPath) {
- this.compressPath = compressPath;
+ private TImage(Uri uri) {
+ this.path = uri.getPath();
}
- public FromType getFromType() {
- return fromType;
+ public String getPath() {
+ return path;
}
- public void setFromType(FromType fromType) {
- this.fromType = fromType;
+ public void setPath(String path) {
+ this.path = path;
}
public boolean isCropped() {
@@ -70,8 +54,4 @@ public boolean isCompressed() {
public void setCompressed(boolean compressed) {
this.compressed = compressed;
}
-
- public enum FromType {
- CAMERA, OTHER
- }
}
diff --git a/takephoto_library/src/main/java/com/jph/takephoto/uitl/IntentUtils.java b/takephoto_library/src/main/java/com/jph/takephoto/uitl/IntentUtils.java
index 4b54c475..8c2ab18e 100644
--- a/takephoto_library/src/main/java/com/jph/takephoto/uitl/IntentUtils.java
+++ b/takephoto_library/src/main/java/com/jph/takephoto/uitl/IntentUtils.java
@@ -5,10 +5,10 @@
import android.net.Uri;
import android.provider.MediaStore;
import android.util.Log;
-import com.darsh.multipleimageselect.activities.AlbumSelectActivity;
-import com.darsh.multipleimageselect.helpers.Constants;
import com.jph.takephoto.model.CropOptions;
import com.jph.takephoto.model.TContextWrap;
+import multipleimageselect.activities.AlbumSelectActivity;
+import multipleimageselect.helpers.Constants;
/**
* Intent工具类用于生成拍照、
@@ -17,76 +17,79 @@
* Date: 2016/6/7 0007 13:41
*/
public class IntentUtils {
- private static final String TAG = IntentUtils.class.getName();
+ private static final String TAG = IntentUtils.class.getName();
- /**
- * 获取图片多选的Intent
- * @param limit 最多选择图片张数的限制
- * */
- public static Intent getPickMultipleIntent(TContextWrap contextWrap, int limit){
- Intent intent = new Intent(contextWrap.getActivity(), AlbumSelectActivity.class);
- intent.putExtra(Constants.INTENT_EXTRA_LIMIT, limit>0? limit:1);
- return intent;
- }
-
- /**
- * 获取裁剪照片的Intent
- * @param targetUri 要裁剪的照片
- * @param outPutUri 裁剪完成的照片
- * @param options 裁剪配置
- * @return
- */
- public static Intent getCropIntentWithOtherApp(Uri targetUri, Uri outPutUri, CropOptions options) {
- boolean isReturnData = TUtils.isReturnData();
- Log.w(TAG, "getCaptureIntentWithCrop:isReturnData:" + (isReturnData ? "true" : "false"));
- Intent intent = new Intent("com.android.camera.action.CROP");
- intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- intent.setDataAndType(targetUri, "image/*");
- intent.putExtra("crop", "true");
- if (options.getAspectX()*options.getAspectY()>0){
- intent.putExtra("aspectX", options.getAspectX());
- intent.putExtra("aspectY", options.getAspectY());
- }
- if (options.getOutputX()*options.getOutputY()>0){
- intent.putExtra("outputX", options.getOutputX());
- intent.putExtra("outputY", options.getOutputY());
- }
- intent.putExtra("scale", true);
- intent.putExtra(MediaStore.EXTRA_OUTPUT, outPutUri);
- intent.putExtra("return-data", isReturnData);
- intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
- intent.putExtra("noFaceDetection", true); // no face detection
- return intent;
- }
+ /**
+ * 获取图片多选的Intent
+ *
+ * @param limit 最多选择图片张数的限制
+ */
+ public static Intent getPickMultipleIntent(TContextWrap contextWrap, boolean cameraEnable,
+ int limit) {
+ Intent intent = new Intent(contextWrap.getActivity(), AlbumSelectActivity.class);
+ intent.putExtra(Constants.EXTRA_CAMERA_ENABLE, cameraEnable);
+ intent.putExtra(Constants.INTENT_EXTRA_LIMIT, limit > 0 ? limit : 1);
+ return intent;
+ }
- /**
- * 获取拍照的Intent
- * @return
- */
- public static Intent getCaptureIntent(Uri outPutUri) {
- Intent intent = new Intent();
- intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
- intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);//设置Action为拍照
- intent.putExtra(MediaStore.EXTRA_OUTPUT, outPutUri);//将拍取的照片保存到指定URI
- return intent;
- }
- /**
- * 获取选择照片的Intent
- * @return
- */
- public static Intent getPickIntentWithGallery() {
- Intent intent = new Intent();
- intent.setAction(Intent.ACTION_PICK);//Pick an item from the data
- intent.setType("image/*");//从所有图片中进行选择
- return intent;
+ /**
+ * 获取裁剪照片的Intent
+ *
+ * @param targetUri 要裁剪的照片
+ * @param outPutUri 裁剪完成的照片
+ * @param options 裁剪配置
+ */
+ public static Intent getCropIntentWithOtherApp(Uri targetUri, Uri outPutUri,
+ CropOptions options) {
+ boolean isReturnData = TUtils.isReturnData();
+ Log.w(TAG, "getCaptureIntentWithCrop:isReturnData:" + (isReturnData ? "true" : "false"));
+ Intent intent = new Intent("com.android.camera.action.CROP");
+ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ intent.setDataAndType(targetUri, "image/*");
+ intent.putExtra("crop", "true");
+ if (options.getAspectX() * options.getAspectY() > 0) {
+ intent.putExtra("aspectX", options.getAspectX());
+ intent.putExtra("aspectY", options.getAspectY());
}
- /**
- * 获取从文件中选择照片的Intent
- * @return
- */
- public static Intent getPickIntentWithDocuments() {
- Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
- intent.setType("image/*");
- return intent;
+ if (options.getOutputX() * options.getOutputY() > 0) {
+ intent.putExtra("outputX", options.getOutputX());
+ intent.putExtra("outputY", options.getOutputY());
}
+ intent.putExtra("scale", true);
+ intent.putExtra(MediaStore.EXTRA_OUTPUT, outPutUri);
+ intent.putExtra("return-data", isReturnData);
+ intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
+ intent.putExtra("noFaceDetection", true); // no face detection
+ return intent;
+ }
+
+ /**
+ * 获取拍照的Intent
+ */
+ public static Intent getCaptureIntent(Uri outPutUri) {
+ Intent intent = new Intent();
+ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+ intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);//设置Action为拍照
+ intent.putExtra(MediaStore.EXTRA_OUTPUT, outPutUri);//将拍取的照片保存到指定URI
+ return intent;
+ }
+
+ /**
+ * 获取选择照片的Intent
+ */
+ public static Intent getPickIntentWithGallery() {
+ Intent intent = new Intent();
+ intent.setAction(Intent.ACTION_PICK);//Pick an item from the data
+ intent.setType("image/*");//从所有图片中进行选择
+ return intent;
+ }
+
+ /**
+ * 获取从文件中选择照片的Intent
+ */
+ public static Intent getPickIntentWithDocuments() {
+ Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
+ intent.setType("image/*");
+ return intent;
+ }
}
diff --git a/takephoto_library/src/main/java/com/jph/takephoto/uitl/TUtils.java b/takephoto_library/src/main/java/com/jph/takephoto/uitl/TUtils.java
index 71e501fe..25bf837a 100644
--- a/takephoto_library/src/main/java/com/jph/takephoto/uitl/TUtils.java
+++ b/takephoto_library/src/main/java/com/jph/takephoto/uitl/TUtils.java
@@ -11,8 +11,6 @@
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
-
-import com.darsh.multipleimageselect.models.Image;
import com.jph.takephoto.R;
import com.jph.takephoto.model.CropOptions;
import com.jph.takephoto.model.TContextWrap;
@@ -20,11 +18,10 @@
import com.jph.takephoto.model.TExceptionType;
import com.jph.takephoto.model.TImage;
import com.jph.takephoto.model.TIntentWap;
-import com.soundcloud.android.crop.Crop;
-
import java.io.File;
import java.util.ArrayList;
import java.util.List;
+import multipleimageselect.models.Image;
/**
* 工具类
@@ -34,167 +31,180 @@
public class TUtils {
private static final String TAG = IntentUtils.class.getName();
-
/**
* 将Image集合转换成Uri集合
- * @param images
- * @return
*/
- public static ArrayList convertImageToUri(Context context,ArrayListimages) throws TException {
- ArrayListuris=new ArrayList();
- for(Image image:images){
- uris.add(FileProvider.getUriForFile(context,TConstant.getFileProviderName(context), new File(image.path)));
+ public static ArrayList convertImageToUri(Context context, ArrayList images)
+ throws TException {
+ ArrayList uris = new ArrayList();
+ for (Image image : images) {
+ uris.add(FileProvider.getUriForFile(context, TConstant.getFileProviderName(context),
+ new File(image.path)));
}
return uris;
}
+
/**
* 将Image集合转换成TImage集合
- * @param images
- * @return
*/
- public static ArrayList getTImagesWithImages(ArrayListimages, TImage.FromType fromType){
- ArrayListtImages=new ArrayList();
- for(Image image:images){
- tImages.add(TImage.of(image.path, fromType));
+ public static ArrayList getTImagesWithImages(ArrayList images) {
+ ArrayList tImages = new ArrayList();
+ for (Image image : images) {
+ tImages.add(TImage.of(image.path));
}
return tImages;
}
+
/**
* 将Uri集合转换成TImage集合
- * @param uris
- * @return
*/
- public static ArrayList getTImagesWithUris(ArrayListuris, TImage.FromType fromType){
- ArrayListtImages=new ArrayList();
- for(Uri uri:uris){
- tImages.add(TImage.of(uri, fromType));
+ public static ArrayList getTImagesWithUris(ArrayList uris) {
+ ArrayList tImages = new ArrayList();
+ for (Uri uri : uris) {
+ tImages.add(TImage.of(uri));
}
return tImages;
}
+
/**
* @param contextWrap
* @param intentWap
*/
- public static void startActivityForResult(TContextWrap contextWrap,TIntentWap intentWap){
- if (contextWrap.getFragment()!=null){
- contextWrap.getFragment().startActivityForResult(intentWap.getIntent(),intentWap.getRequestCode());
- }else {
- contextWrap.getActivity().startActivityForResult(intentWap.getIntent(),intentWap.getRequestCode());
+ public static void startActivityForResult(TContextWrap contextWrap, TIntentWap intentWap) {
+ if (contextWrap.getFragment() != null) {
+ contextWrap.getFragment()
+ .startActivityForResult(intentWap.getIntent(), intentWap.getRequestCode());
+ } else {
+ contextWrap.getActivity()
+ .startActivityForResult(intentWap.getIntent(), intentWap.getRequestCode());
}
}
+
/**
* 安全地发送Intent
- * @param contextWrap
+ *
* @param intentWapList 要发送的Intent以及候选Intent
* @param defaultIndex 默认发送的Intent
* @param isCrop 是否为裁切照片的Intent
* @throws TException
*/
- public static void sendIntentBySafely(TContextWrap contextWrap, List intentWapList, int defaultIndex, boolean isCrop)throws TException{
- if (defaultIndex+1>intentWapList.size())throw new TException(isCrop? TExceptionType.TYPE_NO_MATCH_PICK_INTENT:TExceptionType.TYPE_NO_MATCH_CROP_INTENT);
- TIntentWap intentWap=intentWapList.get(defaultIndex);
- List result=contextWrap.getActivity().getPackageManager().queryIntentActivities(intentWap.getIntent(),PackageManager.MATCH_ALL);
- if (result.isEmpty()){
- sendIntentBySafely(contextWrap,intentWapList,++defaultIndex,isCrop);
- }else {
- startActivityForResult(contextWrap,intentWap);
+ public static void sendIntentBySafely(TContextWrap contextWrap, List intentWapList,
+ int defaultIndex, boolean isCrop) throws TException {
+ if (defaultIndex + 1 > intentWapList.size()) {
+ throw new TException(isCrop ? TExceptionType.TYPE_NO_MATCH_PICK_INTENT
+ : TExceptionType.TYPE_NO_MATCH_CROP_INTENT);
+ }
+ TIntentWap intentWap = intentWapList.get(defaultIndex);
+ List result = contextWrap.getActivity()
+ .getPackageManager()
+ .queryIntentActivities(intentWap.getIntent(), PackageManager.MATCH_ALL);
+ if (result.isEmpty()) {
+ sendIntentBySafely(contextWrap, intentWapList, ++defaultIndex, isCrop);
+ } else {
+ startActivityForResult(contextWrap, intentWap);
}
}
+
/**
* 拍照前检查是否有相机
**/
- public static void captureBySafely(TContextWrap contextWrap,TIntentWap intentWap)throws TException{
- List result=contextWrap.getActivity().getPackageManager().queryIntentActivities(intentWap.getIntent(),PackageManager.MATCH_ALL);
- if (result.isEmpty()){
- Toast.makeText(contextWrap.getActivity(),contextWrap.getActivity().getResources().getText(R.string.tip_no_camera),Toast.LENGTH_SHORT).show();
+ public static void captureBySafely(TContextWrap contextWrap, TIntentWap intentWap)
+ throws TException {
+ List result = contextWrap.getActivity()
+ .getPackageManager()
+ .queryIntentActivities(intentWap.getIntent(), PackageManager.MATCH_ALL);
+ if (result.isEmpty()) {
+ Toast.makeText(contextWrap.getActivity(),
+ contextWrap.getActivity().getResources().getText(R.string.tip_no_camera),
+ Toast.LENGTH_SHORT).show();
throw new TException(TExceptionType.TYPE_NO_CAMERA);
- }else {
- startActivityForResult(contextWrap,intentWap);
+ } else {
+ startActivityForResult(contextWrap, intentWap);
}
}
+
/**
* 通过第三方工具裁切照片,当没有第三方裁切工具时,会自动使用自带裁切工具进行裁切
- * @param contextWrap
- * @param imageUri
- * @param outPutUri
- * @param options
*/
- public static void cropWithOtherAppBySafely(TContextWrap contextWrap, Uri imageUri, Uri outPutUri, CropOptions options){
- Intent nativeCropIntent=IntentUtils.getCropIntentWithOtherApp(imageUri, outPutUri,options);
- List result=contextWrap.getActivity().getPackageManager().queryIntentActivities(nativeCropIntent,PackageManager.MATCH_ALL);
- if (result.isEmpty()){
- cropWithOwnApp(contextWrap,imageUri,outPutUri,options);
- }else {
-// try {
-// imageUri=Uri.fromFile(new File(TUriParse.getFilePathWithDocumentsUri(imageUri,contextWrap.getActivity())));
-// } catch (TException e) {
-// e.printStackTrace();
-// }
- startActivityForResult(contextWrap,new TIntentWap(IntentUtils.getCropIntentWithOtherApp(imageUri, outPutUri,options), TConstant.RC_CROP));
- }
- }
- /**
- * 通过TakePhoto自带的裁切工具裁切图片
- * @param contextWrap
- * @param imageUri
- * @param outPutUri
- * @param options
- */
- public static void cropWithOwnApp(TContextWrap contextWrap, Uri imageUri, Uri outPutUri, CropOptions options){
- if (options.getAspectX()*options.getAspectY()>0){
- if (contextWrap.getFragment()!=null){
- Crop.of(imageUri, outPutUri).withAspect(options.getAspectX(),options.getAspectY()).start(contextWrap.getActivity(),contextWrap.getFragment());
- }else {
- Crop.of(imageUri, outPutUri).withAspect(options.getAspectX(),options.getAspectY()).start(contextWrap.getActivity());
- }
- }else if (options.getOutputX()*options.getOutputY()>0){
- if (contextWrap.getFragment()!=null){
- Crop.of(imageUri, outPutUri).withMaxSize(options.getOutputX(),options.getOutputY()).start(contextWrap.getActivity(),contextWrap.getFragment());
- }else {
- Crop.of(imageUri, outPutUri).withMaxSize(options.getOutputX(),options.getOutputY()).start(contextWrap.getActivity());
- }
- }else {
- if (contextWrap.getFragment()!=null){
- Crop.of(imageUri, outPutUri).asSquare().start(contextWrap.getActivity(),contextWrap.getFragment());
- }else {
- Crop.of(imageUri, outPutUri).asSquare().start(contextWrap.getActivity());
- }
+ public static void cropWithOtherAppBySafely(TContextWrap contextWrap, Uri imageUri, Uri outPutUri,
+ CropOptions options) {
+ Intent nativeCropIntent = IntentUtils.getCropIntentWithOtherApp(imageUri, outPutUri, options);
+ List result = contextWrap.getActivity()
+ .getPackageManager()
+ .queryIntentActivities(nativeCropIntent, PackageManager.MATCH_ALL);
+ if (result.isEmpty()) {
+ //cropWithOwnApp(contextWrap,imageUri,outPutUri,options);
+ } else {
+ // try {
+ // imageUri=Uri.fromFile(new File(TUriParse.getFilePathWithDocumentsUri(imageUri,contextWrap.getActivity())));
+ // } catch (TException e) {
+ // e.printStackTrace();
+ // }
+ startActivityForResult(contextWrap,
+ new TIntentWap(IntentUtils.getCropIntentWithOtherApp(imageUri, outPutUri, options),
+ TConstant.RC_CROP));
}
}
+ ///**
+ // * 通过TakePhoto自带的裁切工具裁切图片
+ // * @param contextWrap
+ // * @param imageUri
+ // * @param outPutUri
+ // * @param options
+ // */
+ //public static void cropWithOwnApp(TContextWrap contextWrap, Uri imageUri, Uri outPutUri, CropOptions options){
+ // if (options.getAspectX()*options.getAspectY()>0){
+ // if (contextWrap.getFragment()!=null){
+ // Crop.of(imageUri, outPutUri).withAspect(options.getAspectX(),options.getAspectY()).start(contextWrap.getActivity(),contextWrap.getFragment());
+ // }else {
+ // Crop.of(imageUri, outPutUri).withAspect(options.getAspectX(),options.getAspectY()).start(contextWrap.getActivity());
+ // }
+ // }else if (options.getOutputX()*options.getOutputY()>0){
+ // if (contextWrap.getFragment()!=null){
+ // Crop.of(imageUri, outPutUri).withMaxSize(options.getOutputX(),options.getOutputY()).start(contextWrap.getActivity(),contextWrap.getFragment());
+ // }else {
+ // Crop.of(imageUri, outPutUri).withMaxSize(options.getOutputX(),options.getOutputY()).start(contextWrap.getActivity());
+ // }
+ // }else {
+ // if (contextWrap.getFragment()!=null){
+ // Crop.of(imageUri, outPutUri).asSquare().start(contextWrap.getActivity(),contextWrap.getFragment());
+ // }else {
+ // Crop.of(imageUri, outPutUri).asSquare().start(contextWrap.getActivity());
+ // }
+ // }
+ //}
+
/**
* 是否裁剪之后返回数据
**/
public static boolean isReturnData() {
- String release= Build.VERSION.RELEASE;
- int sdk= Build.VERSION.SDK_INT;
- Log.i(TAG,"release:"+release+"sdk:"+sdk);
- String manufacturer = android.os.Build.MANUFACTURER;
+ String release = Build.VERSION.RELEASE;
+ int sdk = Build.VERSION.SDK_INT;
+ Log.i(TAG, "release:" + release + "sdk:" + sdk);
+ String manufacturer = Build.MANUFACTURER;
if (!TextUtils.isEmpty(manufacturer)) {
if (manufacturer.toLowerCase().contains("lenovo")) {//对于联想的手机返回数据
return true;
}
}
-// if (sdk>=21){//5.0或以上版本要求返回数据
-// return true;
-// }
+ // if (sdk>=21){//5.0或以上版本要求返回数据
+ // return true;
+ // }
return false;
}
+
/**
* 显示圆形进度对话框
*
+ * @param progressTitle 显示的标题
* @author JPH
* Date 2014-12-12 下午7:04:09
- * @param activity
- * @param progressTitle
- * 显示的标题
- * @return
*/
public static ProgressDialog showProgressDialog(final Activity activity,
- String... progressTitle) {
- if(activity==null||activity.isFinishing())return null;
+ String... progressTitle) {
+ if (activity == null || activity.isFinishing()) return null;
String title = activity.getResources().getString(R.string.tip_tips);
- if (progressTitle != null && progressTitle.length > 0)
- title = progressTitle[0];
+ if (progressTitle != null && progressTitle.length > 0) title = progressTitle[0];
ProgressDialog progressDialog = new ProgressDialog(activity);
progressDialog.setTitle(title);
progressDialog.setCancelable(false);
diff --git a/takephoto_library/src/main/java/multipleimageselect/activities/AlbumSelectActivity.java b/takephoto_library/src/main/java/multipleimageselect/activities/AlbumSelectActivity.java
new file mode 100644
index 00000000..92daa4fb
--- /dev/null
+++ b/takephoto_library/src/main/java/multipleimageselect/activities/AlbumSelectActivity.java
@@ -0,0 +1,334 @@
+package multipleimageselect.activities;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Process;
+import android.provider.MediaStore;
+import android.support.v7.app.ActionBar;
+import android.support.v7.widget.Toolbar;
+import android.util.DisplayMetrics;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.GridView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+import com.jph.takephoto.R;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashSet;
+import multipleimageselect.adapters.CustomAlbumSelectAdapter;
+import multipleimageselect.helpers.Constants;
+import multipleimageselect.models.Album;
+
+/**
+ * Created by Darshan on 4/14/2015.
+ */
+public class AlbumSelectActivity extends HelperActivity
+ implements CustomAlbumSelectAdapter.OnItemClick {
+ private ArrayList albums;
+
+ private TextView errorDisplay, txtTitle;
+
+ private ProgressBar progressBar;
+ private GridView gridView;
+ private CustomAlbumSelectAdapter adapter;
+
+ private ActionBar actionBar;
+
+ private ContentObserver observer;
+ private Handler handler;
+ private Thread thread;
+
+ private final String[] projection = new String[] {
+ MediaStore.Images.Media.BUCKET_ID, MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
+ MediaStore.Images.Media.DATA
+ };
+
+ @Override protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_album_select);
+ setView(findViewById(R.id.layout_album_select));
+
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ txtTitle = (TextView) findViewById(R.id.txt_title);
+ setSupportActionBar(toolbar);
+ //SystemBarHelper.immersiveStatusBar(this);
+ //SystemBarHelper.setHeightAndPadding(this, toolbar);
+ actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setHomeAsUpIndicator(R.drawable.ic_arrow_back);
+ actionBar.setDisplayShowTitleEnabled(false);
+ txtTitle.setText(getString(R.string.album_view));
+ }
+
+ Intent intent = getIntent();
+ if (intent == null) {
+ finish();
+ }
+ Constants.limit = intent.getIntExtra(Constants.INTENT_EXTRA_LIMIT, Constants.DEFAULT_LIMIT);
+ Constants.cameraEnable = intent.getBooleanExtra(Constants.EXTRA_CAMERA_ENABLE, false);
+
+ errorDisplay = (TextView) findViewById(R.id.text_view_error);
+ errorDisplay.setVisibility(View.INVISIBLE);
+
+ progressBar = (ProgressBar) findViewById(R.id.progress_bar_album_select);
+ gridView = (GridView) findViewById(R.id.grid_view_album_select);
+ }
+
+ @Override protected void onStart() {
+ super.onStart();
+
+ handler = new Handler() {
+ @Override public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case Constants.PERMISSION_GRANTED: {
+ loadAlbums();
+ break;
+ }
+
+ case Constants.FETCH_STARTED: {
+ progressBar.setVisibility(View.VISIBLE);
+ gridView.setVisibility(View.INVISIBLE);
+ break;
+ }
+
+ case Constants.FETCH_COMPLETED: {
+ if (adapter == null) {
+ adapter = new CustomAlbumSelectAdapter(getApplicationContext(), albums,
+ Constants.cameraEnable);
+ gridView.setAdapter(adapter);
+ adapter.setOnItemClick(AlbumSelectActivity.this);
+
+ progressBar.setVisibility(View.INVISIBLE);
+ gridView.setVisibility(View.VISIBLE);
+ orientationBasedUI(getResources().getConfiguration().orientation);
+ } else {
+ adapter.notifyDataSetChanged();
+ }
+ break;
+ }
+
+ case Constants.ERROR: {
+ progressBar.setVisibility(View.INVISIBLE);
+ errorDisplay.setVisibility(View.VISIBLE);
+ break;
+ }
+
+ default: {
+ super.handleMessage(msg);
+ }
+ }
+ }
+ };
+ observer = new ContentObserver(handler) {
+ @Override public void onChange(boolean selfChange, Uri uri) {
+ loadAlbums();
+ }
+ };
+ getContentResolver().registerContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
+ false, observer);
+
+ checkPermission();
+ }
+
+ @Override protected void onStop() {
+ super.onStop();
+
+ stopThread();
+
+ getContentResolver().unregisterContentObserver(observer);
+ observer = null;
+
+ if (handler != null) {
+ handler.removeCallbacksAndMessages(null);
+ handler = null;
+ }
+ }
+
+ @Override protected void onDestroy() {
+ super.onDestroy();
+
+ if (actionBar != null) {
+ actionBar.setHomeAsUpIndicator(null);
+ }
+ albums = null;
+ if (adapter != null) {
+ adapter.setOnItemClick(null);
+ adapter.releaseResources();
+ }
+ }
+
+ @Override public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ orientationBasedUI(newConfig.orientation);
+ }
+
+ private void orientationBasedUI(int orientation) {
+ final WindowManager windowManager =
+ (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
+ final DisplayMetrics metrics = new DisplayMetrics();
+ windowManager.getDefaultDisplay().getMetrics(metrics);
+
+ if (adapter != null) {
+ int size = orientation == Configuration.ORIENTATION_PORTRAIT ? metrics.widthPixels / 2
+ : metrics.widthPixels / 4;
+ adapter.setLayoutParams(size);
+ }
+ gridView.setNumColumns(orientation == Configuration.ORIENTATION_PORTRAIT ? 2 : 4);
+ }
+
+ @Override public void onBackPressed() {
+ super.onBackPressed();
+ setResult(RESULT_CANCELED);
+ finish();
+ }
+
+ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ if (requestCode == Constants.REQUEST_CODE && resultCode == RESULT_OK && data != null) {
+ setResult(RESULT_OK, data);
+ finish();
+ }
+ }
+
+ @Override public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home: {
+ onBackPressed();
+ return true;
+ }
+
+ default: {
+ return false;
+ }
+ }
+ }
+
+ private void loadAlbums() {
+ startThread(new AlbumLoaderRunnable());
+ }
+
+ /**
+ * 选择图片
+ */
+ @Override public void select(int position) {
+ Intent intent = new Intent(getApplicationContext(), ImageSelectActivity.class);
+ intent.putExtra(Constants.INTENT_EXTRA_ALBUM, albums.get(position).name);
+ startActivityForResult(intent, Constants.REQUEST_CODE);
+ }
+
+ /**
+ * 拍照
+ */
+ @Override public void takePhoto() {
+ Intent intent = new Intent();
+ intent.putExtra(Constants.INTENT_EXTRA_START_CAMERA, true);
+ setResult(RESULT_OK, intent);
+ finish();
+ }
+
+ private class AlbumLoaderRunnable implements Runnable {
+ @Override public void run() {
+ Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+
+ if (adapter == null) {
+ sendMessage(Constants.FETCH_STARTED);
+ }
+
+ Cursor cursor = getApplicationContext().getContentResolver()
+ .query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, null, null,
+ MediaStore.Images.Media.DATE_ADDED);
+ if (cursor == null) {
+ sendMessage(Constants.ERROR);
+ return;
+ }
+
+ ArrayList temp = new ArrayList<>(cursor.getCount());
+ HashSet albumSet = new HashSet<>();
+ File file;
+ if (cursor.moveToLast()) {
+ do {
+ if (Thread.interrupted()) {
+ return;
+ }
+
+ long albumId = cursor.getLong(cursor.getColumnIndex(projection[0]));
+ String album = cursor.getString(cursor.getColumnIndex(projection[1]));
+ String image = cursor.getString(cursor.getColumnIndex(projection[2]));
+
+ if (!albumSet.contains(albumId)) {
+ /*
+ It may happen that some image file paths are still present in cache,
+ though image file does not exist. These last as long as media
+ scanner is not run again. To avoid get such image file paths, check
+ if image file exists.
+ */
+ file = new File(image);
+ if (file.exists()) {
+ temp.add(new Album(album, image));
+ albumSet.add(albumId);
+ }
+ }
+ } while (cursor.moveToPrevious());
+ }
+ cursor.close();
+
+ if (albums == null) {
+ albums = new ArrayList<>();
+ }
+ albums.clear();
+ albums.addAll(temp);
+
+ sendMessage(Constants.FETCH_COMPLETED);
+ }
+ }
+
+ private void startThread(Runnable runnable) {
+ stopThread();
+ thread = new Thread(runnable);
+ thread.start();
+ }
+
+ private void stopThread() {
+ if (thread == null || !thread.isAlive()) {
+ return;
+ }
+
+ thread.interrupt();
+ try {
+ thread.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void sendMessage(int what) {
+ if (handler == null) {
+ return;
+ }
+
+ Message message = handler.obtainMessage();
+ message.what = what;
+ message.sendToTarget();
+ }
+
+ @Override protected void permissionGranted() {
+ Message message = handler.obtainMessage();
+ message.what = Constants.PERMISSION_GRANTED;
+ message.sendToTarget();
+ }
+
+ @Override protected void hideViews() {
+ progressBar.setVisibility(View.INVISIBLE);
+ gridView.setVisibility(View.INVISIBLE);
+ }
+}
diff --git a/takephoto_library/src/main/java/multipleimageselect/activities/HelperActivity.java b/takephoto_library/src/main/java/multipleimageselect/activities/HelperActivity.java
new file mode 100644
index 00000000..ba27f95a
--- /dev/null
+++ b/takephoto_library/src/main/java/multipleimageselect/activities/HelperActivity.java
@@ -0,0 +1,117 @@
+package multipleimageselect.activities;
+
+import android.Manifest;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.provider.Settings;
+import android.support.annotation.NonNull;
+import android.support.design.widget.Snackbar;
+import android.support.v4.app.ActivityCompat;
+import android.support.v4.content.ContextCompat;
+import android.support.v7.app.AppCompatActivity;
+import android.view.View;
+import com.jph.takephoto.R;
+import multipleimageselect.helpers.Constants;
+
+/**
+ * Created by darshan on 26/9/16.
+ */
+public class HelperActivity extends AppCompatActivity {
+ protected View view;
+
+ private final int maxLines = 4;
+ private final String[] permissions = new String[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE };
+
+ protected void checkPermission() {
+ if (ContextCompat.checkSelfPermission(this,
+ Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
+ permissionGranted();
+
+ } else {
+ ActivityCompat.requestPermissions(this, permissions, Constants.PERMISSION_REQUEST_CODE);
+ }
+ }
+
+ private void requestPermission() {
+ if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
+ showRequestPermissionRationale();
+
+ } else {
+ showAppPermissionSettings();
+ }
+ }
+
+ private void showRequestPermissionRationale() {
+ Snackbar snackbar = Snackbar.make(
+ view,
+ getString(R.string.permission_info),
+ Snackbar.LENGTH_INDEFINITE)
+ .setAction(getString(R.string.permission_ok), new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ ActivityCompat.requestPermissions(
+ HelperActivity.this,
+ permissions,
+ Constants.PERMISSION_REQUEST_CODE);
+ }
+ });
+
+ /*((TextView) snackbar.getView()
+ .findViewById(android.support.design.R.id.snackbar_text)).setMaxLines(maxLines);*/
+ snackbar.show();
+ }
+
+ private void showAppPermissionSettings() {
+ Snackbar snackbar = Snackbar.make(
+ view,
+ getString(R.string.permission_force),
+ Snackbar.LENGTH_INDEFINITE)
+ .setAction(getString(R.string.permission_settings), new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Uri uri = Uri.fromParts(
+ getString(R.string.permission_package),
+ HelperActivity.this.getPackageName(),
+ null);
+
+ Intent intent = new Intent();
+ intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
+ intent.setData(uri);
+ startActivityForResult(intent, Constants.PERMISSION_REQUEST_CODE);
+ }
+ });
+
+ /*((TextView) snackbar.getView()
+ .findViewById(android.support.design.R.id.snackbar_text)).setMaxLines(maxLines);*/
+ snackbar.show();
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull
+ int[] grantResults) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+ if (requestCode != Constants.PERMISSION_REQUEST_CODE
+ || grantResults.length == 0
+ || grantResults[0] == PackageManager.PERMISSION_DENIED) {
+ permissionDenied();
+
+ } else {
+ permissionGranted();
+ }
+ }
+
+ protected void permissionGranted() {}
+
+ private void permissionDenied() {
+ hideViews();
+ requestPermission();
+ }
+
+ protected void hideViews() {}
+
+ protected void setView(View view) {
+ this.view = view;
+ }
+}
diff --git a/takephoto_library/src/main/java/multipleimageselect/activities/ImageSelectActivity.java b/takephoto_library/src/main/java/multipleimageselect/activities/ImageSelectActivity.java
new file mode 100644
index 00000000..e1dc156a
--- /dev/null
+++ b/takephoto_library/src/main/java/multipleimageselect/activities/ImageSelectActivity.java
@@ -0,0 +1,386 @@
+package multipleimageselect.activities;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Process;
+import android.provider.MediaStore;
+import android.support.v7.app.ActionBar;
+import android.support.v7.widget.Toolbar;
+import android.text.TextUtils;
+import android.util.DisplayMetrics;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.AdapterView;
+import android.widget.GridView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+import android.widget.Toast;
+import com.jph.takephoto.R;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashSet;
+import multipleimageselect.adapters.CustomImageSelectAdapter;
+import multipleimageselect.helpers.Constants;
+import multipleimageselect.models.Image;
+
+/**
+ * Created by Darshan on 4/18/2015.
+ */
+public class ImageSelectActivity extends HelperActivity {
+ private ArrayList images;
+ private String album;
+
+ private TextView errorDisplay, txtFinish, txtTitle;
+
+ private ProgressBar progressBar;
+ private GridView gridView;
+ private CustomImageSelectAdapter adapter;
+
+ private ActionBar actionBar;
+
+ private int countSelected;
+
+ private ContentObserver observer;
+ private Handler handler;
+ private Thread thread;
+
+ private final String[] projection = new String[] {
+ MediaStore.Images.Media._ID, MediaStore.Images.Media.DISPLAY_NAME,
+ MediaStore.Images.Media.DATA
+ };
+
+ @Override protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_image_select);
+ setView(findViewById(R.id.layout_image_select));
+ Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ txtFinish = (TextView) findViewById(R.id.txt_finish);
+ txtTitle = (TextView) findViewById(R.id.txt_title);
+ setSupportActionBar(toolbar);
+ //SystemBarHelper.immersiveStatusBar(this);
+ //SystemBarHelper.setHeightAndPadding(this, toolbar);
+ actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setHomeAsUpIndicator(R.drawable.ic_arrow_back);
+ actionBar.setDisplayShowTitleEnabled(false);
+ setTitle(getString(R.string.image_view));
+ }
+ toolbar.setNavigationOnClickListener(new View.OnClickListener() {
+ @Override public void onClick(View view) {
+ onBackPressed();
+ }
+ });
+ txtFinish.setOnClickListener(new View.OnClickListener() {
+ @Override public void onClick(View v) {
+ if (countSelected > 0) sendIntent();
+ }
+ });
+ Intent intent = getIntent();
+ if (intent == null) {
+ finish();
+ }
+ album = intent.getStringExtra(Constants.INTENT_EXTRA_ALBUM);
+
+ errorDisplay = (TextView) findViewById(R.id.text_view_error);
+ errorDisplay.setVisibility(View.INVISIBLE);
+
+ progressBar = (ProgressBar) findViewById(R.id.progress_bar_image_select);
+ gridView = (GridView) findViewById(R.id.grid_view_image_select);
+ gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ toggleSelection(position);
+ String selectFormat = getString(R.string.selected);
+ setTitle(String.format(selectFormat, Constants.limit - countSelected + "张"));
+ txtFinish.setVisibility(View.VISIBLE);
+ if (countSelected == 0) {
+ setTitle(getString(R.string.image_view));
+ txtFinish.setVisibility(View.INVISIBLE);
+ }
+ }
+ });
+ }
+
+ @Override protected void onStart() {
+ super.onStart();
+
+ handler = new Handler() {
+ @Override public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case Constants.PERMISSION_GRANTED: {
+ loadImages();
+ break;
+ }
+
+ case Constants.FETCH_STARTED: {
+ progressBar.setVisibility(View.VISIBLE);
+ gridView.setVisibility(View.INVISIBLE);
+ break;
+ }
+
+ case Constants.FETCH_COMPLETED: {
+ /*
+ If adapter is null, this implies that the loaded images will be shown
+ for the first time, hence send FETCH_COMPLETED message.
+ However, if adapter has been initialised, this thread was run either
+ due to the activity being restarted or content being changed.
+ */
+ if (adapter == null) {
+ adapter = new CustomImageSelectAdapter(getApplicationContext(), images);
+ gridView.setAdapter(adapter);
+
+ progressBar.setVisibility(View.INVISIBLE);
+ gridView.setVisibility(View.VISIBLE);
+ orientationBasedUI(getResources().getConfiguration().orientation);
+ } else {
+ adapter.notifyDataSetChanged();
+ /*
+ Some selected images may have been deleted
+ hence update action mode title
+ */
+ //if (actionMode != null) {
+ // countSelected = msg.arg1;
+ // actionMode.setTitle(countSelected + " 已选");
+ //}
+ }
+ break;
+ }
+
+ case Constants.ERROR: {
+ progressBar.setVisibility(View.INVISIBLE);
+ errorDisplay.setVisibility(View.VISIBLE);
+ break;
+ }
+
+ default: {
+ super.handleMessage(msg);
+ }
+ }
+ }
+ };
+ observer = new ContentObserver(handler) {
+ @Override public void onChange(boolean selfChange) {
+ loadImages();
+ }
+ };
+ getContentResolver().registerContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
+ false, observer);
+
+ checkPermission();
+ }
+
+ @Override protected void onStop() {
+ super.onStop();
+
+ stopThread();
+
+ getContentResolver().unregisterContentObserver(observer);
+ observer = null;
+
+ if (handler != null) {
+ handler.removeCallbacksAndMessages(null);
+ handler = null;
+ }
+ }
+
+ @Override protected void onDestroy() {
+ super.onDestroy();
+
+ if (actionBar != null) {
+ actionBar.setHomeAsUpIndicator(null);
+ }
+ images = null;
+ if (adapter != null) {
+ adapter.releaseResources();
+ }
+ gridView.setOnItemClickListener(null);
+ }
+
+ @Override public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ orientationBasedUI(newConfig.orientation);
+ }
+
+ private void orientationBasedUI(int orientation) {
+ final WindowManager windowManager =
+ (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE);
+ final DisplayMetrics metrics = new DisplayMetrics();
+ windowManager.getDefaultDisplay().getMetrics(metrics);
+
+ if (adapter != null) {
+ int size = orientation == Configuration.ORIENTATION_PORTRAIT ? metrics.widthPixels / 3
+ : metrics.widthPixels / 5;
+ adapter.setLayoutParams(size);
+ }
+ gridView.setNumColumns(orientation == Configuration.ORIENTATION_PORTRAIT ? 3 : 5);
+ }
+
+ private void toggleSelection(int position) {
+ if (!images.get(position).isSelected && countSelected >= Constants.limit) {
+ Toast.makeText(getApplicationContext(), "照片已经达到上限", Toast.LENGTH_SHORT).show();
+ //Toast.makeText(getApplicationContext(),
+ // String.format(getString(R.string.limit_exceeded), Constants.limit), Toast.LENGTH_SHORT)
+ // .show();
+ return;
+ }
+
+ images.get(position).isSelected = !images.get(position).isSelected;
+ if (images.get(position).isSelected) {
+ countSelected++;
+ } else {
+ countSelected--;
+ }
+ adapter.notifyDataSetChanged();
+ }
+
+ private ArrayList getSelected() {
+ ArrayList selectedImages = new ArrayList<>();
+ for (int i = 0, l = images.size(); i < l; i++) {
+ if (images.get(i).isSelected) {
+ selectedImages.add(images.get(i));
+ }
+ }
+ return selectedImages;
+ }
+
+ private void sendIntent() {
+ Intent intent = new Intent();
+ intent.putParcelableArrayListExtra(Constants.INTENT_EXTRA_IMAGES, getSelected());
+ intent.putExtra(Constants.INTENT_EXTRA_START_CAMERA, false);
+ setResult(RESULT_OK, intent);
+ finish();
+ }
+
+ private void loadImages() {
+ startThread(new ImageLoaderRunnable());
+ }
+
+ private class ImageLoaderRunnable implements Runnable {
+ @Override public void run() {
+ Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+ /*
+ If the adapter is null, this is first time this activity's view is
+ being shown, hence send FETCH_STARTED message to show progress bar
+ while images are loaded from phone
+ */
+ if (adapter == null) {
+ sendMessage(Constants.FETCH_STARTED);
+ }
+
+ File file;
+ HashSet selectedImages = new HashSet<>();
+ if (images != null) {
+ Image image;
+ for (int i = 0, l = images.size(); i < l; i++) {
+ image = images.get(i);
+ file = new File(image.path);
+ if (file.exists() && image.isSelected) {
+ selectedImages.add(image.id);
+ }
+ }
+ }
+
+ Cursor cursor =
+ getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection,
+ MediaStore.Images.Media.BUCKET_DISPLAY_NAME + " =?", new String[] { album },
+ MediaStore.Images.Media.DATE_ADDED);
+ if (cursor == null) {
+ sendMessage(Constants.ERROR);
+ return;
+ }
+
+ /*
+ In case this runnable is executed to onChange calling loadImages,
+ using countSelected variable can result in a race condition. To avoid that,
+ tempCountSelected keeps track of number of selected images. On handling
+ FETCH_COMPLETED message, countSelected is assigned value of tempCountSelected.
+ */
+ int tempCountSelected = 0;
+ ArrayList temp = new ArrayList<>(cursor.getCount());
+ if (cursor.moveToLast()) {
+ do {
+ if (Thread.interrupted()) {
+ return;
+ }
+
+ long id = cursor.getLong(cursor.getColumnIndex(projection[0]));
+ String name = cursor.getString(cursor.getColumnIndex(projection[1]));
+ String path = cursor.getString(cursor.getColumnIndex(projection[2]));
+ boolean isSelected = selectedImages.contains(id);
+ if (isSelected) {
+ tempCountSelected++;
+ }
+
+ file = new File(path);
+ if (file.exists()) {
+ temp.add(new Image(id, name, path, isSelected));
+ }
+ } while (cursor.moveToPrevious());
+ }
+ cursor.close();
+
+ if (images == null) {
+ images = new ArrayList<>();
+ }
+ images.clear();
+ images.addAll(temp);
+
+ sendMessage(Constants.FETCH_COMPLETED, tempCountSelected);
+ }
+ }
+
+ private void startThread(Runnable runnable) {
+ stopThread();
+ thread = new Thread(runnable);
+ thread.start();
+ }
+
+ private void stopThread() {
+ if (thread == null || !thread.isAlive()) {
+ return;
+ }
+
+ thread.interrupt();
+ try {
+ thread.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void sendMessage(int what) {
+ sendMessage(what, 0);
+ }
+
+ private void sendMessage(int what, int arg1) {
+ if (handler == null) {
+ return;
+ }
+
+ Message message = handler.obtainMessage();
+ message.what = what;
+ message.arg1 = arg1;
+ message.sendToTarget();
+ }
+
+ @Override protected void permissionGranted() {
+ sendMessage(Constants.PERMISSION_GRANTED);
+ }
+
+ @Override protected void hideViews() {
+ progressBar.setVisibility(View.INVISIBLE);
+ gridView.setVisibility(View.INVISIBLE);
+ }
+
+ private void setTitle(String title) {
+ if (!TextUtils.isEmpty(title)) {
+ txtTitle.setText(title);
+ }
+ }
+}
diff --git a/takephoto_library/src/main/java/multipleimageselect/adapters/CustomAlbumSelectAdapter.java b/takephoto_library/src/main/java/multipleimageselect/adapters/CustomAlbumSelectAdapter.java
new file mode 100644
index 00000000..8c3f9cb1
--- /dev/null
+++ b/takephoto_library/src/main/java/multipleimageselect/adapters/CustomAlbumSelectAdapter.java
@@ -0,0 +1,113 @@
+package multipleimageselect.adapters;
+
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.TextView;
+import com.bumptech.glide.Glide;
+import com.jph.takephoto.R;
+import java.util.ArrayList;
+import multipleimageselect.models.Album;
+
+/**
+ * Created by Darshan on 4/14/2015.
+ */
+public class CustomAlbumSelectAdapter extends CustomGenericAdapter {
+ private boolean enableCamera;
+ private OnItemClick onItemClick;
+
+ public CustomAlbumSelectAdapter(Context context, ArrayList albums, boolean enableCamera) {
+ super(context, albums);
+ this.enableCamera = enableCamera;
+ }
+
+ public void setOnItemClick(OnItemClick onItemClick) {
+ this.onItemClick = onItemClick;
+ }
+
+ @Override public int getCount() {
+ if (enableCamera) {
+ return super.getCount() + 1;
+ }
+ return super.getCount();
+ }
+
+ @Override public View getView(final int position, View convertView, ViewGroup parent) {
+ ViewHolder viewHolder;
+
+ if (convertView == null) {
+ convertView = layoutInflater.inflate(R.layout.grid_view_item_album_select, null);
+
+ viewHolder = new ViewHolder();
+ viewHolder.imageView = (ImageView) convertView.findViewById(R.id.image_view_album_image);
+ viewHolder.textView = (TextView) convertView.findViewById(R.id.text_view_album_name);
+ viewHolder.frameLayout = (FrameLayout) convertView.findViewById(R.id.frame_album_item);
+
+ convertView.setTag(viewHolder);
+ } else {
+ viewHolder = (ViewHolder) convertView.getTag();
+ }
+
+ viewHolder.imageView.getLayoutParams().width = size;
+ viewHolder.imageView.getLayoutParams().height = size;
+ //启用拍照
+ if (enableCamera) {
+ if (0 == position) {
+ if (null != onItemClick) {
+ viewHolder.frameLayout.setOnClickListener(new View.OnClickListener() {
+ @Override public void onClick(View v) {
+ onItemClick.takePhoto();
+ }
+ });
+ }
+ viewHolder.textView.setText("拍照");
+ Glide.with(context).load(R.drawable.ic_camera).centerCrop().into(viewHolder.imageView);
+ } else {
+ if (null != onItemClick) {
+ viewHolder.frameLayout.setOnClickListener(new View.OnClickListener() {
+ @Override public void onClick(View v) {
+ onItemClick.select(position-1);
+ }
+ });
+ }
+ viewHolder.textView.setText(arrayList.get(position - 1).name);
+ Glide.with(context)
+ .load(arrayList.get(position - 1).cover)
+ .placeholder(R.drawable.image_placeholder)
+ .centerCrop()
+ .into(viewHolder.imageView);
+ }
+ } else {
+ //不启用拍照
+ if (null != onItemClick) {
+ viewHolder.frameLayout.setOnClickListener(new View.OnClickListener() {
+ @Override public void onClick(View v) {
+ onItemClick.select(position);
+ }
+ });
+ }
+ viewHolder.textView.setText(arrayList.get(position).name);
+ Glide.with(context)
+ .load(arrayList.get(position).cover)
+ .placeholder(R.drawable.image_placeholder)
+ .centerCrop()
+ .into(viewHolder.imageView);
+ }
+
+ return convertView;
+ }
+
+ private static class ViewHolder {
+ public FrameLayout frameLayout;
+ public ImageView imageView;
+ public TextView textView;
+ }
+
+ public interface OnItemClick {
+ void select(int pos);
+
+ void takePhoto();
+ }
+}
diff --git a/takephoto_library/src/main/java/multipleimageselect/adapters/CustomGenericAdapter.java b/takephoto_library/src/main/java/multipleimageselect/adapters/CustomGenericAdapter.java
new file mode 100644
index 00000000..c1ec2c1b
--- /dev/null
+++ b/takephoto_library/src/main/java/multipleimageselect/adapters/CustomGenericAdapter.java
@@ -0,0 +1,46 @@
+package multipleimageselect.adapters;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.widget.BaseAdapter;
+import java.util.ArrayList;
+
+/**
+ * Created by Darshan on 4/24/2015.
+ */
+public abstract class CustomGenericAdapter extends BaseAdapter {
+ protected ArrayList arrayList;
+ protected Context context;
+ protected LayoutInflater layoutInflater;
+
+ protected int size;
+
+ public CustomGenericAdapter(Context context, ArrayList arrayList) {
+ this.arrayList = arrayList;
+ this.context = context;
+ this.layoutInflater = LayoutInflater.from(this.context);
+ }
+
+ @Override
+ public int getCount() {
+ return arrayList.size();
+ }
+
+ public T getItem(int position) {
+ return arrayList.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ public void setLayoutParams(int size) {
+ this.size = size;
+ }
+
+ public void releaseResources() {
+ arrayList = null;
+ context = null;
+ }
+}
diff --git a/takephoto_library/src/main/java/multipleimageselect/adapters/CustomImageSelectAdapter.java b/takephoto_library/src/main/java/multipleimageselect/adapters/CustomImageSelectAdapter.java
new file mode 100644
index 00000000..c3fcdce4
--- /dev/null
+++ b/takephoto_library/src/main/java/multipleimageselect/adapters/CustomImageSelectAdapter.java
@@ -0,0 +1,65 @@
+package multipleimageselect.adapters;
+
+import android.content.Context;
+import android.support.v4.content.ContextCompat;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import com.bumptech.glide.Glide;
+import com.jph.takephoto.R;
+import java.util.ArrayList;
+import multipleimageselect.models.Image;
+
+/**
+ * Created by Darshan on 4/18/2015.
+ */
+public class CustomImageSelectAdapter extends CustomGenericAdapter {
+ public CustomImageSelectAdapter(Context context, ArrayList images) {
+ super(context, images);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ ViewHolder viewHolder;
+
+ if (convertView == null) {
+ convertView = layoutInflater.inflate(R.layout.grid_view_item_image_select, null);
+
+ viewHolder = new ViewHolder();
+ viewHolder.imageView = (ImageView) convertView.findViewById(R.id.image_view_image_select);
+ viewHolder.view = convertView.findViewById(R.id.view_alpha);
+
+ convertView.setTag(viewHolder);
+
+ } else {
+ viewHolder = (ViewHolder) convertView.getTag();
+ }
+
+ viewHolder.imageView.getLayoutParams().width = size;
+ viewHolder.imageView.getLayoutParams().height = size;
+
+ viewHolder.view.getLayoutParams().width = size;
+ viewHolder.view.getLayoutParams().height = size;
+
+ if (arrayList.get(position).isSelected) {
+ viewHolder.view.setAlpha(0.5f);
+ ((FrameLayout) convertView).setForeground(ContextCompat.getDrawable(context,R.drawable.ic_done_white));
+
+ } else {
+ viewHolder.view.setAlpha(0.0f);
+ ((FrameLayout) convertView).setForeground(null);
+ }
+
+ Glide.with(context)
+ .load(arrayList.get(position).path)
+ .placeholder(R.drawable.image_placeholder).into(viewHolder.imageView);
+
+ return convertView;
+ }
+
+ private static class ViewHolder {
+ public ImageView imageView;
+ public View view;
+ }
+}
diff --git a/takephoto_library/src/main/java/multipleimageselect/helpers/Constants.java b/takephoto_library/src/main/java/multipleimageselect/helpers/Constants.java
new file mode 100644
index 00000000..10d83b49
--- /dev/null
+++ b/takephoto_library/src/main/java/multipleimageselect/helpers/Constants.java
@@ -0,0 +1,33 @@
+package multipleimageselect.helpers;
+
+/**
+ * Created by Darshan on 5/26/2015.
+ */
+public class Constants {
+ public static final int PERMISSION_REQUEST_CODE = 1000;
+ public static final int PERMISSION_GRANTED = 1001;
+ public static final int PERMISSION_DENIED = 1002;
+
+ public static final int REQUEST_CODE = 2000;
+
+ public static final int FETCH_STARTED = 2001;
+ public static final int FETCH_COMPLETED = 2002;
+ public static final int ERROR = 2005;
+
+ /**
+ * Request code for permission has to be < (1 << 8)
+ * Otherwise throws java.lang.IllegalArgumentException: Can only use lower 8 bits for requestCode
+ */
+ public static final int PERMISSION_REQUEST_READ_EXTERNAL_STORAGE = 23;
+
+ public static final String INTENT_EXTRA_ALBUM = "album";
+ public static final String INTENT_EXTRA_IMAGES = "images";
+ public static final String INTENT_EXTRA_LIMIT = "limit";
+ public static final String INTENT_EXTRA_START_CAMERA = "start_camera";
+ public static final String EXTRA_CAMERA_ENABLE = "camera_enable";
+ public static final int DEFAULT_LIMIT = 10;
+
+ //Maximum number of images that can be selected at a time
+ public static int limit;
+ public static boolean cameraEnable;
+}
diff --git a/takephoto_library/src/main/java/multipleimageselect/models/Album.java b/takephoto_library/src/main/java/multipleimageselect/models/Album.java
new file mode 100644
index 00000000..fd4de58f
--- /dev/null
+++ b/takephoto_library/src/main/java/multipleimageselect/models/Album.java
@@ -0,0 +1,14 @@
+package multipleimageselect.models;
+
+/**
+ * Created by Darshan on 4/14/2015.
+ */
+public class Album {
+ public String name;
+ public String cover;
+
+ public Album(String name, String cover) {
+ this.name = name;
+ this.cover = cover;
+ }
+}
diff --git a/takephoto_library/src/main/java/multipleimageselect/models/Image.java b/takephoto_library/src/main/java/multipleimageselect/models/Image.java
new file mode 100644
index 00000000..e34a5ab2
--- /dev/null
+++ b/takephoto_library/src/main/java/multipleimageselect/models/Image.java
@@ -0,0 +1,51 @@
+package multipleimageselect.models;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Created by Darshan on 4/18/2015.
+ */
+public class Image implements Parcelable {
+ public long id;
+ public String name;
+ public String path;
+ public boolean isSelected;
+
+ public Image(long id, String name, String path, boolean isSelected) {
+ this.id = id;
+ this.name = name;
+ this.path = path;
+ this.isSelected = isSelected;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeLong(id);
+ dest.writeString(name);
+ dest.writeString(path);
+ }
+
+ public static final Creator CREATOR = new Creator() {
+ @Override
+ public Image createFromParcel(Parcel source) {
+ return new Image(source);
+ }
+
+ @Override
+ public Image[] newArray(int size) {
+ return new Image[size];
+ }
+ };
+
+ private Image(Parcel in) {
+ id = in.readLong();
+ name = in.readString();
+ path = in.readString();
+ }
+}
diff --git a/takephoto_library/src/main/res/drawable-xhdpi/ic_arrow_back.png b/takephoto_library/src/main/res/drawable-xhdpi/ic_arrow_back.png
new file mode 100644
index 00000000..ce5b878b
Binary files /dev/null and b/takephoto_library/src/main/res/drawable-xhdpi/ic_arrow_back.png differ
diff --git a/takephoto_library/src/main/res/drawable-xhdpi/ic_camera.png b/takephoto_library/src/main/res/drawable-xhdpi/ic_camera.png
new file mode 100644
index 00000000..17aa3be0
Binary files /dev/null and b/takephoto_library/src/main/res/drawable-xhdpi/ic_camera.png differ
diff --git a/takephoto_library/src/main/res/drawable-xhdpi/ic_done_white.png b/takephoto_library/src/main/res/drawable-xhdpi/ic_done_white.png
new file mode 100644
index 00000000..0ebb5555
Binary files /dev/null and b/takephoto_library/src/main/res/drawable-xhdpi/ic_done_white.png differ
diff --git a/takephoto_library/src/main/res/drawable-xxhdpi/ic_arrow_back.png b/takephoto_library/src/main/res/drawable-xxhdpi/ic_arrow_back.png
new file mode 100644
index 00000000..746d7757
Binary files /dev/null and b/takephoto_library/src/main/res/drawable-xxhdpi/ic_arrow_back.png differ
diff --git a/takephoto_library/src/main/res/drawable-xxhdpi/ic_camera.png b/takephoto_library/src/main/res/drawable-xxhdpi/ic_camera.png
new file mode 100644
index 00000000..8d9c05e3
Binary files /dev/null and b/takephoto_library/src/main/res/drawable-xxhdpi/ic_camera.png differ
diff --git a/takephoto_library/src/main/res/drawable-xxhdpi/ic_done_white.png b/takephoto_library/src/main/res/drawable-xxhdpi/ic_done_white.png
new file mode 100644
index 00000000..200dc733
Binary files /dev/null and b/takephoto_library/src/main/res/drawable-xxhdpi/ic_done_white.png differ
diff --git a/takephoto_library/src/main/res/drawable/image_placeholder.xml b/takephoto_library/src/main/res/drawable/image_placeholder.xml
new file mode 100644
index 00000000..43ad7823
--- /dev/null
+++ b/takephoto_library/src/main/res/drawable/image_placeholder.xml
@@ -0,0 +1,5 @@
+
+
+
+
\ No newline at end of file
diff --git a/takephoto_library/src/main/res/layout/activity_album_select.xml b/takephoto_library/src/main/res/layout/activity_album_select.xml
new file mode 100644
index 00000000..16c8e360
--- /dev/null
+++ b/takephoto_library/src/main/res/layout/activity_album_select.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/takephoto_library/src/main/res/layout/activity_image_select.xml b/takephoto_library/src/main/res/layout/activity_image_select.xml
new file mode 100644
index 00000000..9903c168
--- /dev/null
+++ b/takephoto_library/src/main/res/layout/activity_image_select.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/takephoto_library/src/main/res/layout/grid_view_item_album_select.xml b/takephoto_library/src/main/res/layout/grid_view_item_album_select.xml
new file mode 100644
index 00000000..3b1a49ea
--- /dev/null
+++ b/takephoto_library/src/main/res/layout/grid_view_item_album_select.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/takephoto_library/src/main/res/layout/grid_view_item_image_select.xml b/takephoto_library/src/main/res/layout/grid_view_item_image_select.xml
new file mode 100644
index 00000000..19a32a91
--- /dev/null
+++ b/takephoto_library/src/main/res/layout/grid_view_item_image_select.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/takephoto_library/src/main/res/layout/toolbar.xml b/takephoto_library/src/main/res/layout/toolbar.xml
new file mode 100644
index 00000000..a2cce928
--- /dev/null
+++ b/takephoto_library/src/main/res/layout/toolbar.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/takephoto_library/src/main/res/values-en/strings.xml b/takephoto_library/src/main/res/values-en/strings.xml
deleted file mode 100644
index daa40bdc..00000000
--- a/takephoto_library/src/main/res/values-en/strings.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
- Choose not pictures
- No camera
- Tips
- Being compressed...
- "%1$s Picture compression failure:%2$s picturePath:%3$s"
- "There are pictures of crop failures."
- "There are pictures of compress failures."
- " canceled crop"
- "Operation canceled."
- No permission to use the camera, open the rights management
- No permission to use the SD card, open the rights management
- No permission to use the camera and SD card, open the rights management
-
-
diff --git a/takephoto_library/src/main/res/values/color.xml b/takephoto_library/src/main/res/values/color.xml
new file mode 100644
index 00000000..30605ab4
--- /dev/null
+++ b/takephoto_library/src/main/res/values/color.xml
@@ -0,0 +1,17 @@
+
+
+ #FFFFFF
+
+ #2E7D32
+ #1B5E20
+ #C8E6C9
+ #4CAF50
+
+ #212121
+ #727272
+ #B6B6B6
+ #FFFFFF
+
+ #99FFFFFF
+ #000000
+
\ No newline at end of file
diff --git a/takephoto_library/src/main/res/values/strings.xml b/takephoto_library/src/main/res/values/strings.xml
index 23c46910..aba0c364 100644
--- a/takephoto_library/src/main/res/values/strings.xml
+++ b/takephoto_library/src/main/res/values/strings.xml
@@ -1,24 +1,34 @@
-
- 选择的不是图片
- 没有相机
- 提示
- 正在压缩照片...
- "%1$s 图片压缩失败:%2$s picturePath:%3$s"
- "有裁切失败的图片"
- "有压缩失败的图片"
- " 取消裁切"
- "操作被取消"
- 没有使用相机的权限,请在权限管理中开启
- 没有使用SD卡的权限,请在权限管理中开启
- 没有使用相机和SD卡的权限,请在权限管理中开启
+
+ 选择的不是图片
+ 没有相机
+ 提示
+ 正在压缩照片...
+ "%1$s 图片压缩失败:%2$s picturePath:%3$s"
+ "有裁切失败的图片"
+ "有压缩失败的图片"
+ " 取消裁切"
+ "操作被取消"
+ 没有使用相机的权限,请在权限管理中开启
+ 没有使用SD卡的权限,请在权限管理中开启
+ 没有使用相机和SD卡的权限,请在权限管理中开启
-
- 选择图片
- 单击选择
+
- 确定
- 已选
- 最多能选 %d 张
+ 单击选择
+ 选择图片
+
+ 确定
+ OK
+ Settings
+ package
+ App requires permission to Storage to view images.
+ App requires permission to Storage to view images. Tap Settings
+ and go to Permissions to grant permission.
+
+ Oops, something went wrong!
+
+ 还能选%1$s
+ 最多能选 %d 张
diff --git a/takephoto_library/src/main/res/values/style.xml b/takephoto_library/src/main/res/values/style.xml
new file mode 100644
index 00000000..12f5e3b7
--- /dev/null
+++ b/takephoto_library/src/main/res/values/style.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
\ No newline at end of file