@@ -1,13 +1,3 @@ | |||
# Built application files | |||
*.apk | |||
*.ap_ | |||
# Files for the Dalvik VM | |||
*.dex | |||
# Java class files | |||
*.class | |||
# Generated files | |||
bin/ | |||
gen/ | |||
@@ -16,6 +6,7 @@ gen/ | |||
.gradle/ | |||
build/ | |||
/*/build/ | |||
gradlew* | |||
# Local configuration file (sdk path, etc) | |||
local.properties | |||
@@ -25,3 +16,7 @@ proguard/ | |||
# Log Files | |||
*.log | |||
#android-studio file | |||
.idea | |||
*.iml |
@@ -0,0 +1 @@ | |||
/build |
@@ -0,0 +1,25 @@ | |||
apply plugin: 'com.android.application' | |||
android { | |||
compileSdkVersion 22 | |||
buildToolsVersion "21.1.2" | |||
defaultConfig { | |||
applicationId "fr.mobdev.gobelim" | |||
minSdkVersion 11 | |||
targetSdkVersion 22 | |||
versionCode 1 | |||
versionName "1.0" | |||
} | |||
buildTypes { | |||
release { | |||
minifyEnabled false | |||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' | |||
} | |||
} | |||
} | |||
dependencies { | |||
compile fileTree(dir: 'libs', include: ['*.jar']) | |||
compile 'com.android.support:appcompat-v7:22.0.0' | |||
} |
@@ -0,0 +1,13 @@ | |||
package fr.mobdev.gobelim; | |||
import android.app.Application; | |||
import android.test.ApplicationTestCase; | |||
/** | |||
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a> | |||
*/ | |||
public class ApplicationTest extends ApplicationTestCase<Application> { | |||
public ApplicationTest() { | |||
super(Application.class); | |||
} | |||
} |
@@ -0,0 +1,42 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | |||
package="fr.mobdev.gobelim" > | |||
<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" /> | |||
<application | |||
android:allowBackup="true" | |||
android:icon="@mipmap/ic_launcher" | |||
android:label="@string/app_name" | |||
android:theme="@style/AppTheme"> | |||
<activity | |||
android:name="fr.mobdev.gobelim.activity.MainActivity" | |||
android:label="@string/app_name"> | |||
<intent-filter> | |||
<action android:name="android.intent.action.MAIN" /> | |||
<category android:name="android.intent.category.LAUNCHER" /> | |||
</intent-filter> | |||
<intent-filter> | |||
<action android:name="android.intent.action.SEND"/> | |||
<category android:name="android.intent.category.DEFAULT"/> | |||
<data android:mimeType="image/*"/> | |||
</intent-filter> | |||
</activity> | |||
<activity | |||
android:name="fr.mobdev.gobelim.activity.HistoryActivity" | |||
android:label="@string/title_activity_history"> | |||
</activity> | |||
<activity | |||
android:name="fr.mobdev.gobelim.activity.LinkActivity" | |||
android:label="@string/title_activity_link" | |||
> | |||
</activity> | |||
<activity | |||
android:name="fr.mobdev.gobelim.activity.ServersActivity" | |||
android:label="@string/title_activity_servers" | |||
> | |||
</activity> | |||
</application> | |||
</manifest> |
@@ -0,0 +1,162 @@ | |||
package fr.mobdev.gobelim; | |||
import java.util.ArrayList; | |||
import java.util.Calendar; | |||
import java.util.List; | |||
import java.util.TimeZone; | |||
import android.content.ContentValues; | |||
import android.content.Context; | |||
import android.database.Cursor; | |||
import android.database.sqlite.SQLiteDatabase; | |||
import android.database.sqlite.SQLiteDatabase.CursorFactory; | |||
import android.database.sqlite.SQLiteOpenHelper; | |||
import fr.mobdev.gobelim.objects.Img; | |||
import fr.mobdev.gobelim.objects.Server; | |||
public class Database extends SQLiteOpenHelper { | |||
private static Database instance; | |||
public static Database getInstance(Context context) | |||
{ | |||
if(instance == null) | |||
instance = new Database(context, "Lutim.db", null, 1); | |||
return instance; | |||
} | |||
private Database(Context context, String name, CursorFactory factory, int version) { | |||
super(context, name, factory, version); | |||
} | |||
@Override | |||
public void onCreate(SQLiteDatabase db) { | |||
db.execSQL("Create table if not exists history (" + | |||
"id integer primary key autoincrement, url varchar(1024), short_hash varchar(1024), real_short_hash varchar(1024), date INTEGER, storage_duration INTEGER ,thumb TEXT);"); | |||
db.execSQL("Create table if not exists servers (" + | |||
"id integer primary key autoincrement, url varchar(1024), isDefault INTEGER);"); | |||
ContentValues values = new ContentValues(); | |||
values.put("url","https://framapic.org"); | |||
values.put("isDefault",true); | |||
db.insert("servers",null,values); | |||
values.clear(); | |||
values.put("url","https://lut.im"); | |||
values.put("isDefault",false); | |||
db.insert("servers", null, values); | |||
} | |||
@Override | |||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { | |||
//nothing to do right now | |||
} | |||
public List<Img> getHistory() { | |||
List<Img> history = new ArrayList<Img>(); | |||
String orderBy = "date ASC"; | |||
Cursor cursor = getReadableDatabase().query("history", null, null, null, null, null, orderBy); | |||
while(cursor.moveToNext()) | |||
{ | |||
int col = 0; | |||
long id = cursor.getLong(col++); | |||
String url = cursor.getString(col++); | |||
String shortHash = cursor.getString(col++); | |||
String realShortHash = cursor.getString(col++); | |||
long timestamp = cursor.getLong(col++); | |||
int storageDuration = cursor.getInt(col++); | |||
byte[] thumbData = cursor.getBlob(col++); | |||
Calendar date = Calendar.getInstance(); | |||
date.setTimeZone(TimeZone.getTimeZone("Europe/Paris")); | |||
date.setTimeInMillis(timestamp); | |||
Img img = new Img(id, url, shortHash, realShortHash, date, storageDuration, thumbData); | |||
history.add(img); | |||
} | |||
return history; | |||
} | |||
public void deleteImg(List<Img> deletedList) { | |||
for(Img img : deletedList) | |||
{ | |||
String whereClause = "id = ?"; | |||
String[] whereArgs = new String[1]; | |||
whereArgs[0] = String.valueOf(img.getId()); | |||
getWritableDatabase().delete("history", whereClause, whereArgs); | |||
} | |||
} | |||
public void addImage(Img img) { | |||
ContentValues values = new ContentValues(); | |||
values.put("url", img.getUrl()); | |||
values.put("short_hash", img.getShortHash()); | |||
values.put("real_short_hash", img.getRealShortHash()); | |||
values.put("date", img.getDate().getTimeInMillis()); | |||
values.put("storage_duration", img.getStorageDuration()); | |||
if(img.getThumbData() != null) | |||
values.put("thumb",img.getThumbData()); | |||
getWritableDatabase().insert("history", null, values); | |||
} | |||
public void addServer(String url) | |||
{ | |||
ContentValues values = new ContentValues(); | |||
values.put("url",url); | |||
values.put("isDefault",false); | |||
getWritableDatabase().insert("servers", null, values); | |||
} | |||
public List<Server> getServers(boolean defaultFirst) | |||
{ | |||
List<Server> servers = new ArrayList<Server>(); | |||
Cursor cursor = getReadableDatabase().query("servers", null, null, null, null, null, null); | |||
while(cursor.moveToNext()) | |||
{ | |||
int col = 0; | |||
long id = cursor.getLong(col++); | |||
String url = cursor.getString(col++); | |||
int defValue = cursor.getInt(col++); | |||
boolean isDefault = false; | |||
if(defValue == 1) | |||
isDefault = true; | |||
Server server = new Server(id, url, isDefault); | |||
if(defaultFirst && isDefault) | |||
{ | |||
servers.add(0,server); | |||
} | |||
else | |||
{ | |||
servers.add(server); | |||
} | |||
} | |||
return servers; | |||
} | |||
public void deleteServer(long idServer) | |||
{ | |||
String whereClause ="id = ?"; | |||
String[] whereArgs = new String[1]; | |||
whereArgs[0] = String.valueOf(idServer); | |||
getWritableDatabase().delete("servers",whereClause,whereArgs); | |||
} | |||
public void setDefaultServer(long newDefaultId, long oldDefaultId) | |||
{ | |||
String whereClause = "id = ?"; | |||
String[] whereargs = new String[1]; | |||
whereargs[0] = String.valueOf(newDefaultId); | |||
ContentValues values = new ContentValues(); | |||
values.put("isDefault",true); | |||
getWritableDatabase().update("servers", values, whereClause, whereargs); | |||
if(oldDefaultId != -1) { | |||
values.clear(); | |||
whereargs[0] = String.valueOf(oldDefaultId); | |||
values.put("isDefault", false); | |||
getWritableDatabase().update("servers", values, whereClause, whereargs); | |||
} | |||
} | |||
} |
@@ -0,0 +1,215 @@ | |||
package fr.mobdev.gobelim; | |||
import java.io.BufferedReader; | |||
import java.io.DataOutputStream; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.io.InputStreamReader; | |||
import java.net.HttpURLConnection; | |||
import java.net.MalformedURLException; | |||
import java.net.URL; | |||
import java.util.Calendar; | |||
import org.json.JSONException; | |||
import org.json.JSONObject; | |||
import android.content.Context; | |||
import android.net.ConnectivityManager; | |||
import android.net.NetworkInfo; | |||
import android.net.NetworkInfo.State; | |||
import android.util.Log; | |||
import fr.mobdev.gobelim.listener.NetworkListener; | |||
import fr.mobdev.gobelim.objects.Img; | |||
public class NetworkManager { | |||
private NetworkListener listener; | |||
private static NetworkManager instance; | |||
private Context context; | |||
private static int id; | |||
private NetworkManager(NetworkListener listener,Context context) | |||
{ | |||
this.listener = listener; | |||
this.context = context; | |||
} | |||
public static NetworkManager getInstance(NetworkListener listener, Context context){ | |||
if (instance == null) | |||
instance = new NetworkManager(listener,context); | |||
if(listener != instance.getListener()) | |||
instance.setListener(listener); | |||
return instance; | |||
} | |||
private NetworkListener getListener() | |||
{ | |||
return listener; | |||
} | |||
private void setListener(NetworkListener listener) | |||
{ | |||
this.listener = listener; | |||
} | |||
public void upload(final String siteUrl, final int nbDays, final String fileName, final byte[] bytearray) | |||
{ | |||
if(!isConnectedToInternet(context)) | |||
return; | |||
new Thread(new Runnable() { | |||
@Override | |||
public void run() { | |||
Img img = uploadImage(siteUrl,nbDays, fileName,bytearray); | |||
if(img != null) | |||
listener.fileUploaded(img); | |||
} | |||
}).start(); | |||
} | |||
public Img uploadImage(String siteUrl, int nbDays, String fileName, byte[] byteArray) { | |||
Log.v("Url",siteUrl); | |||
//getData | |||
URL url = null; | |||
Img imgOutput = null; | |||
try { | |||
url = new URL(siteUrl); | |||
} catch (MalformedURLException e1) { | |||
e1.printStackTrace(); | |||
} | |||
HttpURLConnection conn = null; | |||
InputStream stream = null; | |||
DataOutputStream request = null; | |||
try { | |||
if(isConnectedToInternet(context)) | |||
{ | |||
String attachmentFileName = fileName; | |||
String crlf = "\r\n"; | |||
String hyphens = "--"; | |||
String boundary = "------------------------dd8a045fcc22b35c"; | |||
conn = (HttpURLConnection) url.openConnection(); | |||
int responseCode = conn.getResponseCode(); | |||
String location = conn.getHeaderField("Location"); | |||
if(location != null) { | |||
siteUrl = location; | |||
url = new URL(location); | |||
} | |||
conn = (HttpURLConnection) url.openConnection(); | |||
conn.setRequestMethod("POST"); | |||
conn.setUseCaches(false); | |||
conn.setDoInput(true); | |||
conn.setDoOutput(true); | |||
conn.setRequestProperty("User-Agent", "Gobelim"); | |||
// conn.setFixedLengthStreamingMode(byteArray.length); | |||
// conn.setChunkedStreamingMode(0); | |||
conn.setInstanceFollowRedirects(true); | |||
//conn.set | |||
conn.setRequestProperty("Expect", "100-continue"); | |||
conn.setRequestProperty("Accept", "*/*"); | |||
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); | |||
request = new DataOutputStream(conn.getOutputStream()); | |||
request.writeBytes(hyphens + boundary + crlf); | |||
request.writeBytes("Content-Disposition: form-data; name=\"format\"" + crlf); | |||
request.writeBytes(crlf); | |||
request.writeBytes("json" + crlf); | |||
request.writeBytes(hyphens + boundary + crlf); | |||
request.writeBytes("Content-Disposition: form-data; name=\"delete-day\"" + crlf); | |||
request.writeBytes(crlf); | |||
request.writeBytes(nbDays + crlf); | |||
request.writeBytes(hyphens + boundary + crlf); | |||
request.writeBytes("Content-Disposition: form-data; name=\"file\"; filename=\"" + attachmentFileName + "\"" + crlf); | |||
request.writeBytes("Content-Type: application/octet-stream" + crlf); | |||
request.writeBytes(crlf); | |||
request.flush(); | |||
request.write(byteArray); | |||
request.writeBytes(crlf); | |||
request.writeBytes(hyphens + boundary + hyphens + crlf); | |||
request.flush(); | |||
stream = conn.getInputStream(); | |||
} | |||
} catch (IOException e1) { | |||
e1.printStackTrace(); | |||
listener.fileUploadError("Network Error"); | |||
} | |||
/******************************************************************************/ | |||
if(stream != null) { | |||
InputStreamReader isr = new InputStreamReader(stream); | |||
BufferedReader br = new BufferedReader(isr); | |||
boolean isReading = true; | |||
String data; | |||
String jsonStr = ""; | |||
do { | |||
try { | |||
data = br.readLine(); | |||
if (data != null) | |||
jsonStr += data; | |||
else | |||
isReading = false; | |||
} catch (IOException e) { | |||
e.printStackTrace(); | |||
isReading = false; | |||
} | |||
} while (isReading); | |||
//parseJSon | |||
try { | |||
request.close(); | |||
stream.close(); | |||
} catch (IOException e) { | |||
e.printStackTrace(); | |||
} | |||
System.out.println("after read answer"); | |||
System.out.println(jsonStr); | |||
try { | |||
JSONObject rootObject = new JSONObject(jsonStr); // Parse the JSON to a JSONObject | |||
JSONObject msg = rootObject.getJSONObject("msg"); // Get the element object | |||
if(msg.has("msg")) { | |||
String error = msg.getString("msg"); | |||
listener.fileUploadError(error); | |||
return null; | |||
} | |||
else if(msg.has("short")) { | |||
String hashOutput = msg.getString("short"); | |||
String realHashOutput = msg.getString("real_short"); | |||
imgOutput = new Img(0, siteUrl, hashOutput, realHashOutput, Calendar.getInstance(), nbDays, null); | |||
} | |||
} catch (JSONException e) { | |||
// JSON Parsing error | |||
e.printStackTrace(); | |||
listener.fileUploadError("JSON Unreadable"); | |||
} | |||
} | |||
return imgOutput; | |||
} | |||
private boolean isConnectedToInternet(Context context) | |||
{ | |||
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); | |||
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); | |||
if (networkInfo != null) | |||
{ | |||
State networkState = networkInfo.getState(); | |||
if (networkState.equals(State.CONNECTED)) | |||
{ | |||
return true; | |||
} | |||
} | |||
return false; | |||
} | |||
} |
@@ -0,0 +1,120 @@ | |||
package fr.mobdev.gobelim.activity; | |||
import android.content.Context; | |||
import android.content.Intent; | |||
import android.support.v7.app.ActionBarActivity; | |||
import android.os.Bundle; | |||
import android.view.LayoutInflater; | |||
import android.view.View; | |||
import android.view.ViewGroup; | |||
import android.widget.AdapterView; | |||
import android.widget.ArrayAdapter; | |||
import android.widget.ImageView; | |||
import android.widget.ListView; | |||
import android.widget.TextView; | |||
import java.text.DateFormat; | |||
import java.util.ArrayList; | |||
import java.util.Calendar; | |||
import java.util.List; | |||
import java.util.Locale; | |||
import java.util.TimeZone; | |||
import fr.mobdev.gobelim.Database; | |||
import fr.mobdev.gobelim.objects.Img; | |||
import fr.mobdev.gobelim.R; | |||
public class HistoryActivity extends ActionBarActivity { | |||
@Override | |||
protected void onCreate(Bundle savedInstanceState) { | |||
super.onCreate(savedInstanceState); | |||
setContentView(R.layout.history); | |||
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); | |||
historyList.setOnItemClickListener(new AdapterView.OnItemClickListener() { | |||
@Override | |||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { | |||
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()); | |||
startActivity(linkIntent); | |||
} | |||
} | |||
}); | |||
} | |||
private class HistoryAdapter extends ArrayAdapter<Img> | |||
{ | |||
private List<Img> images; | |||
private LayoutInflater mInflater; | |||
int resource; | |||
public HistoryAdapter(Context context, int resource, int textViewResourceId, List<Img> objects) { | |||
super(context, resource, textViewResourceId, objects); | |||
images = new ArrayList(objects); | |||
this.resource = resource; | |||
mInflater = LayoutInflater.from(context); | |||
} | |||
@Override | |||
public View getView(int position, View convertView, ViewGroup parent) | |||
{ | |||
Img image = images.get(position); | |||
if (convertView == null) { | |||
convertView = mInflater.inflate(resource, parent, false); | |||
} | |||
TextView urlView = (TextView) convertView.findViewById(R.id.url_history_item); | |||
String url = image.getUrl(); | |||
if(!url.endsWith("/")) | |||
url+="/"; | |||
url+=image.getShortHash(); | |||
urlView.setText(url); | |||
//display date | |||
TextView dateView = (TextView) convertView.findViewById(R.id.date); | |||
Calendar date = image.getDate(); | |||
DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, Locale.getDefault()); | |||
df.setTimeZone(TimeZone.getDefault()); | |||
String dateString = df.format(date.getTime()); | |||
dateView.setText(dateString); | |||
//display durationLastDay | |||
TextView durationView = (TextView) convertView.findViewById(R.id.duration); | |||
int storageDuration = image.getStorageDuration(); | |||
if(storageDuration == 0) { | |||
durationView.setText(getString(R.string.no_duration)); | |||
} | |||
else { | |||
Calendar today = Calendar.getInstance(); | |||
long millis = today.getTimeInMillis() - date.getTimeInMillis(); | |||
long days = millis / (24*60*60*1000); | |||
if(storageDuration - days < 0) { | |||
durationView.setText(getString(R.string.duration_ended)); | |||
} | |||
else { | |||
if(storageDuration - days == 1) | |||
durationView.setText(storageDuration - days +" "+ getString(R.string.day)); | |||
else | |||
durationView.setText(storageDuration - days +" "+ getString(R.string.days)); | |||
} | |||
} | |||
ImageView thumb = (ImageView) convertView.findViewById(R.id.thumbnail); | |||
if(image.getThumb() != null) | |||
thumb.setImageBitmap(image.getThumb()); | |||
return convertView; | |||
} | |||
} | |||
} | |||
@@ -0,0 +1,60 @@ | |||
package fr.mobdev.gobelim.activity; | |||
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.TextView; | |||
import android.content.ClipboardManager; | |||
import android.widget.Toast; | |||
import fr.mobdev.gobelim.R; | |||
public class LinkActivity extends ActionBarActivity { | |||
@Override | |||
protected void onCreate(Bundle savedInstanceState) { | |||
super.onCreate(savedInstanceState); | |||
setContentView(R.layout.link); | |||
Intent receiveIntent = getIntent(); | |||
String url = receiveIntent.getStringExtra("URL"); | |||
String shortHash = receiveIntent.getStringExtra("short"); | |||
if(!url.endsWith("/")) | |||
url = url.concat("/"); | |||
url = url.concat(shortHash); | |||
final String sharedUrl = url; | |||
ImageButton shareButton = (ImageButton) findViewById(R.id.share_button); | |||
shareButton.setOnClickListener(new View.OnClickListener() { | |||
@Override | |||
public void onClick(View v) { | |||
Intent sendIntent = new Intent(); | |||
sendIntent.setAction(Intent.ACTION_SEND); | |||
sendIntent.putExtra(Intent.EXTRA_TEXT, sharedUrl); | |||
sendIntent.setType("text/plain"); | |||
startActivity(sendIntent); | |||
} | |||
}); | |||
ImageButton copyClipboardButton = (ImageButton) findViewById(R.id.copy_clipboard_button); | |||
copyClipboardButton.setOnClickListener(new View.OnClickListener() { | |||
@Override | |||
public void onClick(View v) { | |||
ClipboardManager clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); | |||
android.content.ClipData clip = android.content.ClipData.newPlainText("Copied URL", sharedUrl); | |||
clipboard.setPrimaryClip(clip); | |||
Toast.makeText(LinkActivity.this,getString(R.string.copy_to_clipboard),Toast.LENGTH_SHORT).show(); | |||
} | |||
}); | |||
TextView link = (TextView) findViewById(R.id.link); | |||
link.setText(sharedUrl); | |||
} | |||
} |
@@ -0,0 +1,340 @@ | |||
/* | |||
* 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.gobelim.activity; | |||
import android.app.ProgressDialog; | |||
import android.content.ContentResolver; | |||
import android.content.Intent; | |||
import android.database.Cursor; | |||
import android.graphics.Bitmap; | |||
import android.graphics.BitmapFactory; | |||
import android.net.Uri; | |||
import android.provider.MediaStore; | |||
import android.support.v7.app.ActionBarActivity; | |||
import android.os.Bundle; | |||
import android.view.Menu; | |||
import android.view.MenuItem; | |||
import android.view.View; | |||
import android.widget.ArrayAdapter; | |||
import android.widget.Button; | |||
import android.widget.ImageView; | |||
import android.widget.Spinner; | |||
import android.widget.Toast; | |||
import java.io.ByteArrayOutputStream; | |||
import java.io.File; | |||
import java.io.FileInputStream; | |||
import java.io.FileNotFoundException; | |||
import java.io.IOException; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import fr.mobdev.gobelim.Database; | |||
import fr.mobdev.gobelim.listener.NetworkListener; | |||
import fr.mobdev.gobelim.NetworkManager; | |||
import fr.mobdev.gobelim.objects.Img; | |||
import fr.mobdev.gobelim.objects.Server; | |||
import fr.mobdev.gobelim.R; | |||
public class MainActivity extends ActionBarActivity { | |||
private NetworkListener listener; | |||
private Uri imageUri; | |||
private String fileName; | |||
private List<String> urls; | |||
private List<Integer> deletedDays; | |||
private ProgressDialog progressDialog; | |||
private static final int NEVER = 0; | |||
private static final int ONE = 1; | |||
private static final int SEVEN = 7; | |||
private static final int THIRTY = 30; | |||
private static final int YEAR = 365; | |||
@Override | |||
protected void onCreate(Bundle savedInstanceState) { | |||
super.onCreate(savedInstanceState); | |||
setContentView(R.layout.main); | |||
imageUri = null; | |||
urls = new ArrayList<>(); | |||
deletedDays = new ArrayList<>(); | |||
deletedDays.add(NEVER); | |||
deletedDays.add(ONE); | |||
deletedDays.add(SEVEN); | |||
deletedDays.add(THIRTY); | |||
deletedDays.add(YEAR); | |||
updateServerList(); | |||
if(savedInstanceState != null) { | |||
int selectedServer = savedInstanceState.getInt("selectedServer"); | |||
imageUri = savedInstanceState.getParcelable("imageURI"); | |||
if (selectedServer < urls.size()) { | |||
Spinner servers = (Spinner) findViewById(R.id.servers_spinner); | |||
servers.setSelection(selectedServer); | |||
} | |||
} | |||
listener = new NetworkListener() { | |||
@Override | |||
public void fileUploaded(final Img image) { | |||
runOnUiThread(new Runnable() { | |||
@Override | |||
public void run() { | |||
//add uploaded img to history | |||
Database.getInstance(getApplicationContext()).addImage(image); | |||
//dismiss progressDialog | |||
progressDialog.dismiss(); | |||
//launch LinkActivity | |||
Intent linkIntent = new Intent(MainActivity.this,LinkActivity.class); | |||
linkIntent.putExtra("URL", image.getUrl()); | |||
linkIntent.putExtra("short",image.getShortHash()); | |||
startActivity(linkIntent); | |||
} | |||
}); | |||
} | |||
@Override | |||
public void fileUploadError(final String error) { | |||
runOnUiThread(new Runnable() { | |||
@Override | |||
public void run() { | |||
//display toast error | |||
Toast.makeText(MainActivity.this, error, Toast.LENGTH_SHORT).show(); | |||
progressDialog.dismiss(); | |||
} | |||
}); | |||
} | |||
}; | |||
Button uploadBt = (Button) findViewById(R.id.upload_button); | |||
uploadBt.setOnClickListener(new View.OnClickListener() { | |||
@Override | |||
public void onClick(View v) { | |||
uploadImage(); | |||
} | |||
}); | |||
//prepare for asking user the image he want share | |||
Button selectBt = (Button) findViewById(R.id.select_button); | |||
selectBt.setOnClickListener(new View.OnClickListener() { | |||
@Override | |||
public void onClick(View v) { | |||
requestFile(); | |||
} | |||
}); | |||
//have we receive image from share or do you need to ask it to the user | |||
Intent receiveIntent = getIntent(); | |||
if(receiveIntent == null || receiveIntent.getType() == null || !receiveIntent.getType().contains("image/")) { | |||
uploadBt.setVisibility(View.GONE); | |||
} | |||
else { | |||
selectBt.setVisibility(View.GONE); | |||
imageUri = receiveIntent.getParcelableExtra(Intent.EXTRA_STREAM); | |||
displayImage(); | |||
} | |||
} | |||
@Override | |||
protected void onResume() { | |||
super.onResume(); | |||
//update server list to manage change in ServerActivity | |||
updateServerList(); | |||
} | |||
@Override | |||
protected void onSaveInstanceState(Bundle savedInstanceState) { | |||
savedInstanceState.putParcelable("imageURI", imageUri); | |||
Spinner selectedServer = (Spinner) findViewById(R.id.servers_spinner); | |||
int pos = selectedServer.getSelectedItemPosition(); | |||
savedInstanceState.putInt("selectedServer", pos); | |||
super.onSaveInstanceState(savedInstanceState); | |||
} | |||
private void updateServerList() { | |||
Spinner serversSpinner = (Spinner) findViewById(R.id.servers_spinner); | |||
String selectedServer = (String) serversSpinner.getSelectedItem(); | |||
List<Server> servers = Database.getInstance(getApplicationContext()).getServers(true); | |||
urls.clear(); | |||
int pos = 0; | |||
for(Server server : servers) { | |||
if(server.getUrl().equals(selectedServer)) { | |||
pos = urls.size(); | |||
} | |||
urls.add(server.getUrl()); | |||
} | |||
ArrayAdapter<String> adapter = new ArrayAdapter<>(this,android.R.layout.simple_dropdown_item_1line,urls); | |||
serversSpinner.setAdapter(adapter); | |||
serversSpinner.setSelection(pos); | |||
} | |||
private void displayImage() { | |||
FileInputStream fileStream = null; | |||
File file; | |||
if(imageUri != null) { | |||
ContentResolver contentResolver = getContentResolver(); | |||
Cursor cursor = contentResolver.query(imageUri, null, null, null, null); | |||
cursor.moveToFirst(); | |||
String filePath = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)); | |||
cursor.close(); | |||
file = new File(filePath); | |||
fileName = file.getName(); | |||
try { | |||
fileStream = new FileInputStream(file); | |||
} catch (FileNotFoundException e) { | |||
e.printStackTrace(); | |||
} | |||
} | |||
if(fileStream != null) { | |||
try { | |||
ByteArrayOutputStream outStream = new ByteArrayOutputStream(); | |||
int readed = 0; | |||
byte[] buffer = new byte[1024]; | |||
while(readed != -1) { | |||
try { | |||
readed = fileStream.read(buffer); | |||
if(readed != -1) | |||
outStream.write(buffer,0,readed); | |||
} catch (IOException e) { | |||
e.printStackTrace(); | |||
readed = -1; | |||
} | |||
} | |||
byte[] bytearray = outStream.toByteArray(); | |||
Bitmap bt = BitmapFactory.decodeByteArray(bytearray,0,bytearray.length); | |||
ImageView view = (ImageView) findViewById(R.id.thumbnail_main); | |||
view.setImageBitmap(bt); | |||
} | |||
catch (Exception e) | |||
{ | |||
e.printStackTrace(); | |||
} | |||
} | |||
} | |||
private void uploadImage() { | |||
//what server we use | |||
Spinner urlSpinner = (Spinner)findViewById(R.id.servers_spinner); | |||
int pos = urlSpinner.getSelectedItemPosition(); | |||
if(urls.size() < pos) { | |||
Toast.makeText(this,getString(R.string.server_list_error),Toast.LENGTH_LONG).show(); | |||
return; | |||
} | |||
String url = urls.get(pos); | |||
Spinner deleteSpinner = (Spinner)findViewById(R.id.delete_day_spinner); | |||
pos = deleteSpinner.getSelectedItemPosition(); | |||
int delete = deletedDays.get(pos); | |||
byte[] bytearray = null; | |||
FileInputStream fileStream = null; | |||
if(imageUri != null) { | |||
ContentResolver contentResolver = getContentResolver(); | |||
Cursor cursor = contentResolver.query(imageUri, null, null, null, null); | |||
cursor.moveToFirst(); | |||
String filePath = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA)); | |||
cursor.close(); | |||
File file = new File(filePath); | |||
fileName = file.getName(); | |||
try { | |||
fileStream = new FileInputStream(file); | |||
} catch (FileNotFoundException e) { | |||
e.printStackTrace(); | |||
} | |||
} | |||
if(fileStream != null) { | |||
ByteArrayOutputStream outStream = new ByteArrayOutputStream(); | |||
int readed = 0; | |||
byte[] buffer = new byte[1024]; | |||
while(readed != -1) { | |||
try { | |||
readed = fileStream.read(buffer); | |||
if(readed != -1) | |||
outStream.write(buffer,0,readed); | |||
} catch (IOException e) { | |||
e.printStackTrace(); | |||
readed = -1; | |||
} | |||
} | |||
bytearray = outStream.toByteArray(); | |||
} | |||
if(bytearray != null && bytearray.length > 0) { | |||
progressDialog = new ProgressDialog(MainActivity.this); | |||
progressDialog.setMessage(getString(R.string.upload_progress)); | |||
progressDialog.setCancelable(false); | |||
progressDialog.show(); | |||
NetworkManager.getInstance(listener, getApplicationContext()).upload(url, delete, fileName, bytearray); | |||
} | |||
else { | |||
listener.fileUploadError("Empty file or Unable to read the file"); | |||
} | |||
} | |||
protected void requestFile() { | |||
Intent requestFileIntent = new Intent(Intent.ACTION_PICK); | |||
requestFileIntent.setType("image/*"); | |||
startActivityForResult(requestFileIntent, 0); | |||
} | |||
@Override | |||
public void onActivityResult(int requestCode, int resultCode,Intent returnIntent) { | |||
if(resultCode == RESULT_OK){ | |||
imageUri = returnIntent.getData(); | |||
Button uploadBt = (Button) findViewById(R.id.upload_button); | |||
uploadBt.setVisibility(View.VISIBLE); | |||
Button selectButton = (Button) findViewById(R.id.select_button); | |||
selectButton.setVisibility(View.GONE); | |||
displayImage(); | |||
} | |||
} | |||
@Override | |||
public boolean onCreateOptionsMenu(Menu menu) { | |||
getMenuInflater().inflate(R.menu.menu_main, menu); | |||
return true; | |||
} | |||
@Override | |||
public boolean onOptionsItemSelected(MenuItem item) { | |||
int id = item.getItemId(); | |||
if (id == R.id.action_manage_server) { | |||
Intent serverIntent = new Intent(this,ServersActivity.class); | |||
startActivity(serverIntent); | |||
return true; | |||
} | |||
else if (id == R.id.action_show_history){ | |||
Intent historyIntent = new Intent(this,HistoryActivity.class); | |||
startActivity(historyIntent); | |||
return true; | |||
} | |||
return super.onOptionsItemSelected(item); | |||
} | |||
} |
@@ -0,0 +1,175 @@ | |||
package fr.mobdev.gobelim.activity; | |||
import android.app.AlertDialog; | |||
import android.content.Context; | |||
import android.content.DialogInterface; | |||
import android.content.Intent; | |||
import android.graphics.Typeface; | |||
import android.provider.ContactsContract; | |||
import android.support.v7.app.ActionBarActivity; | |||
import android.os.Bundle; | |||
import android.view.LayoutInflater; | |||
import android.view.Menu; | |||
import android.view.MenuItem; | |||
import android.view.View; | |||
import android.view.ViewGroup; | |||
import android.widget.AdapterView; | |||
import android.widget.ArrayAdapter; | |||
import android.widget.ImageButton; | |||
import android.widget.ImageView; | |||
import android.widget.ListView; | |||
import android.widget.TextView; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import fr.mobdev.gobelim.Database; | |||
import fr.mobdev.gobelim.dialog.ServerDialog; | |||
import fr.mobdev.gobelim.listener.ServerListener; | |||
import fr.mobdev.gobelim.objects.Server; | |||
import fr.mobdev.gobelim.R; | |||
public class ServersActivity extends ActionBarActivity { | |||
private List<Server> dbServers; | |||
private View.OnClickListener listener; | |||
@Override | |||
protected void onCreate(Bundle savedInstanceState) { | |||
super.onCreate(savedInstanceState); | |||
setContentView(R.layout.servers); | |||
ListView serverList = (ListView) findViewById(R.id.servers_list); | |||
serverList.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { | |||
@Override | |||
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { | |||
//find oldDefault | |||
Server oldDefaultServer = null; | |||
for(Server server : dbServers) | |||
{ | |||
if(server.isDefaultServer()) | |||
{ | |||
oldDefaultServer = server; | |||
break; | |||
} | |||
} | |||
Server newDefaultServer = dbServers.get(position); | |||
if(oldDefaultServer == null) { | |||
Database.getInstance(getApplicationContext()).setDefaultServer(newDefaultServer.getId(),-1); | |||
} | |||
else { | |||
Database.getInstance(getApplicationContext()).setDefaultServer(newDefaultServer.getId(), oldDefaultServer.getId()); | |||
} | |||
updateServers(); | |||
return true; | |||
} | |||
}); | |||
listener = new View.OnClickListener() { | |||
@Override | |||
public void onClick(View v) { | |||
ListView serverList = (ListView) findViewById(R.id.servers_list); | |||
Integer pos = (Integer)v.getTag(); | |||
if(pos == null) | |||
return; | |||
final Server server = dbServers.get(pos.intValue()); | |||
//ask delete | |||
AlertDialog.Builder builder = new AlertDialog.Builder(ServersActivity.this); | |||
builder.setMessage(getString(R.string.delete_server_message)+" "+server.getUrl()) | |||
.setCancelable(false) | |||
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { | |||
public void onClick(DialogInterface dialog, int id) { | |||
dbServers.remove(server); | |||
Database.getInstance(getApplicationContext()).deleteServer(server.getId()); | |||
updateServers(); | |||
} | |||
}) | |||
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { | |||
public void onClick(DialogInterface dialog, int id) { | |||
dialog.cancel(); | |||
} | |||
}); | |||
AlertDialog alert = builder.create(); | |||
alert.show(); | |||
} | |||
}; | |||
updateServers(); | |||
} | |||
private void updateServers() | |||
{ | |||
dbServers = Database.getInstance(getApplicationContext()).getServers(false); | |||
ServerAdapter adapter = new ServerAdapter(this,R.layout.server_item,R.id.server_name,dbServers,listener); | |||
ListView serverList = (ListView) findViewById(R.id.servers_list); | |||
serverList.setAdapter(adapter); | |||
} | |||
@Override | |||
public boolean onCreateOptionsMenu(Menu menu) { | |||
getMenuInflater().inflate(R.menu.menu_servers, menu); | |||
return true; | |||
} | |||
@Override | |||
public boolean onOptionsItemSelected(MenuItem item) { | |||
int id = item.getItemId(); | |||
if (id == R.id.action_add_server) { | |||
ServerDialog serverDialog = new ServerDialog(); | |||
ServerListener serverListener = new ServerListener() { | |||
@Override | |||
public void updateServerList() { | |||
updateServers(); | |||
} | |||
}; | |||
serverDialog.setServerListener(serverListener); | |||
serverDialog.show(getSupportFragmentManager(),"Server Dialog"); | |||
return true; | |||
} | |||
return super.onOptionsItemSelected(item); | |||
} | |||
private class ServerAdapter extends ArrayAdapter<Server> | |||
{ | |||
private List<Server> servers; | |||
private LayoutInflater mInflater; | |||
private View.OnClickListener listener; | |||
int resource; | |||
public ServerAdapter(Context context, int resource, int textViewResourceId, List<Server> objects, View.OnClickListener listener) { | |||
super(context, resource, textViewResourceId, objects); | |||
servers = new ArrayList(objects); | |||
this.listener = listener; | |||
this.resource = resource; | |||
mInflater = LayoutInflater.from(context); | |||
} | |||
@Override | |||
public View getView(int position, View convertView, ViewGroup parent) | |||
{ | |||
Server server = servers.get(position); | |||
if (convertView == null) { | |||
convertView = mInflater.inflate(resource, parent, false); | |||
} | |||
TextView view = (TextView) convertView.findViewById(R.id.server_name); | |||
if(server.isDefaultServer()) { | |||
Typeface typeface = view.getTypeface(); | |||
Typeface newTypeface = Typeface.create(typeface,Typeface.BOLD); | |||
view.setTypeface(newTypeface); | |||
} | |||
view.setText(server.getUrl()); | |||
ImageView delete = (ImageView) convertView.findViewById(R.id.server_delete); | |||
delete.setOnClickListener(listener); | |||
delete.setTag(Integer.valueOf(position)); | |||
return convertView; | |||
} | |||
} | |||
} |
@@ -0,0 +1,67 @@ | |||
package fr.mobdev.gobelim.dialog; | |||
import android.app.AlertDialog; | |||
import android.app.Dialog; | |||
import android.content.DialogInterface; | |||
import android.os.Bundle; | |||
import android.support.v4.app.DialogFragment; | |||
import android.view.LayoutInflater; | |||
import android.view.View; | |||
import android.widget.EditText; | |||
import android.widget.Spinner; | |||
import fr.mobdev.gobelim.Database; | |||
import fr.mobdev.gobelim.listener.ServerListener; | |||
import fr.mobdev.gobelim.R; | |||
public class ServerDialog extends DialogFragment { | |||
private static final int HTTP_POSITION = 0; | |||
private static final int HTTPS_POSITION = 1; | |||
private ServerListener listener; | |||
public void setServerListener(ServerListener listener) | |||
{ | |||
this.listener = listener; | |||
} | |||
@Override | |||
public Dialog onCreateDialog(Bundle savedInstanceState) | |||
{ | |||
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); | |||
LayoutInflater inflater = getActivity().getLayoutInflater(); | |||
final View view = inflater.inflate(R.layout.server_dialog, null); | |||
EditText urlText = (EditText) view.findViewById(R.id.url_text); | |||
//mask for url? | |||
builder.setView(view) | |||
.setTitle(R.string.server_title) | |||
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { | |||
@Override | |||
public void onClick(DialogInterface dialog, int which) { | |||
String url = "http"; | |||
Spinner httpSpinner = (Spinner) view.findViewById(R.id.http_spinner); | |||
if(httpSpinner.getSelectedItemPosition() == HTTPS_POSITION) | |||
url += "s"; | |||
url +="://"; | |||
EditText urlText = (EditText) view.findViewById(R.id.url_text); | |||
if(urlText.getText().length() > 0) | |||
url += urlText.getText(); | |||
Database.getInstance(getActivity().getApplicationContext()).addServer(url); | |||
listener.updateServerList(); | |||
dismiss(); | |||
} | |||
}) | |||
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { | |||
@Override | |||
public void onClick(DialogInterface dialog, int which) { | |||
dismiss(); | |||
} | |||
}); | |||
return builder.create(); | |||
} | |||
} |
@@ -0,0 +1,11 @@ | |||
package fr.mobdev.gobelim.listener; | |||
import java.util.EventListener; | |||
import java.util.List; | |||
import fr.mobdev.gobelim.objects.Img; | |||
public interface NetworkListener extends EventListener{ | |||
void fileUploaded(Img image); | |||
void fileUploadError(String error); | |||
} |
@@ -0,0 +1,7 @@ | |||
package fr.mobdev.gobelim.listener; | |||
import java.util.EventListener; | |||
public interface ServerListener extends EventListener { | |||
public void updateServerList(); | |||
} |
@@ -0,0 +1,77 @@ | |||
package fr.mobdev.gobelim.objects; | |||
import android.graphics.Bitmap; | |||
import java.io.ByteArrayOutputStream; | |||
import java.util.Calendar; | |||
public class Img { | |||
private Long id; | |||
private String url; | |||
private Calendar date; | |||
private int storageDuration; | |||
private Bitmap image; | |||
private String shortHash; | |||
private String realShortHash; | |||
public Img(long id, String url, String shortHash, String realShortHash, Calendar date, int storageDuration, byte[] thumbData) { | |||
this.url = url; | |||
this.shortHash = shortHash; | |||
this.id = id; | |||
this.realShortHash = realShortHash; | |||
this.date = date; | |||
this.storageDuration = storageDuration; | |||
} | |||
public Long getId() | |||
{ | |||
return id; | |||
} | |||
public String getUrl() | |||
{ | |||
return url; | |||
} | |||
public Calendar getDate() | |||
{ | |||
return date; | |||
} | |||
public Bitmap getThumb() | |||
{ | |||
return image; | |||
} | |||
public String getShortHash() | |||
{ | |||
return shortHash; | |||
} | |||
public String getRealShortHash() | |||
{ | |||
return realShortHash; | |||
} | |||
public int getStorageDuration() | |||
{ | |||
return storageDuration; | |||
} | |||
public byte[] getThumbData() | |||
{ | |||
if(image != null) { | |||
ByteArrayOutputStream stream = new ByteArrayOutputStream(); | |||
image.compress(Bitmap.CompressFormat.PNG, 100, stream); | |||
byte[] byteArray = stream.toByteArray(); | |||
return byteArray; | |||
} | |||
else { | |||
return null; | |||
} | |||
} | |||
} |
@@ -0,0 +1,31 @@ | |||
package fr.mobdev.gobelim.objects; | |||
public class Server { | |||
private long id; | |||
private String url; | |||
private boolean defaultServer; | |||
public Server(long id, String url, boolean defaultServer) | |||
{ | |||
this.id = id; | |||
this.url = url; | |||
this.defaultServer = defaultServer; | |||
} | |||
public String getUrl() | |||
{ | |||
return url; | |||
} | |||
public long getId() | |||
{ | |||
return id; | |||
} | |||
public boolean isDefaultServer() | |||
{ | |||
return defaultServer; | |||
} | |||
} |
@@ -0,0 +1,13 @@ | |||
<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.gobelim.activity.HistoryActivity"> | |||
<ListView | |||
android:id="@+id/history_list" | |||
android:layout_width="match_parent" | |||
android:layout_height="match_parent"/> | |||
</RelativeLayout> |
@@ -0,0 +1,40 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||
android:layout_width="match_parent" | |||
android:layout_height="100dp" | |||
android:layout_gravity="center_vertical"> | |||
<LinearLayout | |||
android:layout_alignParentRight="true" | |||
android:id="@+id/date_duration_layout" | |||
android:orientation="vertical" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content"> | |||
<TextView | |||
android:id="@+id/date" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" /> | |||
<TextView | |||
android:textColor="#FF0000" | |||
android:id="@+id/duration" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" /> | |||
</LinearLayout> | |||
<ImageView | |||
android:id="@+id/thumbnail" | |||
android:layout_alignParentLeft="true" | |||
android:layout_width="100dp" | |||
android:layout_height="100dp" /> | |||
<TextView | |||
android:gravity="center_vertical" | |||
android:layout_toLeftOf="@+id/date_duration_layout" | |||
android:layout_toRightOf="@+id/thumbnail" | |||
android:textAppearance="?android:attr/textAppearanceMedium" | |||
android:id="@+id/url_history_item" | |||
android:layout_width="wrap_content" | |||
android:layout_height="match_parent" /> | |||
</RelativeLayout> |
@@ -0,0 +1,45 @@ | |||
<LinearLayout 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.gobelim.activity.LinkActivity" | |||
android:orientation="vertical" | |||
android:gravity="center"> | |||
<TextView | |||
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:gravity="center" | |||
android:id="@+id/buttons_layout" | |||
android:orientation="horizontal" | |||
android:layout_width="match_parent" | |||
android:layout_height="wrap_content" | |||
> | |||
<ImageButton | |||
android:id="@+id/copy_clipboard_button" | |||
android:src="@drawable/abc_ic_menu_copy_mtrl_am_alpha" | |||
android:layout_width="60dp" | |||
android:layout_height="60dp" | |||
/> | |||
<ImageButton | |||
android:src="@android:drawable/ic_menu_share" | |||
android:id="@+id/share_button" | |||
android:layout_width="60dp" | |||
android:layout_height="60dp" | |||
/> | |||
</LinearLayout> | |||
</LinearLayout> |
@@ -0,0 +1,67 @@ | |||
<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=".MainActivity"> | |||
<Button | |||
android:layout_width="match_parent" | |||
android:layout_height="wrap_content" | |||
android:text="@string/upload_pict" | |||
android:id="@+id/upload_button" | |||
android:layout_alignParentBottom="true" | |||
android:layout_centerHorizontal="true" | |||
android:layout_marginTop="25dp" | |||
/> | |||
<Button | |||
android:layout_above="@+id/upload_button" | |||
android:layout_width="match_parent" | |||
android:layout_height="wrap_content" | |||
android:text="@string/select_pict" | |||
android:id="@+id/select_button" | |||
android:layout_alignParentBottom="true" | |||
android:layout_centerHorizontal="true" | |||
android:layout_marginTop="25dp" | |||
/> | |||
<LinearLayout | |||
android:orientation="horizontal" | |||
android:layout_above="@+id/select_button" | |||
android:id="@+id/layout_days" | |||
android:layout_width="match_parent" | |||
android:layout_height="wrap_content" | |||
android:layout_marginTop="25dp" | |||
android:gravity="center_vertical" | |||
> | |||
<TextView | |||
android:text="@string/duration" | |||
android:singleLine="false" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:layout_marginLeft="15dp"/> | |||
<Spinner | |||
android:layout_width="match_parent" | |||
android:layout_height="wrap_content" | |||
android:id="@+id/delete_day_spinner" | |||
android:entries="@array/deleted_days" | |||
/> | |||
</LinearLayout> | |||
<Spinner | |||
android:layout_above="@+id/layout_days" | |||
android:layout_width="match_parent" | |||
android:layout_height="wrap_content" | |||
android:id="@+id/servers_spinner" | |||
android:layout_marginTop="25dp" | |||
/> | |||
<ImageView | |||
android:layout_above="@+id/servers_spinner" | |||
android:id="@+id/thumbnail_main" | |||
android:layout_width="match_parent" | |||
android:layout_height="wrap_content" | |||
android:layout_alignParentTop="true" | |||
android:layout_centerHorizontal="true" | |||
/> | |||
</RelativeLayout> |
@@ -0,0 +1,21 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||
android:orientation="horizontal" android:layout_width="match_parent" | |||
android:layout_height="match_parent"> | |||
<Spinner | |||
android:id="@+id/http_spinner" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" | |||
android:entries="@array/https" | |||
/> | |||
<EditText | |||
android:id="@+id/url_text" | |||
android:layout_width="match_parent" | |||
android:layout_height="wrap_content" | |||
android:hint="@string/url" | |||
android:inputType="textUri" | |||
/> | |||
</LinearLayout> |
@@ -0,0 +1,20 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" | |||
android:layout_width="match_parent" | |||
android:layout_height="match_parent"> | |||
<ImageView | |||
android:layout_alignParentRight="true" | |||
android:layout_alignParentTop="true" | |||
android:src="@android:drawable/ic_delete" | |||
android:id="@+id/server_delete" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" /> | |||
<TextView | |||
android:layout_toLeftOf="@+id/server_delete" | |||
android:textAppearance="?android:attr/textAppearanceMedium" | |||
android:id="@+id/server_name" | |||
android:layout_alignParentLeft="true" | |||
android:layout_alignParentTop="true" | |||
android:layout_width="wrap_content" | |||
android:layout_height="wrap_content" /> | |||
</RelativeLayout> |
@@ -0,0 +1,15 @@ | |||
<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.gobelim.activity.ServersActivity"> | |||
<ListView | |||
android:id="@+id/servers_list" | |||
android:layout_width="match_parent" | |||
android:layout_height="match_parent" | |||
android:choiceMode="singleChoice" | |||
/> | |||
</RelativeLayout> |
@@ -0,0 +1,14 @@ | |||
<menu xmlns:android="http://schemas.android.com/apk/res/android" | |||
xmlns:app="http://schemas.android.com/apk/res-auto" | |||
xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity"> | |||
<item | |||
android:icon="@android:drawable/ic_menu_manage" | |||
android:id="@+id/action_manage_server" | |||
android:title="@string/manage_server" | |||
app:showAsAction="ifRoom" /> | |||
<item | |||
android:icon="@android:drawable/ic_menu_recent_history" | |||
android:id="@+id/action_show_history" | |||
android:title="@string/show_history" | |||
app:showAsAction="ifRoom" /> | |||
</menu> |
@@ -0,0 +1,8 @@ | |||
<menu xmlns:android="http://schemas.android.com/apk/res/android" | |||
xmlns:app="http://schemas.android.com/apk/res-auto" | |||
xmlns:tools="http://schemas.android.com/tools" tools:context="fr.mobdev.gobelim.activity.ServersActivity"> | |||
<item android:id="@+id/action_add_server" | |||
android:icon="@android:drawable/ic_menu_add" | |||
android:title="@string/add_server" | |||
app:showAsAction="ifRoom" /> | |||
</menu> |
@@ -0,0 +1,6 @@ | |||
<resources> | |||
<!-- Example customization of dimensions originally defined in res/values/dimens.xml | |||
(such as screen margins) for screens with more than 820dp of available width. This | |||
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). --> | |||
<dimen name="activity_horizontal_margin">64dp</dimen> | |||
</resources> |
@@ -0,0 +1,5 @@ | |||
<resources> | |||
<!-- Default screen margins, per the Android Design guidelines. --> | |||
<dimen name="activity_horizontal_margin">16dp</dimen> | |||
<dimen name="activity_vertical_margin">16dp</dimen> | |||
</resources> |
@@ -0,0 +1,36 @@ | |||
<resources> | |||
<string name="app_name">Gobelim</string> | |||
<string name="action_settings">Paramètres</string> | |||
<string name="title_activity_share">Partager</string> | |||
<string name="title_activity_history">Historique</string> | |||
<string name="title_activity_link">Partager le lien</string> | |||
<string name="title_activity_servers">Liste des serveurs</string> | |||
<string name="upload_pict">Envoyer</string> | |||
<string name="select_pict">Selectionner une Image</string> | |||
<string name="duration">durée de\nConservation</string> | |||
<string name="copy_to_clipboard">Lien copié dans le presse-papier</string> | |||
<string name="server_title">Ajouter un serveur</string> | |||
<string name="url">Adresse du site</string> | |||
<string name="add_server">Ajouter un serveur</string> | |||
<string name="manage_server">Gérer les serveurs</string> | |||
<string name="show_history">Voir l\'historique</string> | |||
<string name="delete_server_message">Supprimer le server</string> | |||
<string name="upload_progress">Envoi en cours</string> | |||
<string name="no_duration"></string> | |||
<string name="duration_ended">Supprimée</string> | |||
<string name="days">Jours restants</string> | |||
<string name="day">Jour restant</string> | |||
<string name="server_list_error">Vous n\t fetch'avez aucun serveur configuré, merci d\'en ajouter un</string> | |||
<string-array name="deleted_days"> | |||
<item>Pas de limitation</item> | |||
<item>24 Heures</item> | |||
<item>7 Jours</item> | |||
<item>30 Jours</item> | |||
<item>1 an</item> | |||
</string-array> | |||
<string-array name="https"> | |||
<item>http://</item> | |||
<item>https://</item> | |||
</string-array> | |||
</resources> |
@@ -0,0 +1,8 @@ | |||
<resources> | |||
<!-- Base application theme. --> | |||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> | |||
<!-- Customize your theme here. --> | |||
</style> | |||
</resources> |
@@ -0,0 +1,19 @@ | |||
// Top-level build file where you can add configuration options common to all sub-projects/modules. | |||
buildscript { | |||
repositories { | |||
jcenter() | |||
} | |||
dependencies { | |||
classpath 'com.android.tools.build:gradle:1.2.3' | |||
// NOTE: Do not place your application dependencies here; they belong | |||
// in the individual module build.gradle files | |||
} | |||
} | |||
allprojects { | |||
repositories { | |||
jcenter() | |||
} | |||
} |
@@ -0,0 +1,6 @@ | |||
#Wed Apr 10 15:27:10 PDT 2013 | |||
distributionBase=GRADLE_USER_HOME | |||
distributionPath=wrapper/dists | |||
zipStoreBase=GRADLE_USER_HOME | |||
zipStorePath=wrapper/dists | |||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip |
@@ -0,0 +1 @@ | |||
include ':app' |