From 9688e5af83972db765bcac07317f41127a1a5da6 Mon Sep 17 00:00:00 2001 From: floydbloke Date: Sat, 13 Apr 2019 14:04:49 +1200 Subject: [PATCH 1/2] Added option for selective upload. *Selection-activity class and activity layout, with supporting classes (ScalingBitmapview and BitmapUtil) *SelectedImages class - List to hold user selected images. --- app/build.gradle | 2 +- app/src/main/AndroidManifest.xml | 18 +- .../AppNotificationManager.java | 32 ++++ .../LubikR/synologyuploader/BaseActivity.java | 6 + .../LubikR/synologyuploader/BitmapUtil.java | 30 +++ .../synologyuploader/ConnectActivity.java | 2 + .../LubikR/synologyuploader/MainActivity.java | 176 ++++++++++++------ .../synologyuploader/ScalingBitmapView.java | 55 ++++++ .../synologyuploader/SelectedImages.java | 8 + .../synologyuploader/SelectionActivity.java | 78 ++++++++ .../LubikR/synologyuploader/WifiActivity.java | 5 + app/src/main/res/layout/activity_main.xml | 133 ++++++++----- app/src/main/res/layout/image.xml | 10 + app/src/main/res/layout/image_list_item.xml | 21 +++ app/src/main/res/layout/list.xml | 10 + app/src/main/res/values/strings.xml | 14 +- 16 files changed, 488 insertions(+), 112 deletions(-) create mode 100644 app/src/main/java/com/github/LubikR/synologyuploader/AppNotificationManager.java create mode 100644 app/src/main/java/com/github/LubikR/synologyuploader/BitmapUtil.java create mode 100644 app/src/main/java/com/github/LubikR/synologyuploader/ScalingBitmapView.java create mode 100644 app/src/main/java/com/github/LubikR/synologyuploader/SelectedImages.java create mode 100644 app/src/main/java/com/github/LubikR/synologyuploader/SelectionActivity.java create mode 100644 app/src/main/res/layout/image.xml create mode 100644 app/src/main/res/layout/image_list_item.xml create mode 100644 app/src/main/res/layout/list.xml diff --git a/app/build.gradle b/app/build.gradle index 1dcf672..391ba6f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,7 +9,7 @@ android { minSdkVersion 10 targetSdkVersion 10 versionCode 6 - versionName "1.5" + versionName "1.6" } compileOptions { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a908bf5..0e983af 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,9 +4,9 @@ - - - + + + + - + + + + diff --git a/app/src/main/java/com/github/LubikR/synologyuploader/AppNotificationManager.java b/app/src/main/java/com/github/LubikR/synologyuploader/AppNotificationManager.java new file mode 100644 index 0000000..89f6862 --- /dev/null +++ b/app/src/main/java/com/github/LubikR/synologyuploader/AppNotificationManager.java @@ -0,0 +1,32 @@ +package com.github.LubikR.synologyuploader; + +import java.util.ArrayList; + +public class AppNotificationManager { + public interface NotificationListener { + void onNotify(String message); + } + + private static final AppNotificationManager instance = new AppNotificationManager(); + + public static AppNotificationManager getInstance() { + return instance; + } + + private ArrayList listeners = new ArrayList(); + + private AppNotificationManager() {} + + public void notify(String message) { + for (NotificationListener listener : listeners) + listener.onNotify(message); + } + + public void addListener(NotificationListener listener) { + listeners.add(listener); + } + + public void removeListener(NotificationListener listener) { + listeners.remove(listener); + } +} diff --git a/app/src/main/java/com/github/LubikR/synologyuploader/BaseActivity.java b/app/src/main/java/com/github/LubikR/synologyuploader/BaseActivity.java index 29cb4ea..796bde1 100644 --- a/app/src/main/java/com/github/LubikR/synologyuploader/BaseActivity.java +++ b/app/src/main/java/com/github/LubikR/synologyuploader/BaseActivity.java @@ -4,9 +4,13 @@ import android.content.Intent; import android.view.KeyEvent; +import com.github.ma1co.openmemories.framework.DisplayManager; import com.sony.scalar.sysutil.ScalarInput; public class BaseActivity extends Activity { + public static final String NOTIFICATION_DISPLAY_CHANGED = "NOTIFICATION_DISPLAY_CHANGED"; + + @Override public boolean onKeyDown(int keyCode, KeyEvent event) { @@ -32,4 +36,6 @@ protected void setAutoPowerOffMode(boolean enable) { intent.putExtra("apo_info", mode); sendBroadcast(intent); } + + } diff --git a/app/src/main/java/com/github/LubikR/synologyuploader/BitmapUtil.java b/app/src/main/java/com/github/LubikR/synologyuploader/BitmapUtil.java new file mode 100644 index 0000000..321387d --- /dev/null +++ b/app/src/main/java/com/github/LubikR/synologyuploader/BitmapUtil.java @@ -0,0 +1,30 @@ +package com.github.LubikR.synologyuploader; + +import android.graphics.Bitmap; +import android.graphics.Matrix; +import android.media.ExifInterface; + +public class BitmapUtil { + public static Bitmap fixOrientation(Bitmap bitmap, int orientation) { + int degrees = getExifOrientationDegrees(orientation); + if (bitmap != null && degrees != 0) { + Matrix matrix = new Matrix(); + matrix.postRotate(degrees); + return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); + } + return bitmap; + } + + public static int getExifOrientationDegrees(int orientation) { + switch (orientation) { + case ExifInterface.ORIENTATION_ROTATE_90: + return 90; + case ExifInterface.ORIENTATION_ROTATE_180: + return 180; + case ExifInterface.ORIENTATION_ROTATE_270: + return 270; + default: + return 0; + } + } +} diff --git a/app/src/main/java/com/github/LubikR/synologyuploader/ConnectActivity.java b/app/src/main/java/com/github/LubikR/synologyuploader/ConnectActivity.java index 9164ce6..4a0d37e 100644 --- a/app/src/main/java/com/github/LubikR/synologyuploader/ConnectActivity.java +++ b/app/src/main/java/com/github/LubikR/synologyuploader/ConnectActivity.java @@ -25,6 +25,8 @@ protected void onResume() { public void onWifiStateChanged() { WifiState state = getWifiState(); textView.setText(state.toString()); + + if (state == WifiState.CONNECTED) { setKeepWifiOn(); finish(); diff --git a/app/src/main/java/com/github/LubikR/synologyuploader/MainActivity.java b/app/src/main/java/com/github/LubikR/synologyuploader/MainActivity.java index b0049ed..0e3ff49 100644 --- a/app/src/main/java/com/github/LubikR/synologyuploader/MainActivity.java +++ b/app/src/main/java/com/github/LubikR/synologyuploader/MainActivity.java @@ -36,6 +36,8 @@ public class MainActivity extends WifiActivity { DateFormat formatter = new SimpleDateFormat("ddMMyyyy", Locale.US); Button btnSettings; + Button btnSelectimages; + Button btnUploadSelected; Button btnUpload; TextView statusTextView; ProgressBar progressBar; @@ -51,6 +53,8 @@ protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_main); btnSettings = (Button) findViewById(R.id.Settings); + btnSelectimages = (Button) findViewById(R.id.btnSelectimages); + btnUploadSelected = (Button) findViewById(R.id.btnUploadselected); btnUpload = (Button) findViewById(R.id.Upload_Now); statusTextView = (TextView) findViewById(R.id.textviewStatus); progressBar = (ProgressBar) findViewById(R.id.progressBar); @@ -70,6 +74,15 @@ public void onClick(View view) { startActivity(intent); } }); + + btnSelectimages.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + setKeepWifiOn(); + Intent intent = new Intent(MainActivity.this, SelectionActivity.class); + startActivity(intent); + } + }); } @Override @@ -93,6 +106,7 @@ protected void onResume() { private void checkIfAlreadySet() { if ((SharedPreferencesManager.read(getString(R.string.port), null)) == null) { btnUpload.setEnabled(false); + btnUploadSelected.setEnabled(false); } else { ip = SharedPreferencesManager.read(getString(R.string.address), null); port = SharedPreferencesManager.read(getString(R.string.port), null); @@ -102,16 +116,27 @@ private void checkIfAlreadySet() { deleteAfterUpload = SharedPreferencesManager.readBoolean(getString(R.string.chckBoxDelete), false); debug = SharedPreferencesManager.readBoolean(getString(R.string.chkkBoxLog), false); btnUpload.setEnabled(true); + if (SelectedImages.selectedimages.isEmpty()){ + btnUploadSelected.setEnabled(false); + } + else + btnUploadSelected.setEnabled(true); } } + public void uploadSelectedClick(View view) { + UploadPictures uploadPictures = new UploadPictures(); + uploadPictures.execute(true); + } + + public void uploadNowClick(View view) { UploadPictures uploadPictures = new UploadPictures(); - uploadPictures.execute(); + uploadPictures.execute(false); } //uploading pictures by Multipart class - class UploadPictures extends AsyncTask { + class UploadPictures extends AsyncTask { @Override protected void onPreExecute() { @@ -119,12 +144,15 @@ protected void onPreExecute() { publishProgress(getString(R.string.connecting)); btnSettings.setEnabled(false); btnUpload.setEnabled(false); + btnSelectimages.setEnabled(false); + btnUploadSelected.setEnabled(false); } @Override - protected Integer doInBackground(Void... voids) { + protected Integer doInBackground(Boolean... selectedOnly) { int result = 0; int count = 0; + boolean flaggedForUpload = false; MediaManager mediaManager = MediaManager.create(getApplicationContext()); Cursor cursor = mediaManager.queryImages(); @@ -171,68 +199,98 @@ protected Integer doInBackground(Void... voids) { String model = DeviceInfo.getInstance().getModel(); String directory = SharedPreferencesManager.read(getString(R.string.settingViewDirectory), null); + if(selectedOnly[0]){ + count = SelectedImages.selectedimages.size(); + } + while (cursor.moveToNext()) { - i++; + final ImageInfo info = mediaManager.getImageInfo(cursor); String filename = info.getFilename(); Date date = info.getDate(); + Long imageId = info.getImageId(); + if (SelectedImages.selectedimages.contains(imageId)){ + flaggedForUpload = true; + } - publishProgress("Uploading " + i + " / " + count); - runOnUiThread(new Runnable() { - @Override - public void run() { - int i = 0; - progressBar.setVisibility(ProgressBar.VISIBLE); - try { - FileChannel fc = ((FileInputStream) info.getFullImage()).getChannel(); - i = (int) fc.size(); - fc.close(); - } - catch (IOException e) { - //TODO : Do something with exeption + + if(!selectedOnly[0] || flaggedForUpload) { + i++; + publishProgress("Uploading " + i + " / " + count); + runOnUiThread(new Runnable() { + @Override + public void run() { + int i = 0; + progressBar.setVisibility(ProgressBar.VISIBLE); + try { + FileChannel fc = ((FileInputStream) info.getFullImage()).getChannel(); + i = (int) fc.size(); + fc.close(); + } catch (IOException e) { + //TODO : Do something with exeption + } + progressBar.setMax(i); } - progressBar.setMax(i); + }); + + MultiPartUpload multipart = new MultiPartUpload(address + + SynologyAPI.uploadAPI, "UTF-8", sid); + + multipart.addFormField("api", "SYNO.FileStation.Upload"); + multipart.addFormField("version", maxVersionUpload); + if (debug) { + Logger.info(TAG, "UploadVersion=" + maxVersionUpload); } - }); - - MultiPartUpload multipart = new MultiPartUpload(address + - SynologyAPI.uploadAPI, "UTF-8", sid); - - multipart.addFormField("api", "SYNO.FileStation.Upload"); - multipart.addFormField("version", maxVersionUpload); - if (debug) { Logger.info(TAG, "UploadVersion=" + maxVersionUpload); } - multipart.addFormField("method", "upload"); - multipart.addFormField("path", "/" + directory + "/" + model + "/" + formatter.format(date)); - if (debug) { Logger.info(TAG, "Path=" + "/" + directory + "/" + model + "/" + - formatter.format(date)); } - multipart.addFormField("create_parents", "true"); - multipart.addFilePart("file", (FileInputStream) info.getFullImage(), filename, getApplicationContext()); - if (debug) { Logger.info(TAG, "Filename=" + filename); } - - String json2 = new String(multipart.finish()); - String uploadResult = new JSONObject(json2).getString("success"); - - if (uploadResult.equals("true")) { - if (deleteAfterUpload) { - // Delete uploaded image - ContentResolver resolver = getApplicationContext().getContentResolver(); - Uri uri = mediaManager.getImageContentUri(); - long id = mediaManager.getImageId(cursor); - AvindexStore.Images.Media.deleteImage(resolver, uri, id); + multipart.addFormField("method", "upload"); + multipart.addFormField("path", "/" + directory + "/" + model + "/" + formatter.format(date)); + if (debug) { + Logger.info(TAG, "Path=" + "/" + directory + "/" + model + "/" + + formatter.format(date)); } - } else { - String errorCode = new JSONObject(json2).getJSONObject("error").getString("code"); - if (debug) { Logger.info(TAG, "Error during upload: " + errorCode); } - throw new HttpException(errorCode); - } + multipart.addFormField("create_parents", "true"); + multipart.addFilePart("file", (FileInputStream) info.getFullImage(), filename, getApplicationContext()); + if (debug) { + Logger.info(TAG, "Filename=" + filename); + } + + String json2 = new String(multipart.finish()); + String uploadResult = new JSONObject(json2).getString("success"); + + if (uploadResult.equals("true")) { + if (deleteAfterUpload) { + // Delete uploaded image + ContentResolver resolver = getApplicationContext().getContentResolver(); + Uri uri = mediaManager.getImageContentUri(); + long id = mediaManager.getImageId(cursor); + AvindexStore.Images.Media.deleteImage(resolver, uri, id); + } + if (flaggedForUpload){ + flaggedForUpload = false; + SelectedImages.selectedimages.remove(imageId); + } + if( !selectedOnly[0] && deleteAfterUpload){ + SelectedImages.selectedimages.clear(); + } - //Reset progress bar - runOnUiThread(new Runnable() { - @Override - public void run() { - progressBar.setProgress(0); + } else { + String errorCode = new JSONObject(json2).getJSONObject("error").getString("code"); + if (debug) { + Logger.info(TAG, "Error during upload: " + errorCode); + } + throw new HttpException(errorCode); } - }); + + + //Reset progress bar + runOnUiThread(new Runnable() { + @Override + public void run() { + progressBar.setProgress(0); + + } + + }); + } } cursor.close(); @@ -282,6 +340,14 @@ protected void onPostExecute(Integer result) { } btnUpload.setEnabled(true); btnSettings.setEnabled(true); + btnSelectimages.setEnabled(true); + if (SelectedImages.selectedimages.isEmpty()){ + btnUploadSelected.setEnabled(false); + } + else { + btnUploadSelected.setEnabled(true); + } + progressBar.setVisibility(ProgressBar.INVISIBLE); } } diff --git a/app/src/main/java/com/github/LubikR/synologyuploader/ScalingBitmapView.java b/app/src/main/java/com/github/LubikR/synologyuploader/ScalingBitmapView.java new file mode 100644 index 0000000..2669a2e --- /dev/null +++ b/app/src/main/java/com/github/LubikR/synologyuploader/ScalingBitmapView.java @@ -0,0 +1,55 @@ +package com.github.LubikR.synologyuploader; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.util.AttributeSet; +import android.widget.ImageView; + +import com.github.ma1co.openmemories.framework.DisplayManager; + +public class ScalingBitmapView extends ImageView implements AppNotificationManager.NotificationListener { + protected class ScaledBitmapDrawable extends BitmapDrawable { + private float xScale; + + public ScaledBitmapDrawable(Bitmap bitmap, float xScale) { + super(bitmap); + this.xScale = xScale; + } + + @Override + public int getIntrinsicWidth() { + return Math.round(super.getIntrinsicWidth() * xScale); + } + } + + private Bitmap bitmap; + + public ScalingBitmapView(Context context, AttributeSet attrs) { + super(context, attrs); + AppNotificationManager.getInstance().addListener(this); + } + + @Override + public void setImageBitmap(Bitmap bitmap) { + this.bitmap = bitmap; + update(); + } + + + @Override + public void onNotify(String message) { + if (message.equals(BaseActivity.NOTIFICATION_DISPLAY_CHANGED)) + update(); + } + + + private void update() { + DisplayManager displayManager = DisplayManager.create(getContext()); + float displayAspect = displayManager.getActiveDisplayInfo().aspectRatio; + float frameBufferAspect = displayManager.getFrameBufferInfo().aspectRatio; + displayManager.release(); + + setImageDrawable(new ScaledBitmapDrawable(bitmap, frameBufferAspect / displayAspect)); + } +} diff --git a/app/src/main/java/com/github/LubikR/synologyuploader/SelectedImages.java b/app/src/main/java/com/github/LubikR/synologyuploader/SelectedImages.java new file mode 100644 index 0000000..97247c1 --- /dev/null +++ b/app/src/main/java/com/github/LubikR/synologyuploader/SelectedImages.java @@ -0,0 +1,8 @@ +package com.github.LubikR.synologyuploader; + +import java.util.ArrayList; +import java.util.List; + +public class SelectedImages { + public static List selectedimages = new ArrayList(); +} diff --git a/app/src/main/java/com/github/LubikR/synologyuploader/SelectionActivity.java b/app/src/main/java/com/github/LubikR/synologyuploader/SelectionActivity.java new file mode 100644 index 0000000..cb1eba4 --- /dev/null +++ b/app/src/main/java/com/github/LubikR/synologyuploader/SelectionActivity.java @@ -0,0 +1,78 @@ +package com.github.LubikR.synologyuploader; + +import android.content.Context; +import android.database.Cursor; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.Bundle; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ListView; +import android.widget.ResourceCursorAdapter; +import android.widget.TextView; + +import com.github.ma1co.openmemories.framework.ImageInfo; +import com.github.ma1co.openmemories.framework.MediaManager; + +import java.text.SimpleDateFormat; + +public class SelectionActivity extends BaseActivity implements AdapterView.OnItemClickListener { + private MediaManager mediaManager; + ListView listView; + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.list); + + listView = (ListView) findViewById(R.id.listView); + + mediaManager = MediaManager.create(this); + Cursor cursor = mediaManager.queryNewestImages(); + + final Bitmap checkmark = BitmapFactory.decodeResource(getResources(),R.drawable.checkmarkimage); + + + listView.setAdapter(new ResourceCursorAdapter(this, R.layout.image_list_item, cursor) { + @Override + public void bindView(View view, Context context, Cursor cursor) { + ImageInfo info = mediaManager.getImageInfo(cursor); + + String text1 = info.getFolder() + "/" + info.getFilename(); + String text2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(info.getDate()) + + " ID:" + info.getImageId(); + Bitmap thumbnail = BitmapUtil.fixOrientation(BitmapFactory.decodeStream(info.getThumbnail()), info.getOrientation()); + + ((TextView) view.findViewById(android.R.id.text1)).setText(text1); + ((TextView) view.findViewById(android.R.id.text2)).setText(text2); + ((ScalingBitmapView) view.findViewById(R.id.imageView)).setImageBitmap(thumbnail); + + //mycode + boolean isselected = SelectedImages.selectedimages.contains(info.getImageId()); + ((ScalingBitmapView) view.findViewById(R.id.checkmarkView)).setImageBitmap(null); + if(isselected ) { + ((ScalingBitmapView) view.findViewById(R.id.checkmarkView)).setImageBitmap(checkmark); + } + } + }); + + listView.setOnItemClickListener(this); + } + + @Override + public void onItemClick(AdapterView adapterView, View view, int position, long listId) { + Cursor cursor = (Cursor) adapterView.getItemAtPosition(position); + long id = mediaManager.getImageId(cursor); + + if (SelectedImages.selectedimages.contains(id)){ + SelectedImages.selectedimages.remove(id); + } + else{ + SelectedImages.selectedimages.add(id); + } + + listView.invalidateViews(); + } +} + diff --git a/app/src/main/java/com/github/LubikR/synologyuploader/WifiActivity.java b/app/src/main/java/com/github/LubikR/synologyuploader/WifiActivity.java index 741cfc1..d3db582 100644 --- a/app/src/main/java/com/github/LubikR/synologyuploader/WifiActivity.java +++ b/app/src/main/java/com/github/LubikR/synologyuploader/WifiActivity.java @@ -74,10 +74,13 @@ protected void onPause() { public void onWifiStateChanged() { if (getWifiState() != WifiState.CONNECTED) { startActivity(new Intent(this, ConnectActivity.class)); + + } } public WifiState getWifiState() { + switch (wifiManager.getWifiState()) { case WifiManager.WIFI_STATE_ENABLED: if (connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnected()) { @@ -99,6 +102,7 @@ public WifiState getWifiState() { default: return WifiState.DISABLED; } + } public void setWifiEnabled(boolean enabled) { @@ -108,4 +112,5 @@ public void setWifiEnabled(boolean enabled) { public void setKeepWifiOn() { keepWifiOn = true; } + } diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 18b9d6f..17dfbc9 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,51 +1,92 @@ - + android:layout_height="match_parent"> -