working on GF integration (i)

parent d257711b
...@@ -41,8 +41,11 @@ android { ...@@ -41,8 +41,11 @@ android {
} }
productFlavors { productFlavors {
FernandoFlavor { FernandoFlavor {
resValue "string", "server", "https://127.0.0.1:9944" resValue "string", "server", "https://pre.yottacode.com"
applicationId "com.yottacode.pictogrammar" applicationId "com.yottacode.pictogrammar"
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
}
} }
ArturoFlavor { ArturoFlavor {
resValue "string", "server", "https://192.168.1.37:1337" resValue "string", "server", "https://192.168.1.37:1337"
......
package com.yottacode.pictogrammar;
import java.io.Serializable;
public class Language implements Serializable {
private static final long serialVersionUID = 1L;
private final String mLangCode;
private final String mLangName;
private final String mConcrete;
private final int mKeyboardPage1Resource;
private final int mKeyboardPage2Resource;
public Language(String langCode, String langName, String concrete,
int keyboardResource) {
mLangCode = langCode;
mLangName = langName;
mConcrete = concrete;
mKeyboardPage1Resource = keyboardResource;
mKeyboardPage2Resource = keyboardResource;
}
public Language(String langCode, String langName, String concrete,
int keyboardPage1Resource, int keyboardPage2Resource) {
mLangCode = langCode;
mLangName = langName;
mConcrete = concrete;
mKeyboardPage1Resource = keyboardPage1Resource;
mKeyboardPage2Resource = keyboardPage2Resource;
}
public String getLangCode() {
return mLangCode;
}
public String getLangName() {
return mLangName;
}
public int getKeyboardPage1Resource() {
return mKeyboardPage1Resource;
}
public int getKeyboardPage2Resource() {
return mKeyboardPage2Resource;
}
String getConcrete() {
return mConcrete;
}
@Override
public String toString() {
return getLangName();
}
@Override
public boolean equals(Object o) {
Language other = (Language) o;
return mLangCode.equals(other.mLangCode);
}
}
\ No newline at end of file
...@@ -13,140 +13,59 @@ package com.yottacode.pictogrammar; ...@@ -13,140 +13,59 @@ package com.yottacode.pictogrammar;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.os.AsyncTask; import android.os.AsyncTask;
import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.LinkedList;
import java.util.Vector;
import org.grammaticalframework.sg.*;
import org.grammaticalframework.PGF; import org.grammaticalframework.pgf.*;
import org.json.JSONException;
import org.json.JSONObject;
import com.yottacode.pictogram.action.PictoAction;
import com.yottacode.pictogram.action.PictosAction;
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.iImgDownloaderListener;
import com.yottacode.pictogram.tools.Img;
import com.yottacode.pictogram.tools.PCBcontext;
import com.yottacode.pictogram.tts.TTSHelper; import com.yottacode.pictogram.tts.TTSHelper;
import com.yottacode.pictogram.R; import com.yottacode.pictogram.R;
import com.yottacode.net.SSLDummyContext;
public class Translate extends Activity implements iVocabularyListener, iImgDownloaderListener
public class Translate extends Activity
{ {
private ArrayAdapter mArrayAdapter; private ArrayAdapter mArrayAdapter;
private PGF mPGF; private PGF mPGF;
private TTSHelper tts; private TTSHelper tts;
LinkedList<Picto> pictos; private GrammarLoader mGrammarLoader;
private ConcrLoader mSourceLoader;
private ConcrLoader mTargetLoader;
private ConcrLoader mOtherLoader;
private String mGrammar = "supo.pgf" ;
// String constant for logs // String constant for logs
private final String LOG_TAG = this.getClass().getSimpleName(); // Or .getCanonicalName() private final String TAG = this.getClass().getSimpleName(); // Or .getCanonicalName()
// String constan for token // String constan for token
private final String TOKEN = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJvZmZpY2UiOnsiaWQiOjM4MywibmFtZSI6IkNvbXVuaWNhY2nDs24gQXVtZW50YXRpdmEgSkHDqW4gKENBSkEpIiwiYWRkcmVzcyI6IlBhcmFqZSBMYXMgTGFndW5pbGxhcywgRWQgQTMsIHByaW1lcmEgcGxhdGEsIDIzMDcxLiBKYcOpbiIsImVtYWlsIjoiZG9mZXJAdWphZW4uZXMiLCJwaG9uZTEiOiIrMzQgOTUzIDIxIDI4IDg4IiwicGhvbmUyIjpudWxsLCJsYW5nIjoiZXMtZXMiLCJjb3VudHJ5IjoiRVMiLCJhZG1pbiI6MjMsImNvbnRhY3RQZXJzb24iOiJGZXJuYW5kbyBNYXJ0w61uZXogU2FudGlhZ28iLCJtYXhTdHVkZW50cyI6MiwiY3VycmVudFN0dWRlbnRzIjowfSwiaWQiOjIzLCJuYW1lIjoiRmVybmFuZG8iLCJzdXJuYW1lIjoiTWFydMOtbmV6IFNhbnRpYWdvIiwiZ2VuZGVyIjoiTSIsInBpYyI6Imh0dHA6Ly93d3dkaS51amFlbi5lcy9zaXRlcy9kZWZhdWx0L2ZpbGVzL3lvLmpwZz8xNDQ4MDE5MzU2IiwiYWRkcmVzcyI6bnVsbCwiY291bnRyeSI6bnVsbCwiZW1haWwiOiJkb2ZlckB1amFlbi5lcyIsInBob25lIjoiKzM0OTUzMjEyODg4IiwibGFuZyI6ImVzLWVzIiwiYWN0aXZlIjp0cnVlLCJ0dHNFbmdpbmUiOm51bGwsImlzU3VwQWRtaW4iOnRydWUsImlhdCI6MTQ1Mjg4NjE1NSwiZXhwIjoxNDUyODkzMzU1fQ.dmxKE4qH1DqBM7BYakgwD0L6y1437_2Ba3T7rHnOIcE"; private final String TOKEN = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJvZmZpY2UiOnsiaWQiOjM4MywibmFtZSI6IkNvbXVuaWNhY2nDs24gQXVtZW50YXRpdmEgSkHDqW4gKENBSkEpIiwiYWRkcmVzcyI6IlBhcmFqZSBMYXMgTGFndW5pbGxhcywgRWQgQTMsIHByaW1lcmEgcGxhdGEsIDIzMDcxLiBKYcOpbiIsImVtYWlsIjoiZG9mZXJAdWphZW4uZXMiLCJwaG9uZTEiOiIrMzQgOTUzIDIxIDI4IDg4IiwicGhvbmUyIjpudWxsLCJsYW5nIjoiZXMtZXMiLCJjb3VudHJ5IjoiRVMiLCJhZG1pbiI6MjMsImNvbnRhY3RQZXJzb24iOiJGZXJuYW5kbyBNYXJ0w61uZXogU2FudGlhZ28iLCJtYXhTdHVkZW50cyI6MiwiY3VycmVudFN0dWRlbnRzIjowfSwiaWQiOjIzLCJuYW1lIjoiRmVybmFuZG8iLCJzdXJuYW1lIjoiTWFydMOtbmV6IFNhbnRpYWdvIiwiZ2VuZGVyIjoiTSIsInBpYyI6Imh0dHA6Ly93d3dkaS51amFlbi5lcy9zaXRlcy9kZWZhdWx0L2ZpbGVzL3lvLmpwZz8xNDQ4MDE5MzU2IiwiYWRkcmVzcyI6bnVsbCwiY291bnRyeSI6bnVsbCwiZW1haWwiOiJkb2ZlckB1amFlbi5lcyIsInBob25lIjoiKzM0OTUzMjEyODg4IiwibGFuZyI6ImVzLWVzIiwiYWN0aXZlIjp0cnVlLCJ0dHNFbmdpbmUiOm51bGwsImlzU3VwQWRtaW4iOnRydWUsImlhdCI6MTQ1Mjg4NjE1NSwiZXhwIjoxNDUyODkzMzU1fQ.dmxKE4qH1DqBM7BYakgwD0L6y1437_2Ba3T7rHnOIcE";
private login() {
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
String operation = "sup/login";
Hashtable<String, String> postDataParams = new Hashtable<String, String>();
postDataParams.put("email", username);
postDataParams.put("password", password);
wrapper.ask(operation, postDataParams, "post", (iRestapiListener) context);
} else{
// Es un estudiante
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{
// 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
}
// ....
}
}
/** Called when the activity is first created. */ /** Called when the activity is first created. */
@Override @Override
public void onCreate(Bundle savedInstanceState) public void onCreate(Bundle savedInstanceState)
{ {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
pictos=new LinkedList<Picto>();
setContentView(R.layout.activity_main); setContentView(R.layout.activity_main);
mGrammarLoader = new GrammarLoader();
mGrammarLoader.start();
Language prefSourceLang = new Language("es-ES", "Spanish", "AppSpa", R.xml.qwerty);
Language prefTargetLang = new Language("en-US", "English", "AppEng", R.xml.qwerty);
/*Abrimos la base de datos*/ mSourceLoader = new ConcrLoader(prefSourceLang);
Log.i(LOG_TAG, "1) opening pcb"); mSourceLoader.start();
SSLDummyContext.init(getResources().getBoolean(R.bool.ssl_connect));
// TODO token for device or for user?
Vector<User> users = new Vector<User>(3);
try {
User adela_user= new User(37,"Adela", "Carmona","upload/supervisors/1064159640.jpg", "F", "es-es", "{\"stu-att\" : [{ \"categories\" : \"on\", \"input feedback\" : [ \"vibration\", \"tts\" ], \"input selection\" : \"click\", \"pictogram size\" : \"medium\", \"tts engine\" : \"IVONA Text-to-Speech HQ\", \"tts voice\": \"es\" }]}",
32, "Belen", "Lopez", "http://www4.ujaen.es/~dofer/pictures/supervisor/belen.jpg", "F", "es-es", "");
users.add(adela_user);
users.add(new User(2, "Carlos", "Carmona", "http://www4.ujaen.es/~dofer/pictures/student/carlos.jpg", "M", "es-es", "{\"stu-att\" : [{ \"categories\" : \"on\", \"input feedback\" : \"light_up\" , \"input selection\" : \"drag\", \"pictogram size\" : \"large\" }]}",
1, "Belen", "Lopez", "http://www4.ujaen.es/~dofer/pictures/supervisor/belen.jpg","M", "es-es", ""));
users.add(new User(2, "Carlos", "Carmona", "http://www4.ujaen.es/~dofer/pictures/student/carlos.jpg", "M", "es-es", "{\"stu-att\" : [{ \"categories\" : \"on\", \"input feedback\" : \"light_up\" , \"input selection\" : \"drag\", \"pictogram size\" : \"large\" }]}",
2, "Antonio", "Roldan", "http://www4.ujaen.es/~dofer/pictures/supervisor/antonio.jpg", "M", "es-es", ""));
users.add(new User(3, "Juan", "Tartán", "http://www4.ujaen.es/~dofer/pictures/student/juan.jpg", "M", "es-es", "",
2, "Antonio", "Roldan", "http://www4.ujaen.es/~dofer/pictures/supervisor/antonio.jpg", "M", "es-es", ""));
users.add(new User(4, "Rosa", "Mateos", "http://www4.ujaen.es/~dofer/pictures/student/rosa.jpg", "M", "es-es", "",
2, "Antonio", "Roldan", "http://www4.ujaen.es/~dofer/pictures/supervisor/antonio.jpg", "M", "es-es", ""));
User alumno_picto = new User(23, "Arturito", "Alumno" +
" Arturo", "http://www4.ujaen.es/~dofer/pictures/student/rosa.jpg", "M", "es-es", "");
users.add(alumno_picto);
PCBcontext.init(this);
PCBcontext.getDevice().setSerial("serial1");
PCBcontext.getDevice().setDeviceID("deviceID");
PCBcontext.set_user(alumno_picto, TOKEN, this);
Log.i(LOG_TAG, "2) OnCreate - Serial:" + PCBcontext.getDevice().getSerial() + " dev. id:" +
PCBcontext.getDevice().getDeviceID() + " token:" + TOKEN);
// ITERAR SOBRE EL VOCABULARIO
//for(Picto p : vocabulary)
// Log.d(LOG_TAG, "4)" + p.toString());
PCBcontext.getVocabulary().listen(PCBcontext.getRoom(), this);
// room2=new Room2(getResources().getString(R.string.url_server), 443);
} catch (JSONException e) { if (prefSourceLang == prefTargetLang) {
e.printStackTrace(); mTargetLoader = mSourceLoader;
Log.e(LOG_TAG,"5) USER JSON ERROR: "+e.getMessage()); } else {
} catch (IOException e) { mTargetLoader = new ConcrLoader(prefTargetLang);
e.printStackTrace(); mTargetLoader.start();
Log.e(LOG_TAG,"5) IO EXCEPTION: "+e.getMessage());
} }
tts = new TTSHelper(this,"IVONA Text-to-Speech HQ");
tts = new TTSHelper(this);
//new LoadPGFTask().execute();
mArrayAdapter = new ArrayAdapter(this, R.layout.listitem); mArrayAdapter = new ArrayAdapter(this, R.layout.listitem);
...@@ -174,43 +93,7 @@ public class Translate extends Activity implements iVocabularyListener, iImgDown ...@@ -174,43 +93,7 @@ public class Translate extends Activity implements iVocabularyListener, iImgDown
mArrayAdapter.add(input); mArrayAdapter.add(input);
} }
public void changeit(View v) { public void changeit(View v) {
try {
Vector<User> users = PCBcontext.getDevice().getUsers();
TextView tv = (TextView)findViewById(R.id.edittext_student);
String input = tv.getText().toString();
ImageView image = (ImageView) findViewById(R.id.image);
//this.vocabularyTalk.addPicto(input);
//room2.setup();
mArrayAdapter.clear();
mArrayAdapter.add("*Students*");
boolean found=false;
for (User user : users) {
if (user.get_name_stu().equalsIgnoreCase(input)) {
found=true;
mArrayAdapter.add(user.get_name_stu() + "..." + user.get_img_stu().exists_bitmap(this) + "...." + user.get_img_stu().get_bitmap(this));
((ImageView) findViewById(R.id.image)).setImageBitmap(user.get_img_stu().get_bitmap(this));
} else mArrayAdapter.add(user.get_name_stu());
}
if (!found) {
for (Picto picto: PCBcontext.getVocabulary())
if (picto.get_translation().equalsIgnoreCase(input)) {
((ImageView) findViewById(R.id.image)).setImageBitmap(picto.get_bitmap(this));
PCBcontext.getActionLog().log(new PictoAction(PictoAction.ADD, picto));
pictos.add(picto);
}
}
if (input.equals("entrega")) {
PCBcontext.getActionLog().log(new PictosAction(pictos));
pictos.clear();
}
} catch (IOException e) {
Log.e(this.getClass().getCanonicalName(), "IO ERROR: " + e.getMessage());
} catch (JSONException e) {
Log.e(this.getClass().getCanonicalName(), "JSON ERROR: " + e.getMessage());
}
} }
public void showTTS(View v) { public void showTTS(View v) {
...@@ -230,22 +113,6 @@ public class Translate extends Activity implements iVocabularyListener, iImgDown ...@@ -230,22 +113,6 @@ public class Translate extends Activity implements iVocabularyListener, iImgDown
} }
/* JSONObject --> Hashtable<arg, Object> */
@Override
public void change(action action, int picto_cat, int picto_id, JSONObject args) {
Log.e(this.getClass().getName(),"Vocabulary action listened: "+action);
}
@Override
public void loadComplete() {
Log.i(this.getClass().getName(),"Vocabulary load images completed");
}
@Override
public void loadImg(Img image) {
Log.i(this.getClass().getName(),"Vocabulary image modified");
}
/** /**
* This class is used to load the PGF file asychronously. * This class is used to load the PGF file asychronously.
...@@ -294,32 +161,7 @@ public class Translate extends Activity implements iVocabularyListener, iImgDown ...@@ -294,32 +161,7 @@ public class Translate extends Activity implements iVocabularyListener, iImgDown
} }
protected String[] doInBackground(String... s) { protected String[] doInBackground(String... s) {
try { return null;
// Creating a Parser object for the FoodEng concrete grammar
tts.speakText(s[0]);
Parser mParser = new Parser(mPGF, "SUpO_ES");
// Spliting the input (basic tokenization)
String[] tokens = s[0].split(" ");
//parsing the tokens
ParseState mParseState = mParser.parse(tokens);
Tree[] trees = (Tree[])mParseState.getTrees();
tokens=mParseState.predict();
/* String[] translations = new String[trees.length];
// Creating a Linearizer object for the FoodCat concrete grammar
Linearizer mLinearizer = new Linearizer(mPGF, "SUpO_EN");
// Linearizing all the trees
for (int i = 0 ; i < trees.length ; i++) {
try {
String t = mLinearizer.linearizeString(trees[i]);
translations[i] = t;
} catch (java.lang.Exception e) {
translations[i] = "/!\\ Linearization error";
}
}
return translations;*/ return s;
} catch (Exception e) {
throw new RuntimeException(e);
}
} }
protected void onPostExecute(String[] result) { protected void onPostExecute(String[] result) {
...@@ -330,4 +172,92 @@ public class Translate extends Activity implements iVocabularyListener, iImgDown ...@@ -330,4 +172,92 @@ public class Translate extends Activity implements iVocabularyListener, iImgDown
this.progress.dismiss(); // Remove loading popup this.progress.dismiss(); // Remove loading popup
} }
} }
private class GrammarLoader extends Thread {
private PGF mPGF;
public GrammarLoader() {
mPGF = null;
}
public PGF getGrammar() {
return mPGF;
}
public void run() {
InputStream in = null;
try {
in = getAssets().open(mGrammar);
Log.d(TAG, "Trying to open " + mGrammar);
long t1 = System.currentTimeMillis();
mPGF = PGF.readPGF(in);
long t2 = System.currentTimeMillis();
Log.d(TAG, mGrammar + " loaded ("+(t2-t1)+" ms)");
} catch (FileNotFoundException e) {
Log.e(TAG, "File not found", e);
} catch (IOException e) {
Log.e(TAG, "Error loading grammar", e);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
Log.e(TAG, "Error closing the stream", e);
}
}
}
}
}
private class ConcrLoader extends Thread {
private Language mLanguage;
private Concr mConcr;
public ConcrLoader(Language lang) {
this.mLanguage = lang;
this.mConcr = null;
}
public Language getLanguage() {
return mLanguage;
}
public Concr getConcr() {
return mConcr;
}
public void run() {
try {
mGrammarLoader.join();
} catch (InterruptedException e) {
Log.d(TAG, "interrupted", e);
}
InputStream in = null;
try {
String name = mLanguage.getConcrete()+".pgf_c";
in = getAssets().open(name);
Log.d(TAG, "Trying to load " + name);
long t1 = System.currentTimeMillis();
mConcr = mGrammarLoader.getGrammar().getLanguages().get(mLanguage.getConcrete());
mConcr.load(in);
long t2 = System.currentTimeMillis();
Log.d(TAG, name + " loaded ("+(t2-t1)+" ms)");
} catch (FileNotFoundException e) {
Log.e(TAG, "File not found", e);
} catch (IOException e) {
Log.e(TAG, "Error loading concrete", e);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
Log.e(TAG, "Error closing the stream", e);
}
}
}
}
}
} }
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
android:keyWidth="10%p"
android:horizontalGap="0px"
android:verticalGap="0px"
android:keyHeight="@dimen/key_height"
>
<Row>
<Key android:codes="113" android:keyLabel="q" android:keyEdgeFlags="left"/>
<Key android:codes="119" android:keyLabel="w"/>
<Key android:codes="101" android:keyLabel="e" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="èéêěëę"/>
<Key android:codes="114" android:keyLabel="r"/>
<Key android:codes="116" android:keyLabel="t"/>
<Key android:codes="121" android:keyLabel="y" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="ỳýÿ"/>
<Key android:codes="117" android:keyLabel="u" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="ùúûǔūü"/>
<Key android:codes="105" android:keyLabel="i" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="ìíîǐï"/>
<Key android:codes="111" android:keyLabel="o" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="òóôõöǫœø"/>
<Key android:codes="112" android:keyLabel="p" android:keyEdgeFlags="right"/>
</Row>
<Row>
<Key android:codes="97" android:keyLabel="a" android:horizontalGap="5%p"
android:keyEdgeFlags="left" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="àáâǎãäåæ"/>
<Key android:codes="115" android:keyLabel="s" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="ŝšß"/>
<Key android:codes="100" android:keyLabel="d" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="đ"/>
<Key android:codes="102" android:keyLabel="f"/>
<Key android:codes="103" android:keyLabel="g" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="ǵ"/>
<Key android:codes="104" android:keyLabel="h"/>
<Key android:codes="106" android:keyLabel="j" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="ǰ"/>
<Key android:codes="107" android:keyLabel="k" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="ḱ"/>
<Key android:codes="108" android:keyLabel="l" android:keyEdgeFlags="right"/>
</Row>
<Row>
<Key android:codes="-1" android:keyIcon="@drawable/sym_keyboard_shift"
android:keyWidth="15%p" android:isModifier="true"
android:isSticky="true" android:keyEdgeFlags="left"/>
<Key android:codes="122" android:keyLabel="z" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="ẑž"/>
<Key android:codes="120" android:keyLabel="x"/>
<Key android:codes="99" android:keyLabel="c" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="ćč"/>
<Key android:codes="118" android:keyLabel="v"/>
<Key android:codes="98" android:keyLabel="b"/>
<Key android:codes="110" android:keyLabel="n" android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters="ńñ"/>
<Key android:codes="109" android:keyLabel="m"/>
<Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete"
android:keyWidth="15%p" android:keyEdgeFlags="right"
android:isRepeatable="true"/>
</Row>
<Row android:rowEdgeFlags="bottom" android:keyboardMode="@string/normalKeyboardMode">
<Key android:codes="-100" android:keyLabel="Sr" android:keyWidth="13%p" android:keyEdgeFlags="left"/>
<Key android:codes="-200" android:keyLabel="Tr" android:keyWidth="13%p"/>
<Key android:codes="-2" android:keyLabel="123" android:keyWidth="13%p"/>
<Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
android:keyWidth="29%p" android:isRepeatable="true"/>
<Key android:codes="46" android:keyLabel="." android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters=","
android:keyWidth="14%p"/>
<Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return"
android:keyWidth="19%p" android:keyEdgeFlags="right"/>
</Row>
<Row android:rowEdgeFlags="bottom" android:keyboardMode="@string/internalKeyboardMode">
<Key android:codes="-2" android:keyLabel="123" android:keyWidth="15%p" android:horizontalGap="10%p" android:keyEdgeFlags="left"/>
<Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
android:keyWidth="30%p" android:isRepeatable="true"/>
<Key android:codes="46" android:keyLabel="." android:popupKeyboard="@xml/popup_keyboard" android:popupCharacters=","
android:keyWidth="15%p"/>
<Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return"
android:keyWidth="20%p" android:keyEdgeFlags="right"/>
</Row>
</Keyboard>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment