Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
yotta
/
pictogram
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
60
Merge Requests
0
Pipelines
Wiki
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
889b9572
authored
Mar 14, 2016
by
Arturo Montejo Ráez
Browse files
Options
_('Browse Files')
Download
Plain Diff
Merge branch 'master' of
http://scm.ujaen.es/softuno/pictogram
parents
25c0f999
f4d53000
Hide whitespace changes
Inline
Side-by-side
Showing
31 changed files
with
657 additions
and
537 deletions
android/Pictogram/app/build.gradle
android/Pictogram/app/src/fernandoFlavor/java/com/yottacode/pictogrammar/Translate.java
android/Pictogram/app/src/main/AndroidManifest.xml
android/Pictogram/app/src/main/java/com/yottacode/net/RestapiWrapper.java
android/Pictogram/app/src/main/java/com/yottacode/pictogram/action/Action.java
android/Pictogram/app/src/main/java/com/yottacode/pictogram/action/ActionLog.java
android/Pictogram/app/src/main/java/com/yottacode/pictogram/action/PictosAction.java
android/Pictogram/app/src/main/java/com/yottacode/pictogram/action/Room.java
android/Pictogram/app/src/main/java/com/yottacode/pictogram/dao/Device.java
android/Pictogram/app/src/main/java/com/yottacode/pictogram/dao/PCBDBHelper.java
android/Pictogram/app/src/main/java/com/yottacode/pictogram/dao/Picto.java
android/Pictogram/app/src/main/java/com/yottacode/pictogram/dao/User.java
android/Pictogram/app/src/main/java/com/yottacode/pictogram/grammar/Vocabulary.java
android/Pictogram/app/src/main/java/com/yottacode/pictogram/grammar/VocabularyIterator.java
android/Pictogram/app/src/main/java/com/yottacode/pictogram/grammar/VocabularyTalk.java
android/Pictogram/app/src/main/java/com/yottacode/pictogram/grammar/iVocabularyListener.java
android/Pictogram/app/src/main/java/com/yottacode/pictogram/gui/LoginActivity.java
android/Pictogram/app/src/main/java/com/yottacode/pictogram/gui/PanelAdapter.java
android/Pictogram/app/src/main/java/com/yottacode/pictogram/gui/PictogramActivity.java
android/Pictogram/app/src/main/java/com/yottacode/pictogram/gui/SerialActivity.java
android/Pictogram/app/src/main/java/com/yottacode/pictogram/net/ImgDownloader.java
android/Pictogram/app/src/main/java/com/yottacode/pictogram/net/NetService.java
android/Pictogram/app/src/main/java/com/yottacode/pictogram/net/PictoUploader.java
android/Pictogram/app/src/main/java/com/yottacode/pictogram/tools/Img.java
android/Pictogram/app/src/main/java/com/yottacode/pictogram/tools/PCBcontext.java
android/Pictogram/app/src/main/java/com/yottacode/tools/FileTools.java
android/Pictogram/app/src/main/res/layout/activity_splash_screen.xml
android/Pictogram/app/src/main/res/raw/pcbdb_create.sql
android/Pictogram/app/src/main/res/values-en/strings.xml
android/Pictogram/app/src/main/res/values-es/strings.xml
android/Pictogram/app/src/main/res/values/strings.xml
android/Pictogram/app/build.gradle
View file @
889b9572
...
...
@@ -3,12 +3,6 @@ apply plugin: 'com.android.application'
android
{
signingConfigs
{
release_config
{
/*
storeFile file('F:/Users/Fernando/GoogleDrive/tmp/keystore.jks')
keyAlias 'default_key'
keyPassword 'danoia'
storePassword 'danoia'
*/
}
}
compileSdkVersion
21
...
...
@@ -32,17 +26,17 @@ android {
resValue
"bool"
,
"force_img_download"
,
"false"
resValue
"integer"
,
"netservice_timing"
,
"20"
resValue
"integer"
,
"rows"
,
"5"
resValue
"integer"
,
"columns"
,
"
8
"
resValue
"integer"
,
"columns"
,
"
10
"
}
debug
{
resValue
"string"
,
"db_name"
,
"PCB.db"
resValue
"bool"
,
"force_db_create"
,
"
fals
e"
resValue
"bool"
,
"force_db_create"
,
"
tru
e"
resValue
"bool"
,
"ssl_connect"
,
"false"
resValue
"bool"
,
"force_img_download"
,
"false"
resValue
"integer"
,
"netservice_timing"
,
"20"
resValue
"integer"
,
"rows"
,
"5"
resValue
"integer"
,
"columns"
,
"
8
"
resValue
"integer"
,
"columns"
,
"
10
"
}
}
productFlavors
{
...
...
android/Pictogram/app/src/fernandoFlavor/java/com/yottacode/pictogrammar/Translate.java
View file @
889b9572
...
...
@@ -83,7 +83,7 @@ public class Translate extends Activity implements iVocabularyListener, iImgDown
PCBcontext
.
init
(
this
);
PCBcontext
.
getDevice
().
setSerial
(
"serial1"
);
PCBcontext
.
getDevice
().
setDeviceID
(
"deviceID"
);
PCBcontext
.
getDevice
().
deleteDeprecatedImgs
();
PCBcontext
.
set_user
(
alumno_picto
,
TOKEN
,
this
);
Log
.
i
(
LOG_TAG
,
"2) OnCreate - Serial:"
+
PCBcontext
.
getDevice
().
getSerial
()
+
" dev. id:"
+
PCBcontext
.
getDevice
().
getDeviceID
()
+
" token:"
+
TOKEN
);
...
...
android/Pictogram/app/src/main/AndroidManifest.xml
View file @
889b9572
...
...
@@ -17,6 +17,13 @@
<android:uses-permission
android:name=
"android.permission.READ_PHONE_STATE"
/>
<android:uses-permission
android:name=
"android.permission.READ_EXTERNAL_STORAGE"
/>
<!-- To auto-complete the email text field in the login form with the user's emails -->
<uses-permission
android:name=
"android.permission.GET_ACCOUNTS"
/>
<uses-permission
android:name=
"android.permission.READ_PROFILE"
/>
<uses-permission
android:name=
"android.permission.READ_CONTACTS"
/>
<android:uses-permission
android:name=
"android.permission.READ_CALL_LOG"
/>
<application
android:name=
".kiosk.AppContext"
android:allowBackup=
"true"
...
...
@@ -36,24 +43,22 @@
<activity
android:name=
".gui.MainActivity"
android:label=
"@string/app_name"
android:screenOrientation=
"landscape"
>
</activity>
android:screenOrientation=
"landscape"
/>
<activity
android:name=
".gui.SerialActivity"
android:label=
"@string/title_activity_serial"
android:screenOrientation=
"landscape"
>
</activity>
android:screenOrientation=
"landscape"
/>
<activity
android:name=
".gui.LoginActivity"
android:exported=
"true"
android:label=
"@string/title_activity_login_activity_fragments"
android:screenOrientation=
"landscape"
/>
android:screenOrientation=
"landscape"
/>
<activity
android:name=
".gui.PictogramActivity"
android:exported=
"true"
android:label=
"@string/app_name"
android:launchMode=
"singleTop"
android:screenOrientation=
"landscape"
/>
android:screenOrientation=
"landscape"
/>
<!-- Intent Filter to run the app when the boot is completed -->
<receiver
android:name=
".kiosk.BootReceiver"
>
<intent-filter>
...
...
@@ -66,7 +71,16 @@
android:exported=
"false"
/>
<service
android:name=
".net.NetService"
android:exported=
"false"
/>
android:exported=
"false"
/>
<activity
android:name=
".ImgLabelActivity"
android:label=
"@string/title_activity_img_label"
android:parentActivityName=
".gui.PictogramActivity"
>
<meta-data
android:name=
"android.support.PARENT_ACTIVITY"
android:value=
"com.yottacode.pictogram.gui.PictogramActivity"
/>
</activity>
</application>
</manifest>
android/Pictogram/app/src/main/java/com/yottacode/net/RestapiWrapper.java
View file @
889b9572
...
...
@@ -116,48 +116,50 @@ public class RestapiWrapper {
public
static
boolean
ping
(
String
server
,
String
ping_op
,
iRestapiListener
error_listener
)
{
StrictMode
.
ThreadPolicy
policy
=
new
StrictMode
.
ThreadPolicy
.
Builder
().
permitAll
().
build
();
StrictMode
.
setThreadPolicy
(
policy
);
boolean
pingResult
=
GET
(
server
+
"/"
+
ping_op
,
null
,
error_listener
)!=
null
;
boolean
pingResult
=
false
;
try
{
pingResult
=
GET
(
server
+
"/"
+
ping_op
,
null
)!=
null
;
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
Log
.
e
(
com
.
yottacode
.
net
.
RestapiWrapper
.
class
.
getName
(),
"ping failed at"
+
ping_op
);
error_listener
.
error
(
e
);
}
return
pingResult
;
}
public
static
String
GET
(
String
surl
,
Hashtable
<
String
,
String
>
params
,
iRestapiListener
listener
)
{
public
static
String
GET
(
String
surl
,
Hashtable
<
String
,
String
>
params
)
throws
IOException
{
String
result
=
null
;
InputStream
inputStream
=
null
;
URL
url
=
null
;
try
{
if
(
params
!=
null
)
{
if
(
params
!=
null
)
{
surl
+=
'?'
;
for
(
String
param
:
params
.
keySet
())
{
String
value
=
params
.
get
(
param
);
surl
+=
param
+
'='
+
value
+
'&'
;
}
surl
=
surl
.
substring
(
0
,
surl
.
length
()-
1
);
}
url
=
new
URL
(
surl
);
HttpURLConnection
urlConnection
=
null
;
urlConnection
=
(
HttpsURLConnection
)
url
.
openConnection
();
urlConnection
.
setReadTimeout
(
60000
);
urlConnection
.
setConnectTimeout
(
60000
);
urlConnection
.
setRequestMethod
(
"GET"
);
urlConnection
.
setDoInput
(
true
);
urlConnection
.
connect
();
inputStream
=
urlConnection
.
getInputStream
();
}
url
=
new
URL
(
surl
);
HttpURLConnection
urlConnection
=
null
;
urlConnection
=
(
HttpsURLConnection
)
url
.
openConnection
();
urlConnection
.
setReadTimeout
(
60000
);
urlConnection
.
setConnectTimeout
(
60000
);
urlConnection
.
setRequestMethod
(
"GET"
);
urlConnection
.
setDoInput
(
true
);
urlConnection
.
connect
();
inputStream
=
urlConnection
.
getInputStream
();
// convert inputstream to string
if
(
inputStream
!=
null
)
result
=
convertInputStreamToString
(
inputStream
);
}
catch
(
IOException
e
)
{
if
(
listener
!=
null
)
listener
.
error
(
e
);
result
=
e
.
getMessage
();
}
if
(
inputStream
!=
null
)
result
=
convertInputStreamToString
(
inputStream
);
return
result
;
}
public
String
POST
(
String
surl
,
String
request_method
,
Hashtable
<
String
,
String
>
params
,
boolean
json_params
)
{
public
String
POST
(
String
surl
,
String
request_method
,
Hashtable
<
String
,
String
>
params
,
boolean
json_params
)
throws
IOException
{
URL
url
=
null
;
String
response
=
""
;
try
{
url
=
new
URL
(
surl
);
HttpURLConnection
urlConnection
=
null
;
...
...
@@ -206,10 +208,6 @@ public class RestapiWrapper {
while
((
line
=
br
.
readLine
())
!=
null
)
{
response
+=
line
;
}
}
catch
(
IOException
e
)
{
Log
.
e
(
com
.
yottacode
.
net
.
RestapiWrapper
.
class
.
getName
(),
"Error:"
+
e
.
getLocalizedMessage
()
+
" when asking for "
+
surl
);
response
=
e
.
getMessage
();
}
return
response
;
}
...
...
@@ -233,6 +231,7 @@ public class RestapiWrapper {
protected
boolean
json_params
;
protected
iRestapiListener
listener
;
protected
String
result
;
protected
Exception
error
;
}
private
class
HttpAsyncTask
extends
AsyncTask
<
HttpAsyncTaskParams
,
Void
,
HttpAsyncTaskParams
>
{
...
...
@@ -240,9 +239,15 @@ public class RestapiWrapper {
@Override
protected
HttpAsyncTaskParams
doInBackground
(
HttpAsyncTaskParams
...
params
)
{
params
[
0
].
result
=
params
[
0
].
request_method
.
equalsIgnoreCase
(
"GET"
)
?
GET
(
params
[
0
].
url
,
params
[
0
].
url_params
,
null
)
:
POST
(
params
[
0
].
url
,
params
[
0
].
request_method
,
params
[
0
].
url_params
,
params
[
0
].
json_params
);
try
{
params
[
0
].
result
=
params
[
0
].
request_method
.
equalsIgnoreCase
(
"GET"
)
?
GET
(
params
[
0
].
url
,
params
[
0
].
url_params
)
:
POST
(
params
[
0
].
url
,
params
[
0
].
request_method
,
params
[
0
].
url_params
,
params
[
0
].
json_params
);
}
catch
(
IOException
e
)
{
Log
.
e
(
com
.
yottacode
.
net
.
RestapiWrapper
.
class
.
getName
(),
"Error:"
+
e
.
getLocalizedMessage
()
+
" when asking for "
+
params
[
0
].
url
);
params
[
0
].
result
=
null
;
params
[
0
].
error
=
e
;
}
return
params
[
0
];
}
...
...
@@ -250,9 +255,10 @@ public class RestapiWrapper {
@Override
protected
void
onPostExecute
(
HttpAsyncTaskParams
params
)
{
try
{
//if (params.e)
if
(
params
.
error
!=
null
)
params
.
listener
.
error
(
params
.
error
);
else
if
(
params
.
result
!=
null
)
{
Log
.
d
(
LOG_TAG
,
"JSON
: "
+
params
.
result
);
Log
.
i
(
LOG_TAG
,
"Picto JSON Result
: "
+
params
.
result
);
Object
jsonResult
=
new
JSONTokener
(
params
.
result
).
nextValue
();
if
(
jsonResult
instanceof
JSONObject
)
{
...
...
@@ -269,7 +275,7 @@ public class RestapiWrapper {
}
catch
(
JSONException
e
)
{
params
.
listener
.
error
(
e
);
}
params
.
url_params
.
clear
();
if
(
params
.
url_params
!=
null
)
params
.
url_params
.
clear
();
}
}
}
\ No newline at end of file
android/Pictogram/app/src/main/java/com/yottacode/pictogram/action/Action.java
View file @
889b9572
...
...
@@ -52,7 +52,7 @@ public abstract class Action {
jsonObject
.
put
(
param_id_sup
,
PCBcontext
.
getPcbdb
().
getCurrentUser
().
get_id_sup
());
//TODO Decidir qué almacenar con DEVICE
//if (PCBcontext.getDevice().getDeviceID()!=null)
//
jsonObject.put(param_id_dev, PCBcontext.getDevice().getDeviceID());
//
jsonObject.put(param_id_dev, PCBcontext.getDevice().getDeviceID());
return
jsonObject
;
}
catch
(
JSONException
e
)
{
...
...
android/Pictogram/app/src/main/java/com/yottacode/pictogram/action/ActionLog.java
View file @
889b9572
...
...
@@ -35,10 +35,10 @@ public class ActionLog implements iRestapiListener {
*/
public
void
log
(
Action
action
)
{
if
(
PCBcontext
.
getRoom
().
inRoom
())
PCBcontext
.
getRoom
().
emit
(
action
.
get_action
(),
action
);
PCBcontext
.
getRoom
().
emit
(
action
);
else
{
// If there is no room, the action is stored in local DB
// If there is no room, the action is stored in
to the
local DB
PCBcontext
.
getPcbdb
().
insertAction
(
action
);
actions_buffer
.
add
(
action
.
getDescription
());
Log
.
i
(
this
.
getClass
().
getCanonicalName
(),
" Batch action included: "
+
action
.
getDescription
());
...
...
@@ -50,13 +50,19 @@ public class ActionLog implements iRestapiListener {
if
(!
actions_buffer
.
isEmpty
())
{
Hashtable
<
String
,
String
>
params
=
new
Hashtable
<>(
1
);
String
url
=
"stu/actions_batch"
;
String
actions
=
""
;
JSONArray
actions
=
new
JSONArray
();
for
(
JSONObject
action:
actions_buffer
)
actions
+=
","
+
action
.
toString
();
actions
=
"["
+
actions
.
substring
(
1
)
+
"]"
;
params
.
put
(
"actions"
,
actions
);
actions
.
put
(
action
);
//actions= "{actions: [" + actions.substring(1) + "]}";
try
{
params
.
put
(
"json"
,
new
JSONObject
().
put
(
"actions"
,
actions
).
toString
());
}
catch
(
JSONException
e
)
{
e
.
printStackTrace
();
Log
.
e
(
this
.
getClass
().
getCanonicalName
(),
" Batch action error: "
+
e
.
getMessage
());
}
Log
.
i
(
this
.
getClass
().
getCanonicalName
(),
" Sending batch actions: "
+
url
+
": "
+
actions
);
PCBcontext
.
getRestapiWrapper
().
ask
(
url
,
params
,
"post"
,
this
);
PCBcontext
.
getRestapiWrapper
().
ask
(
url
,
params
,
"post"
,
t
rue
,
t
his
);
}
}
...
...
android/Pictogram/app/src/main/java/com/yottacode/pictogram/action/PictosAction.java
View file @
889b9572
...
...
@@ -59,7 +59,7 @@ public class PictosAction extends Action {
return
null
;
}
}
p
ublic
JSONObject
get_json_picto
(
Picto
picto
)
throws
JSONException
{
p
rivate
JSONObject
get_json_picto
(
Picto
picto
)
throws
JSONException
{
final
String
param_id_json
=
"id"
;
final
String
param_picto
=
"picto"
;
final
String
param_attrs
=
"attributes"
;
...
...
android/Pictogram/app/src/main/java/com/yottacode/pictogram/action/Room.java
View file @
889b9572
...
...
@@ -19,7 +19,9 @@ import com.yottacode.pictogram.tools.PCBcontext;
import
java.sql.SQLDataException
;
import
java.text.SimpleDateFormat
;
import
java.util.Date
;
import
java.util.Enumeration
;
import
java.util.HashMap
;
import
java.util.Hashtable
;
import
java.util.LinkedList
;
...
...
@@ -36,8 +38,9 @@ public class Room {
protected
SailsSocketsIO
socket
=
null
;
protected
boolean
inRoom
=
false
;
protected
Hashtable
<
String
,
Emitter
.
Listener
>
listeners
;
public
Room
(
)
{
listeners
=
new
Hashtable
<>();
reconnect
();
}
...
...
@@ -46,22 +49,23 @@ public class Room {
final
String
attributes_param
=
"attributes"
;
return
new
JSONObject
().
put
(
action_param
,
action
).
put
(
attributes_param
,
attributes
);
}
public
void
emit
(
String
url
,
final
Action
action
)
{
Log
.
d
(
this
.
getClass
().
getName
(),
"Action: "
+
action
.
get_type
()
+
" / Attributes emitted: "
+
action
.
get_json
().
toString
());
/*
public void emit(String url, final Action action) {
Log.
i
(this.getClass().getName(), "Action: " + action.get_type() + " / Attributes emitted: " + action.get_json().toString());
try{
this.socket.emit(url, this.common_data(action.get_type(), action.get_json()), new Ack() {
@Override
public void call(Object... args) {
Log.i(this.getClass().getName(), "Ack");
for (Object arg : args)
Log
.
d
(
this
.
getClass
().
getName
(),
"Ack messsage:"
+
arg
);
Log.
i(this.getClass().getName(),
"Ack messsage:" + arg);
}
});
} catch (JSONException e) {
Log.e(this.getClass().getCanonicalName(), e.getClass().getCanonicalName() + e.getMessage() + "--" + e.getLocalizedMessage());
}
}
public
void
emit
(
final
Action
action
,
String
token
)
{
}*/
public
void
emit
(
final
Action
action
)
{
String
token
=
PCBcontext
.
getRestapiWrapper
().
getToken
();
final
String
token_param
=
"token"
;
Log
.
d
(
this
.
getClass
().
getName
(),
"Action: "
+
action
.
get_type
()
+
" / Attributes emitted: "
+
action
.
get_json
().
toString
());
try
{
...
...
@@ -82,31 +86,39 @@ public class Room {
*/
public
void
reconnect
()
{
final
String
transport
=
"polling"
;
if
(
this
.
socket
!=
null
)
this
.
socket
.
destroy
();
this
.
socket
=
new
SailsSocketsIO
(
PCBcontext
.
getRestapiWrapper
().
getServer
(),
transport
,
new
Emitter
.
Listener
()
{
@Override
public
void
call
(
Object
...
args
)
{
Log
.
i
(
this
.
getClass
().
getName
(),
"Reconnect successful"
);
subscribe
();
listen_again
();
inRoom
=
true
;
}
},
new
Emitter
.
Listener
()
{
@Override
public
void
call
(
Object
...
args
)
{
Log
.
i
(
this
.
getClass
().
getName
(),
"Room exit: "
+
args
[
0
]);
if
(
args
.
length
>
0
&&
args
[
0
].
toString
().
equals
(
"transport error"
)
)
{
inRoom
=
false
;
}
Log
.
i
(
this
.
getClass
().
getName
(),
"Reconnect unsuccesful: "
+
args
[
0
]);
inRoom
=
false
;
}
});
}
public
boolean
inRoom
()
{
return
this
.
inRoom
;}
public
void
listen
(
String
msg
,
Emitter
.
Listener
listener
)
{
this
.
socket
.
registerMessage
(
msg
,
listener
);
this
.
listeners
.
put
(
msg
,
listener
);
}
private
void
listen_again
()
{
for
(
String
msg:
this
.
listeners
.
keySet
())
{
Log
.
i
(
this
.
getClass
().
getName
(),
"Listening to "
+
msg
);
this
.
socket
.
registerMessage
(
msg
,
this
.
listeners
.
get
(
msg
));
}
}
void
subscribe
()
{
try
{
SubscribeAction
action
=
new
SubscribeAction
();
this
.
emit
(
action
,
PCBcontext
.
getRestapiWrapper
().
getToken
()
);
this
.
emit
(
action
);
}
catch
(
Exception
e
)
{
Log
.
e
(
this
.
getClass
().
getCanonicalName
(),
e
.
getMessage
());
}
...
...
android/Pictogram/app/src/main/java/com/yottacode/pictogram/dao/Device.java
View file @
889b9572
...
...
@@ -38,7 +38,6 @@ 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"
;
...
...
@@ -56,7 +55,7 @@ public class Device extends SQLiteOpenHelper {
super
(
context
,
DeviceHelper
.
getDBName
(
context
),
factory
,
version
);
if
(
DeviceHelper
.
force_create
(
context
))
{
Log
.
i
(
this
.
getClass
().
getCanonicalName
(),
"Forcing create new
database"
);
Log
.
i
(
this
.
getClass
().
getCanonicalName
(),
"Forcing create new
Database "
+
DeviceHelper
.
getDBName
(
context
)
);
context
.
deleteDatabase
(
DeviceHelper
.
getDBName
(
context
));
Log
.
i
(
this
.
getClass
().
getCanonicalName
(),
"Database dropped"
);
}
...
...
@@ -307,7 +306,7 @@ public class Device extends SQLiteOpenHelper {
for
(
User
user
:
prev_users
)
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
.
source
.
remote
);
ImgDownloader
downloader
=
new
ImgDownloader
(
this
.
context
,
imgListener
,
ImgDownloader
.
t
source
.
remote
);
downloader
.
executeOnExecutor
(
AsyncTask
.
THREAD_POOL_EXECUTOR
,
imgs
);
...
...
@@ -318,13 +317,17 @@ public class Device extends SQLiteOpenHelper {
/**
* delete the list of images (students, supervisors, pictograms) which are no longer used
*/
public
void
deleteDeprecatedImgs
()
throws
IOException
{
public
void
deleteDeprecatedImgs
()
{
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
);
try
{
(
new
Img
(
cursor
.
getInt
(
0
),
null
,
folder
)).
delete_bitmap
(
this
.
context
);
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
Log
.
i
(
this
.
getClass
().
getCanonicalName
(),
"Image file "
+
cursor
.
getString
(
1
)
+
"."
+
cursor
.
getInt
(
0
)
+
" deleted"
);
}
cursor
.
close
();
...
...
android/Pictogram/app/src/main/java/com/yottacode/pictogram/dao/PCBDBHelper.java
View file @
889b9572
...
...
@@ -11,6 +11,7 @@ import android.database.sqlite.SQLiteOpenHelper;
import
android.util.Log
;
import
java.io.InputStream
;
import
java.util.Arrays
;
import
java.util.Calendar
;
import
java.util.Vector
;
...
...
@@ -201,20 +202,25 @@ public class PCBDBHelper extends SQLiteOpenHelper {
public
void
setStudentVocabulary
(
Vocabulary
vocabulary
)
{
SQLiteDatabase
db
=
this
.
getWritableDatabase
();
int
id_stu
=
this
.
getCurrentUser
().
get_id_stu
();
int
seconds1
=
Calendar
.
getInstance
().
get
(
Calendar
.
SECOND
),
inserts
=
0
;
int
deleted
=
db
.
delete
(
"collection"
,
"id_stu=?"
,
new
String
[]
{
String
.
valueOf
(
id_stu
)});
int
seconds1
=
Calendar
.
getInstance
().
get
(
Calendar
.
SECOND
);
db
.
delete
(
"collection"
,
"id_stu="
+
id_stu
,
null
);
int
newsize
=
0
;
ContentValues
values
=
new
ContentValues
(
5
);
values
.
put
(
"id_stu"
,
id_stu
);
for
(
Picto
picto
:
vocabulary
)
{
newsize
++;
values
.
put
(
"id_picto"
,
picto
.
get_id
());
values
.
put
(
"url"
,
picto
.
get_url
());
values
.
put
(
"translation"
,
picto
.
get_translation
());
values
.
put
(
"attributes"
,
picto
.
get_json_attrs
());
db
.
insert
(
"collection_detail"
,
null
,
values
);
}
int
seconds2
=
Calendar
.
getInstance
().
get
(
Calendar
.
SECOND
);
Log
.
i
(
this
.
getClass
().
getName
(),
" Local student vocabulary updated, id:"
+
id_stu
+
", cats: "
+
vocabulary
.
size
()
+
" time:"
+(
seconds2
-
seconds1
));
Log
.
i
(
this
.
getClass
().
getName
(),
" Local student vocabulary updated, id:"
+
id_stu
+
", cats: "
+
vocabulary
.
size
()
+
" time:"
+
(
seconds2
-
seconds1
)
+
" secs. Size: "
+
newsize
+
" read only?"
+
db
.
isReadOnly
());
db
.
close
();
}
...
...
@@ -247,11 +253,11 @@ public class PCBDBHelper extends SQLiteOpenHelper {
int
id_stu
=
this
.
getCurrentUser
().
get_id_stu
();
SQLiteDatabase
db
=
this
.
getWritableDatabase
();
db
.
delete
(
"collection"
,
"id_stu=? AND id_
sup=? AND id_
picto=?"
,
db
.
delete
(
"collection"
,
"id_stu=? 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
();
PCBcontext
.
getDevice
().
deleteDeprecatedImgs
();
}
/**
* Update a picto of the current collection's student.
...
...
@@ -263,7 +269,10 @@ public class PCBDBHelper extends SQLiteOpenHelper {
public
void
modifyPicto
(
int
picto_id
,
String
attrs
)
{
int
id_stu
=
this
.
getCurrentUser
().
get_id_stu
();
SQLiteDatabase
db
=
this
.
getWritableDatabase
();
db
.
execSQL
(
"UPDATE collection SET attributes='"
+
attrs
+
"' WHERE id_stu="
+
id_stu
+
" AND id_picto="
+
picto_id
);
ContentValues
values
=
new
ContentValues
(
1
);
values
.
put
(
"attributes"
,
attrs
);
int
updates
=
db
.
update
(
"collection"
,
values
,
"id_stu=? AND id_picto=?"
,
new
String
[]
{
Integer
.
toString
(
id_stu
),
Integer
.
toString
(
picto_id
)});
Log
.
i
(
this
.
getClass
().
getCanonicalName
(),
"Modify "
+
updates
+
" Picto, id. "
+
picto_id
+
" attributes="
+
attrs
);
//+ "::"+ Arrays.toString(Thread.currentThread().getStackTrace()));
db
.
close
();
}
...
...
android/Pictogram/app/src/main/java/com/yottacode/pictogram/dao/Picto.java
View file @
889b9572
...
...
@@ -11,8 +11,6 @@ import com.yottacode.pictogram.tools.PCBcontext;
import
org.json.JSONException
;
import
org.json.JSONObject
;
import
java.util.HashMap
;
/**
* A object which represents a pictogram
* *
...
...
@@ -25,14 +23,14 @@ public class Picto extends Img {
private
final
String
LOG_TAG
=
this
.
getClass
().
getSimpleName
();
// Or .getCanonicalName()
public
final
static
class
JSON_ATTTRS
{
static
String
CATEGORY
=
"id_cat"
;
static
String
ROW
=
"coord_x"
;
static
String
COLUMN
=
"coord_y"
;
static
String
MAGNIFY
=
"magnify"
;
static
String
HIGHLIGHT
=
"highlight"
;
static
String
STATUS
=
"status"
;
static
String
COLOR
=
"color"
;
static
String
PCB_STATUS_MODIFICATION
=
"pcb_status_modification"
;
public
static
String
CATEGORY
=
"id_cat"
;
public
static
String
COLUMN
=
"coord_x"
;
public
static
String
ROW
=
"coord_y"
;
public
static
String
MAGNIFY
=
"magnify"
;
public
static
String
HIGHLIGHT
=
"highlight"
;
public
static
String
STATUS
=
"status"
;
public
static
String
COLOR
=
"color"
;
public
static
String
PCB_STATUS_MODIFICATION
=
"pcb_status_modification"
;
}
public
final
static
class
JSON_ATTTR_STATUS_VALUES
{
...
...
@@ -48,7 +46,7 @@ public class Picto extends Img {
private
JSONObject
attributes
;
private
String
translation
;
public
Picto
(
int
id
,
String
url
,
String
translation
,
int
cat
,
int
column
,
int
row
)
throws
JSONException
{
public
Picto
(
int
id
,
String
url
,
String
translation
,
int
cat
,
int
row
,
int
column
)
throws
JSONException
{
this
(
id
,
url
,
translation
,
new
JSONObject
()
.
put
(
JSON_ATTTRS
.
CATEGORY
,
cat
)
.
put
(
JSON_ATTTRS
.
COLUMN
,
column
)
...
...
@@ -102,15 +100,19 @@ public class Picto extends Img {
}
/**
* JSON attribute of the picto
* JSON attrs of the picto except the param regarding is locally modified since this is not saved into the server
*
*
*/
public
String
get_json_attr
(
String
attr
)
{
public
String
get_json_server_attrs
()
{
JSONObject
json
=
null
;
try
{
return
this
.
attributes
.
getString
(
attr
);
json
=
new
JSONObject
(
this
.
attributes
.
toString
()
);
}
catch
(
JSONException
e
)
{
return
null
;
e
.
printStackTrace
()
;
}
json
.
remove
(
JSON_ATTTRS
.
PCB_STATUS_MODIFICATION
);
return
json
.
toString
();
}
/**
* Set JSON attribute of the picto
...
...
@@ -173,7 +175,8 @@ public class Picto extends Img {
*/
public
boolean
is_invisible
()
{
try
{
return
this
.
attributes
.
getString
(
JSON_ATTTRS
.
STATUS
).
equals
(
JSON_ATTTR_STATUS_VALUES
.
INVISIBLE
);
return
this
.
attributes
.
getString
(
JSON_ATTTRS
.
STATUS
).
equals
(
JSON_ATTTR_STATUS_VALUES
.
INVISIBLE
)
||
(
this
.
is_category
()
&&
!
PCBcontext
.
getVocabulary
().
isVisibleCategory
(
this
.
get_id
()));
}
catch
(
JSONException
e
)
{
return
false
;
}
...
...
@@ -318,14 +321,16 @@ public class Picto extends Img {
*/
public
boolean
alter_status
()
{
String
status
=
is_enabled
()
?
JSON_ATTTR_STATUS_VALUES
.
DISABLED
:
JSON_ATTTR_STATUS_VALUES
.
ENABLED
;
Log
.
i
(
this
.
getClass
().
getCanonicalName
(),
"Picto id. "
+
get_id
()+
" status enabled/disabled modified to "
+
is_enabled
());
try
{
this
.
attributes
.
put
(
JSON_ATTTRS
.
STATUS
,
status
);
s
tatus_modified
(
true
);
s
et_local_status
(
true
);
new
PictoUploader
(
this
).
uploadState
();
}
catch
(
JSONException
e
)
{
e
.
printStackTrace
();
Log
.
e
(
this
.
getClass
().
getCanonicalName
(),
e
.
getMessage
());
}
PCBcontext
.
getActionLog
().
log
(
new
VocabularyAction
(
VocabularyAction
.
ALTERATTRS
,
this
));
return
is_enabled
();
}
...
...
@@ -333,24 +338,26 @@ public class Picto extends Img {
*
* @return true if the status of picto was modified from the PCB
*/
public
boolean
status_modified
()
{
public
boolean
local_status
()
{
return
!
this
.
attributes
.
isNull
(
JSON_ATTTRS
.
PCB_STATUS_MODIFICATION
);
}
/**
* when the status is locally modified, it is required to remove when it is uploaded since it is no longer a local modification
*/
public
void
s
tatus_modified
(
boolean
modified
)
{
public
void
s
et_local_status
(
boolean
modified
)
{
if
(
modified
)
try
{
this
.
attributes
.
put
(
JSON_ATTTRS
.
PCB_STATUS_MODIFICATION
,
true
);
PCBcontext
.
get
ActionLog
().
log
(
new
VocabularyAction
(
VocabularyAction
.
ALTERATTRS
,
this
));
PCBcontext
.
get
Pcbdb
().
modifyPicto
(
this
.
get_id
(),
this
.
get_json_attrs
(
));
}
catch
(
JSONException
e
)
{
e
.
printStackTrace
();
Log
.
e
(
this
.
getClass
().
getCanonicalName
(),
e
.
getMessage
());
}
else
else
{
this
.
attributes
.
remove
(
JSON_ATTTRS
.
PCB_STATUS_MODIFICATION
);
PCBcontext
.
getPcbdb
().
modifyPicto
(
this
.
get_id
(),
this
.
get_json_attrs
());
}
}
}
\ No newline at end of file
android/Pictogram/app/src/main/java/com/yottacode/pictogram/dao/User.java
View file @
889b9572
...
...
@@ -246,16 +246,9 @@ public class User {
}
}
/**
*
* @return the id of the real user: stu or sup
public int get_id() {
return this.get_name_sup() == null ? this.get_id_stu() : this.get_id_sup();
public
boolean
is_supervisor
()
{
return
get_id_sup
()!=
User
.
NO_SUPERVISOR
;
}
*/
...
...
android/Pictogram/app/src/main/java/com/yottacode/pictogram/grammar/Vocabulary.java
View file @
889b9572
...
...
@@ -47,11 +47,9 @@ public class Vocabulary implements Iterable<Picto> {
this
.
pictos
=
new
Hashtable
<>(
Vocabulary
.
DEFAULT_VOCABULARY_SIZE
);
this
.
imgListener
=
listener
;
if
(
PCBcontext
.
getNetService
().
online
())
{
Log
.
i
(
this
.
getClass
().
getName
(),
"downloading vocabulary"
);
synchronize
();
}
else
try
{
Log
.
i
(
this
.
getClass
().
getName
(),
"local vocabulary"
);
PCBcontext
.
getPcbdb
().
getStudentVocabulary
(
this
);
listener
.
loadComplete
();
}
catch
(
JSONException
e
)
{
...
...
@@ -69,6 +67,7 @@ public class Vocabulary implements Iterable<Picto> {
break
;
}
case
update:
{
Log
.
i
(
this
.
getClass
().
getCanonicalName
(),
"Picto update "
+
args
.
toString
());
modifyAttsPicto
(
picto_cat
,
picto_id
,
args
);
break
;
}
...
...
@@ -79,7 +78,7 @@ public class Vocabulary implements Iterable<Picto> {
String
uri
=
args
.
getJSONObject
(
"picto"
).
getString
(
"uri"
);
JSONObject
attrs_picto
=
args
.
getJSONObject
(
"attributes"
);
addPicto
(
new
Picto
(
picto_id
,
uri
,
text
,
attrs_picto
),
ImgDownloader
.
source
.
remote
);
addPicto
(
new
Picto
(
picto_id
,
uri
,
text
,
attrs_picto
),
ImgDownloader
.
t
source
.
remote
);
}
catch
(
JSONException
e
)
{
Log
.
e
(
this
.
getClass
().
getCanonicalName
(),
e
.
getClass
().
getCanonicalName
()
+
"--"
+
e
);
...
...
@@ -94,25 +93,45 @@ public class Vocabulary implements Iterable<Picto> {
},
listener
};
talk
=
new
VocabularyTalk
(
room
,
listeners
);
}
/**
* the vocabulary is (i) updated to and (ii) downloaded from the server.
* UPload local status modifications and new pictos. Note that when
* a picto is uploaded is not required to delete from the local PCB
* because the PCB will get the remote vocabulary at the end of the process
* The only issue is: what happens whether the upload fails? --> The image will be lost.
* TODO: keep record of failed uploaded images to re-include as local pictos
*/
p
ublic
void
synchronize
()
{
p
rivate
void
synchronize_upload
()
{
try
{
PCBcontext
.
getPcbdb
().
getStudentVocabulary
(
this
);
}
catch
(
JSONException
e
)
{
Log
.
e
(
this
.
getClass
().
getName
(),
" Picto json error from local storage: "
+
e
.
getMessage
());
}
for
(
Picto
picto:
this
)
{
if
(
picto
.
status_modified
())
new
PictoUploader
(
picto
).
uploadState
();
if
(
picto
.
get_id
()
<
0
)
try
{
new
PictoUploader
(
picto
).
upload
();
//id<0 iif it is a local id
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
Log
.
e
(
this
.
getClass
().
getName
(),
" Picto json error from server: "
+
picto
.
toString
());
}
if
(
picto
.
local_status
())
{
new
PictoUploader
(
picto
).
uploadState
();
Log
.
i
(
this
.
getClass
().
getCanonicalName
(),
"Picto status modified while offline. Picto translation: '"
+
picto
.
get_translation
()
+
"', id:"
+
picto
.
get_id
()
+
" Local status?"
+
picto
.
local_status
());
}
if
(
picto
.
get_id
()
<
0
)
//id<0 iif it is a local id
try
{
new
PictoUploader
(
picto
).
upload
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
Log
.
e
(
this
.
getClass
().
getName
(),
" Picto json error from server: "
+
picto
.
toString
());
}
}
}
/**
* the vocabulary is (i) updated to and (ii) downloaded from the server.
*/
public
void
synchronize
()
{
synchronize_upload
();
//download
final
String
picto_str
=
"/pictos"
;
String
operation
=
PCBcontext
.
getPcbdb
().
getCurrentUser
().
get_restapi_operation_stu
()+
picto_str
;
PCBcontext
.
getRestapiWrapper
().
ask
(
operation
,
new
iRestapiListener
()
{
...
...
@@ -195,19 +214,19 @@ public class Vocabulary implements Iterable<Picto> {
imgs
.
add
(
new
Img
(
picto
.
get_id
(),
picto
.
get_url
(),
Img
.
VOCABULARY
));
}
Log
.
d
(
this
.
getClass
().
getName
(),
"Vocabulary size: "
+
updated_collection
.
length
);
ImgDownloader
downloader
=
new
ImgDownloader
(
PCBcontext
.
getContext
(),
imgListener
,
ImgDownloader
.
source
.
remote
);
ImgDownloader
downloader
=
new
ImgDownloader
(
PCBcontext
.
getContext
(),
imgListener
,
ImgDownloader
.
t
source
.
remote
);
downloader
.
executeOnExecutor
(
AsyncTask
.
THREAD_POOL_EXECUTOR
,
imgs
);
PCBcontext
.
getPcbdb
().
setStudentVocabulary
(
this
);
}
}
public
int
size
()
{
return
this
.
pictos
.
size
();}
/**
* 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
*/
public
void
addPicto
(
Picto
pic
,
ImgDownloader
.
source
source
){
public
void
addPicto
(
Picto
pic
,
ImgDownloader
.
tsource
source
){
addPicto
(
pic
,
source
,
this
.
imgListener
);
}
public
void
addPicto
(
Picto
pic
,
ImgDownloader
.
tsource
source
,
iImgDownloaderListener
imgListener
){
Vector
<
Img
>
imgs
=
new
Vector
<
Img
>(
1
);
imgs
.
add
(
new
Img
(
pic
.
get_id
(),
pic
.
get_url
(),
Img
.
VOCABULARY
));
...
...
@@ -291,14 +310,7 @@ public class Vocabulary implements Iterable<Picto> {
* @return list of pictos which should be selectable at the beginning of a sentence. Empty categories are removed
*/
public
LinkedList
<
Picto
>
startSentence
(){
Iterator
<
Picto
>
pictos
=
this
.
pictos
.
get
(
new
Integer
(
Picto
.
NO_CATEGORY
)).
iterator
();
LinkedList
<
Picto
>
filteredPictos
=
new
LinkedList
<
Picto
>();
while
(
pictos
.
hasNext
())
{
Picto
picto
=
pictos
.
next
();
if
(!
picto
.
is_category
()
||
isVisibleCategory
(
picto
.
get_id
()))
filteredPictos
.
add
(
picto
);
}
return
filteredPictos
;
return
this
.
pictos
.
get
(
new
Integer
(
Picto
.
NO_CATEGORY
));
}
/**
...
...
@@ -306,13 +318,13 @@ public class Vocabulary implements Iterable<Picto> {
* @param id
* @return
*/
p
rivate
boolean
isVisibleCategory
(
int
id
)
{
p
ublic
boolean
isVisibleCategory
(
int
id
)
{
if
(
empty_category
(
id
))
return
false
;
boolean
visible
=
false
;
for
(
Picto
picto
:
this
.
pictos
.
get
(
id
))
{
visible
=
picto
.
is_enabled
();
visible
=
!
picto
.
is_invisible
();
if
(
visible
)
break
;
}
return
visible
;
...
...
@@ -322,18 +334,32 @@ public class Vocabulary implements Iterable<Picto> {
*/
public
Picto
saveLocalPicto
(
String
url
,
String
exp
,
int
cat
,
int
coord_x
,
int
coord_y
)
{
int
id
=
PCBcontext
.
getDevice
().
getNextLocalPictoID
();
Picto
picto
;
final
Picto
picto
[]=
new
Picto
[
1
]
;
try
{
picto
=
new
Picto
(
id
,
url
,
exp
,
cat
,
coord_x
,
coord_y
);
picto
[
0
]
=
new
Picto
(
id
,
url
,
exp
,
cat
,
coord_x
,
coord_y
);
addPicto
(
picto
[
0
],
ImgDownloader
.
tsource
.
local
,
new
iImgDownloaderListener
()
{
@Override
public
void
loadComplete
()
{
try
{
new
PictoUploader
(
picto
[
0
]).
upload
();
//id<0 iif it is a local id
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
@Override
public
void
loadImg
(
Img
image
)
{
}
});
addPicto
(
picto
,
ImgDownloader
.
source
.
local
);
new
PictoUploader
(
picto
).
upload
();
//id<0 iif it is a local id
}
catch
(
Exception
e
)
{
picto
=
null
;
picto
[
0
]
=
null
;
e
.
printStackTrace
();
Log
.
e
(
Vocabulary
.
class
.
getCanonicalName
(),
e
.
getMessage
());
}
return
picto
;
PCBcontext
.
getActionLog
().
log
(
new
VocabularyAction
(
VocabularyAction
.
ADD
,
picto
[
0
]));
return
picto
[
0
];
}
/**
...
...
android/Pictogram/app/src/main/java/com/yottacode/pictogram/grammar/VocabularyIterator.java
View file @
889b9572
...
...
@@ -23,7 +23,7 @@ public class VocabularyIterator implements Iterator<Picto> {
this
.
keys
=
pictos
.
keys
();
if
(
pictos
.
size
()>
1
)
{
this
.
pictos
=
pictos
;
this
.
category
=
pictos
.
keys
()
.
nextElement
();
this
.
category
=
this
.
keys
.
nextElement
();
}
else
{
...
...
android/Pictogram/app/src/main/java/com/yottacode/pictogram/grammar/VocabularyTalk.java
View file @
889b9572
package
com
.
yottacode
.
pictogram
.
grammar
;
import
android.util.Log
;
import
com.github.nkzawa.emitter.Emitter
;
import
org.json.JSONException
;
import
org.json.JSONObject
;
import
com.yottacode.pictogram.dao.Picto
;
import
com.yottacode.pictogram.action.Room
;
/** * Websocket Vocabulary Room based on Room * @author Fernando Martinez Santiago * @version 1.0 */
public
class
VocabularyTalk
implements
Emitter
.
Listener
{
private
static
final
String
URL
=
"vocabulary"
;
private
Room
room
;
iVocabularyListener
listeners
[];
public
VocabularyTalk
(
Room
room
,
iVocabularyListener
listeners
[])
{
this
.
room
=
room
;
this
.
room
.
listen
(
URL
,
this
);
this
.
listeners
=
listeners
;
}
@Override
public
void
call
(
Object
...
args
)
{
final
String
param_action
=
"action"
;
final
String
param_attributes
=
"attributes"
;
final
String
param_picto
=
"picto"
;
final
String
param_picto_cat
=
"id_cat"
;
final
String
action_update
=
"update"
;
final
String
action_add
=
"add"
;
final
String
action_delete
=
"delete"
;
JSONObject
msg
=
(
JSONObject
)
args
[
0
];
try
{
String
action
=
msg
.
getString
(
param_action
).
toLowerCase
();
JSONObject
picto
=
msg
.
getJSONObject
(
param_attributes
).
getJSONObject
(
param_picto
);
JSONObject
attrs_picto
=
picto
.
getJSONObject
(
param_attributes
);
int
picto_id
=
picto
.
getInt
(
param_picto
);
int
picto_cat
=
attrs_picto
.
optInt
(
param_picto_cat
,
Picto
.
NO_CATEGORY
);
Log
.
d
(
this
.
getClass
().
getName
(),
"Received message '"
+
action
+
"' for picto "
+
picto_id
+
" (cat "
+
picto_cat
+
", attrs: "
+
attrs_picto
);
for
(
iVocabularyListener
listener:
this
.
listeners
)
listener
.
change
(
action
.
equals
(
action_update
)
?
iVocabularyListener
.
action
.
update
:
action
.
equals
(
action_add
)
?
iVocabularyListener
.
action
.
add
:
iVocabularyListener
.
action
.
delete
,
picto_cat
,
picto_id
,
attrs_picto
);
}
catch
(
JSONException
e
)
{
Log
.
e
(
this
.
getClass
().
getCanonicalName
(),
e
.
getClass
().
getCanonicalName
()
+
"--"
+
e
);
}
}
}
\ No newline at end of file
package
com
.
yottacode
.
pictogram
.
grammar
;
import
android.util.Log
;
import
com.github.nkzawa.emitter.Emitter
;
import
org.json.JSONException
;
import
org.json.JSONObject
;
import
com.yottacode.pictogram.dao.Picto
;
import
com.yottacode.pictogram.action.Room
;
/** * Websocket Vocabulary Room based on Room * @author Fernando Martinez Santiago * @version 1.0 */
public
class
VocabularyTalk
implements
Emitter
.
Listener
{
private
static
final
String
URL
=
"vocabulary"
;
private
Room
room
;
iVocabularyListener
listeners
[];
public
VocabularyTalk
(
Room
room
,
iVocabularyListener
listeners
[])
{
this
.
room
=
room
;
this
.
room
.
listen
(
URL
,
this
);
this
.
listeners
=
listeners
;
}
@Override
public
void
call
(
Object
...
args
)
{
final
String
param_action
=
"action"
;
final
String
param_attributes
=
"attributes"
;
final
String
param_picto
=
"picto"
;
final
String
param_picto_id
=
"id"
;
final
String
param_picto_cat
=
"id_cat"
;
final
String
action_update
=
"update"
;
final
String
action_add
=
"add"
;
final
String
action_delete
=
"delete"
;
JSONObject
msg
=
(
JSONObject
)
args
[
0
];
try
{
String
action
=
msg
.
getString
(
param_action
).
toLowerCase
();
JSONObject
picto
=
msg
.
getJSONObject
(
param_attributes
).
getJSONObject
(
param_picto
);
JSONObject
attrs_picto
=
picto
.
getJSONObject
(
param_attributes
);
int
picto_id
=
picto
.
getInt
(
param_picto_id
);
int
picto_cat
=
attrs_picto
.
optInt
(
param_picto_cat
,
Picto
.
NO_CATEGORY
);
Log
.
d
(
this
.
getClass
().
getName
(),
"Received message '"
+
action
+
"' for picto "
+
picto_id
+
" (cat "
+
picto_cat
+
", attrs: "
+
attrs_picto
);
for
(
iVocabularyListener
listener:
this
.
listeners
)
listener
.
change
(
action
.
equals
(
action_update
)
?
iVocabularyListener
.
action
.
update
:
action
.
equals
(
action_add
)
?
iVocabularyListener
.
action
.
add
:
iVocabularyListener
.
action
.
delete
,
picto_cat
,
picto_id
,
attrs_picto
);
}
catch
(
JSONException
e
)
{
Log
.
e
(
this
.
getClass
().
getCanonicalName
(),
e
.
getClass
().
getCanonicalName
()
+
"--"
+
e
);
}
}
}
\ No newline at end of file
...
...
android/Pictogram/app/src/main/java/com/yottacode/pictogram/grammar/iVocabularyListener.java
View file @
889b9572
...
...
@@ -16,6 +16,5 @@ import java.util.LinkedList;
*/
public
interface
iVocabularyListener
{
public
enum
action
{
delete
,
add
,
update
}
public
enum
arg
{
attributes
,
expression
,
url
}
public
void
change
(
iVocabularyListener
.
action
action
,
int
picto_cat
,
int
picto_id
,
JSONObject
args
);
}
android/Pictogram/app/src/main/java/com/yottacode/pictogram/gui/LoginActivity.java
View file @
889b9572
...
...
@@ -261,7 +261,6 @@ public class LoginActivity extends FragmentActivity implements iRestapiListener{
}
});
PCBcontext
.
getDevice
().
deleteDeprecatedImgs
();
// Si sólo hay 1 estudiante paso a Pictogram
if
(
users
.
size
()
==
1
){
//close the progress dialog
...
...
@@ -289,8 +288,6 @@ public class LoginActivity extends FragmentActivity implements iRestapiListener{
}
catch
(
JSONException
e
)
{
e
.
printStackTrace
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
...
...
android/Pictogram/app/src/main/java/com/yottacode/pictogram/gui/PanelAdapter.java
View file @
889b9572
...
...
@@ -2,6 +2,7 @@ package com.yottacode.pictogram.gui;
import
android.annotation.TargetApi
;
import
android.content.Context
;
import
android.content.Intent
;
import
android.graphics.Bitmap
;
import
android.graphics.BitmapFactory
;
import
android.graphics.Canvas
;
...
...
@@ -23,7 +24,9 @@ import android.widget.GridView;
import
android.widget.ImageView
;
import
com.yottacode.pictogram.R
;
import
com.yottacode.pictogram.dao.PCBDBHelper
;
import
com.yottacode.pictogram.dao.Picto
;
import
com.yottacode.pictogram.dao.User
;
import
com.yottacode.pictogram.grammar.iVocabularyListener
;
import
com.yottacode.pictogram.tools.PCBcontext
;
...
...
@@ -146,7 +149,8 @@ public class PanelAdapter extends ArrayAdapter {
// Es un hueco en blanco
imageView
.
setImageAlpha
(
0
);
}
else
{
Bitmap
bmp1
=
lPictos
.
get
(
position
).
get_bitmap
(
PCBcontext
.
getContext
());
Picto
picto
=
lPictos
.
get
(
position
);
Bitmap
bmp1
=
picto
.
get_bitmap
(
PCBcontext
.
getContext
());
if
(
bmp1
!=
null
){
// Magnify
if
(
lPictos
.
get
(
position
).
is_magnify
()){
...
...
@@ -157,14 +161,14 @@ public class PanelAdapter extends ArrayAdapter {
imageView
.
setScaleY
(
1
f
);
}
// Estado de los pictos: enabled | disabled | invisible
String
status
=
lPictos
.
get
(
position
).
get_status
();
if
(
status
.
equalsIgnoreCase
(
"invisible"
)){
imageView
.
setImageAlpha
(
0
);
Log
.
d
(
LOG_TAG
,
"POSITION:"
+
position
+
" / STATUS: "
+
status
);
if
(
picto
.
is_invisible
())
{
imageView
.
setImageAlpha
(
PCBcontext
.
getPcbdb
().
getCurrentUser
().
is_supervisor
()
?
50
:
0
);
imageView
.
setImageBitmap
(
bmp1
);
Log
.
d
(
LOG_TAG
,
"POSITION:"
+
position
+
" / STATUS: "
+
picto
.
get_status
());
//imageView.setImageBitmap(bmp1);
}
else
if
(
status
.
equalsIgnoreCase
(
"disabled"
)){
}
if
(
picto
.
is_disabled
()){
imageView
.
setImageAlpha
(
100
);
// Entre 0 y 255
Bitmap
bmp2
=
BitmapFactory
.
decodeResource
(
PCBcontext
.
getContext
().
getResources
(),
R
.
drawable
.
redcross3
);
Bitmap
bmOverlay
=
Bitmap
.
createBitmap
(
bmp1
.
getWidth
(),
bmp1
.
getHeight
(),
bmp1
.
getConfig
());
...
...
@@ -185,7 +189,7 @@ public class PanelAdapter extends ArrayAdapter {
canvas.drawBitmap(bmp2, boardPosX, boardPosY, null);
*/
}
else
{
if
(
picto
.
is_enabled
())
{
/* AÑADO UN BORDE */
/*
final int BORDER_WIDTH = 1;
...
...
android/Pictogram/app/src/main/java/com/yottacode/pictogram/gui/PictogramActivity.java
View file @
889b9572
...
...
@@ -3,7 +3,6 @@ package com.yottacode.pictogram.gui;
import
android.app.Activity
;
import
android.app.AlertDialog
;
import
android.content.ServiceConnection
;
import
android.database.Cursor
;
import
android.graphics.Color
;
import
android.graphics.Point
;
...
...
@@ -18,11 +17,13 @@ import android.os.Bundle;
import
android.provider.MediaStore
;
import
android.provider.Settings
;
import
android.speech.tts.TextToSpeech
;
import
android.text.InputType
;
import
android.util.Log
;
import
android.view.Display
;
import
android.view.DragEvent
;
import
android.view.KeyEvent
;
import
android.view.MotionEvent
;
import
android.view.View
;
import
android.view.ViewGroup
;
import
android.view.Window
;
...
...
@@ -34,24 +35,16 @@ import android.widget.ImageButton;
import
android.widget.RelativeLayout
;
import
android.widget.Toast
;
import
com.yottacode.net.SSLDummyContext
;
import
com.yottacode.pictogram.BuildConfig
;
import
com.yottacode.pictogram.R
;
import
com.yottacode.pictogram.action.Action
;
import
com.yottacode.pictogram.action.ActionLog
;
import
com.yottacode.pictogram.action.PictoAction
;
import
com.yottacode.pictogram.action.PictosAction
;
import
com.yottacode.pictogram.action.TalkAction
;
import
com.yottacode.pictogram.action.VocabularyAction
;
import
com.yottacode.pictogram.dao.Picto
;
import
com.yottacode.pictogram.dao.User
;
import
com.yottacode.pictogram.grammar.Vocabulary
;
import
com.yottacode.pictogram.grammar.iVocabularyListener
;
import
com.yottacode.pictogram.net.PictoUploader
;
import
com.yottacode.pictogram.tools.Img
;
import
com.yottacode.pictogram.tools.PCBcontext
;
import
com.yottacode.pictogram.net.iImgDownloaderListener
;
import
org.json.JSONException
;
import
org.json.JSONObject
;
import
java.util.ArrayList
;
...
...
@@ -69,15 +62,12 @@ public class PictogramActivity extends Activity implements iVocabularyListener,
PanelAdapter
panelAdapter
;
TapeAdapter
tapeAdapter
;
Vocabulary
vocabulary
;
User
student
;
Context
context
;
Picto
actualCategory
;
Picto
currentCategory
;
TextToSpeech
tts
;
static
final
int
SELECT_PICTURE
=
1
;
// For disabling volume button (See method at the end of the class)
private
final
List
blockedKeys
=
new
ArrayList
(
Arrays
.
asList
(
KeyEvent
.
KEYCODE_VOLUME_DOWN
,
KeyEvent
.
KEYCODE_VOLUME_UP
));
...
...
@@ -88,7 +78,8 @@ public class PictogramActivity extends Activity implements iVocabularyListener,
private
boolean
isSupervisor
=
false
;
private
String
selectedImagePath
;
private
static
final
int
SELECT_PICTURE
=
1
;
/*
float xAxis = 0f;
...
...
@@ -104,16 +95,14 @@ public class PictogramActivity extends Activity implements iVocabularyListener,
requestWindowFeature
(
Window
.
FEATURE_NO_TITLE
);
setContentView
(
R
.
layout
.
activity_pictogram
);
Intent
intent
=
getIntent
();
Intent
intent
=
getIntent
();
isSupervisor
=
intent
.
getBooleanExtra
(
"isSupervisor"
,
false
);
//isSupervisor = true;// QUITAR
//Log.d(LOG_TAG, "isSupervisor vale " + isSupervisor);
context
=
this
;
actualCategory
=
null
;
// this for refresh vocabulary when a websocket action arrived from the dashboard
currentCategory
=
null
;
// this for refresh vocabulary when a websocket action arrived from the dashboard
count_deletelong
=
0
;
...
...
@@ -137,17 +126,17 @@ public class PictogramActivity extends Activity implements iVocabularyListener,
// Adapter for grid
panelAdapter
=
new
PanelAdapter
(
new
LinkedList
<
Picto
>());
this
.
vocabulary
=
PCBcontext
.
getVocabulary
();
if
(
this
.
vocabulary
!=
null
&&
this
.
vocabulary
.
size
()
>
0
)
{
Log
.
d
(
LOG_TAG
,
"Vocabulario correcto de tam:"
+
this
.
vocabulary
.
size
());
Vocabulary
vocabulary
=
PCBcontext
.
getVocabulary
();
if
(
vocabulary
!=
null
&&
vocabulary
.
size
()
>
0
)
{
Log
.
d
(
LOG_TAG
,
"Vocabulario correcto de tam:"
+
vocabulary
.
size
());
LinkedList
<
Picto
>
ll
;
if
(
actualCategory
!=
null
)
ll
=
order
(
vocabulary
.
next
(
actual
Category
));
if
(
currentCategory
!=
null
)
ll
=
order
(
vocabulary
.
next
(
current
Category
));
else
ll
=
order
(
vocabulary
.
startSentence
());
panelAdapter
.
clear
();
panelAdapter
.
addAll
(
ll
);
}
// Open websocket connection
vocabulary
.
listen
(
PCBcontext
.
getRoom
(),
this
);
vocabulary
.
listen
(
PCBcontext
.
getRoom
(),
this
);
// Connect the views
final
GridView
tapeGridView
=
(
GridView
)
findViewById
(
R
.
id
.
tape_grid_view
);
...
...
@@ -200,14 +189,14 @@ public class PictogramActivity extends Activity implements iVocabularyListener,
*/
final
GridView
panelGridView
=
(
GridView
)
findViewById
(
R
.
id
.
panel_grid_view
);
final
ImageButton
deleteButton
=
(
ImageButton
)
findViewById
(
R
.
id
.
button_delete
);
final
ImageButton
deleteButton
=
(
ImageButton
)
findViewById
(
R
.
id
.
button_delete
);
//final Button deleteAllButton = (Button) findViewById(R.id.button_delete_all);
final
ImageButton
ttsButton
=
(
ImageButton
)
findViewById
(
R
.
id
.
button_tts
);
// Si los pictogramas son grandes pongo una configuración. Si son pequeños otra...
int
pictogramSize
=
0
;
// ESTE VALOR SE COGE DE LA CONFIGURACION DEL USUARIO (0:normal; 1:large)
if
(
pictogramSize
==
0
)
panelGridView
.
setNumColumns
(
10
);
else
if
(
pictogramSize
==
1
)
panelGridView
.
setNumColumns
(
4
);
if
(
pictogramSize
==
0
)
panelGridView
.
setNumColumns
(
10
);
else
if
(
pictogramSize
==
1
)
panelGridView
.
setNumColumns
(
4
);
panelGridView
.
setAdapter
(
panelAdapter
);
...
...
@@ -236,22 +225,22 @@ public class PictogramActivity extends Activity implements iVocabularyListener,
//rowNumberAdapter.notifyDataSetChanged();
Picto
p
=
panelAdapter
.
getItem
(
position
);
if
(
p
!=
null
&&
!
p
.
is_invisible
()
&&
p
.
is_enabled
())
{
if
(
p
!=
null
&&
!
p
.
is_invisible
()
&&
p
.
is_enabled
())
{
Log
.
d
(
LOG_TAG
,
"Clic en picto: "
+
p
.
toString
());
//Log.d(LOG_TAG, "STATUS: " + p.get_status());
//QUITAR PARA QUE HABLE panelAdapter.ttsPicto(p, tts);
// If is not the blank picto, it isn't invisible or disabled
if
(
p
.
get_id
()
!=
0
&&
if
(
p
.
get_id
()
!=
0
&&
!
p
.
get_status
().
equalsIgnoreCase
(
"invisible"
)
&&
!
p
.
get_status
().
equalsIgnoreCase
(
"disabled"
))
{
LinkedList
<
Picto
>
ll
=
order
(
vocabulary
.
next
(
p
));
LinkedList
<
Picto
>
ll
=
order
(
PCBcontext
.
getVocabulary
()
.
next
(
p
));
//LinkedList<Picto> ll = vocabulary.next(p);
Log
.
d
(
LOG_TAG
,
"Lista de pictos recuperada: "
+
ll
.
toString
());
int
maxInTape
=
getResources
().
getInteger
(
R
.
integer
.
maxInTape
);
int
maxInTape
=
getResources
().
getInteger
(
R
.
integer
.
maxInTape
);
// If the picto is a category
if
(
p
.
is_category
())
{
...
...
@@ -264,19 +253,18 @@ public class PictogramActivity extends Activity implements iVocabularyListener,
//panelAdapter = new PanelAdapter(ll);
// Cambio el color del fondo
RelativeLayout
rl
=
(
RelativeLayout
)
findViewById
(
R
.
id
.
pictogramLayout
);
RelativeLayout
rl
=
(
RelativeLayout
)
findViewById
(
R
.
id
.
pictogramLayout
);
//rl.setBackgroundColor(Color.RED);
if
(
p
.
get_color
()
!=
-
1
){
if
(
p
.
get_color
()
!=
-
1
)
{
rl
.
setBackgroundColor
(
p
.
get_color
());
panelAdapter
.
setColor
(
p
.
get_darkner_color
());
}
actualCategory
=
p
;
Toast
.
makeText
(
context
,
"El picto pulsado es una categoría"
,
Toast
.
LENGTH_SHORT
).
show
();
currentCategory
=
p
;
PCBcontext
.
getActionLog
().
log
(
new
TalkAction
(
TalkAction
.
SELECT
,
p
));
}
else
if
(
tapeAdapter
.
getCount
()
<
maxInTape
)
{
}
else
if
(
tapeAdapter
.
getCount
()
<
maxInTape
)
{
// If the picto selected is not a category and the tape is not full, it is placed in tape
tapeAdapter
.
addItem
(
p
);
tapeAdapter
.
notifyDataSetChanged
();
...
...
@@ -286,7 +274,7 @@ public class PictogramActivity extends Activity implements iVocabularyListener,
panelAdapter
.
addAll
(
ll
);
panelAdapter
.
setColor
(
Color
.
parseColor
(
"#AFAFAF"
));
RelativeLayout
rl
=
(
RelativeLayout
)
findViewById
(
R
.
id
.
pictogramLayout
);
RelativeLayout
rl
=
(
RelativeLayout
)
findViewById
(
R
.
id
.
pictogramLayout
);
rl
.
setBackgroundColor
(
Color
.
parseColor
(
"#BDBDBD"
));
// Call to static log method
...
...
@@ -294,7 +282,7 @@ public class PictogramActivity extends Activity implements iVocabularyListener,
// Send websocket notification
// when clicking a picto, the activity goes to the main category view
actual
Category
=
null
;
current
Category
=
null
;
}
}
}
...
...
@@ -305,33 +293,37 @@ public class PictogramActivity extends Activity implements iVocabularyListener,
panelGridView
.
setOnItemLongClickListener
(
new
AdapterView
.
OnItemLongClickListener
()
{
@Override
public
boolean
onItemLongClick
(
AdapterView
<?>
parent
,
View
view
,
int
position
,
long
id
)
{
if
(
isSupervisor
){
if
(
isSupervisor
)
{
// Si es supervisor al hacer longClick deshabilito ese pictograma o lo habilito
Picto
p
=
panelAdapter
.
getItem
(
position
);
if
(
p
==
null
){
// No tengo pictograma. Abro una nueva ventana de selección desde el Carrete del device
Log
.
d
(
LOG_TAG
,
"No tengo pictograma. Abro carrete..."
);
chooseImage
();
// ...
if
(
p
==
null
)
{
// No tengo pictograma. Abro una nueva ventana de selección desde el Carrete del device si no es categoria
if
(
PictogramActivity
.
this
.
currentCategory
!=
null
)
{
Log
.
d
(
LOG_TAG
,
"No tengo pictograma. Abro carrete..."
);
int
cols
=
getResources
().
getInteger
(
R
.
integer
.
columns
);
addPicto
(
position
%
cols
,
(
int
)
(
position
/
cols
));
}
else
Toast
.
makeText
(
PictogramActivity
.
this
,
PictogramActivity
.
this
.
getResources
().
getString
(
R
.
string
.
notNewCats
),
Toast
.
LENGTH_SHORT
).
show
();
}
else
{
p
.
alter_status
();
LinkedList
<
Picto
>
ll
;
if
(
currentCategory
!=
null
)
ll
=
order
(
PCBcontext
.
getVocabulary
().
next
(
currentCategory
));
else
ll
=
order
(
PCBcontext
.
getVocabulary
().
startSentence
());
panelAdapter
.
clear
();
panelAdapter
.
addAll
(
ll
);
}
else
{
p
.
alter_status
();
LinkedList
<
Picto
>
ll
;
if
(
actualCategory
!=
null
)
ll
=
order
(
vocabulary
.
next
(
actualCategory
));
else
ll
=
order
(
vocabulary
.
startSentence
());
panelAdapter
.
clear
();
panelAdapter
.
addAll
(
ll
);}
}
else
{
}
else
{
ClipData
.
Item
item
=
new
ClipData
.
Item
(
""
+
position
);
String
[]
mimeTypes
=
{
ClipDescription
.
MIMETYPE_TEXT_PLAIN
};
ClipData
data
=
new
ClipData
(
""
+
position
,
mimeTypes
,
item
);
Picto
p
=
panelAdapter
.
getItem
(
position
);
if
(
p
!=
null
&&
!
p
.
is_invisible
()
&&
p
.
is_enabled
())
{
if
(
p
!=
null
&&
!
p
.
is_invisible
()
&&
p
.
is_enabled
())
{
// If is not the blank picto, it isn't invisible or disabled
if
(
p
.
get_id
()
!=
0
&&
if
(
p
.
get_id
()
!=
0
&&
!
p
.
get_status
().
equalsIgnoreCase
(
"invisible"
)
&&
!
p
.
get_status
().
equalsIgnoreCase
(
"disabled"
)
&&
tapeAdapter
.
getCount
()
<
8
)
{
...
...
@@ -393,7 +385,7 @@ public class PictogramActivity extends Activity implements iVocabularyListener,
panelAdapter
.
setColor
(
Color
.
parseColor
(
"#AFAFAF"
));
RelativeLayout
rl
=
(
RelativeLayout
)
findViewById
(
R
.
id
.
pictogramLayout
);
RelativeLayout
rl
=
(
RelativeLayout
)
findViewById
(
R
.
id
.
pictogramLayout
);
rl
.
setBackgroundColor
(
Color
.
parseColor
(
"#BDBDBD"
));
// Load the categories
...
...
@@ -420,19 +412,18 @@ public class PictogramActivity extends Activity implements iVocabularyListener,
});
// Acción para volver a la ventana de login
deleteButton
.
setOnLongClickListener
(
new
AdapterView
.
OnLongClickListener
(){
deleteButton
.
setOnLongClickListener
(
new
AdapterView
.
OnLongClickListener
()
{
@Override
public
boolean
onLongClick
(
View
v
)
{
Log
.
d
(
LOG_TAG
,
"DELETE LONGCLICK..."
);
count_deletelong
++;
//Picto picto=PCBcontext.getVocabulary().saveLocalPicto("/sdcard/DCIM/camera/javo.jpg", "javier", 7515, 2, 2);
if
(
count_deletelong
>=
3
){
if
(
count_deletelong
>=
3
)
{
//Log.d(LOG_TAG, "SALTO A LOGIN");
// Paso un parámetro a la SerialActivity, para controlar de dónde viene
Intent
serialActivity
=
new
Intent
(
getBaseContext
(),
SerialActivity
.
class
);
serialActivity
.
putExtra
(
"activity_name"
,
"PictogramActivity"
);
serialActivity
.
putExtra
(
"activity_name"
,
"PictogramActivity"
);
startActivity
(
serialActivity
);
}
...
...
@@ -441,56 +432,6 @@ public class PictogramActivity extends Activity implements iVocabularyListener,
});
}
/**
* función para la selección de una foto del carrete
*/
public
void
chooseImage
(){
Intent
intent
=
new
Intent
(
Intent
.
ACTION_PICK
);
intent
.
setType
(
"image/*"
);
startActivityForResult
(
intent
,
SELECT_PICTURE
);
}
/**
* Función para la selección de una foto del carrete
* @param requestCode
* @param resultCode
* @param data
*/
public
void
onActivityResult
(
int
requestCode
,
int
resultCode
,
Intent
data
)
{
if
(
resultCode
==
RESULT_OK
)
{
if
(
requestCode
==
SELECT_PICTURE
)
{
Uri
selectedImageUri
=
data
.
getData
();
selectedImagePath
=
getPath
(
selectedImageUri
);
Log
.
d
(
LOG_TAG
,
"selectedImagePath:"
+
selectedImagePath
);
// Ahora guardaría la imagen en la bbdd local y habría que subirla al server y sincronizar las bbdd
// ...
}
}
}
/**
* Función para la selección de una foto del carrete
* @param uri
* @return
*/
public
String
getPath
(
Uri
uri
)
{
if
(
uri
==
null
)
{
return
null
;
}
// this will only work for images selected from gallery
String
[]
projection
=
{
MediaStore
.
Images
.
Media
.
DATA
};
Cursor
cursor
=
managedQuery
(
uri
,
projection
,
null
,
null
,
null
);
if
(
cursor
!=
null
){
int
column_index
=
cursor
.
getColumnIndexOrThrow
(
MediaStore
.
Images
.
Media
.
DATA
);
cursor
.
moveToFirst
();
return
cursor
.
getString
(
column_index
);
}
return
uri
.
getPath
();
}
@Override
public
void
onInit
(
int
status
)
{
...
...
@@ -501,7 +442,7 @@ public class PictogramActivity extends Activity implements iVocabularyListener,
@Override
protected
void
onStart
()
{
super
.
onStart
();
Toast
.
makeText
(
this
,
"onStart"
,
Toast
.
LENGTH_SHORT
).
show
();
//
Toast.makeText(this, "onStart", Toast.LENGTH_SHORT).show();
}
@Override
protected
void
onResume
()
{
...
...
@@ -509,26 +450,26 @@ public class PictogramActivity extends Activity implements iVocabularyListener,
//Toast.makeText(this, "onResume", Toast.LENGTH_SHORT).show();
String
android_id
=
Settings
.
Secure
.
getString
(
this
.
getContentResolver
(),
Secure
.
ANDROID_ID
);
//
String android_id = Settings.Secure.getString(this.getContentResolver(),
//
Secure.ANDROID_ID);
Toast
.
makeText
(
this
,
"onResume - Android ID: "
+
android_id
,
Toast
.
LENGTH_SHORT
).
show
();
//
Toast.makeText(this, "onResume - Android ID: " + android_id, Toast.LENGTH_SHORT).show();
}
@Override
protected
void
onPause
()
{
Toast
.
makeText
(
this
,
"onPause"
,
Toast
.
LENGTH_SHORT
).
show
();
//
Toast.makeText(this, "onPause", Toast.LENGTH_SHORT).show();
super
.
onPause
();
}
@Override
protected
void
onStop
()
{
super
.
onStop
();
Toast
.
makeText
(
this
,
"onStop"
,
Toast
.
LENGTH_SHORT
).
show
();
//
Toast.makeText(this, "onStop", Toast.LENGTH_SHORT).show();
}
@Override
protected
void
onRestart
()
{
super
.
onRestart
();
Toast
.
makeText
(
this
,
"onRestart"
,
Toast
.
LENGTH_SHORT
).
show
();
//
Toast.makeText(this, "onRestart", Toast.LENGTH_SHORT).show();
}
@Override
protected
void
onDestroy
()
{
...
...
@@ -536,7 +477,7 @@ public class PictogramActivity extends Activity implements iVocabularyListener,
if
(
tts
!=
null
){
tts
.
shutdown
();
}
Toast
.
makeText
(
this
,
"onDestroy"
,
Toast
.
LENGTH_SHORT
).
show
();
//
Toast.makeText(this, "onDestroy", Toast.LENGTH_SHORT).show();
}
/**
...
...
@@ -544,13 +485,13 @@ public class PictogramActivity extends Activity implements iVocabularyListener,
* @param v
*/
public
void
load_pictos
(
View
v
)
{
if
(
vocabulary
!=
null
)
Log
.
d
(
LOG_TAG
,
"4) Vocabulario: "
+
vocabulary
.
toString
());
if
(
PCBcontext
.
getVocabulary
()
!=
null
)
Log
.
d
(
LOG_TAG
,
"4) Vocabulario: "
+
PCBcontext
.
getVocabulary
()
.
toString
());
try
{
actual
Category
=
null
;
current
Category
=
null
;
LinkedList
<
Picto
>
ll
=
order
(
vocabulary
.
startSentence
());
LinkedList
<
Picto
>
ll
=
order
(
PCBcontext
.
getVocabulary
()
.
startSentence
());
panelAdapter
.
clear
();
panelAdapter
.
addAll
(
ll
);
...
...
@@ -571,17 +512,12 @@ public class PictogramActivity extends Activity implements iVocabularyListener,
// This is to show the pictos ordered in the 2D Array that represents the panel
int
rows
=
5
;
int
cols
=
10
;
/*
int rows = R.integer.rows;
int cols = R.integer.columns;
*/
int
rows
=
getResources
().
getInteger
(
R
.
integer
.
rows
);
int
cols
=
getResources
().
getInteger
(
R
.
integer
.
columns
);
Picto
[][]
mp
=
new
Picto
[
rows
][
cols
];
for
(
Picto
p
:
list
)
mp
[
p
.
get_
row
()][
p
.
get_column
()]
=
p
;
mp
[
p
.
get_
column
()][
p
.
get_row
()]
=
p
;
try
{
/*
...
...
@@ -612,18 +548,6 @@ public class PictogramActivity extends Activity implements iVocabularyListener,
Log
.
d
(
LOG_TAG
,
"Vocabulary action listened: "
+
action
);
if
(
args
!=
null
)
Log
.
d
(
LOG_TAG
,
"args: "
+
args
.
toString
());
/*
LinkedList<Picto> ll;
if(actualCategory != null) ll = order(vocabulary.next(actualCategory));
else ll = order(vocabulary.startSentence());
panelAdapter.clear();
panelAdapter.addAll(ll);
panelAdapter.notifyDataSetChanged();
*/
// Background task that updates the ui into the main thread.
runOnUiThread
(
new
Runnable
()
{
@Override
...
...
@@ -632,8 +556,8 @@ public class PictogramActivity extends Activity implements iVocabularyListener,
//stuff that updates ui
LinkedList
<
Picto
>
ll
;
if
(
actualCategory
!=
null
)
ll
=
order
(
vocabulary
.
next
(
actual
Category
));
else
ll
=
order
(
vocabulary
.
startSentence
());
if
(
currentCategory
!=
null
)
ll
=
order
(
PCBcontext
.
getVocabulary
().
next
(
current
Category
));
else
ll
=
order
(
PCBcontext
.
getVocabulary
()
.
startSentence
());
panelAdapter
.
clear
();
panelAdapter
.
addAll
(
ll
);
...
...
@@ -642,33 +566,6 @@ public class PictogramActivity extends Activity implements iVocabularyListener,
}
});
switch
(
action
)
{
case
delete:
{
Log
.
d
(
LOG_TAG
,
"Entra en el case delete. Picto cat: "
+
picto_cat
+
" y picto_id: "
+
picto_id
);
//removePicto(picto_cat, picto_id);
break
;
}
case
update:
{
Log
.
d
(
LOG_TAG
,
"Entra en el case update. Picto cat: "
+
picto_cat
+
" y picto_id: "
+
picto_id
);
//modifyAttsPicto(picto_cat, picto_id, (JSONObject) args.get(arg.attributes));
break
;
}
case
add:
{
Log
.
d
(
LOG_TAG
,
"Entra en el case add. Picto_id: "
+
picto_id
);
/*
addPicto(new Picto(picto_id, (String) args.get(arg.url),
(String) args.get(arg.expression),
(JSONObject) args.get(arg.attributes)));
*/
break
;
}
}
}
// Disable Back Button --> Kiosk mode
...
...
@@ -695,13 +592,13 @@ public class PictogramActivity extends Activity implements iVocabularyListener,
// Change the password
if
(
checkBox
.
isChecked
()){
// Show a new dialog
View
dialogChangeEscapeCode
=
View
.
inflate
(
context
,
R
.
layout
.
dialog_change_escape_code
,
null
);
View
dialogChangeEscapeCode
=
View
.
inflate
(
PCBcontext
.
getContext
()
,
R
.
layout
.
dialog_change_escape_code
,
null
);
final
EditText
input1
=
(
EditText
)
dialogChangeEscapeCode
.
findViewById
(
R
.
id
.
editText1
);
final
EditText
input2
=
(
EditText
)
dialogChangeEscapeCode
.
findViewById
(
R
.
id
.
editText2
);
// Build the AlertDialog
AlertDialog
.
Builder
builder
=
new
AlertDialog
.
Builder
(
context
);
builder
.
setTitle
(
context
.
getResources
().
getString
(
R
.
string
.
newEscapeCode
));
AlertDialog
.
Builder
builder
=
new
AlertDialog
.
Builder
(
PCBcontext
.
getContext
()
);
builder
.
setTitle
(
PCBcontext
.
getContext
()
.
getResources
().
getString
(
R
.
string
.
newEscapeCode
));
builder
.
setView
(
dialogChangeEscapeCode
);
// Set up the buttons
...
...
@@ -715,11 +612,11 @@ public class PictogramActivity extends Activity implements iVocabularyListener,
if
(
m_Text1
.
equalsIgnoreCase
(
m_Text2
))
{
// Change the keyword
PCBcontext
.
getDevice
().
setKeyword
(
m_Text1
);
Toast
.
makeText
(
context
,
getResources
().
getString
(
R
.
string
.
codeModified
),
Toast
.
LENGTH_SHORT
).
show
();
Toast
.
makeText
(
PCBcontext
.
getContext
()
,
getResources
().
getString
(
R
.
string
.
codeModified
),
Toast
.
LENGTH_SHORT
).
show
();
// And exit PictogramActivity
finish
();
}
else
Toast
.
makeText
(
context
,
getResources
().
getString
(
R
.
string
.
codesNotEqual
),
Toast
.
LENGTH_SHORT
).
show
();
}
else
Toast
.
makeText
(
PCBcontext
.
getContext
()
,
getResources
().
getString
(
R
.
string
.
codesNotEqual
),
Toast
.
LENGTH_SHORT
).
show
();
}
});
builder
.
setNegativeButton
(
getResources
().
getString
(
R
.
string
.
cancel
),
new
DialogInterface
.
OnClickListener
()
{
...
...
@@ -741,7 +638,7 @@ public class PictogramActivity extends Activity implements iVocabularyListener,
*/
}
// Wrong code
}
else
Toast
.
makeText
(
context
,
getResources
().
getString
(
R
.
string
.
wrongCode
),
Toast
.
LENGTH_SHORT
).
show
();
}
else
Toast
.
makeText
(
PCBcontext
.
getContext
()
,
getResources
().
getString
(
R
.
string
.
wrongCode
),
Toast
.
LENGTH_SHORT
).
show
();
}
});
builder
.
setNegativeButton
(
getResources
().
getString
(
R
.
string
.
cancel
),
new
DialogInterface
.
OnClickListener
()
{
...
...
@@ -921,4 +818,105 @@ public class PictogramActivity extends Activity implements iVocabularyListener,
return
true
;
}
}
/*
* Methods for add a new picto from pcb
*
*/
/**
* add a local picto from pcb
* @param row
* @param col
*/
public
void
addPicto
(
int
row
,
int
col
)
{
Intent
intent
=
new
Intent
(
Intent
.
ACTION_PICK
);
intent
.
setType
(
"image/*"
);
this
.
getIntent
().
putExtra
(
Picto
.
JSON_ATTTRS
.
ROW
,
row
);
this
.
getIntent
().
putExtra
(
Picto
.
JSON_ATTTRS
.
COLUMN
,
col
);
startActivityForResult
(
intent
,
SELECT_PICTURE
);
}
/**
* función para la edición de un texto asociado a una nueva imagen y guardar el nuevo picto
*/
public
void
chooseTextAndSavePicto
(
final
String
selectedImagePath
,
final
int
row
,
final
int
col
)
{
AlertDialog
.
Builder
builder
=
new
AlertDialog
.
Builder
(
this
);
builder
.
setTitle
(
getResources
().
getString
(
R
.
string
.
enterImgLabel
));
// Set up the input
final
EditText
input
=
new
EditText
(
this
);
input
.
setInputType
(
InputType
.
TYPE_CLASS_TEXT
);
builder
.
setView
(
input
);
// Set up the buttons
builder
.
setPositiveButton
(
"OK"
,
new
DialogInterface
.
OnClickListener
()
{
@Override
public
void
onClick
(
DialogInterface
dialog
,
int
which
)
{
int
cat
=
PictogramActivity
.
this
.
currentCategory
!=
null
?
PictogramActivity
.
this
.
currentCategory
.
get_id
()
:
Picto
.
NO_CATEGORY
;
Picto
localPicto
=
PCBcontext
.
getVocabulary
().
saveLocalPicto
(
selectedImagePath
,
input
.
getText
().
toString
(),
cat
,
row
,
col
);
change
(
action
.
add
,
cat
,
localPicto
.
get_id
(),
null
);
//gui must be refresh
}
});
builder
.
show
();
}
/**
* Función para la selección de una foto del carrete
* @param requestCode
* @param resultCode
* @param data
*/
public
void
onActivityResult
(
int
requestCode
,
int
resultCode
,
Intent
data
)
{
super
.
onActivityResult
(
requestCode
,
resultCode
,
data
);
if
(
resultCode
==
Activity
.
RESULT_OK
)
{
if
(
requestCode
==
SELECT_PICTURE
)
{
String
selectedImagePath
;
Uri
selectedImageUri
=
data
.
getData
();
selectedImagePath
=
getPath
(
selectedImageUri
);
int
row
=
this
.
getIntent
().
getIntExtra
(
Picto
.
JSON_ATTTRS
.
ROW
,
-
1
);
int
col
=
this
.
getIntent
().
getIntExtra
(
Picto
.
JSON_ATTTRS
.
COLUMN
,
-
1
);
Log
.
i
(
this
.
getClass
().
getCanonicalName
(),
"0 Picto x y "
+
" "
+
row
+
" "
+
col
);
this
.
getIntent
().
removeExtra
(
Picto
.
JSON_ATTTRS
.
ROW
);
this
.
getIntent
().
removeExtra
(
Picto
.
JSON_ATTTRS
.
COLUMN
);
chooseTextAndSavePicto
(
selectedImagePath
,
row
,
col
);
}
}
}
/**
* Función para la selección de una foto del carrete
* @param uri
* @return
*/
static
public
String
getPath
(
Uri
uri
)
{
if
(
uri
==
null
)
{
return
null
;
}
// this will only work for images selected from gallery
String
[]
projection
=
{
MediaStore
.
Images
.
Media
.
DATA
};
Cursor
cursor
=
PCBcontext
.
getContext
().
getContentResolver
().
query
(
uri
,
projection
,
null
,
null
,
null
);
if
(
cursor
!=
null
){
int
column_index
=
cursor
.
getColumnIndexOrThrow
(
MediaStore
.
Images
.
Media
.
DATA
);
cursor
.
moveToFirst
();
return
cursor
.
getString
(
column_index
);
}
return
uri
.
getPath
();
}
}
android/Pictogram/app/src/main/java/com/yottacode/pictogram/gui/SerialActivity.java
View file @
889b9572
...
...
@@ -108,7 +108,6 @@ public class SerialActivity extends Activity implements iRestapiListener {
password
=
""
;
}
// Escribo los últimos valores indicados
mSerialViewMail
.
setText
(
username
);
//mSerialViewPass.setText(password);
...
...
@@ -124,78 +123,74 @@ public class SerialActivity extends Activity implements iRestapiListener {
Log
.
d
(
LOG_TAG
,
"PCBcontext iniciado"
);
//if (PCBcontext.getDevice().getLastStuId() != 0) {
if
(!
username
.
equals
(
""
)
&&
!
password
.
equals
(
""
)){
// Tengo usuario, sigo con este usuario
RestapiWrapper
wrapper
=
PCBcontext
.
getRestapiWrapper
();
if
(
username
.
contains
(
"@"
)){
// Es un supervisor
String
operation
=
"sup/login"
;
Hashtable
<
String
,
String
>
postDataParams
=
new
Hashtable
<
String
,
String
>();
postDataParams
.
put
(
"email"
,
username
);
postDataParams
.
put
(
"password"
,
password
);
if
(!
username
.
equals
(
""
)
&&
!
password
.
equals
(
""
)){
// Tengo usuario, sigo con este usuario
if
(
RestapiWrapper
.
ping
(
context
.
getResources
().
getString
(
R
.
string
.
server
),
"server/ping"
,
this
))
{
// Tengo conexión a internet. Compruebo ONLINE
RestapiWrapper
wrapper
=
PCBcontext
.
getRestapiWrapper
();
if
(
username
.
contains
(
"@"
)){
// Es un supervisor
String
operation
=
"sup/login"
;
Hashtable
<
String
,
String
>
postDataParams
=
new
Hashtable
<
String
,
String
>();
postDataParams
.
put
(
"email"
,
username
);
postDataParams
.
put
(
"password"
,
password
);
/*
postDataParams.put("idFirmware", _ANDROIDID);
postDataParams.put("desc", _MODEL);
postDataParams.put("serial", serial);
*/
wrapper
.
ask
(
operation
,
postDataParams
,
"post"
,
(
iRestapiListener
)
context
);
}
else
{
// Es un estudiante
Log
.
d
(
LOG_TAG
,
"Entro con usuario y password"
);
String
operation
=
"stu/login"
;
Hashtable
<
String
,
String
>
postDataParams
=
new
Hashtable
<
String
,
String
>();
postDataParams
.
put
(
"username"
,
username
);
postDataParams
.
put
(
"password"
,
password
);
wrapper
.
ask
(
operation
,
postDataParams
,
"post"
,
(
iRestapiListener
)
context
);
}
else
{
// Es un estudiante
Log
.
d
(
LOG_TAG
,
"Entro con usuario y password"
);
String
operation
=
"stu/login"
;
Hashtable
<
String
,
String
>
postDataParams
=
new
Hashtable
<
String
,
String
>();
postDataParams
.
put
(
"username"
,
username
);
postDataParams
.
put
(
"password"
,
password
);
/*
postDataParams.put("idFirmware", _ANDROIDID);
postDataParams.put("desc", _MODEL);
postDataParams.put("serial", serial);
*/
wrapper
.
ask
(
operation
,
postDataParams
,
"post"
,
(
iRestapiListener
)
context
);
}
}
else
{
// Compruebo si tengo acceso a internet
//modificación FERNANDO
if
(!
RestapiWrapper
.
ping
(
context
.
getResources
().
getString
(
R
.
string
.
server
),
"server/ping"
,
this
))
{
// No puedo comprobar si el serial es válido. Muestro un alertdialog de error, y cierro la aplicación
AlertDialog
alertDialog
=
new
AlertDialog
.
Builder
(
SerialActivity
.
this
).
create
();
alertDialog
.
setTitle
(
"Mensaje del sistema"
);
alertDialog
.
setMessage
(
"No hay conexión a Internet. Inténtelo más tarde"
);
//alertDialog.setIcon(R.drawable.tick);
/*
alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(getApplicationContext(), "Saliendo de la aplicación", Toast.LENGTH_SHORT).show();
wrapper
.
ask
(
operation
,
postDataParams
,
"post"
,
(
iRestapiListener
)
context
);
}
}
else
{
// NO Tengo conexión a internet. Compruebo OFFLINE
if
(
username
.
contains
(
"@"
))
{
// Es un supervisor
}
else
{
// Es un estudiante
}
// ....
}
});
*/
alertDialog
.
show
();
// ¿QUÉ HACEMOS CON LA APP?
}
else
{
Button
mEntrarButton
=
(
Button
)
findViewById
(
R
.
id
.
entrar_button
);
mEntrarButton
.
setOnClickListener
(
new
OnClickListener
()
{
@Override
public
void
onClick
(
View
view
)
{
String
username
=
mSerialViewMail
.
getText
().
toString
();
String
password
=
mSerialViewPass
.
getText
().
toString
();
SharedPreferences
settings
=
getSharedPreferences
(
PREFS_NAME
,
0
);
SharedPreferences
.
Editor
editor
=
settings
.
edit
();
editor
.
putString
(
"username"
,
username
);
editor
.
putString
(
"password"
,
password
);
editor
.
commit
();
// DE PRUEBA
// Alumno
//username = "faf0001";
//password = "faf0001";
// Supervisor
//username = "dofer@ujaen.es";
//password = "dofer";
}
else
{
// No tengo aún usuario. Espero a que lo indique
Button
mEntrarButton
=
(
Button
)
findViewById
(
R
.
id
.
entrar_button
);
mEntrarButton
.
setOnClickListener
(
new
OnClickListener
()
{
@Override
public
void
onClick
(
View
view
)
{
String
username
=
mSerialViewMail
.
getText
().
toString
();
String
password
=
mSerialViewPass
.
getText
().
toString
();
SharedPreferences
settings
=
getSharedPreferences
(
PREFS_NAME
,
0
);
SharedPreferences
.
Editor
editor
=
settings
.
edit
();
editor
.
putString
(
"username"
,
username
);
editor
.
putString
(
"password"
,
password
);
editor
.
commit
();
// DE PRUEBA
// Alumno
username
=
"faf0001"
;
password
=
"faf0001"
;
// Supervisor
//username = "dofer@ujaen.es";
//password = "dofer";
// IMPORTANTE. FERNANDO: ¿Para qué el último argumento del listener?
if
(
RestapiWrapper
.
ping
(
context
.
getResources
().
getString
(
R
.
string
.
server
),
"server/ping"
,
null
))
{
// Tengo conexión a internet. Compruebo ONLINE
RestapiWrapper
wrapper
=
PCBcontext
.
getRestapiWrapper
();
if
(
username
.
contains
(
"@"
)){
// Es un supervisor
...
...
@@ -204,11 +199,6 @@ public class SerialActivity extends Activity implements iRestapiListener {
postDataParams
.
put
(
"email"
,
username
);
postDataParams
.
put
(
"password"
,
password
);
/*
postDataParams.put("idFirmware", _ANDROIDID);
postDataParams.put("desc", _MODEL);
postDataParams.put("serial", serial);
*/
wrapper
.
ask
(
operation
,
postDataParams
,
"post"
,
(
iRestapiListener
)
context
);
}
else
{
// Es un estudiante
...
...
@@ -217,16 +207,21 @@ public class SerialActivity extends Activity implements iRestapiListener {
postDataParams
.
put
(
"username"
,
username
);
postDataParams
.
put
(
"password"
,
password
);
/*
postDataParams.put("idFirmware", _ANDROIDID);
postDataParams.put("desc", _MODEL);
postDataParams.put("serial", serial);
*/
wrapper
.
ask
(
operation
,
postDataParams
,
"post"
,
(
iRestapiListener
)
context
);
}
}
else
{
// NO Tengo conexión a internet. Compruebo OFFLINE
if
(
username
.
contains
(
"@"
))
{
// Es un supervisor
// Necesito una función local que dado el username y pass me devuelva el listado de usuarios o el usuario, si es correcto
// ....
}
else
{
// Es un estudiante
}
// ....
}
}
);
}
}
}
);
}
}
...
...
@@ -250,7 +245,7 @@ public class SerialActivity extends Activity implements iRestapiListener {
Log
.
d
(
LOG_TAG
,
"JSON en result:"
+
result
.
toString
());
if
(
result
.
toString
().
contains
(
"error"
)){
progressDialog
.
dismiss
();
if
(
progressDialog
!=
null
)
progressDialog
.
dismiss
();
AlertDialog
.
Builder
builder
=
new
AlertDialog
.
Builder
(
SerialActivity
.
this
);
...
...
@@ -308,7 +303,8 @@ public class SerialActivity extends Activity implements iRestapiListener {
PCBcontext
.
set_user
(
student
,
jsonToken
,
new
iImgDownloaderListener
()
{
@Override
public
void
loadComplete
()
{
progressDialog
.
dismiss
();
if
(
progressDialog
!=
null
)
progressDialog
.
dismiss
();
Intent
pictogramActivity
=
new
Intent
(
SerialActivity
.
this
,
PictogramActivity
.
class
);
startActivity
(
pictogramActivity
);
}
...
...
@@ -331,7 +327,6 @@ public class SerialActivity extends Activity implements iRestapiListener {
setContentView
(
R
.
layout
.
activity_serial
);
}
});
PCBcontext
.
getDevice
().
deleteDeprecatedImgs
();
}
else
{
// Es un Supervisor
...
...
@@ -342,7 +337,7 @@ public class SerialActivity extends Activity implements iRestapiListener {
int
su_id_int
=
su_id
.
intValue
();
//close the progress dialog
if
(!
username
.
contains
(
"@"
)){
if
(!
username
.
contains
(
"@"
)
&&
progressDialog
!=
null
){
progressDialog
.
dismiss
();
}
...
...
@@ -372,8 +367,6 @@ public class SerialActivity extends Activity implements iRestapiListener {
}
catch
(
JSONException
e
)
{
//Log.d(LOG_TAG, "ERROR 2");
e
.
printStackTrace
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
...
...
@@ -382,10 +375,10 @@ public class SerialActivity extends Activity implements iRestapiListener {
Log
.
e
(
this
.
getClass
().
getName
(),
" Server restapi error: "
+
e
.
getLocalizedMessage
());
AlertDialog
.
Builder
builder
=
new
AlertDialog
.
Builder
(
SerialActivity
.
this
);
builder
.
setMessage
(
getString
(
R
.
string
.
serverError
)+
":"
+
e
.
getLocalizedMessage
())
.
setCancelable
(
false
)
.
setPositiveButton
(
"Entendido"
,
new
DialogInterface
.
OnClickListener
()
{
public
void
onClick
(
DialogInterface
dialog
,
int
id
)
{
builder
.
setMessage
(
getString
(
R
.
string
.
serverError
)
+
":"
+
e
.
getLocalizedMessage
())
.
setCancelable
(
false
)
.
setPositiveButton
(
"Entendido"
,
new
DialogInterface
.
OnClickListener
()
{
public
void
onClick
(
DialogInterface
dialog
,
int
id
)
{
//do things
}
});
...
...
android/Pictogram/app/src/main/java/com/yottacode/pictogram/net/ImgDownloader.java
View file @
889b9572
...
...
@@ -8,6 +8,7 @@ import android.util.Log;
import
com.yottacode.pictogram.R
;
import
com.yottacode.pictogram.tools.Img
;
import
com.yottacode.pictogram.tools.PCBcontext
;
import
java.io.File
;
import
java.io.FileInputStream
;
...
...
@@ -29,16 +30,16 @@ public class ImgDownloader extends AsyncTask<Vector<Img>, Void, Img> {
iImgDownloaderListener
imgListener
;
public
static
enum
status
{
downloading
,
downloaded_ok
,
downloaded_failed
}
public
static
enum
source
{
remote
,
local
}
public
static
enum
t
source
{
remote
,
local
}
public
status
current
;
private
boolean
force_download
;
Context
context
;
ActivityManager
.
MemoryInfo
mi
;
ActivityManager
activityManager
;
source
source
;
t
source
source
;
public
ImgDownloader
(
Context
context
,
iImgDownloaderListener
listener
,
source
source
)
{
public
ImgDownloader
(
Context
context
,
iImgDownloaderListener
listener
,
t
source
source
)
{
this
.
imgListener
=
listener
;
this
.
context
=
context
;
this
.
mi
=
new
ActivityManager
.
MemoryInfo
();
...
...
@@ -68,7 +69,7 @@ public class ImgDownloader extends AsyncTask<Vector<Img>, Void, Img> {
if
(!
img
.
exists_bitmap
(
this
.
context
)
||
this
.
force_download
)
try
{
this
.
activityManager
.
getMemoryInfo
(
mi
);
Log
.
i
(
this
.
getClass
().
getCanonicalName
(),
img
.
get_url
()
+
" to be downloaded"
);
Log
.
i
(
this
.
getClass
().
getCanonicalName
(),
"Picto Img "
+
img
.
get_url
()
+
" to be downloaded"
);
if
(
this
.
source
==
source
.
remote
)
{
String
surl
=
context
.
getResources
().
getString
(
R
.
string
.
server
)
+
"/"
+
img
.
get_url
();
URL
url
=
new
URL
(
surl
);
...
...
@@ -113,8 +114,8 @@ public class ImgDownloader extends AsyncTask<Vector<Img>, Void, Img> {
@Override
protected
void
onPostExecute
(
Img
img
)
{
Log
.
d
(
this
.
getClass
().
getCanonicalName
(),
"Inside OnPostExecute()"
+
new
SimpleDateFormat
(
"HH:mm:ss"
)
);
if
(
imgListener
!=
null
)
PCBcontext
.
getDevice
().
deleteDeprecatedImgs
(
);
if
(
imgListener
!=
null
)
if
(
img
==
null
)
imgListener
.
loadComplete
();
else
imgListener
.
loadImg
(
img
);
}
...
...
android/Pictogram/app/src/main/java/com/yottacode/pictogram/net/NetService.java
View file @
889b9572
...
...
@@ -55,14 +55,11 @@ public class NetService implements Runnable {
}
});
Log
.
i
(
this
.
getClass
().
getName
(),
"Checking Pictogram server access..."
);
Log
.
d
(
this
.
getClass
().
getName
(),
this
.
updated
?
"Pictogram server access ok"
:
"Pictogram server access failed, Internet connection available?"
);
Log
.
i
(
this
.
getClass
().
getName
(),
this
.
updated
?
"Pictogram server access ok"
:
"Pictogram server access failed, Internet connection available?"
);
ScheduledThreadPoolExecutor
exec
=
new
ScheduledThreadPoolExecutor
(
1
);
exec
.
scheduleWithFixedDelay
(
this
,
0
,
delay
,
TimeUnit
.
SECONDS
);
}
public
NetService
(){
}
public
boolean
online
()
{
return
updated
;}
...
...
@@ -87,6 +84,7 @@ public class NetService implements Runnable {
if
(
result
==
null
)
{
updated
=
false
;
}
else
if
(!
updated
)
{
Log
.
i
(
this
.
getClass
().
getName
(),
"PCB reconnect"
);
PCBcontext
.
getRoom
().
reconnect
();
PCBcontext
.
getVocabulary
().
synchronize
();
PCBcontext
.
getActionLog
().
batch
();
...
...
android/Pictogram/app/src/main/java/com/yottacode/pictogram/net/PictoUploader.java
View file @
889b9572
package
com
.
yottacode
.
pictogram
.
net
;
import
android.content.Context
;
import
android.util.Log
;
import
com.google.gson.JsonObject
;
...
...
@@ -8,7 +7,6 @@ import com.koushikdutta.ion.Ion;
import
com.koushikdutta.ion.Response
;
import
com.yottacode.net.iRestapiListener
;
import
com.yottacode.pictogram.R
;
import
com.yottacode.pictogram.action.PictoAction
;
import
com.yottacode.pictogram.action.VocabularyAction
;
import
com.yottacode.pictogram.dao.Picto
;
import
com.yottacode.pictogram.tools.Img
;
...
...
@@ -19,7 +17,6 @@ import org.json.JSONException;
import
org.json.JSONObject
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.IOException
;
import
java.io.UnsupportedEncodingException
;
import
java.util.Hashtable
;
...
...
@@ -34,51 +31,17 @@ public class PictoUploader {
this
.
picto
=
picto
;
}
/**
* if the status of a given picto was modifed from the PCB it is uploaded to the server
*
*/
public
void
uploadState
(
){
Hashtable
<
String
,
String
>
params
=
new
Hashtable
<
String
,
String
>(
1
);
params
.
put
(
"attributes"
,
picto
.
get_json_attrs
());
params
.
put
(
"id_stu"
,
Integer
.
toString
(
PCBcontext
.
getPcbdb
().
getCurrentUser
().
get_id_stu
()));
params
.
put
(
"id_pic"
,
Integer
.
toString
(
this
.
picto
.
get_id
()));
picto
.
status_modified
(
false
);
Log
.
i
(
this
.
getClass
().
getCanonicalName
(),
"Uploading "
+
params
.
toString
());
PCBcontext
.
getRestapiWrapper
().
ask
(
PCBcontext
.
getPcbdb
().
getCurrentUser
().
get_restapi_operation_stu
()
+
"/picto"
,
params
,
"put"
,
new
iRestapiListener
()
{
@Override
public
void
preExecute
()
{
}
@Override
public
void
result
(
JSONArray
result
)
{
}
@Override
public
void
result
(
JSONObject
result
)
{
Log
.
i
(
this
.
getClass
().
getCanonicalName
(),
"Uploaded state result: "
+
result
.
toString
());
}
@Override
public
void
error
(
Exception
e
)
{
Log
.
e
(
this
.
getClass
().
getCanonicalName
(),
"Error: "
+
e
.
getLocalizedMessage
());
picto
.
status_modified
(
true
);
}
}
);
PCBcontext
.
getActionLog
().
log
(
new
VocabularyAction
(
VocabularyAction
.
ALTERATTRS
,
this
.
picto
));
}
private
int
uploadImg
(
Img
img
)
throws
UnsupportedEncodingException
{
int
img_id
;
if
(!
img
.
get_filetype
().
equalsIgnoreCase
(
"png"
))
throw
new
UnsupportedEncodingException
(
"Extension "
+
img
.
get_filetype
()+
" is not supported. Only png files"
);
Ion
ion
=
Ion
.
getDefault
(
PCBcontext
.
getContext
());
Log
.
i
(
this
.
getClass
().
getCanonicalName
(),
"Uploading "
+
img
.
file_name
()
+
" from "
+
img
.
get_type
());
try
{
Log
.
i
(
this
.
getClass
().
getCanonicalName
(),
"Uploading Picto img"
+
img
.
file_name
()
+
" from "
+
img
.
get_type
()
+
"size:"
+
img
.
get_bitmap
(
PCBcontext
.
getContext
()).
getWidth
()
+
" "
+
img
.
get_bitmap
(
PCBcontext
.
getContext
()).
getHeight
());
}
catch
(
IOException
e
)
{
Log
.
i
(
this
.
getClass
().
getCanonicalName
(),
"Uploading Picto img"
+
img
.
file_name
()
+
" from "
+
img
.
get_type
());
}
File
file
=
img
.
file
(
PCBcontext
.
getContext
());
Response
<
JsonObject
>
response
=
null
;
...
...
@@ -123,8 +86,7 @@ public class PictoUploader {
/**
* if the a picto was included from the PCB, the translation is uploaded to the server
*/
private
int
uploadAttributes
(
int
id_picto
)
{
final
int
id_stupicto
[]=
new
int
[
1
];
private
void
uploadAttributes
(
int
id_picto
)
{
Hashtable
<
String
,
String
>
params
=
new
Hashtable
<
String
,
String
>(
4
);
try
{
params
.
put
(
"json"
,
new
JSONObject
().
put
(
"attributes"
,
...
...
@@ -149,22 +111,14 @@ public class PictoUploader {
@Override
public
void
result
(
JSONObject
result
)
{
Log
.
i
(
this
.
getClass
().
getCanonicalName
(),
" Attributes uploaded: "
+
result
.
toString
());
/* try {
id_stupicto[0]=result.getJSONObject("picto").getInt("id");
} catch (JSONException e) {
e.printStackTrace();
Log.e(this.getClass().getCanonicalName(), "Error: " + e.getLocalizedMessage());
}*/
}
@Override
public
void
error
(
Exception
e
)
{
Log
.
e
(
this
.
getClass
().
getCanonicalName
(),
" Error uploading attributes: "
+
e
.
getLocalizedMessage
());
id_stupicto
[
0
]=-
1
;
PCBcontext
.
getVocabulary
().
addPicto
(
picto
,
ImgDownloader
.
tsource
.
local
)
;
}
});
return
id_stupicto
[
0
];
}
/**
...
...
@@ -193,21 +147,66 @@ public class PictoUploader {
@Override
public
void
error
(
Exception
e
)
{
Log
.
e
(
this
.
getClass
().
getCanonicalName
(),
"Error: "
+
e
.
getLocalizedMessage
());
PCBcontext
.
getVocabulary
().
addPicto
(
picto
,
ImgDownloader
.
tsource
.
local
);
}
});
}
/**
*Upload local picto. It requires: i) to upload the image, ii) to upload the attributes and iii) to upload the expression
**/
*Try to Upload local picto. It requires:
* i) to upload the image,
* ii) to upload the attributes
* iii) to upload the expression
* iv) delete the old local picto since it will be recovered from the server
**/
public
void
upload
()
throws
IOException
{
int
img_id
=
uploadImg
(
this
.
picto
);
if
(
img_id
>
0
)
{
uploadAttributes
(
img_id
);
uploadTranslation
(
img_id
);
PCBcontext
.
getActionLog
().
log
(
new
VocabularyAction
(
VocabularyAction
.
ADD
,
this
.
picto
));
}
int
old_picto
=
this
.
picto
.
get_id
();
int
img_id
=
uploadImg
(
this
.
picto
);
if
(
img_id
>
0
)
{
uploadAttributes
(
img_id
);
uploadTranslation
(
img_id
);
PCBcontext
.
getRoom
().
emit
(
new
VocabularyAction
(
VocabularyAction
.
ADD
,
PictoUploader
.
this
.
picto
));
PCBcontext
.
getPcbdb
().
deletePicto
(
old_picto
);
}
}
/**
* if the status of a given picto was modifed from the PCB it is uploaded to the server
*
*/
public
void
uploadState
(
){
Hashtable
<
String
,
String
>
params
=
new
Hashtable
<
String
,
String
>(
1
);
params
.
put
(
"attributes"
,
picto
.
get_json_server_attrs
());
params
.
put
(
"id_stu"
,
Integer
.
toString
(
PCBcontext
.
getPcbdb
().
getCurrentUser
().
get_id_stu
()));
params
.
put
(
"id_pic"
,
Integer
.
toString
(
this
.
picto
.
get_id
()));
Log
.
i
(
this
.
getClass
().
getCanonicalName
(),
"Picto Uploading "
+
params
.
toString
());
PCBcontext
.
getRestapiWrapper
().
ask
(
PCBcontext
.
getPcbdb
().
getCurrentUser
().
get_restapi_operation_stu
()
+
"/picto"
,
params
,
"put"
,
new
iRestapiListener
()
{
@Override
public
void
preExecute
()
{
}
@Override
public
void
result
(
JSONArray
result
)
{
}
@Override
public
void
result
(
JSONObject
result
)
{
Log
.
i
(
PictoUploader
.
this
.
getClass
().
getCanonicalName
(),
"Upload ok Picto "
+
PictoUploader
.
this
.
picto
.
get_id
());
picto
.
set_local_status
(
false
);
PCBcontext
.
getRoom
().
emit
(
new
VocabularyAction
(
VocabularyAction
.
ALTERATTRS
,
PictoUploader
.
this
.
picto
));
}
@Override
public
void
error
(
Exception
e
)
{
Log
.
e
(
this
.
getClass
().
getCanonicalName
(),
"Picto Error: "
+
e
.
getLocalizedMessage
());
}
}
);
}
}
android/Pictogram/app/src/main/java/com/yottacode/pictogram/tools/Img.java
View file @
889b9572
...
...
@@ -4,8 +4,11 @@ package com.yottacode.pictogram.tools;
import
android.content.Context
;
import
android.graphics.Bitmap
;
import
android.graphics.BitmapFactory
;
import
android.graphics.Rect
;
import
android.util.Log
;
import
com.yottacode.tools.FileTools
;
import
java.io.ByteArrayOutputStream
;
import
java.io.File
;
import
java.io.FileInputStream
;
...
...
@@ -15,6 +18,7 @@ import java.io.IOException;
import
java.io.InputStream
;
import
java.util.Enumeration
;
/**
* Img
* @author Fernando
...
...
@@ -26,11 +30,17 @@ public class Img {
static
public
String
SUPERVISOR
=
"supervisor"
;
public
static
final
void
mkDirs
(
Context
context
)
{
new
File
(
path
(
context
,
Img
.
VOCABULARY
)
).
mkdirs
()
;
new
File
(
path
(
context
,
Img
.
STUDENT
)
).
mkdirs
()
;
new
File
(
path
(
context
,
Img
.
SUPERVISOR
)
).
mkdirs
()
;
File
file
;
file
=
new
File
(
path
(
context
,
Img
.
VOCABULARY
));
FileTools
.
deleteDirectory
(
file
);
file
.
mkdirs
();
file
=
new
File
(
path
(
context
,
Img
.
STUDENT
));
FileTools
.
deleteDirectory
(
file
);
file
.
mkdirs
();
file
=
new
File
(
path
(
context
,
Img
.
SUPERVISOR
));
FileTools
.
deleteDirectory
(
file
);
file
.
mkdirs
();
}
protected
int
id
;
protected
String
url
;
String
type
;
...
...
@@ -121,12 +131,13 @@ public class Img {
File
file
=
file
(
context
);
FileOutputStream
os
=
new
FileOutputStream
(
file
);
try
{
this
.
bitmap
=
BitmapFactory
.
decodeStream
(
is
);
this
.
bitmap
=
BitmapFactory
.
decodeStream
(
is
,
new
Rect
(
0
,
0
,
78
,
66
),
null
);
}
catch
(
java
.
lang
.
OutOfMemoryError
err
)
{
Log
.
e
(
Img
.
class
.
getCanonicalName
(),
"Out of memory when decoding "
+
this
.
get_url
());
}
ByteArrayOutputStream
outstream
=
new
ByteArrayOutputStream
();
this
.
bitmap
.
setHasAlpha
(
true
);
Log
.
i
(
this
.
getClass
().
getCanonicalName
(),
"Img Uploading Picto img"
+
file_name
()
+
" from "
+
get_type
()
+
"size:"
+
get_bitmap
(
PCBcontext
.
getContext
()).
getWidth
()
+
" "
+
get_bitmap
(
PCBcontext
.
getContext
()).
getHeight
());
this
.
bitmap
.
compress
(
Bitmap
.
CompressFormat
.
PNG
,
100
,
outstream
);
byte
[]
byteArray
=
outstream
.
toByteArray
();
os
.
write
(
byteArray
);
...
...
android/Pictogram/app/src/main/java/com/yottacode/pictogram/tools/PCBcontext.java
View file @
889b9572
...
...
@@ -28,7 +28,7 @@ public final class PCBcontext {
private
static
RestapiWrapper
wrapper
;
private
static
Vocabulary
vocabulary
;
private
static
ActionLog
actionLog
;
private
static
boolean
init
=
false
;
protected
PCBcontext
()
{
// Initialize internal objects. This initialization is run only the first time
...
...
@@ -50,10 +50,15 @@ public final class PCBcontext {
// Init method for passing params to the singleton
public
static
void
init
(
Context
c
){
context
=
c
;
device
=
new
Device
(
c
,
null
,
1
);
wrapper
=
new
RestapiWrapper
(
context
.
getResources
().
getString
(
R
.
string
.
server
),
null
);
Log
.
i
(
PCBcontext
.
class
.
getCanonicalName
(),
"PCB context started, waiting. It's required set user "
);
if
(!
init
)
{
init
=
true
;
context
=
c
;
device
=
new
Device
(
c
,
null
,
1
);
wrapper
=
new
RestapiWrapper
(
context
.
getResources
().
getString
(
R
.
string
.
server
),
null
);
service
=
new
NetService
(
context
.
getResources
().
getInteger
(
R
.
integer
.
netservice_timing
));
Log
.
i
(
PCBcontext
.
class
.
getCanonicalName
(),
"PCB context started. It's required to be invoked set_user method"
);
}
else
Log
.
e
(
PCBcontext
.
class
.
getClass
().
getCanonicalName
(),
"Init method was previously invoked! Please, revise your code"
);
}
/**
...
...
@@ -64,13 +69,14 @@ public final class PCBcontext {
* @param listener
*/
public
static
void
set_user
(
User
student
,
String
token
,
iImgDownloaderListener
listener
)
{
Log
.
i
(
PCBcontext
.
class
.
getCanonicalName
(),
"User set at student "
+
student
.
get_name_stu
());
if
(!
init
)
throw
new
java
.
lang
.
AssertionError
(
"init must be called once previously "
);
Log
.
i
(
PCBcontext
.
class
.
getCanonicalName
(),
"User set at student "
+
student
.
get_name_stu
());
wrapper
.
setToken
(
token
);
pcbdb
=
new
PCBDBHelper
(
null
,
1
,
student
);
service
=
new
NetService
(
context
.
getResources
().
getInteger
(
R
.
integer
.
netservice_timing
));
vocabulary
=
new
Vocabulary
(
listener
);
room
=
new
Room
();
actionLog
=
new
ActionLog
();
vocabulary
=
new
Vocabulary
(
listener
);
}
// Return the context
...
...
android/Pictogram/app/src/main/java/com/yottacode/tools/FileTools.java
0 → 100644
View file @
889b9572
package
com
.
yottacode
.
tools
;
import
java.io.File
;
/**
* Created by Fernando on 14/03/2016.
*/
public
class
FileTools
{
public
static
boolean
deleteDirectory
(
File
path
)
{
if
(
path
.
exists
()
)
{
File
[]
files
=
path
.
listFiles
();
if
(
files
==
null
)
{
return
true
;
}
for
(
int
i
=
0
;
i
<
files
.
length
;
i
++)
{
if
(
files
[
i
].
isDirectory
())
{
deleteDirectory
(
files
[
i
]);
}
else
{
files
[
i
].
delete
();
}
}
}
return
(
path
.
delete
()
);
}
}
android/Pictogram/app/src/main/res/layout/activity_splash_screen.xml
View file @
889b9572
...
...
@@ -13,18 +13,12 @@
android:contentDescription=
"@string/app_name"
android:orientation=
"vertical"
android:src=
"@drawable/yottalogo72p"
android:layout_alignParentTop=
"true"
android:layout_centerHorizontal=
"true"
android:layout_marginTop=
"120dp"
/>
<TextView
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:textAppearance=
"?android:attr/textAppearanceMedium"
android:text=
"presenta..."
android:id=
"@+id/textView2"
android:layout_centerVertical=
"true"
android:layout_centerHorizontal=
"true"
/>
android:scaleX=
"0.5"
android:scaleY=
"0.5"
android:id=
"@+id/imageView2"
android:layout_alignParentBottom=
"true"
android:layout_alignParentEnd=
"true"
android:layout_marginBottom=
"44dp"
/>
<ImageView
android:layout_width=
"200px"
...
...
@@ -32,19 +26,10 @@
android:contentDescription=
"@string/app_name"
android:orientation=
"vertical"
android:src=
"@drawable/logo_pictogram"
android:layout_alignParentBottom=
"true"
android:layout_centerHorizontal=
"true"
android:layout_marginBottom=
"120dp"
android:id=
"@+id/imageView"
/>
<TextView
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:textAppearance=
"?android:attr/textAppearanceMedium"
android:text=
"Pictogram"
android:id=
"@+id/textView3"
android:paddingTop=
"70dp"
android:layout_alignBottom=
"@+id/imageView"
android:id=
"@+id/imageView"
android:scaleX=
"1.5"
android:scaleY=
"1.5"
android:layout_centerVertical=
"true"
android:layout_centerHorizontal=
"true"
/>
</RelativeLayout>
android/Pictogram/app/src/main/res/raw/pcbdb_create.sql
View file @
889b9572
...
...
@@ -53,7 +53,8 @@ constraint ck_users UNIQUE(id_stu,id_sup)
CREATE
TABLE
collection
(
id_stu
INTEGER
NOT
NULL
REFERENCES
student
ON
DELETE
CASCADE
,
id_picto
INTEGER
NOT
NULL
REFERENCES
picto
ON
DELETE
CASCADE
,
attributes
VARCHAR
(
1024
)
attributes
VARCHAR
(
1024
),
constraint
ck_collection
UNIQUE
(
id_stu
,
id_picto
)
)
;
--
...
...
@@ -202,7 +203,7 @@ CREATE TRIGGER trg_delete_collection_detail
INSTEAD
OF
DELETE
ON
collection_detail
FOR
EACH
ROW
BEGIN
DELETE
FROM
collection
WHERE
id_picto
=
OLD
.
id_picto
;
DELETE
FROM
collection
WHERE
id_picto
=
OLD
.
id_picto
AND
id_stu
=
OLD
.
id_stu
;
END
;
--
...
...
android/Pictogram/app/src/main/res/values-en/strings.xml
View file @
889b9572
...
...
@@ -47,4 +47,9 @@
<string
name=
"naturalgrammar"
>
SUpO_EN
</string>
<string
name=
"pictogrammar"
>
SUpO_PICTOEN
</string>
<string
name=
"nogrammar"
>
Warning: unknown language
</string>
<!--Upload local img -->
<string
name=
"enterImgLabel"
>
Enter img label
</string>
<string
name=
"notNewCats"
>
Including new categories is not allowed
</string>
</resources>
android/Pictogram/app/src/main/res/values-es/strings.xml
View file @
889b9572
...
...
@@ -46,10 +46,14 @@
<!--Semantic grammar -->
<string
name=
"loadingGrammar"
>
Por favor espere, cargando gramática semántica
</string>
<string
name=
"naturalgrammar"
>
SUpO_ES
</string>
<string
name=
"pictogrammar"
>
SUpO_PICTOES
</string>
<string
name=
"grammar"
>
SUpO_ES
</string>
<string
name=
"nogrammar"
>
Advertencia: Lenguaje no soportado
</string>
<string
name=
"pictogrammar"
>
SUpO_PICTOES
</string>
<item
type=
"integer"
name=
"maxInTape"
>
8
</item>
<!--Upload local img -->
<string
name=
"enterImgLabel"
>
Introduzca etiqueta de la imagen
</string>
<string
name=
"notNewCats"
>
No puede añadir nuevas categorias
</string>
</resources>
android/Pictogram/app/src/main/res/values/strings.xml
View file @
889b9572
...
...
@@ -45,8 +45,28 @@
<!--Semantic grammar -->
<string
name=
"loadingGrammar"
>
Please wait, loading semmantic grammar
</string>
<string
name=
"naturalgrammar"
>
SUpO_EN
</string>
<string
name=
"grammar"
>
SUpO_EN
</string>
<string
name=
"nogrammar"
>
Warning: unknown language
</string>
<string
name=
"pictogrammar"
>
SUpO_PICTOEN
</string>
<item
type=
"integer"
name=
"maxInTape"
>
8
</item>
<!--Upload local img -->
<string
name=
"enterImgLabel"
>
Introduzca etiqueta de la imagen
</string>
<string
name=
"notNewCats"
>
No puede añadir nuevas categorias
</string>
<item
name=
"maxInTape"
type=
"integer"
>
8
</item>
<string
name=
"title_activity_img_label"
>
img_label
</string>
<!-- Strings related to login -->
<string
name=
"prompt_email"
>
Email
</string>
<string
name=
"prompt_password"
>
Password (optional)
</string>
<string
name=
"action_sign_in"
>
Sign in or register
</string>
<string
name=
"action_sign_in_short"
>
Sign in
</string>
<string
name=
"error_invalid_email"
>
This email address is invalid
</string>
<string
name=
"error_invalid_password"
>
This password is too short
</string>
<string
name=
"error_incorrect_password"
>
This password is incorrect
</string>
<string
name=
"error_field_required"
>
This field is required
</string>
<string
name=
"permission_rationale"
>
"Contacts permissions are needed for providing email
completions."
</string>
</resources>
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment