Check if condition from json - android

I have an int value lets say 10, now i want to check whether 10 is less than 50 or not so i will write if condition as :
if(10<50){
}
But the problem here is that "<50" is coming from json in string format. So how to evaluate this condition?

If you are sure that JSON response will be in following format -
*characterNUMBER*
then you can get int value as follows -
String test = "<50";
int value1 = Integer.parseInt(test.replace("<", ""));
/*
* Using substring method
* String.subString(beginIndex, endIndex);
* Note: beginIndex is inclusive but endIndex is the exclusive
* */
int value2 = Integer.parseInt(test.substring(1,test.length()));
value1 and value2 both will extract int from that String.
For ease of use do create a method inside your Json POJO to return integer values-
public class JSONResponce{
.....
#SerializedName("some_string_value")
private String stringValue;
public int getIntValue(){
//do conversion of String to actual int here
return Integer.parseInt(stringValue.substring(1,stringValue.length()));
}
....
}
Happy coding !

Related

Need to round off two points after decimal digit

I'm working on an app and facing an issue. I've tried a number of solutions but nothing solved my problem.
I need to round off two digits after decimal point.
For Example.
9.225 should be rounded off to 9.23
Thank you.
For Kotlin use "%.2f".format(number), for Java use String.format("%.2f", number)
Result:
You can use String.format("%.2f", d), this will rounded automatically. d is your value.
OR
You can use this
double d = 1.234567;
DecimalFormat df = new DecimalFormat("#.##");
Log.d(df.format(d));
You can get as a float value as well like below.
float value = Float.valueOf(df.format(d)); // Output will be 1.24
I would have gone with a probable over the top solution however this is what i came up with.
It uses regex to split the string value of the number passed and then rounds up/down depending on the leading digit after the decimal place. It will return a Double in the instance but you can change that if you like. It does throw IllegalArgumentException, but thats taste dependant.
/**
* #param value the value that is being transformed
* #param decimalPlace the decimal place you want to return to
* #return transformed value to the decimal place
* #throws IllegalArgumentException
*/
Double roundNumber(#NonNull Double value, #NonNull Integer decimalPlace) throws IllegalArgumentException {
String valueString = value.toString();
if(valueString.length()> decimalPlace+1){
throw new IllegalArgumentException(String.format("The string value of %s is not long enough to have %dplaces", valueString, decimalPlace));
}
Pattern pattern = Pattern.compile("(\\d)('.')(\\d)");
Matcher matcher = pattern.matcher(valueString);
if (matcher.groupCount() != 4) { //0 = entire pattern, so 4 should be the total ?
throw new IllegalArgumentException(String.format("The string value of %s does not contain three groups.", valueString));
}
String decimal = matcher.group(3);
int place = decimal.charAt(decimalPlace);
int afterDecimalPlace = decimal.charAt(decimalPlace + 1);
String newDecimal = decimal.substring(0, decimalPlace - 1);
newDecimal += afterDecimalPlace > 5 ? (place + 1) : place;
return Double.parseDouble(matcher.group(1) + "." + newDecimal);
}

payUmoney integration is giving an error

