Better handle of big picture (thumb,send,display,...)

Fixes #11, #7
This commit is contained in:
Schoumi 2016-11-09 02:15:23 +01:00
parent 94a704708a
commit 0566f7f76a
7 changed files with 145 additions and 112 deletions

View File

@ -1,13 +1,13 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 24
buildToolsVersion "24.0.1"
compileSdkVersion 25
buildToolsVersion "24.0.3"
defaultConfig {
applicationId "fr.mobdev.goblim"
minSdkVersion 15
targetSdkVersion 24
targetSdkVersion 25
versionCode 4
versionName "2.1"
}
@ -22,6 +22,6 @@ android {
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:24.2.0'
compile 'com.android.support:design:24.2.0'
compile 'com.android.support:appcompat-v7:25.0.0'
compile 'com.android.support:design:25.0.0'
}

View File

@ -32,10 +32,12 @@ import org.json.JSONException;
import org.json.JSONObject;
import android.content.Context;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.NetworkInfo.State;
import android.util.Base64;
import android.net.Uri;
import android.provider.OpenableColumns;
import fr.mobdev.goblim.listener.NetworkListener;
import fr.mobdev.goblim.objects.Img;
@ -44,17 +46,15 @@ public class NetworkManager {
private NetworkListener listener;
private static NetworkManager instance;
private Context context;
private NetworkManager(NetworkListener listener,Context context)
private NetworkManager(NetworkListener listener)
{
this.listener = listener;
this.context = context;
}
public static NetworkManager getInstance(NetworkListener listener, Context context){
public static NetworkManager getInstance(NetworkListener listener) {
if (instance == null)
instance = new NetworkManager(listener,context);
instance = new NetworkManager(listener);
if(listener != null && listener != instance.getListener())
instance.setListener(listener);
return instance;
@ -70,7 +70,7 @@ public class NetworkManager {
this.listener = listener;
}
public void upload(final String siteUrl, final int nbDays, final String fileName, final byte[] bytearray)
public void upload(final Context context, final String siteUrl, final int nbDays, final Uri imageUri)
{
if(!isConnectedToInternet(context)) {
listener.fileUploadError(context.getString(R.string.no_network));
@ -80,14 +80,14 @@ public class NetworkManager {
@Override
public void run() {
Img img = uploadImage(siteUrl,nbDays, fileName,bytearray);
Img img = uploadImage(context, siteUrl, nbDays,imageUri);
if(img != null)
listener.fileUploaded(img);
}
}).start();
}
public Img uploadImage(String siteUrl, int nbDays, String fileName, byte[] byteArray) {
private Img uploadImage(Context context, String siteUrl, int nbDays, Uri imageUri) {
URL url = null;
Img imgOutput = null;
@ -97,7 +97,7 @@ public class NetworkManager {
e1.printStackTrace();
}
HttpURLConnection conn;
HttpURLConnection conn = null;
InputStream stream = null;
DataOutputStream request = null;
try {
@ -148,6 +148,15 @@ public class NetworkManager {
duration += crlf;
duration += nbDays + crlf;
request_size += duration.length();
String[] proj = {OpenableColumns.DISPLAY_NAME,OpenableColumns.SIZE};
Cursor cursor = context.getContentResolver().query(imageUri,proj,null,null,null);
String fileName = null;
long size = 0;
if(cursor != null && cursor.moveToFirst()) {
fileName = cursor.getString(0);
size = cursor.getLong(1);
cursor.close();
}
//setup filename and say that octets follow
String outputInformations = hyphens + boundary + crlf;
@ -156,7 +165,7 @@ public class NetworkManager {
outputInformations += crlf;
request_size += outputInformations.length();
request_size += byteArray.length;
request_size += size;
//finish the format http post packet
String endHttp = crlf;
@ -171,26 +180,48 @@ public class NetworkManager {
request.writeBytes(duration);
request.writeBytes(outputInformations);
request.flush();
//write in loop
InputStream streamIn = null;
try{
streamIn = context.getContentResolver().openInputStream(imageUri);
}
catch (Exception e)
{
e.printStackTrace();
}
//read data from the file and write it
if(streamIn != null) {
int readed = 0;
int byteWriten = 0;
int blockSize = byteArray.length / 100;
while(byteWriten < byteArray.length) {
if(byteArray.length - byteWriten < blockSize)
blockSize = byteArray.length - byteWriten;
request.write(byteArray,byteWriten,blockSize);
byteWriten+=blockSize;
listener.uploadProgress(byteWriten,byteArray.length);
int blockSize = 1024;
byte[] buffer = new byte[blockSize];
while(readed != -1) {
try {
readed = streamIn.read(buffer);
if(readed != -1) {
request.write(buffer, 0, readed);
byteWriten+=readed;
listener.uploadProgress(byteWriten,(int)size);
}
} catch (IOException e) {
e.printStackTrace();
readed = -1;
}
}
}
request.writeBytes(endHttp);
request.flush();
//get answer
stream = conn.getInputStream();
}
} catch (IOException e1) {
if(conn != null) {
stream = conn.getErrorStream();
}
else {
e1.printStackTrace();
listener.fileUploadError(context.getString(R.string.network_error));
}
}
if(stream != null) {
@ -213,9 +244,9 @@ public class NetworkManager {
isReading = false;
}
} while (isReading);
//parse JSON answer
try {
if(request != null)
request.close();
stream.close();
} catch (IOException e) {
@ -225,15 +256,15 @@ public class NetworkManager {
// Parse the JSON to a JSONObject
JSONObject rootObject = new JSONObject(jsonStr);
// Get msg (root) element
JSONObject msg = rootObject.getJSONObject("msg");
String msgStr = rootObject.getString("msg");
// is there an error?
if(msg.has("msg")) {
String error = msg.getString("msg");
listener.fileUploadError(error);
if(!msgStr.contains("{")) {
listener.fileUploadError(msgStr);
return null;
}
else if(msg.has("short")) {
else if(rootObject.has("msg")){
//retrieve useful data
JSONObject msg = rootObject.getJSONObject("msg");
String hashOutput = msg.getString("short");
String realHashOutput = msg.getString("real_short");
String token = msg.getString("token");
@ -247,7 +278,7 @@ public class NetworkManager {
return imgOutput;
}
public void deleteImage(final String deleteUrl) {
public void deleteImage(final Context context, final String deleteUrl) {
new Thread(new Runnable() {
@Override
public void run() {

View File

@ -21,7 +21,6 @@ package fr.mobdev.goblim.activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
@ -45,7 +44,7 @@ import fr.mobdev.goblim.objects.Img;
/*
* Activity display the link of the uploaded picture and allow user to share it with other app
* or copy it to cleapboard
* or copy it to clipboard
*/
public class LinkActivity extends AppCompatActivity {
@ -146,7 +145,7 @@ public class LinkActivity extends AppCompatActivity {
long days = millis / (24*60*60*1000);
//storage duration has ended or not?
if(storageDuration == 0 || storageDuration - days >= 0)
NetworkManager.getInstance(listener, getApplicationContext()).deleteImage(deleteUrl);
NetworkManager.getInstance(listener).deleteImage(LinkActivity.this, deleteUrl);
else {
//image is no more on the server, delete is only local now
listener.deleteSucceed();

View File

@ -19,16 +19,15 @@
package fr.mobdev.goblim.activity;
import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.provider.MediaStore;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.DisplayMetrics;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
@ -36,12 +35,12 @@ import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.Toast;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
@ -74,8 +73,6 @@ public class UploadActivity extends AppCompatActivity {
private static final int THIRTY = 30;
private static final int YEAR = 365;
private static final int THUMB_MAX_SIDE = 800;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -104,16 +101,24 @@ public class UploadActivity extends AppCompatActivity {
resetImage();
}
});
ProgressBar thumbProgress = (ProgressBar) findViewById(R.id.progress_thumb);
thumbProgress.setVisibility(View.GONE);
//retrieve previous state if it exist
if(savedInstanceState != null) {
int selectedServer = savedInstanceState.getInt("selectedServer");
imageUri = savedInstanceState.getParcelable("imageURI");
bt = savedInstanceState.getParcelable("thumb");
if(bt != null) {
ImageView th = (ImageView) findViewById(R.id.thumbnail_main);
th.setImageBitmap(bt);
} else {
displayImage();
}
if (selectedServer < urls.size()) {
Spinner servers = (Spinner) findViewById(R.id.servers_spinner);
servers.setSelection(selectedServer);
}
displayImage();
}
//prepare the listener that handle upload result
@ -222,6 +227,7 @@ public class UploadActivity extends AppCompatActivity {
Spinner selectedServer = (Spinner) findViewById(R.id.servers_spinner);
int pos = selectedServer.getSelectedItemPosition();
savedInstanceState.putInt("selectedServer", pos);
savedInstanceState.putParcelable("thumb",bt);
super.onSaveInstanceState(savedInstanceState);
}
@ -250,16 +256,28 @@ public class UploadActivity extends AppCompatActivity {
private void displayImage() {
if(imageUri != null) {
ContentResolver contentResolver = getContentResolver();
//display it in the imageView
try {
bt = MediaStore.Images.Media.getBitmap(contentResolver, imageUri);
bt = generateThumb(bt);
ImageView view = (ImageView) findViewById(R.id.thumbnail_main);
final ProgressBar thumbProgress = (ProgressBar) findViewById(R.id.progress_thumb);
thumbProgress.setVisibility(View.VISIBLE);
final ImageView view = (ImageView) findViewById(R.id.thumbnail_main);
view.setVisibility(View.GONE);
final Button send = (Button) findViewById(R.id.upload_button);
send.setEnabled(false);
new Thread(new Runnable() {
@Override
public void run() {
bt = generateThumb(imageUri);
runOnUiThread(new Runnable() {
@Override
public void run() {
view.setVisibility(View.VISIBLE);
view.setImageBitmap(bt);
} catch (IOException e) {
e.printStackTrace();
thumbProgress.setVisibility(View.GONE);
send.setEnabled(true);
}
});
}
}).start();
}
}
@ -284,36 +302,8 @@ public class UploadActivity extends AppCompatActivity {
int delete = deletedDays.get(pos);
//read image as bytes to upload it
byte[] bytearray = null;
//create a fileStream from the file path
InputStream stream = null;
try{
stream = getContentResolver().openInputStream(imageUri);
}
catch (Exception e)
{
e.printStackTrace();
}
//read data from the file and store it in a byte array
if(stream != null) {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
int readed = 0;
byte[] buffer = new byte[1024];
while(readed != -1) {
try {
readed = stream.read(buffer);
if(readed != -1)
outStream.write(buffer,0,readed);
} catch (IOException e) {
e.printStackTrace();
readed = -1;
}
}
bytearray = outStream.toByteArray();
}
//upload image and display a progress bar
if(bytearray != null && bytearray.length > 0) {
runOnUiThread(new Runnable() {
@Override
public void run() {
@ -325,15 +315,12 @@ public class UploadActivity extends AppCompatActivity {
progressDialog.show();
}
});
NetworkManager.getInstance(listener, getApplicationContext()).upload(url, delete, null, bytearray);
}
else {
listener.fileUploadError(getString(R.string.empty_file));
}
NetworkManager.getInstance(listener).upload(this,url, delete, imageUri);
}
private void resetImage(){
imageUri = null;
bt = null;
ImageView view = (ImageView) findViewById(R.id.thumbnail_main);
view.setImageBitmap(null);
ImageButton resetButton = (ImageButton) findViewById(R.id.reset_button);
@ -352,20 +339,19 @@ public class UploadActivity extends AppCompatActivity {
}
private Bitmap generateThumb(Bitmap original){
private Bitmap generateThumb(Uri imageUri){
int ratio = 1;
if(original.getWidth()>THUMB_MAX_SIDE || original.getHeight() > THUMB_MAX_SIDE){
if(original.getWidth()>original.getHeight())
ratio = original.getWidth()/THUMB_MAX_SIDE;
else
ratio = original.getHeight()/THUMB_MAX_SIDE;
Bitmap thumb = null;
try {
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inScaled = true;
opts.inDensity = 640;
opts.inTargetDensity = DisplayMetrics.DENSITY_MEDIUM;
thumb = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri),null,opts);
System.out.println("thumb "+thumb.getWidth()+"x"+thumb.getHeight());
} catch (FileNotFoundException e) {
e.printStackTrace();
}
int newWidth = original.getWidth()/ratio;
int newHeight = original.getHeight()/ratio;
Bitmap thumb = Bitmap.createScaledBitmap(original,newWidth,newHeight,false);
return thumb;
}

View File

@ -88,7 +88,15 @@
/>
</LinearLayout>
</LinearLayout>
<ProgressBar
android:layout_above="@+id/spinners_layout"
android:layout_below="@+id/reset_button"
android:id="@+id/progress_thumb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
/>
<ImageView
android:layout_above="@+id/spinners_layout"
android:layout_below="@+id/reset_button"

View File

@ -82,6 +82,15 @@
android:layout_marginTop="25dp"
/>
<ProgressBar
android:layout_above="@+id/servers_spinner"
android:layout_below="@+id/reset_button"
android:id="@+id/progress_thumb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
/>
<ImageView
android:layout_above="@+id/servers_spinner"
android:layout_below="@+id/reset_button"

View File

@ -5,7 +5,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.1.3'
classpath 'com.android.tools.build:gradle:2.2.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files