Updated question: I am trying to connect to a terminal emulator using a library in android, this will connect to a serial device and should show me sent/received data. I should be able to send data over the connection via a text box below the terminal or by typing in the terminal itself and hitting enter on the keyboard in both cases.
When I was sending data via textbox I had to append \n to the data to get to a new line when I pressed the enter key like so:
mEntry = (EditText) findViewById(R.id.term_entry);
mEntry.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId,
KeyEvent event) {
/* Ignore enter-key-up events. */
if (event != null && event.getAction() == KeyEvent.ACTION_UP) {
return false;
}
Editable e = (Editable) v.getText();
String data = e.toString() + "\n";
sendOverSerial(data.getBytes());
TextKeyListener.clear(e);
return true;
}
});
And the write method:
public void write(byte[] bytes, int offset, int count) {
super.write(bytes, offset, count);
if (isRunning()) {
doLocalEcho(bytes);
}
return;
}
When I was hitting enter after typing in the terminal session itself no new line was occurring at all. So I had to test the data for \r and replace it with \r\n:
private void doLocalEcho(byte[] data) {
String str = new String(data);
appendToEmulator(data, 0, data.length);
notifyUpdate();
}
public void write(byte[] bytes, int offset, int count) {
// Count the number of CRs
String str = new String(bytes);
int numCRs = 0;
for (int i = offset; i < offset + count; ++i) {
if (bytes[i] == '\r') {
++numCRs;
}
}
if (numCRs == 0) {
// No CRs -- just send data as-is
super.write(bytes, offset, count);
if (isRunning()) {
doLocalEcho(bytes);
}
return;
}
// Convert CRs into CRLFs
byte[] translated = new byte[count + numCRs];
int j = 0;
for (int i = offset; i < offset + count; ++i) {
if (bytes[i] == '\r') {
translated[j++] = '\r';
translated[j++] = '\n';
} else {
translated[j++] = bytes[i];
}
}
super.write(translated, 0, translated.length);
// If server echo is off, echo the entered characters locally
if (isRunning()) {
doLocalEcho(translated);
}
}
So that worked fine, now when I typed in the terminal session itself and hit enter i got the newline I wanted. However now every time I send data from the text box with with \n there was an extra space between every newline as well as getting the extra newline.
http://i.imgur.com/gtdIH.png
So I thought that when counting the number of carriage returns peek ahead at the next byte, and if it is '\n' don't count it:
for (int i = offset; i < offset + count; ++i) {
if (bytes[i] == '\r' &&
(
(i+1 < offset + count) && // next byte isn't out of index
(bytes[i+1] != '\n')
) // next byte isn't a new line
)
{
++numCRs;
}
}
This fixed the problem of the spaces...but that was rather stupid as I am now back in a circle to the original problem, if I type directly in the terminal there is no new line, as it sees the \r\n and sees the next byte is invalid. What would be the best way to get both working together? I either have these weird extra spaces and all input is fine, or normal spacing and I can't enter text directly from the terminal, only the textbox. I assume it's really easy to fix, I just am scratching my head looking at it.
EDIT: Not fixed, thought I had but then when I enter directly from the terminal enter does not produce a new line. It must be because the \n is ignored after the \r
I have most of this fixed. When counting the number of carriage returns peek ahead at the next byte, and if it is '\n' don't count it:
for (int i = offset; i < offset + count; ++i) {
if (bytes[i] == '\r' &&
(
(i+1 < offset + count) && // next byte isn't out of index
(bytes[i+1] != '\n')
) // next byte isn't a new line
)
{
++numCRs;
}
}
The only problem left now is that I still get the prompt back twice like this:
switch#
switch#
Related
This is my code.
I wanna receive two values in Arduino from android app.
I can receive one value but I can't two values.
Here is my code.
I wanna send two values with Bluetooth.send().
How can I do that?
I use bluetoothSPP in android studio.
I wanna receive Go ,Back, Right, Left and seconds in arduino.
so If i receive Go and 2sec, my arduino rc car go for 2 sec.
//Arduino code
#include<SoftwareSerial.h>
#include <Servo.h>
SoftwareSerial BT(blueTx,blueRx);
Servo servo;
char input1;
char input2;
void loop() {
if(BT.available()){
if(Serial.available()){
Serial.println("------");
Serial.println(BT.read());
}
input1 = BT.read();
input2 = BT.read();
}
}
// Android code , i use bluetoothSPP and send method
blockStartButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(!list.isEmpty()) {
delayHandler.postDelayed(new Runnable() {
#Override
public void run() {
while(!list.isEmpty()) {
String blockName = list.get(0);
num1 = inputNum.getText().toString();
list.remove(0);
adapter.notifyDataSetChanged();
if (blockName == "GO") {
Bluetooth.send("G", true);
Bluetooth.send(num1, true);
} else if (blockName == "BACK") {
Bluetooth.send("K", true);
Bluetooth.send(num1, true);
} else if (blockName == "LEFT") {
Bluetooth.send("L", true);
Bluetooth.send(num1, true);
} else if (blockName == "RIGHT") {
Bluetooth.send("R", true);
Bluetooth.send(num1, true);
}
// inputNum.setText(null);
}
}
}, 10);
}
I had similar problem in the problem , though I did'nt use bluetooth spp , but give this a shot , try to send byte array in send
I designed my input like a,b and convert this to byte array , in your case send it like G/K/L/R,num1 see the comma added , to convert this to byte array use getBytes() , in aurdino do the following :
void loop() {
if(Serial.available()){
int available = Serial.available();
for(int i=0; i< available; i++){
char a = Serial.read();
if(i < 1){
input1 = a;
}
if(i > 1){
int c =(int)a - 48;
input2 *= 10;
input2 += c;
}
}
}
Explanation skip comma which is second character(1) , first character is normal so add it to input1 , second one is number so extract ascii values starts from 48 and get the number from it.Input2 is of type int with initial value of 0 , Enjoy!
I'm editing content that may be html in an EditText. Just before saving the result, I use Html.toHtml to convert the input into a string to be sent to the server. However this method call seems to be generating paragraph tags which I dont need. Eg -
Test edited
seems to get converted to
<p dir="ltr">Test edited</p>
I would like to strip out the last paragraph tag before saving the content. If there are other paragraph tags, I would like to keep those. I have this regex that matches all p tags
"(<p.*>)(.*)(</p>)";
but I'm not sure how to match just the last paragraph and remove just the tags for it.
public static void handleOneParagraph(SpannableStringBuilder text) {
int start = 0;
int end = text.length();
String chars1 = "<p";
if (end < 2)
return;
while (start < end ) {
String seq = text.toString().substring(start, start + 2);
if (seq.equalsIgnoreCase(chars1))
break;
start++;
}
if (text.toString().substring(start, start + 2).equalsIgnoreCase(chars1) ) {
int start2 = start + 1;
String chars2 = ">";
while (start2 < end && !text.subSequence(start2, start2+1).toString().equalsIgnoreCase(chars2) ) {
start2++;
}
if (start2 >= end)
return;
text.replace(start, start2+1, "");
end = text.length();
start = end;
String chars3 = "</p>";
while (start > start2 + 4) {
String last_p = text.subSequence(start - 4, start).toString();
if (last_p.equalsIgnoreCase(chars3) ) {
text.replace(start - 4, start, "");
break;
}
start--;
}
}
}
And now, you can use it like this...
SpannableStringBuilder cleaned_text = new SpannableStringBuilder(Html.toHtml(your_text));
handleOneParagraph(cleaned_text);
i got this issue and i don't know how to solve it. Here is the problem:
1 - i have a data in my database who i split into a strings[] and then i split this strings[] into another 2 strings[] (even and odd lines). Everything works fine but when i want to join all the lines into a single String i got a multi line string intead of a single line. Someone can help me?
data
abcdef//
123456//
ghijkl//
789012
code:
String text = "";
vec1 = data.split("//"); //split the data
int LE = 0;
for (int a = 0; a < vec1.length; a++) { //verify how many even and odds line the data have
if (a % 2 == 0) { //if 0, LE++
LE++;
}
}
resul1 = new String[LE];
int contA = 0, contB = 0;
for (int c = 0; c < resul1.length; c++) {
if (c % 2 != 0) {
text += " " + resul1[c].toLowerCase().replace("Á","a").replace("Ã","a").replace("ã","a").replace("â","a").replace("á","a").replace("é","e").replace("É","e")
.replace("ê","e").replace("í","i").replace("Í","i").replace("ó","o").replace("Ó","o").replace("õ","o").replace("Õ","o").replace("ô","o").replace("Ô", "o")
.replace("Ú","u").replace("ú","u").replace("ç","c").replace("_","").replace("<","").replace(">","");
contA++;
}
}
And the String looks like
abcdef
ghijkl
instead of
abcdefghijkl
You should use replaceAll() method.
text.replaceAll("\\r\\n|\\r|\\n", ""); // the method removes all newline characters
I've decided I have to write my own syntax highlighter. So far it's working but it's realtime (you type, it highlights) and it's slow.
I'll try to explain how it works. Each time the user types something into the EditText it runs the highlighter (via TextWatcher). The highlighter searches through the text until it finds the beginning of a word and then searches until it finds the end of the same word. Once it finds a word it searches through an array of keywords, if it finds a match it sets a spannable at that location. It keeps looping until it reaches the end of the document.
Again, it works so far (just trying out this idea before I continue with this method), but it's so slow. Some times it can take over a second just to go through a few lines. It slows down how fast the text appears in the EditText. - I also set where the highlighter starts after text is entered at the last position where the user typed so it doesnt have to go through the whole doc each time, it helps a little but not much.
Here's the basic of my EditText:
public class CodeView extends EditText {
private int mTxtChangeStart;
String mStructures[] = this.getResources().getStringArray(R.array.structures);
public CodeView(Context context, AttributeSet attrs) {
super(context, attrs);
addTextChangedListener(inputTextWatcher);
...
}
TextWatcher inputTextWatcher = new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {
syntaxHighlight();
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
//Set where we should start highlighting
mTxtChangeStart = start;
}
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
}
};
private void syntaxHighlight() {
//Time how long it takes for debugging
long syntime = System.currentTimeMillis();
Log.d("", "Start Syntax Highlight");
//Get the position where to start searching for words
int strt = mTxtChangeStart;
//Get the editable text
Editable txt = getText();
//Back up the starting position to the nearest space
try {
for(;;) {
if(strt <= 0) break;
char c = txt.charAt(strt);
if(c != ' ' && c != '\t' && c != '\n' && c != '\r') {
strt--;
} else {
break;
}
}
} catch (IndexOutOfBoundsException e) {
Log.e("", "Find start position failed: " + e.getMessage());
}
//Just seeing how long this part took
long findStartPosTime = System.currentTimeMillis();
Log.d("", "Find starting position took " + String.valueOf(System.currentTimeMillis() - findStartPosTime) + " milliseconds");
//the 'end of a word' position
int fin = strt;
//Get the total length of the search text
int totalLength = txt.length();
//Start finding words
//This loop is to find the first character of a word
//It loops until the current character isnt a space, tab, linebreak etc.
while(fin < totalLength && strt < totalLength) {
for(;;) {
//Not sure why I added these two lines - not needed here
//fin++;
//if(fin >= totalLength) { break; } //We're at the end of the document
//Check if there is a space at the first character.
try {
for(;;) { //Loop until we find a useable character
char c = txt.charAt(strt);
if (c == ' ' || c == '\t' || c == '\n' || c == '\r'){
strt++; //Go to the next character if there is a space
} else {
break; //Found a character (not a space, tab or linebreak) - break the loop
}
}
}catch(IndexOutOfBoundsException e) {
Log.e("", e.getMessage());
break;
}
//Make sure fin isnt less than strt
if(strt > fin) { fin = strt; }
//Now we search for the end of the word
//Loop until we find a space at the end of a word
try {
for(;;) {
char c = txt.charAt(fin);
if(c != ' ' && c != '\t' && c != '\n' && c != '\r') {
fin++; //Didn't find whitespace here, keep looking
} else {
break; //Now we found whitespace, end of a word
}
}
break;
} catch (IndexOutOfBoundsException e) {
//If this happens it should mean it just reached the end of the document.
Log.e("", "End of doc? : " + e.getMessage());
break;
}
}
Log.d("", "It took " + String.valueOf(System.currentTimeMillis() - findStartPosTime) + " milliseconds to find a word");
//Make sure fin isnt less that start, again
if(strt > fin) { fin = strt; }
//Debug time, how long it took to find a word
long matchTime = System.currentTimeMillis();
//Found a word, see if it matches a word in our string[]
try {
for(String mStruct : mStructures) {
if(String.valueOf(txt.subSequence(strt, fin)).equals(mStruct)) {
//highlight
Spannable s = (Spannable) txt;
s.setSpan(new ForegroundColorSpan(Color.RED), strt, fin, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
//Can someone explain why this is still setting the spannable to the main editable???
//It should be set to txt right???
break;
} else {
/*Spannable s = (Spannable) txt;
s.setSpan(new ForegroundColorSpan(Color.BLACK), strt, fin, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
txt.removeSpan(s);*/
}
}
}catch (IndexOutOfBoundsException e) {
e.printStackTrace();
Log.e("", "word match error: " + e.getMessage());
}
//Finally set strt to fin and start again!
strt = fin;
Log.d("", "match a word time " + String.valueOf(System.currentTimeMillis() - matchTime) + " milliseconds");
}//end main while loop
Log.d("", "Syntax Highlight Finished in " + (System.currentTimeMillis() - syntime) + " milliseconds");
mTextChanged = false;
}
}
"structures" resource (php.xml)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="structures">
<item>if</item>
<item>else</item>
<item>else if</item>
<item>while</item>
<item>do-while</item>
<item>for</item>
<item>foreach</item>
<item>break</item>
<item>continue</item>
<item>switch</item>
<item>declare</item>
<item>return</item>
<item>require</item>
<item>include</item>
<item>require_once</item>
<item>include_once</item>
<item>goto</item>
</string-array>
</resources>
Anyone have any suggestions how to make this search faster? I know I have a lot of loops but I'm not sure how else to do it.
Thanks a lot!
Can you split the string on the delimiters you have there rather than looking at each character? That would speed it up some. (String.split())
In my application there is a search option. If the user enters a search value, I have to get a value from the webservice. I am getting a large webservice value. In my webservice string values are coming. I am getting like <> like xml character entity reference like. I want to replace all characters and parse xml. Can anybody tell me how to do this and give an example?
I tried with StringBuffer for unescapexml character, I am getting out of memory error
public String unescapeXML(String str) {
if (str == null || str.length() == 0)
return "";
StringBuffer buf = new StringBuffer();
int len = str.length();
for (int i = 0; i < len; ++i) {
char c = str.charAt(i);
if (c == '&') {
int pos = str.indexOf(";", i);
if (pos == -1) { // Really evil
buf.append('&');
} else if (str.charAt(i + 1) == '#') {
int val = Integer.parseInt(str.substring(i + 2, pos), 16);
buf.append((char) val);
i = pos;
} else {
String substr = str.substring(i, pos + 1);
if (substr.equals("&"))
buf.append('&');
else if (substr.equals("<"))
buf.append('<');
else if (substr.equals(">"))
buf.append('>');
else if (substr.equals("""))
buf.append('"');
else if (substr.equals("'"))
buf.append('\'');
else if (substr.equals(" "))
buf.append(" ");
else
// ????
buf.append(substr);
i = pos;
}
} else {
buf.append(c);
}
}
return buf.toString();
}
I tried with stream, I am not able to do it. Can anybody give an example how to do this?
You should not parse it on your own. There are better ways - SAX or DOM.
This resource contains a lot of useful inforamtion about these both ways (and code examples too): http://onjava.com/pub/a/onjava/2002/06/26/xml.html
Take a look here in order to get more details about android included parsers :
http://developer.android.com/reference/javax/xml/parsers/package-summary.html
But make your own parser with SAX is probably the best choice in your case ;)