After logging in, it's generating a hash value, but still giving error "Some problem occurred! try again".
PayUmoneySdkInitilizer.PaymentParam.Builder builder =
new PayUmoneySdkInitilizer.PaymentParam.Builder();
builder.setAmount(10.0)
.setTnxId("0nf7" + System.currentTimeMillis())
.setPhone(<My phone>)
.setProductName("product_name")
.setFirstName(<My Name>)
.setEmail(<My email>)
.setsUrl("https://www.payumoney.com/mobileapp/payumoney/success.php")
.setfUrl("https://www.payumoney.com/mobileapp/payumoney/failure.php")
.setUdf1("").setUdf2("").setUdf3("").setUdf4("").setUdf5("")
.setIsDebug(false)
.setKey(<mykey>)
.setMerchantId(<my debug merchant id>);
String tnxId="0nf7" + System.currentTimeMillis();
PayUmoneySdkInitilizer.PaymentParam paymentParam = builder.build();
String hashSequence = "<...>|"+tnxId+"|10.0|product_name|<My name>|<My email>|||||||||||salt";
String serverCalculatedHash= hashCal("SHA-512", hashSequence);
Toast.makeText(getApplicationContext(),
serverCalculatedHash, Toast.LENGTH_SHORT).show();
paymentParam.setMerchantHash(serverCalculatedHash);
// calculateServerSideHashAndInitiatePayment(paymentParam);
PayUmoneySdkInitilizer.startPaymentActivityForResult(TrayActivity.this, paymentParam);
public static String hashCal(String type, String str) {
byte[] hashseq = str.getBytes();
StringBuffer hexString = new StringBuffer();
try {
MessageDigest algorithm = MessageDigest.getInstance(type);
algorithm.reset();
algorithm.update(hashseq);
byte messageDigest[] = algorithm.digest();
for (int i = 0; i<messageDigest.length; i++) {
String hex = Integer.toHexString(0xFF &messageDigest[i]);
if (hex.length() == 1) { hexString.append("0"); }
hexString.append(hex);
}
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} return hexString.toString();
}
You use in the code:
.setTnxId("0nf7" + System.currentTimeMillis())
And then later:
String tnxId="0nf7" + System.currentTimeMillis();
Probably not the only problem, but do you really want to use two different values for these (the time may change between the two calls)? Didn't you want the same tnxId in both cases?
TransactionIdProvider.java:
import java.util.Locale;
public class TransactionIdProvider {
private final static String DEFAULT_PREFIX = "ID";
// Convenient prime number for incrementing the counter
private final static long ID_ADD = 0xF0AD; // "f*ck off and die"
// 64b counter with non-trivial start value
private static long idCounter = 0x0101F00DDEADBEEFL;
/**
* Returns ID consisting of prefix string and 64b counter interleaved
* with 32b per-4s-timestamp.
*
* May produce identical ID (collision) when:
* 1) class is reloaded within 4s
* (to fix: serialize "idCounter" upon shutdown/restart of VM, or
* modify prefix per start of VM)
* 2) more than 2^64 IDs are requested within 4s (no fix, unexpected)
* 3) more than 2^64 IDs are requested after cca. 550 years.
* (no fix, unexpected)
* 4) more than one static instance of TransactionIdProvider is used
* (two or more VMs running the app) (to fix put different prefix in
* every VM/server running this)
*
* Length of returned ID is prefix.length() + 24 alphanumeric symbols.
*/
public static synchronized String getNewId(final String prefix) {
idCounter += ID_ADD; // increment counter
// get 32b timestamp per ~4s (millis/4096) (good for ~550 years)
final int timeStamp = (int)(System.currentTimeMillis()>>12);
final int idPart1 = (int)(idCounter>>32);
final int idPart2 = (int)(idCounter);
return String.format(Locale.US, "%s%08X%08X%08X",
prefix, idPart1, timeStamp, idPart2);
}
public static String getNewId() {
return getNewId(DEFAULT_PREFIX);
}
}
Not sure how much usable is this one, and if the ID may be so long. Feel free to use/modify it any way you wish.
Also I wonder, whether I didn't forget about something important, but can't recall anything.
The security aspect of this one is still quite weak, as within 4s time span the ID will be like simple addition, but at least it's not producing 1, 2, 3... series.
Did found some SDK docs, looks like txnId may be 25 chars long, so you have 1 char for prefix only. Or cut down on timestamp, using %07X in format and masking value with 0x0FFFFFFF, that would make it repeat every ~34 years -> 2 letters for prefix. Or change counter to 32b int, should be still more than enough, unless you expect thousands of transactions per second -> that would remove 8 chars. Or base32/base64 the whole ID to shorten it (depends what alphabet is legal for content)...
Or whatever... already spent enough time with this. Hire a pro.

How to get byte by byte from byte array

