Android plugin now supports thumbnails as well

This commit is contained in:
hanssens
2015-08-19 22:48:21 +02:00
parent 42de0ff3ce
commit 2aab5cd4b7
6 changed files with 315 additions and 25 deletions
Binary file not shown.
Binary file not shown.
+65
View File
@@ -0,0 +1,65 @@
package com.synconset;
import org.json.JSONException;
import org.json.JSONObject;
import android.os.Parcel;
import android.os.Parcelable;
public class FileNameItem implements Parcelable{
public String thumb;
public String original;
public Integer rotation;
public FileNameItem(){
super();
}
public FileNameItem(Parcel in) {
super();
readFromParcel(in);
}
public static final Parcelable.Creator<FileNameItem> CREATOR = new Parcelable.Creator<FileNameItem>() {
public FileNameItem createFromParcel(Parcel in) {
return new FileNameItem(in);
}
public FileNameItem[] newArray(int size) {
return new FileNameItem[size];
}
};
public void readFromParcel(Parcel in) {
thumb = in.readString();
original = in.readString();
rotation = in.readInt();
}
@Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags ) {
// TODO Auto-generated method stub
dest.writeString(thumb);
dest.writeString(original);
dest.writeInt(rotation);
}
/*public JSONObject getJSONObject() {
JSONObject obj = new JSONObject();
try {
obj.put("thumb", thumb);
obj.put("original", orginal);
obj.put("rotation", rotation);
} catch (JSONException e) {
//trace("DefaultListItem.toString JSONException: "+e.getMessage());
}
return obj;
}*/
}
+125 -2
View File
@@ -16,23 +16,32 @@
package com.synconset;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException;
import org.apache.commons.io.FileUtils;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.Matrix;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.provider.MediaStore;
import android.util.Log;
@@ -54,13 +63,43 @@ import android.widget.ImageView;
* performance.
*/
public class ImageFetcher {
private int colWidth;
private long origId;
private ExecutorService executor;
public ImageFetcher() {
File dir_thumb;
private Context context;
private Map<Integer, String> thumbnails = new HashMap<Integer, String>();
public ImageFetcher( Context ct ) {
context = ct;
executor = Executors.newCachedThreadPool();
dir_thumb = new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES),"thumb");
if( !dir_thumb.isDirectory() && !dir_thumb.mkdir() ){
// failed
}
try {
FileUtils.cleanDirectory(dir_thumb);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* Get Thumb URL
* @param id
* @return
*/
public String getThumbFilePath( Integer id ){
String url = thumbnails.get(id);
return url;
}
public void fetch(Integer id, ImageView imageView, int colWidth, int rotate) {
@@ -230,6 +269,10 @@ public class ImageFetcher {
if (isCancelled()) {
bitmap = null;
}
// store bitmap to private storage
storeBitmapToPrivate(position, bitmap);
addBitmapToCache(position, bitmap);
if (imageViewReference != null) {
ImageView imageView = imageViewReference.get();
@@ -245,6 +288,86 @@ public class ImageFetcher {
}
}
}
/**
* Save Thumbnail to private storage.
*/
boolean storeBitmapToPrivate( Integer position, Bitmap bitmap ){
if( thumbnails.containsKey(position) ){
return true;
}
/*String state = Environment.getExternalStorageState();
if ( !Environment.MEDIA_MOUNTED.equals(state)) {
return false;
}
*/
if( !dir_thumb.isDirectory() ){
return false;
}
String state = Environment.getExternalStorageState();
if ( !Environment.MEDIA_MOUNTED.equals(state)) {
return false;
}
File file_thumb;
try {
file_thumb = File.createTempFile("thumb", null, dir_thumb );
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
String url_thumb = file_thumb.getAbsolutePath();
if( !saveBitmapToFileCache(bitmap, file_thumb) ){
file_thumb.delete();
return false;
}
thumbnails.put( position, url_thumb );
return true;
}
private boolean saveBitmapToFileCache(Bitmap bitmap, File file_thumb ) {
//File fileCacheItem = new File(strFilePath);
OutputStream out = null;
boolean result = false;
try
{
//result= fileCacheItem.createNewFile();
out = new FileOutputStream(file_thumb);
bitmap.compress(CompressFormat.JPEG, 100, out);
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
try
{
out.close();
result = true;
}
catch (IOException e)
{
e.printStackTrace();
}
}
return result;
}
/**
* A fake Drawable that will be attached to the imageView while the download
@@ -96,7 +96,10 @@ public class MultiImageChooserActivity extends Activity implements OnItemClickLi
private static final int CURSORLOADER_THUMBS = 0;
private static final int CURSORLOADER_REAL = 1;
private Map<Integer, FileNameItem> fileNameGroup = new HashMap<Integer, FileNameItem>();
private Map<String, Integer> fileNames = new HashMap<String, Integer>();
ArrayList<String> thumbFileNames = new ArrayList<String>();
private SparseBooleanArray checkStatus = new SparseBooleanArray();
@@ -109,7 +112,7 @@ public class MultiImageChooserActivity extends Activity implements OnItemClickLi
private GridView gridView;
private final ImageFetcher fetcher = new ImageFetcher();
private ImageFetcher fetcher;
private int selectedColor = 0xff32b2e1;
private boolean shouldRequestThumb = true;
@@ -121,6 +124,9 @@ public class MultiImageChooserActivity extends Activity implements OnItemClickLi
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fetcher = new ImageFetcher( getApplicationContext() );
fakeR = new FakeR(this);
setContentView(fakeR.getId("layout", "multiselectorgrid"));
fileNames.clear();
@@ -179,12 +185,18 @@ public class MultiImageChooserActivity extends Activity implements OnItemClickLi
@Override
public void onItemClick(AdapterView<?> arg0, View view, int position, long id) {
String name = getImageName(position);
String name = getImageName(position);
String name_thumb = getImageThumbName(position);
int rotation = getImageRotation(position);
if (name == null) {
if (name == null || name_thumb == null ) {
return;
}
boolean be_in_group = fileNameGroup.containsKey( position );
boolean isChecked = !isChecked(position);
if (maxImages == 0 && isChecked) {
isChecked = false;
@@ -199,7 +211,20 @@ public class MultiImageChooserActivity extends Activity implements OnItemClickLi
AlertDialog alert = builder.create();
alert.show();
} else if (isChecked) {
if( !be_in_group ){
FileNameItem fileNameItem = new FileNameItem();
fileNameItem.original = name;
fileNameItem.thumb = name_thumb;
fileNameItem.rotation = rotation;
fileNameGroup.put( position, fileNameItem );
}
fileNames.put(name, new Integer(rotation));
thumbFileNames.add( name_thumb );
if (maxImageCount == 1) {
this.selectClicked(null);
} else {
@@ -213,7 +238,13 @@ public class MultiImageChooserActivity extends Activity implements OnItemClickLi
view.setBackgroundColor(selectedColor);
}
} else {
if( be_in_group ){
fileNameGroup.remove(position);
}
fileNames.remove(name);
thumbFileNames.remove(name_thumb);
maxImages++;
ImageView imageView = (ImageView)view;
if (android.os.Build.VERSION.SDK_INT>=16) {
@@ -296,12 +327,14 @@ public class MultiImageChooserActivity extends Activity implements OnItemClickLi
getActionBar().getCustomView().findViewById(fakeR.getId("id", "actionbar_done")).setEnabled(false);
progress.show();
Intent data = new Intent();
if (fileNames.isEmpty()) {
/*if (fileNames.isEmpty()) {*/
if (fileNameGroup.isEmpty()) {
this.setResult(RESULT_CANCELED);
progress.dismiss();
finish();
} else {
new ResizeImagesTask().execute(fileNames.entrySet());
/*new ResizeImagesTask().execute(fileNames.entrySet());*/
new ResizeImagesTask().execute(fileNameGroup.entrySet());
}
}
@@ -310,9 +343,13 @@ public class MultiImageChooserActivity extends Activity implements OnItemClickLi
* Helper Methods
********************/
private void updateAcceptButton() {
/*((TextView) getActionBar().getCustomView().findViewById(fakeR.getId("id", "actionbar_done_textview")))
.setEnabled(fileNames.size() != 0);*/
((TextView) getActionBar().getCustomView().findViewById(fakeR.getId("id", "actionbar_done_textview")))
.setEnabled(fileNames.size() != 0);
getActionBar().getCustomView().findViewById(fakeR.getId("id", "actionbar_done")).setEnabled(fileNames.size() != 0);
.setEnabled(fileNameGroup.size() != 0);
/*getActionBar().getCustomView().findViewById(fakeR.getId("id", "actionbar_done")).setEnabled(fileNames.size() != 0);*/
getActionBar().getCustomView().findViewById(fakeR.getId("id", "actionbar_done")).setEnabled(fileNameGroup.size() != 0);
}
private void setupHeader() {
@@ -371,6 +408,16 @@ public class MultiImageChooserActivity extends Activity implements OnItemClickLi
return name;
}
private String getImageThumbName( int position ){
imagecursor.moveToPosition(position);
int id = imagecursor.getInt(image_column_index);
String name = fetcher.getThumbFilePath(id);
return name;
}
private int getImageRotation(int position) {
actualimagecursor.moveToPosition(position);
int rotation = 0;
@@ -480,20 +527,21 @@ public class MultiImageChooserActivity extends Activity implements OnItemClickLi
}
private class ResizeImagesTask extends AsyncTask<Set<Entry<String, Integer>>, Void, ArrayList<String>> {
/*private class ResizeImagesTask extends AsyncTask<Set<Entry<String, Integer>>, Void, ArrayList<String>> {*/
private class ResizeImagesTask extends AsyncTask<Set<Entry<Integer, FileNameItem>>, Void, ArrayList<FileNameItem>> {
private Exception asyncTaskError = null;
@Override
protected ArrayList<String> doInBackground(Set<Entry<String, Integer>>... fileSets) {
Set<Entry<String, Integer>> fileNames = fileSets[0];
ArrayList<String> al = new ArrayList<String>();
protected ArrayList<FileNameItem> doInBackground(Set<Entry<Integer, FileNameItem>>... fileSets) {
Set<Entry<Integer, FileNameItem>> fileNames = fileSets[0];
ArrayList<FileNameItem> al = new ArrayList<FileNameItem>();
try {
Iterator<Entry<String, Integer>> i = fileNames.iterator();
Iterator<Entry<Integer, FileNameItem>> i = fileNames.iterator();
Bitmap bmp;
while(i.hasNext()) {
Entry<String, Integer> imageInfo = i.next();
File file = new File(imageInfo.getKey());
int rotate = imageInfo.getValue().intValue();
Entry<Integer, FileNameItem> imageInfo = i.next();
File file = new File(imageInfo.getValue().original);
int rotate = imageInfo.getValue().rotation;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 1;
options.inJustDecodeBounds = true;
@@ -538,27 +586,33 @@ public class MultiImageChooserActivity extends Activity implements OnItemClickLi
}
file = this.storeImage(bmp, file.getName());
al.add(Uri.fromFile(file).toString());
//al.add(Uri.fromFile(file).toString());
FileNameItem filenameitem = new FileNameItem();
filenameitem.original = Uri.fromFile(file).toString();
filenameitem.thumb = imageInfo.getValue().thumb;
filenameitem.rotation = imageInfo.getValue().rotation;
al.add(filenameitem);
fileNameGroup.get( imageInfo.getKey()).original = Uri.fromFile(file).toString();
}
return al;
} catch(IOException e) {
try {
asyncTaskError = e;
for (int i = 0; i < al.size(); i++) {
URI uri = new URI(al.get(i));
URI uri = new URI(al.get(i).original);
File file = new File(uri);
file.delete();
}
} catch(Exception exception) {
// the finally does what we want to do
} finally {
return new ArrayList<String>();
return new ArrayList<FileNameItem>();
}
}
}
@Override
protected void onPostExecute(ArrayList<String> al) {
protected void onPostExecute(ArrayList<FileNameItem> al) {
Intent data = new Intent();
if (asyncTaskError != null) {
@@ -568,7 +622,9 @@ public class MultiImageChooserActivity extends Activity implements OnItemClickLi
setResult(RESULT_CANCELED, data);
} else if (al.size() > 0) {
Bundle res = new Bundle();
res.putStringArrayList("MULTIPLEFILENAMES", al);
res.putParcelableArrayList("MULTIPLEFILENAMES", al);
/*res.putStringArrayList("MULTIPLEFILENAMES", al);
res.putStringArrayList("MULTIPLEFILETHUMBNAMES", thumbFileNames );*/
if (imagecursor != null) {
res.putInt("TOTALFILES", imagecursor.getCount());
}
@@ -617,7 +673,7 @@ public class MultiImageChooserActivity extends Activity implements OnItemClickLi
int index = fileName.lastIndexOf('.');
String name = fileName.substring(0, index);
String ext = fileName.substring(index);
File file = File.createTempFile(name, ext);
File file = File.createTempFile( "_"+name+"_", ext);
OutputStream outStream = new FileOutputStream(file);
if (ext.compareToIgnoreCase(".png") == 0) {
bmp.compress(Bitmap.CompressFormat.PNG, quality, outStream);
@@ -3,17 +3,24 @@
*/
package com.synconset;
import org.apache.commons.io.output.FileWriterWithEncoding;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONStringer;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import java.util.ArrayList;
import java.util.HashMap;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
public class ImagePicker extends CordovaPlugin {
@@ -56,8 +63,47 @@ public class ImagePicker extends CordovaPlugin {
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK && data != null) {
ArrayList<String> fileNames = data.getStringArrayListExtra("MULTIPLEFILENAMES");
JSONArray res = new JSONArray(fileNames);
//HashMap<String, Object> result = new HashMap<String, Object>();
//ArrayList<String> fileNames = data.getStringArrayListExtra("MULTIPLEFILENAMES");
//ArrayList<String> fileThumbNames = data.getStringArrayListExtra("MULTIPLEFILETHUMBNAMES");
ArrayList<FileNameItem> fileNameList = new ArrayList<FileNameItem>();
Bundle bundle = data.getExtras();
if( bundle != null ){
fileNameList = bundle.getParcelableArrayList("MULTIPLEFILENAMES");
}
Gson gson = new Gson();
String str_json = gson.toJson(fileNameList);
JSONArray res;
try {
res = new JSONArray(str_json);
} catch (JSONException e) {
// TODO Auto-generated catch block
String error = "error";
this.callbackContext.error(error);
return;
}
//JsonArray res = gson.toJsonTree(fileNameList).getAsJsonArray();
//result.put( "actual", fileNames );
//result.put("thumb", fileThumbNames );
//JSONObject res_object = new JSONObject(result);
//JSONArray res = new JSONArray(fileNameList);
//JSONArray res = new JSONArray(fileNames);
/*JSONArray res = new JSONArray();
try {
res = new JSONArray( "[" + res_object.toString() + "]" );
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
this.callbackContext.success(res);
} else if (resultCode == Activity.RESULT_CANCELED && data != null) {
String error = data.getStringExtra("ERRORMESSAGE");