I am working on a Android app that modifies the Bluetooth Chat example given with Eclipse to create an On-Board Diagnostic (OBD) reader. My code sends a message to my vehicle's ECU and retrieves data with the use of switches.
Now, my problem is, for some reason when I run my program I only receive data for 6 of my cases and I am not receiving data for the rest of them.
The code is kind of lengthy.
public void startTransmission() {
sendMessage("01 00" + '\r');
}
public void getData(int messagenumber) {
final TextView TX = (TextView) findViewById(R.id.TXView2);
switch (messagenumber) {
case 1:
sendMessage("01 0C" + '\r'); // get RPM
TX.setText("01 0C");
messagenumber++;
break;
case 2:
sendMessage("01 0D" + '\r'); // get MPH
TX.setText("01 0D");
messagenumber++;
break;
case 3:
sendMessage("01 04" + '\r'); // get Engine Load
TX.setText("01 04");
messagenumber++;
break;
case 4:
sendMessage("01 05" + '\r'); // get Coolant Temperature
TX.setText("01 05");
messagenumber++;
break;
case 5:
sendMessage("01 0F" + '\r'); // get Intake Temperature
TX.setText("01 0F");
messagenumber++;
break;
case 6:
sendMessage("AT RV" + '\r'); // get Voltage
TX.setText("AT RV");
messagenumber++;
break;
case 7:
sendMessage("01 06" + '\r'); // get Fuel Trim Bank 1 Sensor 1
TX.setText("01 06");
messagenumber++;
case 8:
sendMessage("01 07" + '\r'); // get Fuel Trim Bank 1 Sensor 2
TX.setText("01 07");
messagenumber++;
case 9:
sendMessage("01 0B" + '\r'); // get Intake Manifold Pressure
TX.setText("01 0B");
messagenumber++;
case 10:
sendMessage("01 0E" + '\r'); // get Timing Advance
TX.setText("01 0E");
messagenumber++;
case 11:
sendMessage("01 11" + '\r'); // get Throttle Position
TX.setText("01 11");
messagenumber++;
case 12:
sendMessage("01 14" + '\r'); // get Oxygen Bank 1 Sensor 1
TX.setText("01 14");
messagenumber++;
case 13:
sendMessage("01 15" + '\r'); // get Oxygen Bank 1 Sensor 2
TX.setText("01 15");
messagenumber++;
default:
;
}
}
private void sendMessage(String message) {
// Check that we're actually connected before trying anything
if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) {
Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT)
.show();
return;
}// end if
// Check that there's actually something to send
if (message.length() > 0) {
// Get the message bytes and tell the BluetoothChatService to write
byte[] send = message.getBytes();
mChatService.write(send);
// Reset out string buffer to zero and clear the edit text field
mOutStringBuffer.setLength(0);
// mOutEditText.setText(mOutStringBuffer);
}// end if
}// end sendMessage method
// The Handler that gets information back from the BluetoothChatService
private final Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
// <--------- Initialize Data Display Fields ---------->//
/* PID = 0C */final TextView RPM = (TextView) findViewById(R.id.numRPM);
/* PID = 0D */final TextView MPH = (TextView) findViewById(R.id.numSpeed);
/* PID = 04 */final TextView engineLoad = (TextView) findViewById(R.id.numLoad);
/* PID = 05 */final TextView coolantTemperature = (TextView) findViewById(R.id.numCoolant);
/* PID = 0F */final TextView intakeTemperature = (TextView) findViewById(R.id.numIntakeAir);
/* PID = RV */final TextView voltage = (TextView) findViewById(R.id.numVoltage);
/* PID = 06 */final TextView fuelTrimB1S1 = (TextView) findViewById(R.id.numFTb1s1);
/* PID = 07 */final TextView fuelTrimB1S2 = (TextView) findViewById(R.id.numFTb1s2);
/* PID = 0A */final TextView intakeManifold = (TextView) findViewById(R.id.numManifold);
/* PID = 0E */final TextView timingAdvance = (TextView) findViewById(R.id.numTiming);
/* PID = 11 */final TextView throttlePos = (TextView) findViewById(R.id.numThrottle);
/* PID = 14 */final TextView oxygenB1s1 = (TextView) findViewById(R.id.numO2b1s1);
/* PID = 15 */final TextView oxygenB1s2 = (TextView) findViewById(R.id.numO2b1s2);
/* displays recieved string */final TextView RX = (TextView) findViewById(R.id.RXView2);
String dataRecieved;
int value = 0;
int value2 = 0;
int PID = 0;
switch (msg.what) {
case MESSAGE_STATE_CHANGE:
if (D)
Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
switch (msg.arg1) {
case BluetoothChatService.STATE_CONNECTED:
setStatus(getString(R.string.title_connected_to,
mConnectedDeviceName));
mConversationArrayAdapter.clear();
break;
case BluetoothChatService.STATE_CONNECTING:
setStatus(R.string.title_connecting);
break;
case BluetoothChatService.STATE_LISTEN:
case BluetoothChatService.STATE_NONE:
setStatus(R.string.title_not_connected);
break;
}
break;
case MESSAGE_WRITE:
// byte[] writeBuf = (byte[]) msg.obj;
// construct a string from the buffer
// String writeMessage = new String(writeBuf);
// mConversationArrayAdapter.add("Me: " + writeMessage);
break;
case MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
// construct a string from the valid bytes in the buffer
String readMessage = new String(readBuf, 0, msg.arg1);
// ------- ADDED CODE FOR OBD -------- //
dataRecieved = readMessage;
RX.setText(dataRecieved);
if ((dataRecieved != null)
&& (dataRecieved
.matches("\\s*[0-9A-Fa-f]{2} [0-9A-Fa-f]{2}\\s*\r?\n?"))) {
dataRecieved = dataRecieved.trim();
String[] bytes = dataRecieved.split(" ");
if ((bytes[0] != null) && (bytes[1] != null)) {
PID = Integer.parseInt(bytes[0].trim(), 16);
value = Integer.parseInt(bytes[1].trim(), 16);
}
switch (PID) {
case 15:// PID(0F): Intake Temperature
value = value - 40; // Formula for Intake Temperature
value = ((value * 9) / 5) + 32; // Convert from Celsius
// to Farenheit
String displayIntakeTemp = String.valueOf(value);
intakeTemperature.setText(displayIntakeTemp + " F");
break;
// end Intake Temperature case
case 4:// PID(04): Engine Load
value = (value * 100) / 255;
String displayEngineLoad = String.valueOf(value);
engineLoad.setText(displayEngineLoad + " %");
break;
// end Engine Load case
case 5:// PID(05): Coolant Temperature
value = value - 40;
value = ((value * 9) / 5) + 32; // convert to deg F
String displayCoolantTemp = String.valueOf(value);
coolantTemperature.setText(displayCoolantTemp);
break;
// end Coolant Temperature case
case 12: // PID(0C): RPM
int RPM_value = (value * 256) / 4;
String displayRPM = String.valueOf(RPM_value);
RPM.setText(displayRPM);
break;
// end RPM case
case 13:// PID(0D): MPH
value = (value * 5) / 8; // convert KPH to MPH
String displayMPH = String.valueOf(value);
MPH.setText(displayMPH + " MPH");
break;
// end MPH case
case 6:// PID(06): Fuel Trim Bank 1 Sensor 1
value = (value - 128) * 100 / 128;
String displayFtB1s1 = String.valueOf(value);
fuelTrimB1S1.setText(displayFtB1s1);
break;
case 7:// PID(07): Fuel Trim Bank 1 Sensor 2
value = (value - 128) * 100 / 128;
String displayFtB1s2 = String.valueOf(value);
fuelTrimB1S2.setText(displayFtB1s2);
break;
case 11: // PID(0A): Intake Manifold Pressure
String displayIntakeManifold = String.valueOf(value);
intakeManifold.setText(displayIntakeManifold);
break;
case 14: // PID(0E): Timing Advance
value = value / 2 - 64;
String displayTimingAdvance = String.valueOf(value);
timingAdvance.setText(displayTimingAdvance);
break;
case 17: // PID(11): Throttle Position
value = value * 100 / 255;
String displayThrottlePos = String.valueOf(value);
throttlePos.setText(displayThrottlePos);
case 20: // PID(14): Oxygen Bank 1 Sensor 1
String displayO2B1s1 = String.valueOf(value);
oxygenB1s1.setText(displayO2B1s1);
break;
case 21: // PID(14): Oxygen Bank 1 Sensor 2
String displayO2B1s2 = String.valueOf(value);
oxygenB1s2.setText(displayO2B1s2);
break;
default:
;
}
} else if ((dataRecieved != null)
&& (dataRecieved
.matches("\\s*[0-9A-Fa-f]{1,2} [0-9A-Fa-f]{2} [0-9A-Fa-f]{2}\\s*\r?\n?"))) {
dataRecieved = dataRecieved.trim();
String[] bytes = dataRecieved.split(" ");
if ((bytes[0] != null) && (bytes[1] != null)
&& (bytes[2] != null)) {
PID = Integer.parseInt(bytes[0].trim(), 16);
value = Integer.parseInt(bytes[1].trim(), 16);
value2 = Integer.parseInt(bytes[2].trim(), 16);
}
// PID(0C): RPM
if (PID == 12) {
int RPM_value = ((value * 256) + value2) / 4;
String displayRPM = String.valueOf(RPM_value);
RPM.setText(displayRPM + " RPM");
} else if ((PID == 1) || (PID == 65)) {
switch (value) {
case 15:// PID(0F): Intake Temperature
value2 = value2 - 40; // formula for INTAKE AIR TEMP
value2 = ((value2 * 9) / 5) + 32; // convert to deg
// F
String displayIntakeTemp = String.valueOf(value2);
intakeTemperature
.setText(displayIntakeTemp + " °F");
break;
// end Intake Temperature case
case 4:// PID(04): Engine Load
value2 = (value2 * 100) / 255;
String displayEngineLoad = String.valueOf(value2);
engineLoad.setText(displayEngineLoad + " %");
break;
// end Engine Load case
case 5:// PID(05): Coolant Temperature
value2 = value2 - 40;
value2 = ((value2 * 9) / 5) + 32; // convert to deg
// F
String displayCoolantTemp = String.valueOf(value2);
coolantTemperature.setText(displayCoolantTemp
+ " °F");
break;
case 13:// PID(0D): MPH
value2 = (value2 * 5) / 8; // convert to MPH
String displayMPH = String.valueOf(value2);
MPH.setText(displayMPH + " MPH");
break;
// case 6:// PID(06): Fuel Trim Bank 1 Sensor 1
//
// value = (value - 128) * 100 / 128;
//
// String displayFtB1s1 = String.valueOf(value);
// fuelTrimB1S1.setText(displayFtB1s1 + " V");
// break;
//
// case 7:// PID(07): Fuel Trim Bank 1 Sensor 2
//
// value = (value - 128) * 100 / 128;
//
// String displayFtB1s2 = String.valueOf(value);
// fuelTrimB1S2.setText(displayFtB1s2 + " V");
// break;
//
// case 11: // PID(0A): Intake Manifold Pressure
//
// String displayIntakeManifold = String
// .valueOf(value);
// intakeManifold.setText(displayIntakeManifold
// + " psi");
// break;
//
// case 14: // PID(0E): Timing Advance
//
// value = value / 2 - 64;
//
// String displayTimingAdvance = String.valueOf(value);
// timingAdvance.setText(displayTimingAdvance + " °");
// break;
//
// case 17: // PID(11): Throttle Position
//
// value = value * 100 / 255;
//
// String displayThrottlePos = String.valueOf(value);
// throttlePos.setText(displayThrottlePos + " %");
//
// case 20: // PID(14): Oxygen Bank 1 Sensor 1
//
// String displayO2B1s1 = String.valueOf(value);
// oxygenB1s1.setText(displayO2B1s1 + " V");
// break;
//
// case 21: // PID(14): Oxygen Bank 1 Sensor 2
//
// String displayO2B1s2 = String.valueOf(value);
// oxygenB1s2.setText(displayO2B1s2 + " V");
// break;
default:
;
}
}
} else if ((dataRecieved != null)
&& (dataRecieved
.matches("\\s*[0-9]+(\\.[0-9]?)?V\\s*\r*\n*"))) {
dataRecieved = dataRecieved.trim();
voltage.setText(dataRecieved);
} else if ((dataRecieved != null)
&& (dataRecieved
.matches("\\s*[0-9]+(\\.[0-9]?)?V\\s*V\\s*>\\s*\r*\n*"))) {
dataRecieved = dataRecieved.trim();
// String volt_number = dataRecieved.substring(0,
// dataRecieved.length() - 1);
voltage.setText(dataRecieved);
} else if ((dataRecieved != null)
&& (dataRecieved
.matches("\\s*[ .A-Za-z0-9\\?*>\r\n]*\\s*>\\s*\r*\n*"))) {
if (message_number == 7)
message_number = 1;
getData(message_number++);
}
break;
}
}
Where I think I want to focus on is:
if ((dataRecieved != null)
&& (dataRecieved
.matches("\\s*[0-9A-Fa-f]{2} [0-9A-Fa-f]{2}\\s*\r?\n?"))) {
dataRecieved = dataRecieved.trim();
String[] bytes = dataRecieved.split(" ");
if ((bytes[0] != null) && (bytes[1] != null)) {
PID = Integer.parseInt(bytes[0].trim(), 16);
value = Integer.parseInt(bytes[1].trim(), 16);
}
This code is based off some research that I have done and I am not sure what the string behind the dataRecieved.matches is. It looks to be an array and I am thinking that the parameters received are causing my switch cases not to fire.
Thanks for any input.
Related
I'm new to Android. I'm trying to develop my first calculator. My calculator output is good, but I'm trying to make some changes to it. Please suggest. My output is 2+2=4.0 How can I get 4 if I put 2+2 and 4.0 when I put 2.8+1.2.
Also, please help me out in trying to figure out how can i keep on adding till i press =.
My code that I'm looking at is below:
private View.OnClickListener buttonClickListerner = new
View.OnClickListener() {
float r;
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.clear:
screen.setText("");
operator.setText("");
FirstNum= 0;
showtext.setText("");
break;
case R.id.buttonAdd:
mMath("+");
operator.setText("+");
showtext.setText(String.valueOf(FirstNum));
break;
case R.id.buttonMinus:
mMath("-");
operator.setText("-");
break;
case R.id.buttonMul:
mMath("*");
operator.setText("*");
break;
case R.id.buttonequal:
mResult();
break;
case R.id.buttonDiv:
mMath("/");
operator.setText("/");
break;
case R.id.buttonPercent:
mMath("%");
r = FirstNum / 100;
showtext.setText("[" + String.valueOf(FirstNum) + "%" + "]");
screen.setText(String.valueOf(r));
break;
default:
String num = ((Button) v).getText().toString();
getKeyboard(num);
break;
}
}
};
public void mMath(String str){
FirstNum = Float.parseFloat(screen.getText().toString());
operation = str;
screen.setText("");
}
public void getKeyboard(String str){
String CurrentScreen = screen.getText().toString();
if(CurrentScreen.equals("0"))
CurrentScreen = "";
CurrentScreen = CurrentScreen + str;
screen.setText(CurrentScreen);
String ExScreen = CurrentScreen;
screen.setText(ExScreen);
}
public void mResult(){
float SecondNum = Float.parseFloat(screen.getText().toString());
float ThirdNum = Float.parseFloat(screen.getText().toString());
float result = 0;
//float exresult = result;
if(operation.equals("+")){
result = FirstNum + SecondNum;
// exresult = result + ThirdNum;
}
if(operation.equals("-")){
result = FirstNum - SecondNum;
//exresult = result - ThirdNum;
}
if(operation.equals("*")){
result = FirstNum * SecondNum;
//exresult = result * ThirdNum;
}
if(operation.equals("/")){
result = FirstNum / SecondNum;
//exresult = result / ThirdNum;
}
screen.setText(String.valueOf(result));
//screen.setText(String.valueOf(exresult));
showtext.setText(String.valueOf(FirstNum + operation + SecondNum));
//showtext.setText(String.valueOf(FirstNum + operation + SecondNum +
operation + ThirdNum));
}
}
I guess you should do your calculations as double and then before setting the output to TextView (or whatever you are using), check for the output if int or not and then decide which form of output to set to the TextView.
if ((variable == Math.floor(variable)) && !Double.isInfinite(variable)) {
// integral type
}
See this
Edit:
The idea is to check that fractional part of the number is 0 (i.e.) the number is integer.
You may also Use these conditions [if true then variable is an Integer]
// check if
variable == Math.ceil(variable)
or
// check if
variable == Math.round(variable)
Also Math.round(float f) will return the interger form of the number!
To add multiple item first set up an array with a size of how long the user can input and then loop through each array adding them equivalently... i know this is a vague answer but you can ask me if anything is unclear and also an up vote would be nice. you got the right idea for the cases just try the following code
// array to sum
int[] numbers = new int[]{ 10, 10, 10, 10};
int sum = 0;
for (int i=0; i < numbers.length ; i++) {
sum = sum + numbers[i];
}
System.out.println("Sum value of array elements is : " + sum);
}
I'm having a hard time getting the childobjects of a listview. So, there are multiple objects in it, visible and not yet visible. When I ask for the size, it returns 5 (those 5 are the visible ones).
I tried to scroll the list view from the bottom item to the top item and store those items but than I face the issue that items from other parts in the listview are recognized. Another method that I tried is to scroll the last item a little bit up, until the new item becomes visible. But here I face the issue that a whole other items text is recognized when the item is scrolled.
The code for the first method:
Within this code, I take the listviews childObjects, iterate through them and store all the textfields. When I do this, some textfields of other items are mixed which makes it unusable.
List AccountList;
ArrayList<String> AccountArray = new ArrayList<String>();
String tempAccountInfo = "";
String AccountType="";
String LastItem = "";
String NewLastItem = "N/A";
List<WebElement> AccountListItems;
AccountList = driver.findElements(getObject("ElementsWithinAccountListView"));
AccountListItems = AccountList.get(AccountList.size() - 1).findElements(By.className("android.widget.TextView"));
while (!NewLastItem.equals(LastItem)) {
for (int i=0; i<AccountList.size();i++){
AccountList = driver.findElements(getObject("ElementsWithinAccountListView"));
AccountListItems = AccountList.get(i).findElements(By.className("android.widget.TextView"));
switch (AccountList.get(i).getAttribute("className")){
case "android.widget.LinearLayout":
if (!AccountListItems.get(0).getText().contains("New ")){
switch(AccountListItems.get(0).getText()){
case "Current accounts":
AccountType = "Current accounts";
break;
case "Savings accounts":
AccountType = "Saving accounts";
break;
case "Investments":
AccountType = "Investments";
break;
case "Credit cards":
AccountType = "Credit cards";
break;
case "Other":
AccountType = "Other";
break;
}
}
break;
case "android.widget.RelativeLayout":
AccountListItems = AccountList.get(i).findElements(By.className("android.widget.TextView"));
if (AccountListItems.size() == 5 || AccountListItems.size() == 4){
tempAccountInfo = AccountType;
for(int j=0; j<AccountListItems.size(); j++){
tempAccountInfo = tempAccountInfo + "|" + AccountListItems.get(j).getText();
LastItem = AccountListItems.get(2).getText();
}
switch(AccountType){
case "Investments":
if (!(AccountListItems.size() == 5)) {
System.out.println(tempAccountInfo);
AccountArray.add(tempAccountInfo);
}
break;
default:
System.out.println(tempAccountInfo);
AccountArray.add(tempAccountInfo);
break;
}
tempAccountInfo = "";
}
break;
}
}
driver.swipe(AccountList.get(AccountList.size()-1).getLocation().x + 70, AccountList.get(AccountList.size()-1).getLocation().y, AccountList.get(1).getLocation().x + 70, AccountList.get(1).getLocation().y, 3000);
Thread.sleep(20000);
AccountListItems = AccountList.get(AccountList.size() - 1).findElements(By.className("android.widget.TextView"));
try {
NewLastItem = AccountListItems.get(2).getText();
} catch (Exception e){
System.out.println("Not at the end of the listview");
NewLastItem = "N/A";
}
System.out.println("LastItem:" + LastItem);
System.out.println("NewLastItem:" + NewLastItem);
}
Objects viewed in Appium
This is the code of the second method that I've tried:
protected void swipeToNextElement(String Element) throws Exception{
List AccountList;
String LastItem;
String NewLastItem;
List<WebElement> AccountListItems;
Boolean loop = true;
AccountList = driver.findElements(getObject(Element));
AccountListItems = AccountList.get(AccountList.size()-1).findElements(By.className("android.widget.TextView"));
LastItem = AccountListItems.get(0).getAttribute("text");
NewLastItem = AccountListItems.get(0).getAttribute("text");
driver.swipe(AccountList.get(AccountList.size()-1).getLocation().x + (AccountList.get(AccountList.size()-1).getSize().width / 2), AccountList.get(AccountList.size()-1).getLocation().y, AccountList.get(AccountList.size()-1).getLocation().x + (AccountList.get(AccountList.size()-1).getSize().width / 2), AccountList.get(AccountList.size()-1).getLocation().y - 70, 1000);
while (loop) {
if (NewLastItem.equals(LastItem)){
AccountList = driver.findElements(getObject(Element));
AccountListItems = AccountList.get(AccountList.size()-1).findElements(By.className("android.widget.TextView"));
driver.swipe(AccountList.get(AccountList.size()-1).getLocation().x + (AccountList.get(AccountList.size()-1).getSize().width / 2), AccountList.get(AccountList.size()-1).getLocation().y, AccountList.get(AccountList.size()-1).getLocation().x + (AccountList.get(AccountList.size()-1).getSize().width / 2), AccountList.get(AccountList.size()-1).getLocation().y - 70, 1000);
NewLastItem = AccountListItems.get(0).getAttribute("text");
} else {
AccountList = driver.findElements(getObject(Element));
AccountListItems = AccountList.get(AccountList.size()-1).findElements(By.className("android.widget.TextView"));
driver.swipe(AccountList.get(AccountList.size()-1).getLocation().x + (AccountList.get(AccountList.size()-1).getSize().width / 2), AccountList.get(AccountList.size()-1).getLocation().y, AccountList.get(AccountList.size()-1).getLocation().x + (AccountList.get(AccountList.size()-1).getSize().width / 2), AccountList.get(AccountList.size()-1).getLocation().y + 70, 1000);
NewLastItem = AccountListItems.get(0).getAttribute("text");
loop = false;
}
}
System.out.println("NewLastItem: " + NewLastItem);
}
Any help is welcome ^^
Thanks in advance!
It's painful when you try to get the items from a long list on Android.
And it's hard to get the complete list if some items are invisible and even harder when some of them are the same to Appium.
So my suggestion is to avoid testing a long list.
I'm coding a method that solve various kind of equation. Now I want that the method receives a String equation that could be in the forms:
ax^2+bx+c=0
or
*ax^2+c=0*
or
bx+c=0
etc. and the order shouldn't matter.
My problem is: How could I parse the equation according the "x" grade?
The eq could contains more values of the same grade for example 2x^2+4x^2+3x+8=2 (max grade x^3).
My method should assign the a value to double a[] if on the left or on the right of a there is x^2, double b[], if on the left or on the right there is x, and double c[] if there isn't any x variable near the value (and should change the value sign if the therms is after the =).
Convert a String number in a double is simple but I don't know how I could disassemble the input String according the x grade as described.
Tested for -2x + 3x^2 - 2 + 3x = 3 - 2x^2
public Double[] parseEquation(String equation)
{
Log.d(TAG, "equation: " + equation);
// Remove all white spaces
equation = equation.replaceAll("[ ]", "");
// Get the left and right sides of =
String[] sides = equation.split("[=]"); // should be of size 2
boolean leftNegative = false;
boolean rightNegative = false;
if (sides.length != 2)
{
// There is no = or more than one = signs.
}
else
{
// if sides i starts with + remove the +
// if - we remove and put it back later
for (int i = 0; i < 2; i++)
{
if (sides[i].charAt(0) == '+')
{
sides[i] = sides[i].substring(1);
}
}
if (sides[0].charAt(0) == '-')
{
leftNegative = true;
sides[0] = sides[0].substring(1);
}
if (sides[1].charAt(0) == '-')
{
rightNegative = true;
sides[1] = sides[1].substring(1);
}
}
Log.d(TAG, "left side:" + sides[0] + " right side: " + sides[1]);
// Terms without signs need to find out later
String[] leftTerms = sides[0].split("[+-]");
String[] rightTerms = sides[1].split("[+-]");
int length = leftTerms[0].length();
if (leftNegative)
{
leftTerms[0] = "-" + leftTerms[0];
}
// put in the minus sign for the rest of the terms
for (int i = 1; i < leftTerms.length; i++)
{
Log.d(TAG, "length = " + length + " " + sides[0].charAt(length));
if (sides[0].charAt(length) == '-')
{
leftTerms[i] = "-" + leftTerms[i];
length += leftTerms[i].length();
}
else
{
length += leftTerms[i].length() + 1;
}
}
length = rightTerms[0].length();
if (rightNegative)
{
rightTerms[0] = "-" + rightTerms[0];
}
for (int i = 1; i < rightTerms.length; i++)
{
Log.d(TAG, "length = " + length + " " + sides[1].charAt(length));
if (sides[1].charAt(length) == '-')
{
rightTerms[i] = "-" + rightTerms[i];
length += rightTerms[i].length();
}
else
{
length += rightTerms[i].length() + 1;
}
}
// Now we put all the factors and powers in a list
List<ContentValues> leftLists = new ArrayList<ContentValues>();
// left side
for (int i = 0; i < leftTerms.length; i++)
{
Log.d(TAG, "leftTerm: " + leftTerms[i]);
ContentValues contentValues = new ContentValues();
int indexOfX = leftTerms[i].indexOf('x');
if (indexOfX == -1)
{
// no x mean a constant term
contentValues.put("factor", leftTerms[i]);
contentValues.put("power", "0");
}
else
{
int indexOfHat = leftTerms[i].indexOf('^');
if (indexOfHat == -1)
{
// no hat mean power = 1
contentValues.put("power", "1");
String factor = leftTerms[i].substring(0, indexOfX).trim();
contentValues.put("factor", factor);
}
else
{
String power = leftTerms[i].substring(indexOfX + 2).trim();
String factor = leftTerms[i].substring(0, indexOfX).trim();
contentValues.put("factor", factor);
contentValues.put("power", power);
}
}
Log.d(TAG, contentValues.toString());
leftLists.add(contentValues);
}
List<ContentValues> rightLists = new ArrayList<ContentValues>();
for (int i = 0; i < rightTerms.length; i++)
{
Log.d(TAG, "rightTerm: " + rightTerms[i]);
ContentValues contentValues = new ContentValues();
int indexOfX = rightTerms[i].indexOf('x');
if (indexOfX == -1)
{
// no hat mean a constant term
contentValues.put("factor", rightTerms[i]);
contentValues.put("power", "0");
}
else
{
int indexOfHat = rightTerms[i].indexOf('^');
if (indexOfHat == -1)
{
// no hat mean power = 1
contentValues.put("power", "1");
String factor = rightTerms[i].substring(0, indexOfX).trim();
contentValues.put("factor", factor);
}
else
{
String power = rightTerms[i].substring(indexOfX + 2).trim();
String factor = rightTerms[i].substring(0, indexOfX).trim();
contentValues.put("factor", factor);
contentValues.put("power", power);
}
}
Log.d(TAG, contentValues.toString());
rightLists.add(contentValues);
}
// Now add the factors with same powers.
// Suppose we solve for cubic here the end result will be
// 4 terms constant, x, x^2 and x^3
// Declare a double array of dim 4 the first will hold constant
// the second the x factor etc...
// You can allow arbitrary power by looping through the lists and get the max power
Double[] result = new Double[]{0.0, 0.0, 0.0, 0.0};
for (ContentValues c : leftLists)
{
switch (c.getAsInteger("power"))
{
case 0:
//Log.d(TAG, "power = 0, factor = " + c.toString());
result[0] += c.getAsDouble("factor");
break;
case 1:
result[1] += c.getAsDouble("factor");
break;
case 2:
result[2] += c.getAsDouble("factor");
break;
case 3:
result[3] += c.getAsDouble("factor");
break;
}
}
for (ContentValues c : rightLists)
{
switch (c.getAsInteger("power"))
{
case 0:
//Log.d(TAG, "power = 0, factor = " + c.toString());
result[0] -= c.getAsDouble("factor");
break;
case 1:
result[1] -= c.getAsDouble("factor");
break;
case 2:
result[2] -= c.getAsDouble("factor");
break;
case 3:
result[3] -= c.getAsDouble("factor");
break;
}
}
Log.d(TAG, "constant term = " + result[0] + ", x^1 = " + result[1]
+ ", x^2 = " + result[2] + ", x^3 = " + result[3]);
return result;
}
If you weren't limited by Android, I'd suggest using a lexer and parser. These are code generators, so they can work anywhere the base language works, but they tend to produce bloated code. Android might not appreciate that.
How can I make this code trimmed down?
prefsDisplay = getSharedPreferences("spinnerSelection",
Context.MODE_PRIVATE);
prefsPlan = getSharedPreferences("spinnerSelection1",
Context.MODE_PRIVATE);
if (prefsDisplay.getInt("spinnerSelection", 0) == 0) {
s1 = 0;
} else if (prefsDisplay.getInt("spinnerSelection", 0) == 1) {
s1 = 1;
} else if (prefsDisplay.getInt("spinnerSelection", 0) == 2) {
s1 = 2;
} else if (prefsDisplay.getInt("spinnerSelection", 0) == 3) {
s1 = 3;
} else {
s1 = 0;
DP.BreakdownMonths = 0;
}
if (prefsPlan.getInt("spinnerSelection1", 0) == 0) {
s2 = 0;
} else if (prefsPlan.getInt("spinnerSelection1", 0) == 1) {
s2 = 1;
} else if (prefsPlan.getInt("spinnerSelection1", 0) == 2) {
s2 = 2;
} else {
s2 = 0;
DP.PlanType = "highint";
}
Basically, what I am doing, when the app logs in, I want it to check SharedPreferences. If it finds a value, it assigns it, otherwise, it defaults to a value.
The following does exactly what your code does. Use the value assigned to shared prefs, and if empty, assign 0 AND also assign DP.
prefsDisplay = getSharedPreferences("spinnerSelection",
Context.MODE_PRIVATE);
prefsPlan = getSharedPreferences("spinnerSelection1",
Context.MODE_PRIVATE);
s1 = prefsDisplay.getInt("spinnerSelection", -1 );
if( s1 < 0 ) {
s1 = 0;
DP.BreakdownMonths = 0;
}
s2 = prefsPlan.getInt("spinnerSelection1", -1 );
if( s2 < 0 ) {
s2 = 0;
DP.PlanType = "highint";
}
Use switch and case to define for respective if statement and use default to assign if it doesn't match any of the if statement.
example:
int month = 8;
String monthString;
switch (month) {
case 1: monthString = "January";
break;
case 2: monthString = "February";
break;
case 3: monthString = "March";
break;
case 4: monthString = "April";
break;
case 5: monthString = "May";
break;
case 6: monthString = "June";
break;
case 7: monthString = "July";
break;
case 8: monthString = "August";
break;
case 9: monthString = "September";
break;
case 10: monthString = "October";
break;
case 11: monthString = "November";
break;
case 12: monthString = "December";
break;
default: monthString = "Invalid month";
break;
}
System.out.println(monthString);
What I am trying to do is to handle multitouch buttons. I have 6 buttons and the user may touch from 1 to 6 buttons. The problem is that MotionEvent can handle up to 3 pointers but what I need is up to 6 pointers. Any help please?
This is the code:
public class MultitouchtestActivity extends Activity {
private class TouchListener implements OnTouchListener {
#Override
public boolean onTouch(final View v, final MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
switch (v.getId()) {
case R.id.button1:
sqText = "Square 1 Pressed::Pointer count = "
+ String.valueOf(event.getPointerCount());
break;
case R.id.button2:
sq1Text = "Square 2 Pressed::Pointer count = "
+ String.valueOf(event.getPointerCount());
break;
case R.id.button3:
sq2Text = "Square 3 Pressed::Pointer count = "
+ String.valueOf(event.getPointerCount());
break;
case R.id.button4:
sq3Text = "Square 4 Pressed::Pointer count = "
+ String.valueOf(event.getPointerCount());
break;
case R.id.button5:
sq4Text = "Square 5 Pressed::Pointer count = "
+ String.valueOf(event.getPointerCount());
break;
case R.id.button6:
sq5Text = "Square 6 Pressed::Pointer count = "
+ String.valueOf(event.getPointerCount());
break;
}
} else if (event.getAction() == MotionEvent.ACTION_POINTER_1_DOWN) {
switch (v.getId()) {
case R.id.button1:
sqText = "Square 1 Pointer1Down::Pointer count = "
+ String.valueOf(event.getPointerCount()) + "\n";
break;
case R.id.button2:
sq1Text = "Square 2 Pointer1Down::Pointer count = "
+ String.valueOf(event.getPointerCount()) + "\n";
break;
case R.id.button3:
sq2Text = "Square 3 Pointer1Down::Pointer count = "
+ String.valueOf(event.getPointerCount()) + "\n";
break;
case R.id.button4:
sq3Text = "Square 4 Pointer1Down::Pointer count = "
+ String.valueOf(event.getPointerCount()) + "\n";
break;
}
} else if (event.getAction() == MotionEvent.ACTION_POINTER_2_DOWN) {
switch (v.getId()) {
case R.id.button1:
sqText = "Square 1 Pointer2Down::Pointer count = "
+ String.valueOf(event.getPointerCount()) + "\n";
break;
case R.id.button2:
sq1Text = "Square 2 Pointer2Down::Pointer count = "
+ String.valueOf(event.getPointerCount()) + "\n";
break;
case R.id.button3:
sq2Text = "Square 3 Pointer2Down::Pointer count = "
+ String.valueOf(event.getPointerCount()) + "\n";
break;
case R.id.button4:
sq3Text = "Square 4 Pointer2Down::Pointer count = "
+ String.valueOf(event.getPointerCount()) + "\n";
break;
}
} else if (event.getAction() == MotionEvent.ACTION_POINTER_3_DOWN) {
switch (v.getId()) {
case R.id.button1:
sqText = "Square 1 Pointer3Down::Pointer count = "
+ String.valueOf(event.getPointerCount()) + "\n";
break;
case R.id.button2:
sq1Text = "Square 2 Pointer3Down::Pointer count = "
+ String.valueOf(event.getPointerCount()) + "\n";
break;
case R.id.button3:
sq2Text = "Square 3 Pointer3Down::Pointer count = "
+ String.valueOf(event.getPointerCount()) + "\n";
break;
case R.id.button4:
sq3Text = "Square 4 Pointer3Down::Pointer count = "
+ String.valueOf(event.getPointerCount()) + "\n";
break;
}
}
// TODO Auto-generated method stub
return true;
}
}
protected Button sq1;
protected Button sq2;
protected Button sq3;
protected Button sq4;
protected Button sq5;
protected Button sq6;
protected String sqText = new String();
protected String sq1Text = new String();
protected String sq2Text = new String();
protected String sq3Text = new String();
protected String sq4Text = new String();
protected String sq5Text = new String();
private final Handler handler = new Handler();
private final Runnable mUpdateUITimerTask = new Runnable() {
#Override
public void run() {
// do whatever you want to change here, like:
updateTextField();
}
};
/** Called when the activity is first created. */
#Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setViews();
handler.postDelayed(mUpdateUITimerTask, 5000);
}
private void setViews() {
sq1 = (Button) findViewById(R.id.button1);
sq2 = (Button) findViewById(R.id.button2);
sq3 = (Button) findViewById(R.id.button3);
sq4 = (Button) findViewById(R.id.button4);
sq5 = (Button) findViewById(R.id.button5);
sq6 = (Button) findViewById(R.id.button6);
sq1.setOnTouchListener(new TouchListener());
sq2.setOnTouchListener(new TouchListener());
sq3.setOnTouchListener(new TouchListener());
sq4.setOnTouchListener(new TouchListener());
sq5.setOnTouchListener(new TouchListener());
sq6.setOnTouchListener(new TouchListener());
}
private void updateTextField() {
final TextView view1 = (TextView) findViewById(R.id.logView);
final TextView view2 = (TextView) findViewById(R.id.logView1);
final TextView view3 = (TextView) findViewById(R.id.logView2);
final TextView view4 = (TextView) findViewById(R.id.logView3);
final TextView view5 = (TextView) findViewById(R.id.logView4);
final TextView view6 = (TextView) findViewById(R.id.logView5);
// view1.append(sqText + "\n");
view1.setText(sqText);
view2.setText(sq1Text);
view3.setText(sq2Text);
view4.setText(sq3Text);
view5.setText(sq4Text);
view6.setText(sq5Text);
handler.post(mUpdateUITimerTask);
}
}
The number of pointers that you can detect with android depends on the device. Some older ones can only detect one whereas more modern ones may be able to detect more.
Please make sure that your app also works on devices with less pointers if you want to publish it on the market.