I am getting response from server in string format like
V1YYZZ0x0000010x0D0x00112050x0C152031962061900x0D410240x0E152031962061900x0F410240x1021TATADOCOMOINTERNET101
Then I am converting it in to byte array because i need to get value from this byte by byte.
I tried to use
Arrays.copyOfRange(original,
from , to);
but it work on index basis not on byte basis.
I also tried following solution but it also truncating String(if I use string instead of byte[]) on length basis.
public static String truncateWhenUTF8(String s, int maxBytes) {
int b = 0;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
// ranges from http://en.wikipedia.org/wiki/UTF-8
int skip = 0;
int more;
if (c <= 0x007f) {
more = 1;
} else if (c <= 0x07FF) {
more = 2;
} else if (c <= 0xd7ff) {
more = 3;
} else if (c <= 0xDFFF) {
// surrogate area, consume next char as well
more = 4;
skip = 1;
} else {
more = 3;
}
if (b + more > maxBytes) {
return s.substring(0, i);
}
b += more;
i += skip;
}
return s;
}
I know how to calculate string in byte length but it giving only full string length in byte like
Here is how I need to extract packet on byte basis.
Above codes and parameters is only example. I need to get byte by byte from string/byte array.
I searched lot but didn't get any solution or link which I can refer. I am not getting how to split string using byte length because I know byte length for each parameter and for value also.
Please give me any reference or hint.
To determine what is equal to one byte in a String is not trivial. Your String contains bytes in hexadecimal text form: 0x0D (one byte, equal to 13), but also contains values as substrings. For example 1024 can be interpreted as an integer which in this case fits into 2 bytes, but could also be interpreted as a text made up by 4 chars, totaling to 8 bytes.
Anyways, I would split the string using a regular expression, and then further split the parts to length and value:
String message = "V1YYZZ0x0000010x0D0x00112050x0C152031962061900x0D41024"+
"0x0E152031962061900x0F410240x1021TATADOCOMOINTERNET101";
String regex = "(0)(x)(\\w\\w)";
String[] parts = message.split(regex);
Log.d(TAG,"HEADER = "+parts[0]);
for (int i=1; i<parts.length; i++) {
String s = parts[i];
// Only process if it has length > 0
if (s.length()>0) {
String len = "", val = "";
// String s is now in format LVVVV where L is the length, V is the value
if (s.length() < 11) {
// 1 character indicates length, up to 9 contains value
len = s.substring(0, 1);
val = s.substring(1);
} else if (s.length() > 10) {
// 2 characters indicate length, up to 99 contains value
len = s.substring(0, 2);
val = s.substring(2);
} else if (s.length() > 101) {
// 3 characters indicate length, up to 999 contains value
len = s.substring(0, 3);
val = s.substring(3);
}
Log.d(TAG, "Length: " + len + " Value: " + val);
}
}
This produces the following output:
D/Activity: HEADER = V1YYZZ
D/Activity: Length: 0 Value: 001
D/Activity: Length: 1 Value: 1205
D/Activity: Length: 15 Value: 203196206190
D/Activity: Length: 4 Value: 1024
D/Activity: Length: 15 Value: 203196206190
D/Activity: Length: 4 Value: 1024
D/Activity: Length: 21 Value: TATADOCOMOINTERNET101
Then you can check the packages (the first two package in the header is not needed), convert Strings to whatever you would like (e.g. Integer.parseInt(val))
If you explain the structure of the header (V1YYZZ0x0000010x0D0x0011205), I can improve my answer to find the message count.
I think it is doable with Scanner
import java.util.Scanner;
public class Library {
public static void main(String[] args) {
String s = "V1YYZZ0x0000010x0D0x001120"
+ "50x0C152031962061900x0D410240x0E152031962061900x0F410240x1"
+ "021TATADOCOMOINTERNET101";
// Skip first 9? bytes. I'm not sure how you define them
// so I just assumed it is 26 chars long.
s = s.substring(26, s.length());
System.out.println(s);
Scanner scanner = new Scanner(s);
// Use byte as delimiter i.e. 0xDC, 0x00
// Maybe you should use smth like 0x[\\da-fA-F]{2}
// And if you want to know that byte, you should use
// just 0x and get first 2 chars later
scanner.useDelimiter("0x\\w{2}");
// Easily extracted
int numberOfParams = scanner.nextInt();
for (int i = 0; i < numberOfParams; i++) {
String extracted = scanner.next();
// Length of message
int l = extracted.length();
boolean c = getLength(l) == getLength(l - getLength(l));
l -= getLength(l);
l = c ? l : l-1;
System.out.println("length="
+ extracted.substring(0, extracted.length()-l));
System.out.println("message="
+ extracted.substring(extracted.length()-l, extracted.length()));
}
// close the scanner
scanner.close();
}
// Counting digits assuming number is decimal
private static int getLength(int l) {
int length = (int) (Math.log10(l) + 1);
System.out.println("counted length = " + length);
return length;
}
}
We definitely need more information about rules, how string is formed. And what exactly you need to do. This code might be good enough you. And without comments it is really short and simple.
This is not a answer to accessing a byte array byte by byte, but is an answer for the situation in which you find yourself.
Your explanation and description have the appearance of being confused as to what it is that you are really getting from the server (e.g. it is quite hard to represent "V1YYZZ0x0000010x0D0x001120" as a 9 byte field (note it probably ends on the 2, not the 0)). Alternately, that you are using the wrong method to get it from the server, or not getting it as the intended data type.
Your code indicates that you believe that what you are getting is a UTF8 string. The data shown in your question does not appear to indicate that it is intended to be in that format.
Keep in mind when doing something like this that some other programmer had to create structure for the data that you are seeing. They had to define it somewhere with the intent that it be able to be decoded by their intended recipients. Unless there are other considerations (security, minimal bandwidth, etc.), such formats are usually defined in a way that is both easy to encode and decode.
The existence of the multiple "0x"-ASCII-encoded hexadecimal numbers --particularly the single byte representing the parameter (called "varam" in your graphic)-- strongly implies that this data was intended to be interpreted as a ASCII encoded string. While that might not be the case, it should be kept in mind when looking at the problem from a larger perspective.
You are having to put too much effort into decoding the information you are getting from the server. It, probably, should be relatively easy unless there are considerations why it would have intentionally been made difficult.
All of this indicates that the real problem exists in an area for which you have provided us with no information.
Step back:
Think about things like:
How are you receiving this from the server (what function/interface)?
In the call requesting the information from the server is there a way to specify the encoding type be bytes, an ASCII string, or some other format that is easier to deal with than UTF8? At a minimum, it appears to be clear that the data was not intended to be handled as a UTF8 string. There should be a way for you to get it without it having been converted to UTF8.
Also, you should try to find an actual specification for the format of the data. You have not explained much about the source, so it may be you are reverse-engineering something and have no access to specifications.
Basically, it looks like this is a problem where it might be a good idea to step back and ask if you are starting from the point that makes it easiest to solve and if you are headed in the right direction for doing so.
I'm sure I'm missing something obvious...
String.getBytes();
And if you want to process it in order taking defined objects from the array, just wrap using
ByteBuffer.wrap();
The result being something along the lines of:
String s = "OUTPUT FROM SERVER";
byte[] bytes = s.getBytes();
ByteBuffer bb = ByteBuffer.wrap(bytes);
What did I miss from the initial question? :/

