Commit 8005ee19 by Arturo Montejo Ráez

Merge branch 'master' of http://scm.ujaen.es/softuno/pictogram

parents ac779b3b 6383f43e
Showing with 535 additions and 415 deletions
......@@ -33,10 +33,10 @@ sails/src/node_modules
sails/src/assets/app/bower_components
sails/src/.tmp
sails/config/tmp.sql
android/Pictogrammar/.idea
android/Pictogram/.idea
.idea
android/Pictogrammar/app/app.iml
android/Pictogrammar/Pictogrammar.iml
android/Pictogram/app/app.iml
android/Pictogram/Pictogrammar.iml
# Packages #
############
......
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="Pictogram" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="java-gradle" name="Java-Gradle">
<configuration>
<option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
<option name="BUILDABLE" value="false" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
......@@ -4,7 +4,7 @@ android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "com.yottacode.pictogrammar"
applicationId "com.yottacode.pictogram"
minSdkVersion 19
targetSdkVersion 21
versionCode 1
......@@ -37,6 +37,7 @@ android {
productFlavors {
FernandoFlavor {
resValue "string", "server", "https://127.0.0.1:9944"
applicationId "com.yottacode.pictogrammar"
}
ArturoFlavor {
resValue "string", "server", "https://192.168.1.37:1337"
......@@ -52,7 +53,6 @@ android {
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
//compile fileTree(dir: 'E:\\Users\\Fernando\\Google Drive\\experimentos\\Pictogrammar\\android\\app\\libs', include: ['*.jar'])
compile 'com.google.android.gms:play-services:6.5.87'
compile 'com.android.support:appcompat-v7:21.0.3'
compile 'com.github.nkzawa:socket.io-client:0.5.0'
......
......@@ -3,6 +3,7 @@ package com.yottacode.pictogrammar;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.widget.ProgressBar;
import com.github.nkzawa.socketio.client.IO;
......@@ -12,6 +13,7 @@ import com.koushikdutta.ion.Ion;
import com.yottacode.net.FakeSSLTrustManager;
import com.yottacode.net.SSLDummyContext;
import com.yottacode.pictogram.R;
import com.yottacode.pictogram.tools.PCBcontext;
import java.io.File;
import java.security.NoSuchAlgorithmException;
......@@ -30,40 +32,48 @@ public class UploadActivity extends Activity {
ProgressBar uploadProgressBar;
uploadProgressBar = (ProgressBar) findViewById(R.id.progressBar2);
SSLDummyContext.init(getResources().getBoolean(R.bool.ssl_connect));
final Context context = UploadActivity.this;
SSLContext mySSLContext = SSLDummyContext.get();
PCBcontext.init(this);
PCBcontext.getRestapiWrapper().setToken("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJvZmZpY2UiOnsiaWQiOjM4MywibmFtZSI6IkNvbXVuaWNhY2nDs24gQXVtZW50YXRpdmEgSkHDqW4gKENBSkEpIiwiYWRkcmVzcyI6IlBhcmFqZSBMYXMgTGFndW5pbGxhcywgRWQgQTMsIHByaW1lcmEgcGxhdGEsIDIzMDcxLiBKYcOpbiIsImVtYWlsIjoiZG9mZXJAdWphZW4uZXMiLCJwaG9uZTEiOiIrMzQgOTUzIDIxIDI4IDg4IiwicGhvbmUyIjpudWxsLCJsYW5nIjoiZXMtZXMiLCJjb3VudHJ5IjoiRVMiLCJhZG1pbiI6MjMsImNvbnRhY3RQZXJzb24iOiJGZXJuYW5kbyBNYXJ0w61uZXogU2FudGlhZ28iLCJtYXhTdHVkZW50cyI6MiwiY3VycmVudFN0dWRlbnRzIjowfSwiaWQiOjIzLCJuYW1lIjoiRmVybmFuZG8iLCJzdXJuYW1lIjoiTWFydMOtbmV6IFNhbnRpYWdvIiwiZ2VuZGVyIjoiTSIsInBpYyI6Imh0dHA6Ly93d3dkaS51amFlbi5lcy9zaXRlcy9kZWZhdWx0L2ZpbGVzL3lvLmpwZz8xNDQ4MDE5MzU2IiwiYWRkcmVzcyI6bnVsbCwiY291bnRyeSI6bnVsbCwiZW1haWwiOiJkb2ZlckB1amFlbi5lcyIsInBob25lIjoiKzM0OTUzMjEyODg4IiwibGFuZyI6ImVzLWVzIiwiYWN0aXZlIjp0cnVlLCJ0dHNFbmdpbmUiOm51bGwsImlzU3VwQWRtaW4iOnRydWUsImlhdCI6MTQ1NDM4OTI0MywiZXhwIjoxNDU0Mzk2NDQzfQ.X-31SdZDYHH1SdBEsFVmajavg1VlIQQhImc3ROrnDzg");
Ion ion = Ion.getDefault(context);
/* try {
try {
ion.configure().createSSLContext("TLS");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
*/
//ion.getHttpClient().getSSLSocketMiddleware().setSSLContext(mySSLContext);
//ion.getHttpClient().getSSLSocketMiddleware().setTrustManagers(new TrustManager[]{new FakeSSLTrustManager()});
Log.i(this.getClass().getCanonicalName(), " Uploading 1 ");
ion.getHttpClient().getSSLSocketMiddleware().setSSLContext(mySSLContext);
ion.getHttpClient().getSSLSocketMiddleware().setTrustManagers(new TrustManager[]{new FakeSSLTrustManager()});
Log.i(this.getClass().getCanonicalName(), " Uploading 2 ");
ion.with(context)
.load(context.getResources().getString(R.string.server) + "/picto/upload")
.uploadProgressBar(uploadProgressBar)
.uploadProgressBar(uploadProgressBar).setTimeout(20000)
.setMultipartParameter("filename", "foo-bar")
.setMultipartParameter("extension", "jpg")
.setMultipartParameter("owner", "10")
.setMultipartParameter("folder", "custompictos")
.setMultipartParameter("source", "1")
.setMultipartParameter("token", "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJvZmZpY2UiOnsiaWQiOjM4MywibmFtZSI6IkNvbXVuaWNhY2nDs24gQXVtZW50YXRpdmEgSkHDqW4gKENBSkEpIiwiYWRkcmVzcyI6IlBhcmFqZSBMYXMgTGFndW5pbGxhcywgRWQgQTMsIHByaW1lcmEgcGxhdGEsIDIzMDcxLiBKYcOpbiIsImVtYWlsIjoiZG9mZXJAdWphZW4uZXMiLCJwaG9uZTEiOiIrMzQgOTUzIDIxIDI4IDg4IiwicGhvbmUyIjpudWxsLCJsYW5nIjoiZXMtZXMiLCJjb3VudHJ5IjoiRVMiLCJhZG1pbiI6MjMsImNvbnRhY3RQZXJzb24iOiJGZXJuYW5kbyBNYXJ0w61uZXogU2FudGlhZ28iLCJtYXhTdHVkZW50cyI6MiwiY3VycmVudFN0dWRlbnRzIjowfSwiaWQiOjIzLCJuYW1lIjoiRmVybmFuZG8iLCJzdXJuYW1lIjoiTWFydMOtbmV6IFNhbnRpYWdvIiwiZ2VuZGVyIjoiTSIsInBpYyI6Imh0dHA6Ly93d3dkaS51amFlbi5lcy9zaXRlcy9kZWZhdWx0L2ZpbGVzL3lvLmpwZz8xNDQ4MDE5MzU2IiwiYWRkcmVzcyI6bnVsbCwiY291bnRyeSI6bnVsbCwiZW1haWwiOiJkb2ZlckB1amFlbi5lcyIsInBob25lIjoiKzM0OTUzMjEyODg4IiwibGFuZyI6ImVzLWVzIiwiYWN0aXZlIjp0cnVlLCJ0dHNFbmdpbmUiOm51bGwsImlzU3VwQWRtaW4iOnRydWUsImlhdCI6MTQ1Mzg2MTkyNSwiZXhwIjoxNDUzODY5MTI1fQ.41Zpp1WHayS9x4VsYUKz0KchUAs0fcQB7wU7FotELKc")
.setMultipartFile("file", "image/jpeg", new File("/storage/emulated/0/DCIM/Camera/shot1.jpg"))
.setMultipartParameter("token", PCBcontext.getRestapiWrapper().getToken())
.setMultipartFile("file", "image/jpeg", new File("/storage/emulated/0/DCIM/Camera/IMG_20160202_053728.jpg"))
.asJsonObject()
.setCallback(new FutureCallback<JsonObject>() {
@Override
public void onCompleted(Exception e, JsonObject result) {
if (e == null)
System.out.println("Uploaded to " + context.getResources().getString(R.string.server) + " " + result);
Log.i(this.getClass().getCanonicalName(), " Uploaded to " + context.getResources().getString(R.string.server) + " " + result);
else
Log.e(this.getClass().getCanonicalName(), "error uploading");
if (result != null)
Log.i(this.getClass().getCanonicalName(), result.toString());
else
System.out.println("Error " + e.getMessage());
e.printStackTrace();
Log.i(this.getClass().getCanonicalName(), "no result");
}
});
ion.dump();
Log.i(this.getClass().getCanonicalName(), " Uploading 3 ");
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yottacode.pictogram">
<uses-sdk android:minSdkVersion="21" />
<!-- The app has the permission to receive the RECEIVE_BOOT_COMPLETED broadcast -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- For kiosk mode -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- For the service that restarts the app when another app go to foreground -->
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<android:uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<android:uses-permission android:name="android.permission.READ_PHONE_STATE" />
<android:uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:name=".kiosk.AppContext"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name=".gui.SplashScreenActivity"
android:label="@string/app_name"
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".gui.MainActivity"
android:label="@string/app_name"
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
<activity
android:name=".gui.SerialActivity"
android:label="@string/title_activity_serial"
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
<activity
android:name=".gui.LoginActivity"
android:exported="true"
android:label="@string/title_activity_login_activity_fragments"
android:screenOrientation="landscape"/>
<activity
android:name="com.yottacode.pictogrammar.UploadActivity"
android:label="@string/app_name"
android:launchMode="singleTop"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".gui.PictogramActivity"
android:exported="true"
android:label="@string/app_name"
android:launchMode="singleTop"
android:screenOrientation="landscape"/>
<!-- Intent Filter to run the app when the boot is completed -->
<receiver android:name=".kiosk.BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<!-- Service for restarting the app when another app go to foreground -->
<service
android:name=".kiosk.KioskService"
android:exported="false" />
<service
android:name=".net.NetService"
android:exported="false"/>
</application>
</manifest>
......@@ -51,7 +51,7 @@ public class RestapiWrapper {
this.token=token;
}
public String getToken() {
return token;
if (token==null) throw new java.lang.NullPointerException("Token has no value. Use constructor properly or RestapiWrapper.setToken must be invoked previously"); return token;
}
public String getServer() {
return server;
......@@ -219,7 +219,6 @@ public class RestapiWrapper {
@Override
protected HttpAsyncTaskParams doInBackground(HttpAsyncTaskParams... params) {
Log.d(LOG_TAG, "POST params doIn:" + params[0].url_params.toString()+" Get?"+params[0].get);
params[0].result = params[0].get ? GET(params[0].url, params[0].url_params, null)
: POST(params[0].url, params[0].url_params);
return params[0];
......
package com.yottacode.pictogram.dao;
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 android.util.Log;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.InputStream;
import java.util.Vector;
import com.yottacode.pictogram.action.Action;
import com.yottacode.pictogram.tools.Img;
import com.yottacode.pictogram.net.ImgDownloader;
import com.yottacode.pictogram.net.iImgDownloaderListener;
import org.json.JSONException;
/**
* Data Access Object to manage Pictogram Communicator Board database
* This class requires:
* The script to create the DB allocated in res/raw/pcbdb_create.sql
* The entries db_name and db_script_error in strings.xml
*
* @author Fernando Martinez Santiago
* @version 1.1
*/
public class Device extends SQLiteOpenHelper {
Context context;
final static class PARAMS {
static String keyword="key";
static String token="token";
static String deviceID="deviceID";
static String serial="serial";
static String stu_id="last__stu_id";
static String sup_id="last__sup_id";
}
/**
* Create a helper object to create, open, and/or manage a database.
*
* @param context the context of the activity
* @param factory null
* @param version 1
*/
public Device(Context context, CursorFactory factory, int version) {
super(context, DeviceHelper.getDBName(context), factory, version);
if (DeviceHelper.force_create(context)) {
Log.i(this.getClass().getCanonicalName(),"Forcing create new database");
context.deleteDatabase(DeviceHelper.getDBName(context));
Log.i(this.getClass().getCanonicalName(), "Database dropped");
}
this.context = context;
}
/**
* Set the value of a param.
*
* @return serial the official Yotta device ID or null if it is not specified
*/
private void setParam(String param, String value) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values=new ContentValues(2);
values.put("key", param);
values.put("value", value);
long result=db.replace("params", null, values);
if (result==-1) Log.e(this.getClass().getCanonicalName(),"Error when updating param "+param+"="+value);
db.close();
getParamValue(param);
}
/**
* Retrieve the value of a param.
*
* @return value of key param
*/
public String getParamValue(String key) {
SQLiteDatabase db = this.getReadableDatabase();
String value;
Cursor cursor = db.query("params", new String[]{"value"}, "key=?", new String[]{key}, null, null, null, null);
if (cursor.getCount() == 0){
value = null;
Log.e(this.getClass().getCanonicalName(), "Error when getting param " + key);
}else {
cursor.moveToFirst();
value = cursor.getString(0);
}
db.close();
return value;
}
/**
* Save the yotta ID of the device, if it is official.
*
* @param serial the official Yotta device ID
*/
public void setSerial(String serial) {
setParam(PARAMS.serial, serial);
}
/**
* Retrieve de serial of the device, if it is registered and official. It returns NULL in other cases.
*
* @return serial the official Yotta device ID or null if it is not specified
*/
public String getSerial() {
return getParamValue(PARAMS.serial);
}
/**
* Save the keyord to escape from the kiosk mode
* @param keyword to chage in DB
*/
public void setKeyword(String keyword) {
setParam(PARAMS.keyword, keyword);
}
/**
* Retrieve the keyword use to escape the kiosk mode
* @author emblanco,fernando
* @return keyword
*/
public String getKeyword() {
return getParamValue(PARAMS.keyword);
}
/**
* Save the device ID, such as the Android ID.
* @param deviceID the platform dependent ID
* @see Device#getDeviceID()
*/
public void setDeviceID(String deviceID) {
setParam(PARAMS.deviceID, deviceID);
}
/**
* @return the platform device ID, such as Android ID, if it is registered, or null if it is not specified.
* @see Device#setDeviceID(String)
*/
public String getDeviceID() {
return getParamValue(PARAMS.deviceID);
}
/**
* Save the id of the student selected
* @param stu_id of the device.
*/
public void setLastStuId(int stu_id) {
setParam(PARAMS.stu_id, String.valueOf(stu_id));
}
/**
* Save the id of the last supervisor
* @param sup_id of the device.
*
*/
public void setLastSupId(int sup_id) {
setParam(PARAMS.sup_id, String.valueOf(sup_id));
}
/**
* Retrieve de last logged user
* @author Miguel Ángel
* @version 1.0
* @return user_id selected or 0.
*/
public int getLastStuId() {
return Integer.valueOf(getParamValue(PARAMS.stu_id));
}
/**
* Retrieve the last supervisor id selected in Login
*
* @return sup_id selected or 0.
*/
public int getLastSupId() {
return Integer.parseInt(getParamValue(PARAMS.sup_id));
}
/**
* @param id_stu
* @param id_sup
* @return the information of an specific user, if they are available in the local DB
* @see Device#getUsers()
*/
public User findUser(int id_stu, int id_sup) throws JSONException {
SQLiteDatabase db = this.getReadableDatabase();
User user = null;
Cursor cursor = db.query("users_detail", null, null, null, null, null, null, null);
while (cursor.moveToNext() && user == null)
if (cursor.getInt(0) == id_stu && cursor.getInt(7) == id_sup)
user = new User(cursor.getInt(0), cursor.getString(1), cursor.getString(2), cursor.getString(3), cursor.getString(4), cursor.getString(5), cursor.getString(6),
cursor.getInt(7), cursor.getString(8), cursor.getString(9), cursor.getString(10), cursor.getString(11), cursor.getString(12), cursor.getString(13));
cursor.close();
db.close();
return user;
}
/**
* @return a Vector<User> with the whole user who has been registered.
* @see User
* @see com.yottacode.pictogram.dao.PCBDBHelper
*/
public Vector<User> getUsers() throws JSONException {
SQLiteDatabase db = this.getReadableDatabase();
User user;
Cursor cursor = db.query("users_detail", null, null, null, null, null, null, null);
Vector<User> users = new Vector<User>(cursor.getCount());
while (cursor.moveToNext()) {
user = new User(cursor.getInt(0), cursor.getString(1), cursor.getString(2), cursor.getString(3), cursor.getString(4), cursor.getString(5), cursor.getString(6),
cursor.getInt(7), cursor.getString(8), cursor.getString(9), cursor.getString(10), cursor.getString(11), cursor.getString(12), cursor.getString(13));
users.add(user);
}
cursor.close();
db.close();
return users;
}
private void updateUser(User user, SQLiteDatabase db) {
db.execSQL("UPDATE users_detail SET " +
"name_stu='" + user.get_name_stu() + "', " +
"surname_stu='" + user.get_surname_stu() + "', " +
"url_img_stu='" + user.get_url_img_stu() + "', " +
"gender_stu='" + user.get_gender_stu() + "', " +
"lang_stu='" + user.get_lang_stu() + "', " +
"attributes_stu='" + user.get_json_attrs() + "', " +
"name_sup='" + user.get_name_sup() + "', " +
"surname_sup='" + user.get_surname_sup() + "', " +
"url_img_sup='" + user.get_url_img_sup() + "', " +
"gender_sup='" + user.get_gender_sup() + "', " +
"lang_sup='" + user.get_lang_sup() + "', " +
"tts_engine_sup='" + user.get_tts_engine_sup() + "'" +
" WHERE id_stu=" + user.get_id_stu() + " AND id_sup=" + user.get_id_sup());
}
private void insertUser(User user, SQLiteDatabase db) {
db.execSQL("INSERT INTO users_detail values (" +
user.get_id_stu() + ", " +
"'" + user.get_name_stu() + "', " +
"'" + user.get_surname_stu() + "', " +
"'" + user.get_url_img_stu() + "', " +
"'" + user.get_gender_stu() + "', " +
"'" + user.get_lang_stu() + "', " +
"'" + user.get_json_attrs() + "', " +
"'" + user.get_id_sup() + "', " +
"'" + user.get_name_sup() + "', " +
"'" + user.get_surname_sup() + "', " +
"'" + user.get_url_img_sup() + "'," +
"'" + user.get_gender_sup() + "'," +
"'" + user.get_lang_sup() + "'," +
"'" + user.get_tts_engine_sup() + "'" +
")");
}
/**
* Set the current set of users, a hashtable with the whole users who have been registered. The hashcode is calculated as {@link User#hashCode()} depicts.
* For each user:
* if the user exists in the db, he/she is updated
* if the user doesn't exits in the db, he/she is included
* Users who are no longer registered are fully deleted from the DB, even the pictos in case of not any more users using the given picto. Nevertheless, the actions are preserved.
* Student and Supervisor profile images are updated from the server
*
* @param users a hashtable with the set of available users. The key of the hashtable is the same User object
* @see User
* @see com.yottacode.pictogram.dao.PCBDBHelper
*/
public void synchronizeUsers(Vector<User> users, iImgDownloaderListener imgListener) throws JSONException {
Vector<User> prev_users = getUsers();
Vector<Img> imgs = new Vector<Img>(users.size() * 2);
SQLiteDatabase db = this.getWritableDatabase();
for (User user : users) {
if (prev_users.contains(user)) {
updateUser(user, db);
prev_users.remove(user);
} else
insertUser(user, db);
if (!imgs.contains(user.get_Img_stu())) imgs.add(user.get_Img_stu());
if (!imgs.contains(user.get_Img_sup())) imgs.add(user.get_Img_sup());
}
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());
ImgDownloader downloader = new ImgDownloader(this.context, imgListener);
downloader.execute(imgs);
db.close();
}
/**
* delete the list of images (students, supervisors, pictograms) which are no longer used
*/
public void deleteDeprecatedImgs() throws IOException {
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.query("deprecated_images", null, null, null, null, null, null);
while (cursor.moveToNext()) {
String type = cursor.getString(1);
String folder = type.equals("stu") ? Img.STUDENT : type.equals("sup") ? Img.SUPERVISOR : Img.VOCABULARY;
(new Img(cursor.getInt(0), null, folder)).delete_bitmap(this.context);
Log.i(this.getClass().getCanonicalName(), "Image file " + cursor.getString(1) + "." + cursor.getInt(0) + " deleted");
}
cursor.close();
db.delete("deprecated_images", null, null);
db.close();
}
/**
* Execute the script of the database
* IMPORTANT: every DDL sentence has to finish with the sequence: ;--
*
* @param database picto.db helper
* @param inputStream the stream where the ddl of picto.db is depicted
* @throws IOException
*/
protected static void executeSQLScript(SQLiteDatabase database, InputStream inputStream)
throws IOException {
Vector<String> commands = new Vector<String>(50);
BufferedReader r = new BufferedReader(new InputStreamReader(inputStream));
String command = "";
do {
String line = r.readLine();
if (line == null) break;
if (line.equals(";--")) {
commands.add(command + ";");
command = "";
} else if (!line.startsWith("--")) command += line + " ";
} while (true);
r.close();
for (String sqlStatement : commands)
database.execSQL(sqlStatement);
Log.i(Device.class.getName(), "Database created");
}
/**
* @param url
* @return the local parth where the picto is located or null
*/
public String getPictoPath(String url) {
String path;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query("picto", new String[]{"path"}, "'url'=?", new String[]{url}, null, null, null, null);
path = cursor.getCount() > 0 ? cursor.getString(0) : null;
cursor.close();
db.close();
return path;
}
@Override
public void onCreate(SQLiteDatabase db) throws RuntimeException {
try {
executeSQLScript(db, DeviceHelper.getDBScriptStream(this.context));
Img.mkDirs(this.context);
} catch (java.io.IOException io) {
throw new RuntimeException("Update database error", io);
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
package com.yottacode.pictogram.dao;
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 android.util.Log;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.InputStream;
import java.util.Vector;
import com.yottacode.pictogram.action.Action;
import com.yottacode.pictogram.tools.Img;
import com.yottacode.pictogram.net.ImgDownloader;
import com.yottacode.pictogram.net.iImgDownloaderListener;
import org.json.JSONException;
/**
* Data Access Object to manage Pictogram Communicator Board database
* This class requires:
* The script to create the DB allocated in res/raw/pcbdb_create.sql
* The entries db_name and db_script_error in strings.xml
*
* @author Fernando Martinez Santiago
* @version 1.1
*/
public class Device extends SQLiteOpenHelper {
Context context;
final static class PARAMS {
static String keyword="key";
static String token="token";
static String deviceID="deviceID";
static String serial="serial";
static String stu_id="last__stu_id";
static String sup_id="last__sup_id";
}
/**
* Create a helper object to create, open, and/or manage a database.
*
* @param context the context of the activity
* @param factory null
* @param version 1
*/
public Device(Context context, CursorFactory factory, int version) {
super(context, DeviceHelper.getDBName(context), factory, version);
if (DeviceHelper.force_create(context)) {
Log.i(this.getClass().getCanonicalName(),"Forcing create new database");
context.deleteDatabase(DeviceHelper.getDBName(context));
Log.i(this.getClass().getCanonicalName(), "Database dropped");
}
this.context = context;
}
/**
* Set the value of a param.
*
* @return serial the official Yotta device ID or null if it is not specified
*/
private void setParam(String param, String value) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values=new ContentValues(2);
values.put("key", param);
values.put("value", value);
long result=db.replace("params", null, values);
if (result==-1) Log.e(this.getClass().getCanonicalName(),"Error when updating param "+param+"="+value);
db.close();
getParamValue(param);
}
/**
* Retrieve the value of a param.
*
* @return value of key param
*/
public String getParamValue(String key) {
SQLiteDatabase db = this.getReadableDatabase();
String value;
Cursor cursor = db.query("params", new String[]{"value"}, "key=?", new String[]{key}, null, null, null, null);
if (cursor.getCount() == 0){
value = null;
Log.e(this.getClass().getCanonicalName(), "Error when getting param " + key);
}else {
cursor.moveToFirst();
value = cursor.getString(0);
}
db.close();
return value;
}
/**
* Save the yotta ID of the device, if it is official.
*
* @param serial the official Yotta device ID
*/
public void setSerial(String serial) {
setParam(PARAMS.serial, serial);
}
/**
* Retrieve de serial of the device, if it is registered and official. It returns NULL in other cases.
*
* @return serial the official Yotta device ID or null if it is not specified
*/
public String getSerial() {
return getParamValue(PARAMS.serial);
}
/**
* Save the keyord to escape from the kiosk mode
* @param keyword to chage in DB
*/
public void setKeyword(String keyword) {
setParam(PARAMS.keyword, keyword);
}
/**
* Retrieve the keyword use to escape the kiosk mode
* @author emblanco,fernando
* @return keyword
*/
public String getKeyword() {
return getParamValue(PARAMS.keyword);
}
/**
* Save the device ID, such as the Android ID.
* @param deviceID the platform dependent ID
* @see Device#getDeviceID()
*/
public void setDeviceID(String deviceID) {
setParam(PARAMS.deviceID, deviceID);
}
/**
* @return the platform device ID, such as Android ID, if it is registered, or null if it is not specified.
* @see Device#setDeviceID(String)
*/
public String getDeviceID() {
return getParamValue(PARAMS.deviceID);
}
/**
* Save the id of the student selected
* @param stu_id of the device.
*/
public void setLastStuId(int stu_id) {
setParam(PARAMS.stu_id, String.valueOf(stu_id));
}
/**
* Save the id of the last supervisor
* @param sup_id of the device.
*
*/
public void setLastSupId(int sup_id) {
setParam(PARAMS.sup_id, String.valueOf(sup_id));
}
/**
* Retrieve de last logged user
* @author Miguel Ángel
* @version 1.0
* @return user_id selected or 0.
*/
public int getLastStuId() {
return Integer.valueOf(getParamValue(PARAMS.stu_id));
}
/**
* Retrieve the last supervisor id selected in Login
*
* @return sup_id selected or 0.
*/
public int getLastSupId() {
return Integer.parseInt(getParamValue(PARAMS.sup_id));
}
/**
* @param id_stu
* @param id_sup
* @return the information of an specific user, if they are available in the local DB
* @see Device#getUsers()
*/
public User findUser(int id_stu, int id_sup) throws JSONException {
SQLiteDatabase db = this.getReadableDatabase();
User user = null;
Cursor cursor = db.query("users_detail", null, null, null, null, null, null, null);
while (cursor.moveToNext() && user == null)
if (cursor.getInt(0) == id_stu && cursor.getInt(7) == id_sup)
user = new User(cursor.getInt(0), cursor.getString(1), cursor.getString(2), cursor.getString(3), cursor.getString(4), cursor.getString(5), cursor.getString(6),
cursor.getInt(7), cursor.getString(8), cursor.getString(9), cursor.getString(10), cursor.getString(11), cursor.getString(12), cursor.getString(13));
cursor.close();
db.close();
return user;
}
/**
* @return a Vector<User> with the whole user who has been registered.
* @see User
* @see com.yottacode.pictogram.dao.PCBDBHelper
*/
public Vector<User> getUsers() throws JSONException {
SQLiteDatabase db = this.getReadableDatabase();
User user;
Cursor cursor = db.query("users_detail", null, null, null, null, null, null, null);
Vector<User> users = new Vector<User>(cursor.getCount());
while (cursor.moveToNext()) {
user = new User(cursor.getInt(0), cursor.getString(1), cursor.getString(2), cursor.getString(3), cursor.getString(4), cursor.getString(5), cursor.getString(6),
cursor.getInt(7), cursor.getString(8), cursor.getString(9), cursor.getString(10), cursor.getString(11), cursor.getString(12), cursor.getString(13));
users.add(user);
}
cursor.close();
db.close();
return users;
}
private void updateUser(User user, SQLiteDatabase db) {
db.execSQL("UPDATE users_detail SET " +
"name_stu='" + user.get_name_stu() + "', " +
"surname_stu='" + user.get_surname_stu() + "', " +
"url_img_stu='" + user.get_url_img_stu() + "', " +
"gender_stu='" + user.get_gender_stu() + "', " +
"lang_stu='" + user.get_lang_stu() + "', " +
"attributes_stu='" + user.get_json_attrs() + "', " +
"name_sup='" + user.get_name_sup() + "', " +
"surname_sup='" + user.get_surname_sup() + "', " +
"url_img_sup='" + user.get_url_img_sup() + "', " +
"gender_sup='" + user.get_gender_sup() + "', " +
"lang_sup='" + user.get_lang_sup() + "', " +
"tts_engine_sup='" + user.get_tts_engine_sup() + "'" +
" WHERE id_stu=" + user.get_id_stu() + " AND id_sup=" + user.get_id_sup());
}
private void insertUser(User user, SQLiteDatabase db) {
db.execSQL("INSERT INTO users_detail values (" +
user.get_id_stu() + ", " +
"'" + user.get_name_stu() + "', " +
"'" + user.get_surname_stu() + "', " +
"'" + user.get_url_img_stu() + "', " +
"'" + user.get_gender_stu() + "', " +
"'" + user.get_lang_stu() + "', " +
"'" + user.get_json_attrs() + "', " +
"'" + user.get_id_sup() + "', " +
"'" + user.get_name_sup() + "', " +
"'" + user.get_surname_sup() + "', " +
"'" + user.get_url_img_sup() + "'," +
"'" + user.get_gender_sup() + "'," +
"'" + user.get_lang_sup() + "'," +
"'" + user.get_tts_engine_sup() + "'" +
")");
}
/**
* Set the current set of users, a hashtable with the whole users who have been registered. The hashcode is calculated as {@link User#hashCode()} depicts.
* For each user:
* if the user exists in the db, he/she is updated
* if the user doesn't exits in the db, he/she is included
* Users who are no longer registered are fully deleted from the DB, even the pictos in case of not any more users using the given picto. Nevertheless, the actions are preserved.
* Student and Supervisor profile images are updated from the server
*
* @param users a hashtable with the set of available users. The key of the hashtable is the same User object
* @see User
* @see com.yottacode.pictogram.dao.PCBDBHelper
*/
public void synchronizeUsers(Vector<User> users, iImgDownloaderListener imgListener) throws JSONException {
Vector<User> prev_users = getUsers();
Vector<Img> imgs = new Vector<Img>(users.size() * 2);
SQLiteDatabase db = this.getWritableDatabase();
for (User user : users) {
if (prev_users.contains(user)) {
updateUser(user, db);
prev_users.remove(user);
} else
insertUser(user, db);
if (!imgs.contains(user.get_Img_stu())) imgs.add(user.get_Img_stu());
if (!imgs.contains(user.get_Img_sup())) imgs.add(user.get_Img_sup());
}
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());
ImgDownloader downloader = new ImgDownloader(this.context, imgListener);
downloader.execute(imgs);
db.close();
}
/**
* delete the list of images (students, supervisors, pictograms) which are no longer used
*/
public void deleteDeprecatedImgs() throws IOException {
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.query("deprecated_images", null, null, null, null, null, null);
while (cursor.moveToNext()) {
String type = cursor.getString(1);
String folder = type.equals("stu") ? Img.STUDENT : type.equals("sup") ? Img.SUPERVISOR : Img.VOCABULARY;
(new Img(cursor.getInt(0), null, folder)).delete_bitmap(this.context);
Log.i(this.getClass().getCanonicalName(), "Image file " + cursor.getString(1) + "." + cursor.getInt(0) + " deleted");
}
cursor.close();
db.delete("deprecated_images", null, null);
db.close();
}
/**
* Execute the script of the database
* IMPORTANT: every DDL sentence has to finish with the sequence: ;--
*
* @param database picto.db helper
* @param inputStream the stream where the ddl of picto.db is depicted
* @throws IOException
*/
protected static void executeSQLScript(SQLiteDatabase database, InputStream inputStream)
throws IOException {
Vector<String> commands = new Vector<String>(50);
BufferedReader r = new BufferedReader(new InputStreamReader(inputStream));
String command = "";
do {
String line = r.readLine();
if (line == null) break;
if (line.equals(";--")) {
commands.add(command + ";");
command = "";
} else if (!line.startsWith("--")) command += line + " ";
} while (true);
r.close();
for (String sqlStatement : commands)
database.execSQL(sqlStatement);
Log.i(Device.class.getName(), "Database created");
}
/**
* @param url
* @return the local parth where the picto is located or null
*/
public String getPictoPath(String url) {
String path;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query("picto", new String[]{"path"}, "'url'=?", new String[]{url}, null, null, null, null);
path = cursor.getCount() > 0 ? cursor.getString(0) : null;
cursor.close();
db.close();
return path;
}
@Override
public void onCreate(SQLiteDatabase db) throws RuntimeException {
try {
executeSQLScript(db, DeviceHelper.getDBScriptStream(this.context));
Img.mkDirs(this.context);
} catch (java.io.IOException io) {
throw new RuntimeException("Update database error", io);
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
\ No newline at end of file
......@@ -39,8 +39,7 @@ public class MainActivity extends Activity {
//PCBcontext pcb = PCBcontext.getInstance();
PCBcontext.init(this);
Log.d(LOG_TAG, "PCBcontext iniciado");
// Compruebo si tengo token ya guardado en la bbdd para abrir el intent del registro
String token = PCBcontext.getRestapiWrapper().getToken();
//if (1==0){ // Fuerzo a que entre en serialActivity
Intent serialActivity = new Intent(this, SerialActivity.class);
......
......@@ -72,35 +72,35 @@ public final class PCBcontext {
// Return the context
// modified by Fernando
public static Context getContext(){ return context; }
public static Context getContext(){ if (context==null) throw new java.lang.NullPointerException("Context is null. PCBcontext.init must be invoked previously"); return context; }
// Return the device
// modified by Fernando
public static Device getDevice(){ return device; }
public static Device getDevice(){ if (device==null) throw new java.lang.NullPointerException("Device is null. PCBcontext.init must be invoked previously");return device; }
// Return the PCBDB
// modified by Fernando
public static PCBDBHelper getPcbdb(){ return pcbdb; }
public static PCBDBHelper getPcbdb(){ if (context==null) throw new java.lang.NullPointerException("PCBDB is null. PCBcontext.set_user must be invoked previously");return pcbdb; }
// Return the NetService
// modified by Fernando
public static NetService getNetService(){ return service; }
public static NetService getNetService(){ if (service==null) throw new java.lang.NullPointerException("NetService is null. PCBcontext.set_user must be invoked previously"); return service; }
// Return the RestapiWrapper
// modified by Fernando
public static RestapiWrapper getRestapiWrapper(){ return wrapper; }
public static RestapiWrapper getRestapiWrapper(){ if (wrapper==null) throw new java.lang.NullPointerException("RestapiWrapper is null. PCBcontext.init must be invoked previously"); return wrapper; }
// Return the Room
// modified by Fernando
public static Room getRoom(){ return room; }
public static Room getRoom(){ if (room==null) throw new java.lang.NullPointerException("Room is null. PCBcontext.set_user must be invoked previously"); return room; }
// Return the Vocabulary
// modified by Fernando
public static Vocabulary getVocabulary(){ return vocabulary; }
public static Vocabulary getVocabulary(){ if (vocabulary==null) throw new java.lang.NullPointerException("Vocabulary is null. PCBcontext.set_user must be invoked previously"); return vocabulary; }
// Return the ActionLog
// modified by Fernando
public static ActionLog getActionLog(){ return actionLog; }
public static ActionLog getActionLog(){ if (actionLog==null) throw new java.lang.NullPointerException("ActionLog is null. PCBcontext.set_user must be invoked previously"); return actionLog; }
}
......@@ -132,6 +132,7 @@
"office_not_updated": "Office not updated",
"office_updated": "Office updated",
"offices": "Offices",
"own_pictos": "Your pictograms",
"pages": "Pages",
"password": "Password",
"password_confirm": "Repeat password",
......
......@@ -132,6 +132,7 @@
"office_not_updated": "El gabinete no se ha podido actualizar",
"office_updated": "Gabinete actualizado",
"offices": "Gabinetes",
"own_pictos": "Propios",
"pages": "Páginas",
"password": "Contraseña",
"password_confirm": "Repita la contraseña",
......
......@@ -2,7 +2,7 @@
<div class="modal-header">
<div class="btn-group">
<label class="btn btn-default" ng-model="source" btn-radio="'symbolstx'" ng-click="open_category_from_bc('0')">Symbolstx</label>
<label class="btn btn-default" ng-model="source" btn-radio="'ownpictos'" ng-click="load_own_pictos()">Propios</label>
<label class="btn btn-default" ng-model="source" btn-radio="'ownpictos'" ng-click="load_own_pictos()" translate>own_pictos</label>
</div>
</div>
<div class="modal-body">
......
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