Working on vocabulary management from PCB

parent 3e0c1d65
...@@ -70,5 +70,6 @@ dependencies { ...@@ -70,5 +70,6 @@ dependencies {
compile 'com.github.nkzawa:socket.io-client:0.5.0' compile 'com.github.nkzawa:socket.io-client:0.5.0'
compile 'com.koushikdutta.async:androidasync:2.+' compile 'com.koushikdutta.async:androidasync:2.+'
compile 'com.android.support:support-v4:21.0.+' compile 'com.android.support:support-v4:21.0.+'
compile 'com.koushikdutta.ion:ion:2.+' //required for upload images
} }
...@@ -66,14 +66,15 @@ public class UploadActivity extends Activity { ...@@ -66,14 +66,15 @@ public class UploadActivity extends Activity {
if (e == null) if (e == null)
Log.i(this.getClass().getCanonicalName(), " Uploaded to " + context.getResources().getString(R.string.server) + " " + result); Log.i(this.getClass().getCanonicalName(), " Uploaded to " + context.getResources().getString(R.string.server) + " " + result);
else else
Log.e(this.getClass().getCanonicalName(), "error uploading"); Log.e(this.getClass().getCanonicalName(), "Upload error:" + e.getMessage());
if (result != null) if (result != null)
Log.i(this.getClass().getCanonicalName(), result.toString()); Log.i(this.getClass().getCanonicalName(), "Upload result:" + result.toString());
else else
Log.i(this.getClass().getCanonicalName(), "no result"); Log.i(this.getClass().getCanonicalName(), "no result");
} }
}); });
ion.dump();
Log.i(this.getClass().getCanonicalName(), " Uploading 3 "); Log.i(this.getClass().getCanonicalName(), " Uploading 3 ");
ion.dump();
} }
} }
...@@ -23,7 +23,8 @@ import java.util.LinkedList; ...@@ -23,7 +23,8 @@ import java.util.LinkedList;
* @see Room * @see Room
*/ */
public class Action { public class Action {
private String type;
protected String type;
/** /**
* It creates an action for any user, both online and offline actions. * It creates an action for any user, both online and offline actions.
......
...@@ -23,10 +23,6 @@ import java.util.LinkedList; ...@@ -23,10 +23,6 @@ import java.util.LinkedList;
* @see Room * @see Room
*/ */
public class PictoAction extends Action { public class PictoAction extends Action {
private String type;
private String timestamp;
private int id_sup;
private int id_stu;
private Picto picto; private Picto picto;
private float gps_lat; private float gps_lat;
private float gps_lon; private float gps_lon;
...@@ -48,7 +44,7 @@ public class PictoAction extends Action { ...@@ -48,7 +44,7 @@ public class PictoAction extends Action {
super(type); super(type);
this.picto=picto; this.picto=picto;
} }
@Override
public JSONObject get_json(){ public JSONObject get_json(){
final String param_picto="picto"; final String param_picto="picto";
try { try {
......
...@@ -23,10 +23,6 @@ import java.util.LinkedList; ...@@ -23,10 +23,6 @@ import java.util.LinkedList;
* @see Room * @see Room
*/ */
public class PictosAction extends Action { public class PictosAction extends Action {
private String type;
private String timestamp;
private int id_sup;
private int id_stu;
LinkedList<Picto> pictos; LinkedList<Picto> pictos;
private float gps_lat; private float gps_lat;
private float gps_lon; private float gps_lon;
...@@ -45,7 +41,7 @@ public class PictosAction extends Action { ...@@ -45,7 +41,7 @@ public class PictosAction extends Action {
this.pictos=pictos; this.pictos=pictos;
} }
@Override
public JSONObject get_json() { public JSONObject get_json() {
final String param_pictos="pictos"; final String param_pictos="pictos";
try{ try{
......
package com.yottacode.pictogram.action;
import android.util.Log;
import com.yottacode.pictogram.dao.Picto;
import com.yottacode.pictogram.tools.PCBcontext;
import org.json.JSONException;
import org.json.JSONObject;
/**
* The vocabulary is modified from the PCB by a supervisor for a given student
* @author Fernando Martinez Santiago
* @version 1.0
* @see Room
*/
public class VocabularyAction extends Action {
Picto picto;
//Picto Action types
public static final String ADD="Vocabulay_Add";
public static final String DELETE="Vocabulay_Delete";
public static final String DISABLE="Vocabulay_Disable";
public static final String ENABLE="Vocabulay_Enable";
/**
* It creates an action for any user regarding a picto, both online and offline actions.
*
* @param type
* @param picto
*/
public VocabularyAction(String type, Picto picto){
super(type);
this.picto=picto;
}
@Override
public JSONObject get_json(){
final String param_picto="picto";
try {
return super.get_json().put(param_picto, this.get_json_picto());
}catch(JSONException e) {
Log.e(this.getClass().getCanonicalName(),e.getLocalizedMessage());
return null;
}
}
public JSONObject get_json_picto() throws JSONException {
final String param_id_json="id";
final String param_picto="picto";
final String param_expression="expression";
final String param_expr_lang="lang";
final String param_expr_text="text";
final String param_attrs="attributes";
final String param_picto_id="id";
final String param_picto_uri="uri";
final String param_picto_cat="category";
JSONObject subsubPicto = new JSONObject().put(param_picto_id, picto.get_id())
.put(param_picto_uri, picto.get_url())
.put(param_picto_cat, picto.get_category());
JSONObject attributes = new JSONObject(picto.get_json_attrs());
JSONObject expression = new JSONObject().put(param_expr_lang,PCBcontext.getPcbdb().getCurrentUser().get_lang_stu())
.put(param_expr_text,picto.get_translation());
JSONObject subPicto = new JSONObject().put(param_id_json, 1470)
.put(param_picto, subsubPicto)
.put(param_expression,expression)
.put(param_attrs, attributes);
return subPicto;
}
}
\ No newline at end of file
...@@ -14,10 +14,9 @@ import java.io.BufferedReader; ...@@ -14,10 +14,9 @@ import java.io.BufferedReader;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Vector; import java.util.Vector;
import com.yottacode.pictogram.action.Action;
import com.yottacode.pictogram.tools.Img; import com.yottacode.pictogram.tools.Img;
import com.yottacode.pictogram.net.ImgDownloader; import com.yottacode.pictogram.net.ImgDownloader;
import com.yottacode.pictogram.net.iImgDownloaderListener; import com.yottacode.pictogram.net.iImgDownloaderListener;
...@@ -26,7 +25,7 @@ import org.json.JSONException; ...@@ -26,7 +25,7 @@ import org.json.JSONException;
/** /**
* Data Access Object to manage Pictogram Communicator Board database * Data Access Object to manage Pictogram Communicator Board database regarding App information that is not user-dependent
* This class requires: * This class requires:
* The script to create the DB allocated in res/raw/pcbdb_create.sql * The script to create the DB allocated in res/raw/pcbdb_create.sql
* The entries db_name and db_script_error in strings.xml * The entries db_name and db_script_error in strings.xml
...@@ -287,7 +286,7 @@ public class Device extends SQLiteOpenHelper { ...@@ -287,7 +286,7 @@ public class Device extends SQLiteOpenHelper {
* @see com.yottacode.pictogram.dao.PCBDBHelper * @see com.yottacode.pictogram.dao.PCBDBHelper
*/ */
public void synchronizeUsers(Vector<User> users, iImgDownloaderListener imgListener) throws JSONException { public void synchronizeUsers(Vector<User> users, iImgDownloaderListener imgListener) throws JSONException {
Log.d("LoginActivity", "1:" + new SimpleDateFormat("HH:mm:ss"));
Vector<User> prev_users = getUsers(); Vector<User> prev_users = getUsers();
Vector<Img> imgs = new Vector<Img>(users.size() * 2); Vector<Img> imgs = new Vector<Img>(users.size() * 2);
...@@ -306,11 +305,12 @@ public class Device extends SQLiteOpenHelper { ...@@ -306,11 +305,12 @@ public class Device extends SQLiteOpenHelper {
} }
for (User user : prev_users) for (User user : prev_users)
db.execSQL("DELETE FROM users_detail WHERE id_stu=" + user.get_id_stu() + " AND id_sup=" + user.get_id_sup()); db.delete("users_detail","id_stu=? AND id_sup=?",new String[]{Integer.toString(user.get_id_stu()),Integer.toString(user.get_id_sup())});
ImgDownloader downloader = new ImgDownloader(this.context, imgListener); ImgDownloader downloader = new ImgDownloader(this.context, imgListener, ImgDownloader.source.remote );
downloader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,imgs); downloader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,imgs);
db.close(); db.close();
} }
...@@ -374,6 +374,24 @@ public class Device extends SQLiteOpenHelper { ...@@ -374,6 +374,24 @@ public class Device extends SQLiteOpenHelper {
db.close(); db.close();
return path; return path;
} }
/**
* get the next local id for a new local pictogram
*
* @see com.yottacode.pictogram.dao.Picto
*/
public int getNextLocalPictoID() {
SQLiteDatabase db = this.getReadableDatabase();
int next_key;
Cursor cursor = db.query("picto", new String[]{"MIN(id)"}, null, null, null, null, null, "1");
cursor.moveToFirst();
next_key=cursor.getInt(1)-1;
cursor.close();
db.close();
return next_key;
}
@Override @Override
public void onCreate(SQLiteDatabase db) throws RuntimeException { public void onCreate(SQLiteDatabase db) throws RuntimeException {
......
...@@ -26,6 +26,7 @@ import org.json.JSONObject; ...@@ -26,6 +26,7 @@ import org.json.JSONObject;
/** /**
* Platform abstraction (Android) * Platform abstraction (Android)
* @see PCBDBHelper
* * * *
* *
* @author Fernando Martinez Santiago * @author Fernando Martinez Santiago
...@@ -50,7 +51,7 @@ class DeviceHelper { ...@@ -50,7 +51,7 @@ class DeviceHelper {
} }
/** /**
* Data Access Object to manage Pictogram Communicator Board database * Data Access Object to manage Pictogram Communicator Board database regarding a logged user
* This class requires: * This class requires:
* The script to create the DB allocated in res/raw/pcbdb_create.sql * The script to create the DB allocated in res/raw/pcbdb_create.sql
* The entries db_name and db_script_error in strings.xml * The entries db_name and db_script_error in strings.xml
...@@ -132,7 +133,7 @@ public class PCBDBHelper extends SQLiteOpenHelper { ...@@ -132,7 +133,7 @@ public class PCBDBHelper extends SQLiteOpenHelper {
public void insertAction(Action action) { public void insertAction(Action action) {
SQLiteDatabase db = this.getWritableDatabase(); SQLiteDatabase db = this.getWritableDatabase();
ContentValues values=new ContentValues(1); ContentValues values=new ContentValues(1);
values.put("json_action",action.getDescription().toString()); values.put("json_action", action.getDescription().toString());
db.insert("action", null, values); db.insert("action", null, values);
db.close(); db.close();
} }
...@@ -188,6 +189,9 @@ public class PCBDBHelper extends SQLiteOpenHelper { ...@@ -188,6 +189,9 @@ public class PCBDBHelper extends SQLiteOpenHelper {
return vocabulary; return vocabulary;
} }
/** /**
* Set/update the set of pictos of the current student. Pictos which are no longer used are dropped from the DB * Set/update the set of pictos of the current student. Pictos which are no longer used are dropped from the DB
* *
...@@ -242,7 +246,11 @@ public class PCBDBHelper extends SQLiteOpenHelper { ...@@ -242,7 +246,11 @@ public class PCBDBHelper extends SQLiteOpenHelper {
public void deletePicto(int picto_id) { public void deletePicto(int picto_id) {
int id_stu = this.getCurrentUser().get_id_stu(); int id_stu = this.getCurrentUser().get_id_stu();
SQLiteDatabase db = this.getWritableDatabase(); SQLiteDatabase db = this.getWritableDatabase();
db.execSQL("DELETE FROM collection WHERE id_stu=" + id_stu + " AND id_picto=" + picto_id);
db.delete("collection","id_stu=? AND id_sup=? AND id_picto=?",
new String[]{ Integer.toString(this.currentUser.get_id_stu()),
Integer.toString(this.currentUser.get_id_sup()),
Integer.toString(picto_id)});
db.close(); db.close();
} }
/** /**
......
...@@ -39,7 +39,9 @@ public class Picto extends Img { ...@@ -39,7 +39,9 @@ public class Picto extends Img {
private JSONObject attributes; private JSONObject attributes;
private String translation; private String translation;
public Picto(int id, String translation, int cat, int column, int row) throws JSONException {
this(id, null, translation, new JSONObject().put(JSON_ATTTRS.CATEGORY,cat).put(JSON_ATTTRS.COLUMN,column).put(JSON_ATTTRS.ROW,row));
}
public Picto(int id, String url,String translation, String attributes) throws JSONException { public Picto(int id, String url,String translation, String attributes) throws JSONException {
this(id, url, translation, new JSONObject(attributes)); this(id, url, translation, new JSONObject(attributes));
} }
......
...@@ -4,8 +4,12 @@ import android.os.AsyncTask; ...@@ -4,8 +4,12 @@ import android.os.AsyncTask;
import android.os.Environment; import android.os.Environment;
import android.util.Log; import android.util.Log;
import com.google.gson.JsonObject;
import com.yottacode.pictogram.dao.PCBDBHelper;
import com.yottacode.pictogram.dao.Picto; import com.yottacode.pictogram.dao.Picto;
import com.yottacode.pictogram.net.ImgDownloader; import com.yottacode.pictogram.net.ImgDownloader;
import com.yottacode.pictogram.net.ImgUploader;
import com.yottacode.pictogram.net.iImgUploaderListener;
import com.yottacode.pictogram.tools.Img; import com.yottacode.pictogram.tools.Img;
import com.yottacode.net.iRestapiListener; import com.yottacode.net.iRestapiListener;
import com.yottacode.pictogram.action.Room; import com.yottacode.pictogram.action.Room;
...@@ -20,7 +24,9 @@ import java.io.File; ...@@ -20,7 +24,9 @@ import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.InputMismatchException;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.Set; import java.util.Set;
...@@ -81,7 +87,7 @@ public class Vocabulary implements Iterable<Picto> { ...@@ -81,7 +87,7 @@ public class Vocabulary implements Iterable<Picto> {
String uri=args.getJSONObject("picto").getString("uri"); String uri=args.getJSONObject("picto").getString("uri");
JSONObject attrs_picto = args.getJSONObject("attributes"); JSONObject attrs_picto = args.getJSONObject("attributes");
addPicto(new Picto(picto_id, uri, text, attrs_picto)); addPicto(new Picto(picto_id, uri, text, attrs_picto),ImgDownloader.source.remote);
} catch (JSONException e) { } catch (JSONException e) {
Log.e(this.getClass().getCanonicalName(), e.getClass().getCanonicalName() + "--" + e); Log.e(this.getClass().getCanonicalName(), e.getClass().getCanonicalName() + "--" + e);
...@@ -162,7 +168,6 @@ public class Vocabulary implements Iterable<Picto> { ...@@ -162,7 +168,6 @@ public class Vocabulary implements Iterable<Picto> {
Vector<Img> imgs=new Vector<Img>(updated_collection.length); Vector<Img> imgs=new Vector<Img>(updated_collection.length);
this.pictos.clear(); this.pictos.clear();
for (Picto updated_picto: updated_collection) { for (Picto updated_picto: updated_collection) {
LinkedList<Picto> pictos_cat; LinkedList<Picto> pictos_cat;
...@@ -180,43 +185,118 @@ public class Vocabulary implements Iterable<Picto> { ...@@ -180,43 +185,118 @@ public class Vocabulary implements Iterable<Picto> {
imgs.add(new Img(picto.get_id(), picto.get_url(), Img.VOCABULARY)); imgs.add(new Img(picto.get_id(), picto.get_url(), Img.VOCABULARY));
} }
Log.d(this.getClass().getName(), "Vocabulary size: " + updated_collection.length); Log.d(this.getClass().getName(), "Vocabulary size: " + updated_collection.length);
ImgDownloader downloader = new ImgDownloader(PCBcontext.getContext(), imgListener); ImgDownloader downloader = new ImgDownloader(PCBcontext.getContext(), imgListener,ImgDownloader.source.remote);
downloader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, imgs); downloader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, imgs);
PCBcontext.getPcbdb().setStudentVocabulary(this); PCBcontext.getPcbdb().setStudentVocabulary(this);
} }
public int size() { return this.pictos.size();} public int size() { return this.pictos.size();}
/** /**
* It includes/updates a new picto to the user collection: download de image, add the picto to the current vocabulary and update the database * It includes/updates a new picto to the user collection: download the image from remote or local storage, add the picto to the current vocabulary and update the database
* @param pic * @param pic
*/ */
public void addPicto(Picto pic){ public void addPicto(Picto pic, ImgDownloader.source source){
Vector<Img> imgs=new Vector<Img>(1); Vector<Img> imgs=new Vector<Img>(1);
imgs.add(new Img(pic.get_id(), pic.get_url(), Img.VOCABULARY)); imgs.add(new Img(pic.get_id(), pic.get_url(), Img.VOCABULARY));
ImgDownloader downloader = new ImgDownloader(PCBcontext.getContext(), imgListener); ImgDownloader downloader = new ImgDownloader(PCBcontext.getContext(), imgListener,source);
downloader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, imgs); downloader.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, imgs);
loadPicto(pic); loadPicto(pic);
PCBcontext.getPcbdb().addPicto(pic); PCBcontext.getPcbdb().addPicto(pic);
} }
/*
* It saves locally a new picto obtained from the PCB
*/
public void savePicto(String exp, int cat, int coord_x, int coord_y) {
int id=PCBcontext.getDevice().getNextLocalPictoID();
try {
Picto picto = new Picto(id, exp, cat, coord_x, coord_y);
addPicto(picto, ImgDownloader.source.local);
} catch (JSONException e) {
e.printStackTrace();
Log.e(Vocabulary.class.getCanonicalName(),e.getMessage());
}
}
/** /**
*TODO: to be finished and tried *TODO: Upload a local picto. It requires: i) to upload the image, ii) to upload the expression and iii) to include the picto to the current student vocabulary
*/ *
public void uploadPicto(String path, String name, String exp, int cat, int coord_x, int coord_y) throws IOException { **/
File file = new File(path); public void uploadPicto(final Picto picto) throws IOException {
File file = picto.file(PCBcontext.getContext());
FileInputStream imageInFile = new FileInputStream(file); FileInputStream imageInFile = new FileInputStream(file);
byte imageData[] = new byte[(int)file.length()]; byte imageData[] = new byte[(int)file.length()];
imageInFile.read(imageData); imageInFile.read(imageData);
Hashtable<String,String> params=new Hashtable<>(3); final Hashtable<String,String> params=new Hashtable<>(3);
params.put("filename", name);
params.put("folder", "custompictos"); ImgUploader uploader= new ImgUploader(PCBcontext.getContext());
params.put("id", String.valueOf(PCBcontext.getPcbdb().getCurrentUser().get_id_stu())); uploader.upload(picto, new iImgUploaderListener() {
params.put("file", String.valueOf(imageData)); @Override
public void complete(JsonObject result) {
PCBcontext.getRestapiWrapper().ask("upload", params, "post", null); Log.d(this.getClass().getCanonicalName(), "Uploaded img result: " + result.getAsString());
Hashtable<String, String> params=new Hashtable<String, String>(3);
params.put("id_cat",Integer.toString(picto.get_category()));
params.put("coord_x",Integer.toString(picto.get_column()));
params.put("coord_y",Integer.toString(picto.get_row()));
PCBcontext.getRestapiWrapper().ask("stu/"+PCBcontext.getPcbdb().getCurrentUser().get_id_stu()+"/picto", params, "post", new iRestapiListener() {
@Override
public void preExecute() {
}
@Override
public void result(JSONArray result) {
}
@Override
public void result(JSONObject result) {
Log.d(this.getClass().getCanonicalName(), "Uploaded picto result: " + result.toString());
int remoteid_picto=0;
Hashtable<String, String> params=new Hashtable<String, String>(3);
params.put("picto",Integer.toString(remoteid_picto));
params.put("lang",PCBcontext.getPcbdb().getCurrentUser().get_lang_stu());
params.put("text", picto.get_translation());
PCBcontext.getRestapiWrapper().ask("picto/exp", params, "post", new iRestapiListener() {
@Override
public void preExecute() {
}
@Override
public void result(JSONArray result) {
}
@Override
public void result(JSONObject result) {
PCBcontext.getPcbdb().deletePicto(picto.get_id());
}
@Override
public void error(Exception e) {
}
});
}
@Override
public void error(Exception e) {
}
});
}
@Override
public void error(Exception e, int http_code) {
Log.e("Upload", "Error: " + e.getLocalizedMessage() + " HTTP code:" + http_code);
for (StackTraceElement s : e.getStackTrace())
Log.e("Upload", s.toString());
}
});
} }
/** /**
......
...@@ -9,6 +9,8 @@ import android.util.Log; ...@@ -9,6 +9,8 @@ import android.util.Log;
import com.yottacode.pictogram.R; import com.yottacode.pictogram.R;
import com.yottacode.pictogram.tools.Img; import com.yottacode.pictogram.tools.Img;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URL; import java.net.URL;
...@@ -18,7 +20,7 @@ import java.util.Calendar; ...@@ -18,7 +20,7 @@ import java.util.Calendar;
import java.util.Vector; import java.util.Vector;
/** /**
* Image downloader from the server for pictograms and student's and supervisor's profile pictures. * Image downloader from the server or local for pictograms and student's and supervisor's profile pictures.
* Permissions required in AndroidManifest.xml: * Permissions required in AndroidManifest.xml:
* <uses-permission android:name="android.permission.INTERNET" /> * <uses-permission android:name="android.permission.INTERNET" />
...@@ -27,25 +29,27 @@ public class ImgDownloader extends AsyncTask<Vector<Img>, Void, Img> { ...@@ -27,25 +29,27 @@ public class ImgDownloader extends AsyncTask<Vector<Img>, Void, Img> {
iImgDownloaderListener imgListener; iImgDownloaderListener imgListener;
public static enum status {downloading, downloaded_ok, downloaded_failed} public static enum status {downloading, downloaded_ok, downloaded_failed}
public static enum source{remote,local}
public status current; public status current;
private boolean force_download; private boolean force_download;
Context context; Context context;
ActivityManager.MemoryInfo mi; ActivityManager.MemoryInfo mi;
ActivityManager activityManager; ActivityManager activityManager;
source source;
public ImgDownloader(Context context, iImgDownloaderListener listener, source source) {
public ImgDownloader(Context context, iImgDownloaderListener listener) {
this.imgListener = listener; this.imgListener = listener;
this.context=context; this.context=context;
this.mi = new ActivityManager.MemoryInfo(); this.mi = new ActivityManager.MemoryInfo();
this.activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); this.activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
this.force_download=context.getResources().getBoolean(R.bool.force_img_download); this.force_download=context.getResources().getBoolean(R.bool.force_img_download);
this.source=source;
} }
@Override @Override
protected void onPreExecute() { protected void onPreExecute() {
Log.d(this.getClass().getCanonicalName(), "Pre-EXEC");
} }
protected Img doInBackground( Vector<Img> imgs) { protected Img doInBackground( Vector<Img> imgs) {
...@@ -59,24 +63,27 @@ public class ImgDownloader extends AsyncTask<Vector<Img>, Void, Img> { ...@@ -59,24 +63,27 @@ public class ImgDownloader extends AsyncTask<Vector<Img>, Void, Img> {
int seconds = Calendar.getInstance().get(Calendar.SECOND); int seconds = Calendar.getInstance().get(Calendar.SECOND);
try { try {
String surl=null;
for (Img img: imgs) { for (Img img: imgs) {
if (!img.exists_bitmap(this.context) || this.force_download) try { if (!img.exists_bitmap(this.context) || this.force_download) try {
surl=context.getResources().getString(R.string.server)+"/"+img.get_url();
this.activityManager.getMemoryInfo(mi); this.activityManager.getMemoryInfo(mi);
URL url = new URL(surl);
URLConnection ucon = url.openConnection(); if (this.source==source.remote) {
is = ucon.getInputStream(); String surl = context.getResources().getString(R.string.server) + "/" + img.get_url();
URL url = new URL(surl);
URLConnection ucon = url.openConnection();
is = ucon.getInputStream();
}else {
File file=new File(img.get_url());
is=new FileInputStream(file);
}
int size=img.save_bitmap(this.context, is); int size=img.save_bitmap(this.context, is);
allsize+=size; allsize+=size;
i++; i++;
} catch (IOException e) { } catch (IOException e) {
j++; j++;
Log.e(this.getClass().getCanonicalName(), surl + " was not downloaded: "+e); Log.e(this.getClass().getCanonicalName(), img.get_url() + " was not downloaded: "+e);
} finally { } finally {
if (is != null) is.close(); if (is != null) is.close();
} }
...@@ -88,7 +95,7 @@ public class ImgDownloader extends AsyncTask<Vector<Img>, Void, Img> { ...@@ -88,7 +95,7 @@ public class ImgDownloader extends AsyncTask<Vector<Img>, Void, Img> {
} }
seconds=Calendar.getInstance().get(Calendar.SECOND)-seconds; seconds=Calendar.getInstance().get(Calendar.SECOND)-seconds;
Log.i(this.getClass().getCanonicalName(), Log.i(this.getClass().getCanonicalName(),
"LoginActivity: Downloaded: " + i+"/"+imgs.size()+ " (size:"+allsize/1024+" Kbytes)"+ "Images Downloaded: " + i+"/"+imgs.size()+ " (size:"+allsize/1024+" Kbytes)"+
". Cached: "+ (imgs.size()-i)+"/"+imgs.size()+ ". Cached: "+ (imgs.size()-i)+"/"+imgs.size()+
". Download failed: "+ j+"/"+imgs.size()+ ". Download failed: "+ j+"/"+imgs.size()+
". Memory required:"+((mi.availMem / 1048576L)-availableMegs)+" MB"+ ". Memory required:"+((mi.availMem / 1048576L)-availableMegs)+" MB"+
...@@ -106,7 +113,7 @@ public class ImgDownloader extends AsyncTask<Vector<Img>, Void, Img> { ...@@ -106,7 +113,7 @@ public class ImgDownloader extends AsyncTask<Vector<Img>, Void, Img> {
@Override @Override
protected void onPostExecute(Img img) { protected void onPostExecute(Img img) {
Log.d(this.getClass().getCanonicalName(), "LoginActivity: Inside OnPostExecute()"+new SimpleDateFormat("HH:mm:ss")); Log.d(this.getClass().getCanonicalName(), "Inside OnPostExecute()"+new SimpleDateFormat("HH:mm:ss"));
if (imgListener!=null) if (imgListener!=null)
if(img == null) imgListener.loadComplete(); if(img == null) imgListener.loadComplete();
else imgListener.loadImg(img); else imgListener.loadImg(img);
......
package com.yottacode.pictogram.net;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.concurrent.ExecutionException;
import com.google.gson.JsonObject;
import com.koushikdutta.async.future.FutureCallback;
import com.koushikdutta.ion.Ion;
import com.koushikdutta.ion.Response;
import com.yottacode.net.SSLDummyContext;
import com.yottacode.pictogram.R;
import com.yottacode.pictogram.tools.Img;
import com.yottacode.pictogram.tools.PCBcontext;
import android.content.Context;
import android.util.Log;
/**
* Image downloader from the server for pictograms and student's and supervisor's profile pictures.
* Permissions required in AndroidManifest.xml:
* <uses-permission android:name="android.permission.INTERNET" />
*/
public class ImgUploader {
iImgUploaderListener imgListener;
Context context;
public ImgUploader(Context context) {
this.context=context;
}
public void upload( Img img, final iImgUploaderListener listener) throws UnsupportedEncodingException {
if (!img.get_filetype().equalsIgnoreCase("png"))
throw new UnsupportedEncodingException("Extension "+img.get_filetype()+" is not supported. Only png files");
Ion ion = Ion.getDefault(context);
Log.i(this.getClass().getCanonicalName(), "Uploading " + img.file_name()+"."+img.get_type());
File file = new File(img.file_name());
Response<JsonObject> response=null;
try {
response=ion.with(context)
.load("POST", context.getResources().getString(R.string.server) + "/picto/upload")
.setMultipartParameter("filename", Integer.toString(img.get_id()))
.setMultipartParameter("extension", img.get_filetype())
.setMultipartParameter("owner", Integer.toString(PCBcontext.getPcbdb().getCurrentUser().get_id_sup()))
.setMultipartParameter("folder", "custompictos")
.setMultipartParameter("source", "2")
.setMultipartParameter("token", PCBcontext.getRestapiWrapper().getToken())
.setMultipartFile("file", "image/png", file)
.asJsonObject()
.withResponse().get();
if (response != null && response.getHeaders().code() == 200) {
JsonObject result = response.getResult();
Log.i(this.getClass().getCanonicalName(), "Image uploaded:"+result.getAsString());
listener.complete(result);
} else {
Log.i(this.getClass().getCanonicalName(), "Image upload failed ");
if (response != null)
Log.e(this.getClass().getCanonicalName(), "Image upload response: " + response.getHeaders());
listener.error(new Exception("ImgUploader error when upload "+img.get_url()), response == null ? -1 : response.getHeaders().code());
}
} catch (InterruptedException e) {
Log.e(this.getClass().getCanonicalName(), "Image upload error: " + e.getMessage());
listener.error(e, response == null ? -1 : response.getHeaders().code());
} catch (ExecutionException e) {
Log.e(this.getClass().getCanonicalName(), "Image upload error: " + e.getMessage());
listener.error(e, response == null ? -1 : response.getHeaders().code());
}
ion.dump();
}
}
package com.yottacode.pictogram.net;
import com.google.gson.JsonObject;
/**
* Created by Fernando on 26/02/16.
*/
public interface iImgUploaderListener {
public void complete(JsonObject result);
public void error(Exception e, int http_code);
}
...@@ -34,13 +34,14 @@ public class Img { ...@@ -34,13 +34,14 @@ public class Img {
protected int id; protected int id;
protected String url; protected String url;
String type; String type;
final static String FILETYPE="png";
Bitmap bitmap; Bitmap bitmap;
/** /**
* *
* @param id * @param id
* @param url * @param url
* @param type is Vocabuylary, Student or Supervisor * @param type is Vocabulary, Student or Supervisor
*/ */
public Img(int id, String url, String type) { public Img(int id, String url, String type) {
this.id = id; this.id = id;
...@@ -48,11 +49,12 @@ public class Img { ...@@ -48,11 +49,12 @@ public class Img {
this.type=type; this.type=type;
this.bitmap=null; this.bitmap=null;
} }
public String file_name() { return this.id+".png"; } public String file_name() { return this.id+Img.FILETYPE; }
public int get_id() { return this.id;} public int get_id() { return this.id;}
public String get_url() { return this.url;} public String get_url() { return this.url;}
public String get_type() { return this.type;} public String get_type() { return this.type;}
public String get_filetype() { return Img.FILETYPE;}
/** /**
* Load if necessary the bitmap from disk, and it is returned. IIf it is not available, return null * Load if necessary the bitmap from disk, and it is returned. IIf it is not available, return null
...@@ -62,7 +64,7 @@ public class Img { ...@@ -62,7 +64,7 @@ public class Img {
*/ */
public Bitmap get_bitmap(Context context) throws IOException { public Bitmap get_bitmap(Context context) throws IOException {
if (this.bitmap==null) { if (this.bitmap==null) {
File file = file(context, this.type); File file = file(context);
if (file.exists()) { if (file.exists()) {
FileInputStream is = new FileInputStream(file); FileInputStream is = new FileInputStream(file);
this.bitmap = BitmapFactory.decodeStream(is); this.bitmap = BitmapFactory.decodeStream(is);
...@@ -78,7 +80,7 @@ public class Img { ...@@ -78,7 +80,7 @@ public class Img {
* @throws FileNotFoundException * @throws FileNotFoundException
*/ */
public void delete_bitmap(Context context) throws IOException { public void delete_bitmap(Context context) throws IOException {
File file = file(context, this.type); File file = file(context);
file.delete(); file.delete();
} }
...@@ -88,17 +90,22 @@ public class Img { ...@@ -88,17 +90,22 @@ public class Img {
* @return true if the bitmap is locally stored * @return true if the bitmap is locally stored
*/ */
public boolean exists_bitmap(Context context) { public boolean exists_bitmap(Context context) {
return file(context, this.type).exists(); return file(context).exists();
} }
private static String path(Context context, String type) { public static String path(Context context, String type) {
String path = context.getFilesDir()+File.separator +"pictures" + File.separatorChar + type + File.separatorChar; String path = context.getFilesDir()+File.separator +"pictures" + File.separatorChar + type + File.separatorChar;
return path; return path;
} }
private File file(Context context, String type) { /**
* The local file where the img is saved. It depends on the image type
* @param context
* @return
*/
public File file(Context context) {
String path=path(context, this.type); String path=path(context, this.type);
return new File(path, file_name()); return new File(path, file_name());
} }
...@@ -110,7 +117,7 @@ public class Img { ...@@ -110,7 +117,7 @@ public class Img {
*/ */
public int save_bitmap(Context context, InputStream is) throws IOException { public int save_bitmap(Context context, InputStream is) throws IOException {
File file = file(context, this.type); File file = file(context);
FileOutputStream os = new FileOutputStream(file); FileOutputStream os = new FileOutputStream(file);
try { try {
this.bitmap = BitmapFactory.decodeStream(is); this.bitmap = BitmapFactory.decodeStream(is);
......
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 sign in to comment