android int to hex converting

I have to convert an int to an hex value. This is for example the int value:
int_value = -13516;
To convert to a hex value i do:
hex_value = Integer.toHexString(int_value);
The value that I should get is : -34CC (I don't know if i should make it positive).
The thing is that doing the conversion that way, the value that I get is: ffff cb34
Can't I use this function to make this conversion?
Documentation says Integer.toHexString returns the hexadecimal representation of the int as an unsigned value.
I believe Integer.toString(value, 16) will accomplish what you want.
public static int convert(int n) {
return Integer.valueOf(String.valueOf(n), 16);
}
// in onstart:
Log.v("TAG", convert(20) + ""); // 32
Log.v("TAG", convert(54) + ""); // 84
From: Java Convert integer to hex integer
Both Integer.toHexString, as well as String.format("%x") do not support signs. To solve the problem, you can use a ternary expression:
int int_value = -13516;
String hex_value = int_value < 0
? "-" + Integer.toHexString(-int_value)
: Integer.toHexString(int_value);
String.format("#%06X", (0xFFFFFF & colorYellow));
Output: #FFC107
Go through following code for Integer to hex and Hex to integer Conversion
public class MainActivity extends Activity {
int number;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
number = 678668;
Log.i("ACT", "Integer Number " + number);
/**
* Code for convert integer number to hex number. two mwthods.
*/
Log.i("ACT", String.format("#%x", number)); // use lower case x for
// lowercase hex
Log.i("ACT", "#" + Integer.toHexString(number));
/**
* Code for convert hex number to integer number
*/
String hex = Integer.toHexString(number).replace("/^#/", "");
int intValue = Integer.parseInt(hex, 16);
Log.i("ACT", "Integer Number " + intValue);
}
}
I don't think the above answers would give you the exact value for the signed bits. For example the value of 11 is 0B but the value of -11 would be F5 and not -B since 2's complement gets into the game to solve this i have modified the above answer
int int_value = -11;
String hex_value = int_value < 0
? Integer.toHexString(int_value+65536) : Integer.toHexString(int_value);
String shortHexString = hex_value.substring(2);
where, 65536 is 2^16 now you can get the expected results . Happy coding :)
List item

Convert String to Double excluding part of the string

How to convert double to a string value that I get from the spinner, for example: "10 (ton)."
In summary:
How to convert string to double and delete the part (ton)?
I need only the value 10
Another option is using Java's substring method in the String class.
The signature is:
substring(int beginIndex, int endIndex)
Where endIndex equals to the index of the last character you want to include + 1.
In the case of your example, it will look like this:
String myString = "10 (ton)";
Double dbl = Double.parseDouble(myString.substring(0, 2));
Here is the link to the method:
Java substring
You must parse this String. Here is some example. Also use search.
Check these methods Double.parseDouble() and Double.toString() use these functions for converting double to string or vice-versa.
first you have to get rid of "(ton)" which can be achieved by using a String method for example
String inputString = "10 (ton)";
String str = inputString.split(" ")[0];
After that just parse the double Value
Double dbl = Double.parseDouble(str);
BTW: Not sure whether you want to go from double to string or vice-versa
i have a similar problem.
for correct formatting EditText text content to double value i use this code:
try {
String eAm = etAmount.getText().toString();
DecimalFormat dF = new DecimalFormat("0.00");
Number num = dF.parse(eAm);
mPayContext.amount = num.doubleValue();
} catch (Exception e) {
mPayContext.amount = 0.0d;
}
this is independet from current phone locale and return correct double value.
hope it's help;

Categories

Resources