Commit af0a5a03 authored by Schoumi's avatar Schoumi

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

Fixe #11, #7
parent 94a70470
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
android { android {
compileSdkVersion 24 compileSdkVersion 25
buildToolsVersion "24.0.1" buildToolsVersion "24.0.3"
defaultConfig { defaultConfig {
applicationId "fr.mobdev.goblim" applicationId "fr.mobdev.goblim"
minSdkVersion 15 minSdkVersion 15
targetSdkVersion 24 targetSdkVersion 25
versionCode 4 versionCode 4
versionName "2.1" versionName "2.1"
} }
...@@ -22,6 +22,6 @@ android { ...@@ -22,6 +22,6 @@ android {
dependencies { dependencies {
compile fileTree(dir: 'libs', include: ['*.jar']) compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:24.2.0' compile 'com.android.support:appcompat-v7:25.0.0'
compile 'com.android.support:design:24.2.0' compile 'com.android.support:design:25.0.0'
} }
...@@ -32,10 +32,12 @@ import org.json.JSONException; ...@@ -32,10 +32,12 @@ import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import android.content.Context; import android.content.Context;
import android.database.Cursor;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.NetworkInfo; import android.net.NetworkInfo;
import android.net.NetworkInfo.State; 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.listener.NetworkListener;
import fr.mobdev.goblim.objects.Img; import fr.mobdev.goblim.objects.Img;
...@@ -44,17 +46,15 @@ public class NetworkManager { ...@@ -44,17 +46,15 @@ public class NetworkManager {
private NetworkListener listener; private NetworkListener listener;
private static NetworkManager instance; private static NetworkManager instance;
private Context context;
private NetworkManager(NetworkListener listener,Context context) private NetworkManager(NetworkListener listener)
{ {
this.listener = listener; this.listener = listener;
this.context = context;
} }
public static NetworkManager getInstance(NetworkListener listener, Context context){ public static NetworkManager getInstance(NetworkListener listener) {
if (instance == null) if (instance == null)
instance = new NetworkManager(listener,context); instance = new NetworkManager(listener);
if(listener != null && listener != instance.getListener()) if(listener != null && listener != instance.getListener())
instance.setListener(listener); instance.setListener(listener);
return instance; return instance;
...@@ -70,7 +70,7 @@ public class NetworkManager { ...@@ -70,7 +70,7 @@ public class NetworkManager {
this.listener = listener; 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)) { if(!isConnectedToInternet(context)) {
listener.fileUploadError(context.getString(R.string.no_network)); listener.fileUploadError(context.getString(R.string.no_network));
...@@ -80,14 +80,14 @@ public class NetworkManager { ...@@ -80,14 +80,14 @@ public class NetworkManager {
@Override @Override
public void run() { public void run() {
Img img = uploadImage(siteUrl,nbDays, fileName,bytearray); Img img = uploadImage(context, siteUrl, nbDays,imageUri);
if(img != null) if(img != null)
listener.fileUploaded(img); listener.fileUploaded(img);
} }
}).start(); }).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; URL url = null;
Img imgOutput = null; Img imgOutput = null;
...@@ -97,7 +97,7 @@ public class NetworkManager { ...@@ -97,7 +97,7 @@ public class NetworkManager {
e1.printStackTrace(); e1.printStackTrace();
} }
HttpURLConnection conn; HttpURLConnection conn = null;
InputStream stream = null; InputStream stream = null;
DataOutputStream request = null; DataOutputStream request = null;
try { try {
...@@ -148,6 +148,15 @@ public class NetworkManager { ...@@ -148,6 +148,15 @@ public class NetworkManager {
duration += crlf; duration += crlf;
duration += nbDays + crlf; duration += nbDays + crlf;
request_size += duration.length(); 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 //setup filename and say that octets follow
String outputInformations = hyphens + boundary + crlf; String outputInformations = hyphens + boundary + crlf;
...@@ -156,7 +165,7 @@ public class NetworkManager { ...@@ -156,7 +165,7 @@ public class NetworkManager {
outputInformations += crlf; outputInformations += crlf;
request_size += outputInformations.length(); request_size += outputInformations.length();
request_size += byteArray.length; request_size += size;
//finish the format http post packet //finish the format http post packet
String endHttp = crlf; String endHttp = crlf;
...@@ -171,26 +180,48 @@ public class NetworkManager { ...@@ -171,26 +180,48 @@ public class NetworkManager {
request.writeBytes(duration); request.writeBytes(duration);
request.writeBytes(outputInformations); request.writeBytes(outputInformations);
request.flush(); request.flush();
//write in loop InputStream streamIn = null;
int byteWriten = 0; try{
int blockSize = byteArray.length / 100; streamIn = context.getContentResolver().openInputStream(imageUri);
while(byteWriten < byteArray.length) { }
if(byteArray.length - byteWriten < blockSize) catch (Exception e)
blockSize = byteArray.length - byteWriten; {
request.write(byteArray,byteWriten,blockSize); e.printStackTrace();
byteWriten+=blockSize; }
listener.uploadProgress(byteWriten,byteArray.length); //read data from the file and write it
if(streamIn != null) {
int readed = 0;
int byteWriten = 0;
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.writeBytes(endHttp);
request.flush(); request.flush();
//get answer //get answer
stream = conn.getInputStream(); stream = conn.getInputStream();
} }
} catch (IOException e1) { } catch (IOException e1) {
e1.printStackTrace(); if(conn != null) {
listener.fileUploadError(context.getString(R.string.network_error)); stream = conn.getErrorStream();
}
else {
e1.printStackTrace();
listener.fileUploadError(context.getString(R.string.network_error));
}
} }
if(stream != null) { if(stream != null) {
...@@ -213,10 +244,10 @@ public class NetworkManager { ...@@ -213,10 +244,10 @@ public class NetworkManager {
isReading = false; isReading = false;
} }
} while (isReading); } while (isReading);
//parse JSON answer //parse JSON answer
try { try {
request.close(); if(request != null)
request.close();
stream.close(); stream.close();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
...@@ -225,15 +256,15 @@ public class NetworkManager { ...@@ -225,15 +256,15 @@ public class NetworkManager {
// Parse the JSON to a JSONObject // Parse the JSON to a JSONObject
JSONObject rootObject = new JSONObject(jsonStr); JSONObject rootObject = new JSONObject(jsonStr);
// Get msg (root) element // Get msg (root) element
JSONObject msg = rootObject.getJSONObject("msg"); String msgStr = rootObject.getString("msg");
// is there an error? // is there an error?
if(msg.has("msg")) { if(!msgStr.contains("{")) {
String error = msg.getString("msg"); listener.fileUploadError(msgStr);
listener.fileUploadError(error);
return null; return null;
} }
else if(msg.has("short")) { else if(rootObject.has("msg")){
//retrieve useful data //retrieve useful data
JSONObject msg = rootObject.getJSONObject("msg");
String hashOutput = msg.getString("short"); String hashOutput = msg.getString("short");
String realHashOutput = msg.getString("real_short"); String realHashOutput = msg.getString("real_short");
String token = msg.getString("token"); String token = msg.getString("token");
...@@ -247,7 +278,7 @@ public class NetworkManager { ...@@ -247,7 +278,7 @@ public class NetworkManager {
return imgOutput; return imgOutput;
} }
public void deleteImage(final String deleteUrl) { public void deleteImage(final Context context, final String deleteUrl) {
new Thread(new Runnable() { new Thread(new Runnable() {
@Override @Override
public void run() { public void run() {
......
...@@ -21,7 +21,6 @@ package fr.mobdev.goblim.activity; ...@@ -21,7 +21,6 @@ package fr.mobdev.goblim.activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
...@@ -45,7 +44,7 @@ import fr.mobdev.goblim.objects.Img; ...@@ -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 * 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 { public class LinkActivity extends AppCompatActivity {
...@@ -146,7 +145,7 @@ public class LinkActivity extends AppCompatActivity { ...@@ -146,7 +145,7 @@ public class LinkActivity extends AppCompatActivity {
long days = millis / (24*60*60*1000); long days = millis / (24*60*60*1000);
//storage duration has ended or not? //storage duration has ended or not?
if(storageDuration == 0 || storageDuration - days >= 0) if(storageDuration == 0 || storageDuration - days >= 0)
NetworkManager.getInstance(listener, getApplicationContext()).deleteImage(deleteUrl); NetworkManager.getInstance(listener).deleteImage(LinkActivity.this, deleteUrl);
else { else {
//image is no more on the server, delete is only local now //image is no more on the server, delete is only local now
listener.deleteSucceed(); listener.deleteSucceed();
......
...@@ -19,16 +19,15 @@ ...@@ -19,16 +19,15 @@
package fr.mobdev.goblim.activity; package fr.mobdev.goblim.activity;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.Intent; import android.content.Intent;
import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.drawable.Drawable; import android.graphics.BitmapFactory;
import android.net.Uri; import android.net.Uri;
import android.provider.MediaStore;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import android.util.DisplayMetrics;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
...@@ -36,12 +35,12 @@ import android.widget.ArrayAdapter; ...@@ -36,12 +35,12 @@ import android.widget.ArrayAdapter;
import android.widget.Button; import android.widget.Button;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Spinner; import android.widget.Spinner;
import android.widget.Toast; import android.widget.Toast;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
...@@ -74,8 +73,6 @@ public class UploadActivity extends AppCompatActivity { ...@@ -74,8 +73,6 @@ public class UploadActivity extends AppCompatActivity {
private static final int THIRTY = 30; private static final int THIRTY = 30;
private static final int YEAR = 365; private static final int YEAR = 365;
private static final int THUMB_MAX_SIDE = 800;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
...@@ -104,16 +101,24 @@ public class UploadActivity extends AppCompatActivity { ...@@ -104,16 +101,24 @@ public class UploadActivity extends AppCompatActivity {
resetImage(); resetImage();
} }
}); });
ProgressBar thumbProgress = (ProgressBar) findViewById(R.id.progress_thumb);
thumbProgress.setVisibility(View.GONE);
//retrieve previous state if it exist //retrieve previous state if it exist
if(savedInstanceState != null) { if(savedInstanceState != null) {
int selectedServer = savedInstanceState.getInt("selectedServer"); int selectedServer = savedInstanceState.getInt("selectedServer");
imageUri = savedInstanceState.getParcelable("imageURI"); 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()) { if (selectedServer < urls.size()) {
Spinner servers = (Spinner) findViewById(R.id.servers_spinner); Spinner servers = (Spinner) findViewById(R.id.servers_spinner);
servers.setSelection(selectedServer); servers.setSelection(selectedServer);
} }
displayImage();
} }
//prepare the listener that handle upload result //prepare the listener that handle upload result
...@@ -222,6 +227,7 @@ public class UploadActivity extends AppCompatActivity { ...@@ -222,6 +227,7 @@ public class UploadActivity extends AppCompatActivity {
Spinner selectedServer = (Spinner) findViewById(R.id.servers_spinner); Spinner selectedServer = (Spinner) findViewById(R.id.servers_spinner);
int pos = selectedServer.getSelectedItemPosition(); int pos = selectedServer.getSelectedItemPosition();
savedInstanceState.putInt("selectedServer", pos); savedInstanceState.putInt("selectedServer", pos);
savedInstanceState.putParcelable("thumb",bt);
super.onSaveInstanceState(savedInstanceState); super.onSaveInstanceState(savedInstanceState);
} }
...@@ -250,16 +256,28 @@ public class UploadActivity extends AppCompatActivity { ...@@ -250,16 +256,28 @@ public class UploadActivity extends AppCompatActivity {
private void displayImage() { private void displayImage() {
if(imageUri != null) { if(imageUri != null) {
ContentResolver contentResolver = getContentResolver();
//display it in the imageView //display it in the imageView
try { final ProgressBar thumbProgress = (ProgressBar) findViewById(R.id.progress_thumb);
bt = MediaStore.Images.Media.getBitmap(contentResolver, imageUri); thumbProgress.setVisibility(View.VISIBLE);
bt = generateThumb(bt); final ImageView view = (ImageView) findViewById(R.id.thumbnail_main);
ImageView view = (ImageView) findViewById(R.id.thumbnail_main); view.setVisibility(View.GONE);
view.setImageBitmap(bt); final Button send = (Button) findViewById(R.id.upload_button);
} catch (IOException e) { send.setEnabled(false);
e.printStackTrace(); 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);
thumbProgress.setVisibility(View.GONE);
send.setEnabled(true);
}
});
}
}).start();
} }
} }
...@@ -284,56 +302,25 @@ public class UploadActivity extends AppCompatActivity { ...@@ -284,56 +302,25 @@ public class UploadActivity extends AppCompatActivity {
int delete = deletedDays.get(pos); int delete = deletedDays.get(pos);
//read image as bytes to upload it //read image as bytes to upload it
byte[] bytearray = null;
//create a fileStream from the file path //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 //upload image and display a progress bar
if(bytearray != null && bytearray.length > 0) { runOnUiThread(new Runnable() {
runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
progressDialog = new ProgressDialog(UploadActivity.this); progressDialog = new ProgressDialog(UploadActivity.this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setMax(100); progressDialog.setMax(100);
progressDialog.setMessage(getString(R.string.upload_progress)); progressDialog.setMessage(getString(R.string.upload_progress));
progressDialog.setCancelable(false); progressDialog.setCancelable(false);
progressDialog.show(); progressDialog.show();
} }
}); });
NetworkManager.getInstance(listener, getApplicationContext()).upload(url, delete, null, bytearray); NetworkManager.getInstance(listener).upload(this,url, delete, imageUri);
}
else {
listener.fileUploadError(getString(R.string.empty_file));
}
} }
private void resetImage(){ private void resetImage(){
imageUri = null; imageUri = null;
bt = null;
ImageView view = (ImageView) findViewById(R.id.thumbnail_main); ImageView view = (ImageView) findViewById(R.id.thumbnail_main);
view.setImageBitmap(null); view.setImageBitmap(null);
ImageButton resetButton = (ImageButton) findViewById(R.id.reset_button); ImageButton resetButton = (ImageButton) findViewById(R.id.reset_button);
...@@ -352,20 +339,19 @@ public class UploadActivity extends AppCompatActivity { ...@@ -352,20 +339,19 @@ public class UploadActivity extends AppCompatActivity {
} }
private Bitmap generateThumb(Bitmap original){ private Bitmap generateThumb(Uri imageUri){
int ratio = 1; Bitmap thumb = null;
if(original.getWidth()>THUMB_MAX_SIDE || original.getHeight() > THUMB_MAX_SIDE){ try {
if(original.getWidth()>original.getHeight()) BitmapFactory.Options opts = new BitmapFactory.Options();
ratio = original.getWidth()/THUMB_MAX_SIDE; opts.inScaled = true;
else opts.inDensity = 640;
ratio = original.getHeight()/THUMB_MAX_SIDE; 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; return thumb;
} }
......
...@@ -88,7 +88,15 @@ ...@@ -88,7 +88,15 @@
/> />
</LinearLayout> </LinearLayout>
</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 <ImageView
android:layout_above="@+id/spinners_layout" android:layout_above="@+id/spinners_layout"
android:layout_below="@+id/reset_button" android:layout_below="@+id/reset_button"
......
...@@ -82,6 +82,15 @@ ...@@ -82,6 +82,15 @@
android:layout_marginTop="25dp" 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 <ImageView
android:layout_above="@+id/servers_spinner" android:layout_above="@+id/servers_spinner"
android:layout_below="@+id/reset_button" android:layout_below="@+id/reset_button"
......
...@@ -5,7 +5,7 @@ buildscript { ...@@ -5,7 +5,7 @@ buildscript {
jcenter() jcenter()
} }
dependencies { 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 // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment