Commit b70f24a5 authored by Schoumi's avatar Schoumi

Adding support of G+/Picasa photos

Adding support of photo deletion
Adding support of thumbnail
parent b751c3ec
......@@ -2,6 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="fr.mobdev.goblim" >
<uses-sdk android:minSdkVersion="11"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
......
......@@ -43,7 +43,7 @@ public class Database extends SQLiteOpenHelper {
public static Database getInstance(Context context)
{
if(instance == null)
instance = new Database(context, "Lutim.db", null, 1);
instance = new Database(context, "Lutim.db", null, 2);
return instance;
}
......@@ -70,7 +70,10 @@ public class Database extends SQLiteOpenHelper {
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//nothing to do right now
if(oldVersion == 1)
{
db.execSQL("Alter table history add column token varchar(1024);");
}
}
public List<Img> getHistory() {
......@@ -88,14 +91,15 @@ public class Database extends SQLiteOpenHelper {
String realShortHash = cursor.getString(col++);
long timestamp = cursor.getLong(col++);
int storageDuration = cursor.getInt(col++);
byte[] thumbData = cursor.getBlob(col);
byte[] thumbData = cursor.getBlob(col++);
String token = cursor.getString(col);
//convert Long date to Calendar
Calendar date = Calendar.getInstance();
date.setTimeZone(TimeZone.getDefault());
date.setTimeInMillis(timestamp);
Img img = new Img(id, url, shortHash, realShortHash, date, storageDuration, thumbData);
Img img = new Img(id, url, shortHash, realShortHash, date, storageDuration, thumbData, token);
history.add(img);
}
......@@ -103,7 +107,6 @@ public class Database extends SQLiteOpenHelper {
return history;
}
//not used today but will be used in v2 version
public void deleteImg(List<Img> deletedList) {
for(Img img : deletedList)
{
......@@ -114,7 +117,7 @@ public class Database extends SQLiteOpenHelper {
}
}
public void addImage(Img img) {
public Long addImage(Img img) {
ContentValues values = new ContentValues();
values.put("url", img.getUrl());
values.put("short_hash", img.getShortHash());
......@@ -123,7 +126,8 @@ public class Database extends SQLiteOpenHelper {
values.put("storage_duration", img.getStorageDuration());
if(img.getThumbData() != null)
values.put("thumb",img.getThumbData());
getWritableDatabase().insert("history", null, values);
values.put("token",img.getToken());
return getWritableDatabase().insert("history", null, values);
}
public void addServer(String url)
......@@ -167,7 +171,7 @@ public class Database extends SQLiteOpenHelper {
String whereClause ="id = ?";
String[] whereArgs = new String[1];
whereArgs[0] = String.valueOf(idServer);
getWritableDatabase().delete("servers",whereClause,whereArgs);
getWritableDatabase().delete("servers", whereClause, whereArgs);
}
public void setDefaultServer(long newDefaultId, long oldDefaultId)
......@@ -186,4 +190,29 @@ public class Database extends SQLiteOpenHelper {
getWritableDatabase().update("servers", values, whereClause, whereargs);
}
}
public Img getImage(Long imageId) {
Img image = null;
String whereClause = "id = ?";
String[] whereArgs = new String[1];
whereArgs[0] = String.valueOf(imageId);
Cursor cursor = getReadableDatabase().query("history", null, whereClause, whereArgs, null, null, null);
if(cursor.moveToFirst()) {
int col = 0;
Long id = cursor.getLong(col++);
String url = cursor.getString(col++);
String short_hash = cursor.getString(col++);
String real_short_hash = cursor.getString(col++);
Long date = cursor.getLong(col++);
int duration = cursor.getInt(col++);
byte[] thumb = cursor.getBlob(col++);
String token = cursor.getString(col);
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(date);
image = new Img(id,url,short_hash,real_short_hash,cal,duration,thumb,token);
}
cursor.close();
return image;
}
}
......@@ -35,7 +35,7 @@ import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.NetworkInfo.State;
import android.util.Log;
import android.util.Base64;
import fr.mobdev.goblim.listener.NetworkListener;
import fr.mobdev.goblim.objects.Img;
......@@ -55,7 +55,7 @@ public class NetworkManager {
public static NetworkManager getInstance(NetworkListener listener, Context context){
if (instance == null)
instance = new NetworkManager(listener,context);
if(listener != instance.getListener())
if(listener != null && listener != instance.getListener())
instance.setListener(listener);
return instance;
}
......@@ -72,8 +72,10 @@ public class NetworkManager {
public void upload(final String siteUrl, final int nbDays, final String fileName, final byte[] bytearray)
{
if(!isConnectedToInternet(context))
if(!isConnectedToInternet(context)) {
listener.fileUploadError(context.getString(R.string.no_network));
return;
}
new Thread(new Runnable() {
@Override
......@@ -211,7 +213,13 @@ public class NetworkManager {
//retrieve useful data
String hashOutput = msg.getString("short");
String realHashOutput = msg.getString("real_short");
imgOutput = new Img(0, siteUrl, hashOutput, realHashOutput, Calendar.getInstance(), nbDays, null);
String token = msg.getString("token");
String thumb = msg.getString("thumb");
//get thumbnail and transform it to useful data
thumb = thumb.substring(thumb.indexOf(","));
byte[] thumbData = Base64.decode(thumb, Base64.DEFAULT);
System.out.println("Data is not null? " + thumbData.length);
imgOutput = new Img(0, siteUrl, hashOutput, realHashOutput, Calendar.getInstance(), nbDays, thumbData,token);
}
} catch (JSONException e) {
e.printStackTrace();
......@@ -220,7 +228,40 @@ public class NetworkManager {
}
return imgOutput;
}
public void deleteImage(final String deleteUrl) {
new Thread(new Runnable() {
@Override
public void run() {
if (!isConnectedToInternet(context))
listener.deleteError(context.getString(R.string.no_network));
URL url = null;
try {
url = new URL(deleteUrl);
} catch (Exception e) {
e.printStackTrace();
}
if (url != null) {
try {
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
if(urlConnection != null) {
InputStream stream = urlConnection.getInputStream();
stream.close();
}
else {
listener.deleteError(context.getString(R.string.network_error));
}
} catch (Exception e) {
e.printStackTrace();
}
listener.deleteSucceed();
}
}
}).start();
}
private boolean isConnectedToInternet(Context context)
{
//verify the connectivity
......@@ -236,4 +277,5 @@ public class NetworkManager {
}
return false;
}
}
\ No newline at end of file
......@@ -47,6 +47,8 @@ import fr.mobdev.goblim.R;
*/
public class HistoryActivity extends ActionBarActivity {
private List<Img> images;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
......@@ -54,9 +56,7 @@ public class HistoryActivity extends ActionBarActivity {
ListView historyList = (ListView) findViewById(R.id.history_list);
final List<Img> images = Database.getInstance(getApplicationContext()).getHistory();
HistoryAdapter adapter = new HistoryAdapter(this,R.layout.history_item,R.id.url_history_item,images);
historyList.setAdapter(adapter);
updateHistory();
historyList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
......@@ -65,8 +65,7 @@ public class HistoryActivity extends ActionBarActivity {
Intent linkIntent = new Intent(HistoryActivity.this,LinkActivity.class);
if(position < images.size()) {
Img image = images.get(position);
linkIntent.putExtra("URL", image.getUrl());
linkIntent.putExtra("short", image.getShortHash());
linkIntent.putExtra("imageId", image.getId());
startActivity(linkIntent);
}
}
......@@ -74,6 +73,22 @@ public class HistoryActivity extends ActionBarActivity {
});
}
@Override
protected void onResume()
{
super.onResume();
updateHistory();
}
private void updateHistory()
{
ListView historyList = (ListView) findViewById(R.id.history_list);
images = Database.getInstance(getApplicationContext()).getHistory();
HistoryAdapter adapter = new HistoryAdapter(this,R.layout.history_item,R.id.url_history_item,images);
historyList.setAdapter(adapter);
}
//Adapter to handle History Items
private class HistoryAdapter extends ArrayAdapter<Img>
{
......@@ -138,8 +153,7 @@ public class HistoryActivity extends ActionBarActivity {
//Display miniatures if it exist
ImageView thumb = (ImageView) convertView.findViewById(R.id.thumbnail);
if(image.getThumb() != null)
thumb.setImageBitmap(image.getThumb());
thumb.setImageBitmap(image.getThumb());
return convertView;
}
......
......@@ -18,17 +18,28 @@
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.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.content.ClipboardManager;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import fr.mobdev.goblim.Database;
import fr.mobdev.goblim.NetworkManager;
import fr.mobdev.goblim.R;
import fr.mobdev.goblim.listener.NetworkAdapter;
import fr.mobdev.goblim.objects.Img;
/*
* Activity display the link of the uploaded picture and allow user to share it with other app
......@@ -43,15 +54,21 @@ public class LinkActivity extends ActionBarActivity {
//get url information
Intent receiveIntent = getIntent();
String url = receiveIntent.getStringExtra("URL");
String shortHash = receiveIntent.getStringExtra("short");
Long imageId = receiveIntent.getLongExtra("imageId", -1);
final Img image = Database.getInstance(getApplicationContext()).getImage(imageId);
String url = image.getUrl();
String shortHash = image.getShortHash();
String realShortHash = image.getRealShortHash();
String token = image.getToken();
ImageView iv = (ImageView) findViewById(R.id.thumbnail_link);
iv.setImageBitmap(image.getThumb());
//add a / at the end of the url before adding the hash
if(!url.endsWith("/"))
url = url.concat("/");
url = url.concat(shortHash);
final String sharedUrl = url;
final String sharedUrl = url.concat(shortHash);
final String deleteUrl = url.concat("d/"+realShortHash+"/"+token);
//manage the sharing button
ImageButton shareButton = (ImageButton) findViewById(R.id.share_button);
......@@ -78,6 +95,69 @@ public class LinkActivity extends ActionBarActivity {
}
});
final NetworkAdapter listener = new NetworkAdapter() {
@Override
public void deleteSucceed()
{
List<Img> images = new ArrayList<>();
images.add(image);
Database.getInstance(getApplicationContext()).deleteImg(images);
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(LinkActivity.this, R.string.delete_succeed, Toast.LENGTH_SHORT).show();
}
});
finish();
}
@Override
public void deleteError(final String error)
{
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(LinkActivity.this, error, Toast.LENGTH_SHORT).show();
}
});
}
};
ImageButton deleteImageButton = (ImageButton) findViewById(R.id.delete_button);
deleteImageButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(LinkActivity.this);
builder.setMessage(getString(R.string.delete_this_image))
.setCancelable(false)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
int storageDuration = image.getStorageDuration();
Calendar date = image.getDate();
Calendar today = Calendar.getInstance();
long millis = today.getTimeInMillis() - date.getTimeInMillis();
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);
else {
//image is no more on the server, delete is only local now
listener.deleteSucceed();
}
}
})
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
}
});
//add the url to the textview
TextView link = (TextView) findViewById(R.id.link);
link.setText(sharedUrl);
......
/*
* Copyright (C) 2015 Anthony Chomienne, anthony@mob-dev.fr
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package fr.mobdev.goblim.listener;
import fr.mobdev.goblim.objects.Img;
public class NetworkAdapter implements NetworkListener{
@Override
public void fileUploaded(Img image) {
//do nothing
}
@Override
public void fileUploadError(String error) {
//do nothing
}
@Override
public void deleteSucceed() {
//do nothing
}
@Override
public void deleteError(String Error) {
//do nothing
}
}
......@@ -25,4 +25,6 @@ import fr.mobdev.goblim.objects.Img;
public interface NetworkListener extends EventListener{
void fileUploaded(Img image);
void fileUploadError(String error);
void deleteSucceed();
void deleteError(String error);
}
......@@ -19,6 +19,7 @@
package fr.mobdev.goblim.objects;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import java.io.ByteArrayOutputStream;
import java.util.Calendar;
......@@ -32,14 +33,21 @@ public class Img {
private Bitmap image;
private String shortHash;
private String realShortHash;
private String token;
public Img(long id, String url, String shortHash, String realShortHash, Calendar date, int storageDuration, byte[] thumbData) {
public Img(long id, String url, String shortHash, String realShortHash, Calendar date, int storageDuration, byte[] thumbData, String token) {
this.url = url;
this.shortHash = shortHash;
this.id = id;
this.realShortHash = realShortHash;
this.date = date;
this.storageDuration = storageDuration;
this.token = token;
if(thumbData != null) {
image = BitmapFactory.decodeByteArray(thumbData, 0, thumbData.length);
}
else
image = null;
}
public Long getId()
......@@ -89,5 +97,9 @@ public class Img {
}
}
public String getToken(){
return token;
}
}
......@@ -64,11 +64,21 @@
<ImageView
android:layout_above="@+id/spinners_layout"
android:layout_below="@+id/reset_button"
android:id="@+id/thumbnail_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
/>
<ImageButton
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginBottom="10dp"
android:src="@android:drawable/ic_delete"
android:id="@+id/reset_button"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
/>
</RelativeLayout>
......@@ -27,7 +27,8 @@
android:id="@+id/thumbnail"
android:layout_alignParentLeft="true"
android:layout_width="100dp"
android:layout_height="100dp" />
android:layout_height="100dp"
android:layout_marginRight="10dp"/>
<TextView
android:gravity="center_vertical"
......
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="fr.mobdev.goblim.activity.LinkActivity"
android:orientation="vertical"
android:gravity="center">
>
<ImageView
android:layout_above="@+id/link"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/thumbnail_link"
android:layout_gravity="center_horizontal"/>
<TextView
android:layout_above="@+id/buttons_layout"
android:layout_centerHorizontal="true"
android:textAppearance="?android:attr/textAppearanceLarge"
android:gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:autoLink="web"
android:id="@+id/link"
android:text="Toto"
android:layout_marginBottom="30dp"
/>
<LinearLayout
android:layout_alignParentBottom="true"
android:gravity="center"
android:id="@+id/buttons_layout"
android:orientation="horizontal"
......@@ -39,7 +49,13 @@
android:layout_width="60dp"
android:layout_height="60dp"
/>
<ImageButton
android:src="@android:drawable/ic_menu_delete"
android:layout_width="60dp"
android:layout_height="60dp"
android:id="@+id/delete_button" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
......@@ -57,11 +57,21 @@
<ImageView
android:layout_above="@+id/servers_spinner"
android:layout_below="@+id/reset_button"
android:id="@+id/thumbnail_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
/>
<ImageButton
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginBottom="10dp"
android:src="@android:drawable/ic_delete"
android:id="@+id/reset_button"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
/>
</RelativeLayout>
......@@ -5,11 +5,21 @@
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="fr.mobdev.goblim.activity.ServersActivity">
<ListView
android:id="@+id/servers_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:choiceMode="singleChoice"
<TextView
android:gravity="center"
android:text="@string/default_server"
android:layout_alignParentTop="true"
android:id="@+id/default_indications"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
/>
<ListView
android:layout_below="@+id/default_indications"
android:id="@+id/servers_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:choiceMode="singleChoice"
/>
</RelativeLayout>
......@@ -27,6 +27,12 @@
<string name="unreadable_json">JSON Illisible</string>
<string name="empty_file">Fichier vide ou impossible à lire</string>
<string name="too_large_file">Le fichier est peut être trop grand</string>
<string name="no_network">Réseau indisponible</string>
<string name="cant_load_image">L\'image ne peut pas être chargé</string>
<string name="download_progress">Téléchargement en cours</string>
<string name="delete_succeed">Suppression Réussie</string>
<string name="default_server">Appuie long pour choisir votre serveur par défaut</string>
<string name="delete_this_image">Supprimer cette image?</string>
<string-array name="deleted_days">
<item>Pas de limitation</item>
<item>24 Heures</item>
......
......@@ -27,6 +27,12 @@
<string name="unreadable_json">Unreadable JSON</string>
<string name="empty_file">Empty file or unable to read it</string>
<string name="too_large_file">The file may be too large</string>
<string name="no_network">Network Unavailable</string>
<string name="cant_load_image">Image can\'t be load</string>
<string name="download_progress">Download in progress</string>
<string name="delete_succeed">Delete Succeed</string>
<string name="default_server">Long click to choose your default server</string>
<string name="delete_this_image">Delete this image?</string>
<string-array name="deleted_days">
<item>No limitation</item>
<item>24 Hours</item>
......
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