I am making the calculator app. It shows double at the result even when I don't use double.
Example) 1+1 = 2.0
But I want like 1+1= 2
Of course, I want to keep double when there is double like 1.2+1.3= 2.5
How should I have to edit?
I tried to edit like this, but there is an error.
public void equalsOnClick(View view)
{
Integer result = null;
ScriptEngine engine = new ScriptEngineManager().getEngineByName("rhino");
try {
result = (int)engine.eval(workings);
} catch (ScriptException e)
{
Toast.makeText(this, "Invalid Input", Toast.LENGTH_SHORT).show();
}
if(result != null)
resultsTV.setText(String.valueOf(result.intValue()));
}
MainActivity
public class MainActivity extends AppCompatActivity {
TextView workingsTV;
TextView resultsTV;
String workings = "";
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initTextView();
}
private void initTextView()
{
workingsTV = (TextView)findViewById(R.id.workingsTextView);
resultsTV = (TextView)findViewById(R.id.resultTextView);
}
private void setWorkings(String givenValue)
{
workings = workings + givenValue;
workingsTV.setText(workings);
}
public void equalsOnClick(View view)
{
Double result = null;
ScriptEngine engine = new ScriptEngineManager().getEngineByName("rhino");
try {
result = (double)engine.eval(workings);
} catch (ScriptException e)
{
Toast.makeText(this, "Invalid Input", Toast.LENGTH_SHORT).show();
}
if(result != null)
resultsTV.setText(String.valueOf(result.doubleValue()));
}
public void clearOnClick(View view)
{
workingsTV.setText("");
workings = "";
resultsTV.setText("");
leftBracket = true;
}
}
It is happening because you have declared result of type, Double. Therefore, until you cast it's doubleValue() into an int and set the same to resultsTV, its double value will be set there.
Change your method definition as follows:
public void equalsOnClick(View view) {
Double result = null;
ScriptEngine engine = new ScriptEngineManager().getEngineByName("rhino");
try {
result = (Double)engine.eval(workings);
if(result != null) {
int intVal = (int)result.doubleValue();
if(result == intVal) {// Check if it's value is equal to its integer part
resultsTV.setText(String.valueOf(intVal));
} else {
resultsTV.setText(String.valueOf(result));
}
}
} catch (ScriptException e) {
Toast.makeText(this, "Invalid Input", Toast.LENGTH_SHORT).show();
}
}
Note that I have also moved resultsTV.setText inside the try-catch block so that it gets executed only when result = (Double)engine.eval(workings) does not throw an exception.
Use the modulo operator to check whether a double is an Integer
(result %1 ==0)
or Math.floor then check whether result changed or not.
If it is, you can use Integer.valueOf(result)
Integer has a built in toString method by the way.
Nothing to do.
Just check the string on whether it ended with ".0"
If so, just replace the string like this: replace(".0","");
In the else condition, insert the string as you input like now.
Related
sorry for my bad english.
I want to ask about android telephony : CellSignalStrength
I have code like below to display signal strength information on android..
public class MainActivity extends AppCompatActivity {
private TextView textView2;
public String gsmStrength;
#SuppressLint("MissingPermission")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView2 = (TextView) findViewById(R.id.textView2);
TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
try {
for (CellInfo info : tm.getAllCellInfo()) {
if (info instanceof CellInfoGsm) {
CellSignalStrengthGsm gsm = ((CellInfoGsm) info).getCellSignalStrength();
// do what you need
gsmStrength = String.valueOf(gsm.getDbm());
} else if (info instanceof CellInfoCdma) {
CellSignalStrengthCdma cdma = ((CellInfoCdma) info).getCellSignalStrength();
gsmStrength = String.valueOf(cdma.getDbm());
} else if (info instanceof CellInfoLte) {
CellSignalStrengthLte lte = ((CellInfoLte) info).getCellSignalStrength();
gsmStrength = String.valueOf(lte.getDbm());
} else {
gsmStrength = String.valueOf("UNknown");
}
}
}catch (Exception e){
Log.d("SignalStrength", "+++++++++++++++++++++++++++++++ null array spot 3: " + e);
}
textView2.setText(gsmStrength.toString());
when I run it shows the result is -93
so what I want is the result in the form of a string with what information it is:
SIGNAL_STRENGTH_GOOD
SIGNAL_STRENGTH_GREAT
SIGNAL_STRENGTH_MODERATE
SIGNAL_STRENGTH_POOR
like the picture below:
not the number -93 earlier
Instead of using getDbm() which return the "signal strength as dBm" you should use getLevel()
Retrieve an abstract level value for the overall signal quality.
Returns int value between SIGNAL_STRENGTH_NONE_OR_UNKNOWN and SIGNAL_STRENGTH_GREAT inclusive
https://developer.android.com/reference/android/telephony/CellSignalStrengthGsm#getLevel()
So you get one of the int values from CellSignalStrength:
CellSignalStrength.SIGNAL_STRENGTH_GOOD
CellSignalStrength.SIGNAL_STRENGTH_GREAT
CellSignalStrength.SIGNAL_STRENGTH_MODERATE
CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN
CellSignalStrength.SIGNAL_STRENGTH_POOR
If you still want to get a string instead of the int you can use
public static String getLevelString(int level) {
switch(level) {
case CellSignalStrength.SIGNAL_STRENGTH_GOOD:
return "SIGNAL_STRENGTH_GOOD";
case CellSignalStrength.SIGNAL_STRENGTH_GREAT:
return "SIGNAL_STRENGTH_GREAT";
case CellSignalStrength.SIGNAL_STRENGTH_MODERATE:
return "SIGNAL_STRENGTH_MODERATE";
case CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN:
return "SIGNAL_STRENGTH_NONE_OR_UNKNOWN";
case CellSignalStrength.SIGNAL_STRENGTH_POOR:
return "SIGNAL_STRENGTH_POOR";
default:
throw new RuntimeException("Unsupported level " + level);
}
}
Basically, I am trying to get some value from the Api callback response, then assign those value to some of my member variables, but It seems like the program has to run over my getPatientRecord() method each time before it could go to my call, which I have never encountered before.
The Log output result is :
viewPatient: paitient method
viewPatient: secondHello worldnullnull
100SN9 - David Hello H M H 1971-08-09
This is my code:
public class ViewPatientRecord extends AppCompatActivity{
TextView tvName, tvGender, tvBirthDate, tvAddress;
String pGender, pAddress, pBirthdate;
String pName = "Hello world";
Patient myPatient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_patient_record);
tvName = findViewById(R.id.tvFullName);
tvGender = findViewById(R.id.tvGender);
tvBirthDate = findViewById(R.id.tvDb);
tvAddress = findViewById(R.id.tvAddress);
myPatient= new Patient();
try {
getPatientRecord();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void getPatientRecord() throws InterruptedException {
SharedPreferences myPre = getSharedPreferences("PatientRecord", MODE_PRIVATE);
if(myPre.getString("uuid",null)!=null){
retrievePatientByUuid(myPre.getString("uuid",null));
Log.d("viewPatient", "second"+pName+pGender+pBirthdate);
tvName.setText(pName);
tvGender.setText(pGender);
tvBirthDate.setText(pBirthdate);
tvAddress.setText(pAddress);
}else{
Toast.makeText(ViewPatientRecord.this, "Something went wrong, please contact the administrator for help!", Toast.LENGTH_SHORT).show();
}
}
private void retrievePatientByUuid(String uuid) throws InterruptedException {
RestApi api = RetrofitInstance.getRetrofitInstance().create(RestApi.class);
Log.d("viewPatient", "paitient method");
Call<Patient> call = api.getPatientByUUID(uuid, null);
call.enqueue(new Callback<Patient>() {
private volatile Patient obj = new Patient();
#Override
public void onResponse(Call<Patient> call, Response<Patient> response) {
if (response.body() != null) {
Patient patient = response.body();
if (patient != null) {
if (!patient.getDisplay().isEmpty()) {
pName = patient.getDisplay();
pGender = patient.getPerson().getGender();
pBirthdate = patient.getPerson().getBirthdate();
Log.d("viewPatient", pName.toString() + " H " + pGender.toString() + " H " + pBirthdate.toString() + " ?? ");
pAddress = "";
} else {
Log.d("viewPatient", "no results");
}
} else {
Toast.makeText(ViewPatientRecord.this, "Something went wrong...Please try later!", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(ViewPatientRecord.this, "Something went wrong...Please try later!", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<Patient> call, Throwable t) {
t.printStackTrace();
}
});
}
}
I don't see the problem. The call is done in retrievePatientByUuid which is called by getPatientRecord. So yes, you have to go through getPatientRecord. The call is async. It's in the callback that you should set your TextViews :
tvName.setText(pName);
tvGender.setText(pGender);
tvBirthDate.setText(pBirthdate);
tvAddress.setText(pAddress);
I'm making an app that needs to get the results in my MainActivity, when I call getData() I get the data from my instantiation, but when i try to calculate the position it returns null.
This is my Location.class
public class Location implements GoogleApiClient.OnConnectionFailedListener {
private List<Integer> mTypeList;
private ArrayList<String> listItems;
ArrayAdapter<String> adapter;
ListView listView;
LatLng mLatLang;
private PlaceLikelihood pl;
private Context mContext;
private GoogleApiClient mGoogleApiClient;
public Location(Context context) {
this.listItems = new ArrayList<>();
this.mTypeList = new ArrayList<>();
mContext = context;
buildGoogleApiClient();
connect();
getData();
}
public void buildGoogleApiClient(){
mGoogleApiClient = new GoogleApiClient
.Builder(mContext)
.addApi(Places.GEO_DATA_API)
.addApi(Places.PLACE_DETECTION_API)
.build();
}
public void connect() {
if (mGoogleApiClient != null) {
mGoogleApiClient.connect();
}
}
public void getData() {
if (ActivityCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
final PendingResult<PlaceLikelihoodBuffer> result = Places.PlaceDetectionApi
.getCurrentPlace(mGoogleApiClient, null);
result.setResultCallback(new ResultCallback<PlaceLikelihoodBuffer>() {
#Override
public void onResult(#NonNull PlaceLikelihoodBuffer placeLikelihoods) {
pl = placeLikelihoods.get(0);
Log.e("singleplacetype", "onResult: "+pl.getPlace().getPlaceTypes());
Log.e("singleliketype2", "onResult: "+pl.getLikelihood());
Log.e("singleliketype3", "onResult: "+pl.getPlace().getName());
mTypeList = pl.getPlace().getPlaceTypes();
//Latitude and longitude
mLatLang = pl.getPlace().getLatLng();
String latlongshrink = mLatLang.toString();
Matcher m = Pattern.compile("\\(([^)]+)\\)").matcher(latlongshrink);
while (m.find()) {
Log.e("Test", "" + m.group(1));
latlongshrink = m.group(1);
}
for (int i = 0; i < mTypeList.size(); i++) {
try {
nearestPlaces(latlongshrink, getPlaceTypeForValue(mTypeList.get(i)));
} catch (Exception e) {
e.printStackTrace();
}
try {
listItems.add(pl.getPlace().getName() + " " + pl.getLikelihood() + " " + mTypeList + " " + getPlaceTypeForValue(mTipoList.get(i)));
Log.e("singleList", "onResult: "+listItems );
} catch (Exception e) {
e.printStackTrace();
}
}
placeLikelihoods.release();
}
});
}
public Integer getTypes(int posicion) {
Log.e("listType", "getTypes: "+mTypeList);
int type;
if(mTypeList.size()>0){
type = mTypeList.get(posicion);
}else{
return null;
}
return type;
}
Now, that's my Location.class, I call that class in my MainActivity like this
Location loc = new Location(getApplicationContext());
I have another class that calculates some values with the first class, so after I instantiate the Location.class I can succefull see that getData() is executed as it returns to me some places.
json.class
private Integer getPosition(Location loc) {
return loc.getTypes(0);
}
so, now again into my MainActivity i'm trying to fetch te values from Location.class but from json.class, since getPosition does something else before it is beign executed
MainActivity.class
Json json = new Json(getApplicationContext());
Log.e("jsonClassData", "onCreate: "+json.getPosition(loc));
now, this line is returning null , but I dont know why since getData() have been created but getTypes have inside mTypeList that is returning 0 as size and returning null since mTypeList.size is 0
Also if in MainActivity.class I call this line it returns null too
Location loc = new Location(getApplicationContext());
loc.getType(0);
it seems getData() is not saving the values inside mTypeList
Why is this happening ?
thanks
Location loc = new Location(getApplicationContext());
You are not supposed to create an activity with the new operator.
You should use an intent for that.
And so do away with all those public member functions.
The problem was that getData() is an asynchronous operation that is waiting for the results. Now, if I don't wait for that data to be done, getTypes does not have any value on it. Now, thanks to Mike M. I just solved the problem using a simple interface.
I created an interface called PlaceSuccessListener
public interface PlaceSuccessListener {
void onPlaceFound(int placeFound);
}
called it at the last of my pendingResult
private PlaceSuccessListener mPlaceSuccessListener;
getData();
.....
placeLikelihoods.release();
mPlaceSuccessListener.onPlaceFound(200);
}
And then in my MainActivity I just waited for the result to be done in order to access my data. I implemented PlaceSuccessListener and attached the setInterface(this)
#Override
public void onPlaceFound(int placeFound) {
if(placeFound==200){
Log.e("jsonClassData", "onCreate: "+json.getPosition(loc));
}
}
I tried different things for solution but as I failed, I need to know what's wrong with my code and what it should be.
Here is my logcat error
E/AndroidRuntime: FATAL EXCEPTION: main
Process: freemig.freemigmessenger, PID: 31699
java.lang.NumberFormatException: s == null
at java.lang.Integer.parseInt(Integer.java:570)
at java.lang.Integer.parseInt(Integer.java:643)
And it happens on a button click event which is
private class SentMessageHolder extends RecyclerView.ViewHolder {
TextView messageText, timeText;
ImageButton iB;
MsgDltAPIService msgDltAPIService;
String rec_id;
String content_id;
int[] ids = new int[100];
SentMessageHolder(final View itemView) {
super(itemView);
messageText = itemView.findViewById(R.id.text_message_body);
timeText = itemView.findViewById(R.id.text_message_time);
iB = itemView.findViewById(R.id.sentMessageTextDelete);
msgDltAPIService = RestClient.getClient().create(MsgDltAPIService.class);
iB.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
userAuthenticationKey = new UserAuthenticationKey(mContext.getApplicationContext());
sharedPreferences = mContext.getApplicationContext().getSharedPreferences("user authentication", MODE_PRIVATE);
editor = sharedPreferences.edit();
ids[0] = Integer.parseInt(content_id);
final MsgDltRequest msgDltRequest = new MsgDltRequest(
ids,
rec_id);
Call<MsgDltResponse> call =
msgDltAPIService.msgDlt(userAuthenticationKey.getUserTokenKey(),
msgDltRequest);
call.enqueue(new Callback<MsgDltResponse>() {
#Override
public void onResponse(Call<MsgDltResponse> call, Response<MsgDltResponse> response) {
Toast.makeText(mContext.getApplicationContext(), "" + response.body().getData(),
Toast.LENGTH_LONG).show();
}
#Override
public void onFailure(Call<MsgDltResponse> call, Throwable t) {
Toast.makeText(mContext.getApplicationContext(), "please try again",
Toast.LENGTH_LONG).show();
}
});
}
});
}
void bind(Datum2 message) {
messageText.setText(message.getMsg());
// Format the stored timestamp into a readable String using method.
timeText.setText(message.getCreatedAt().getFormatTime());
content_id.valueOf(message.getContentId().toString()) ;
if (! message.getOriginatorId().equals(userID)){
rec_id.valueOf(message.getOriginatorId());
}
else {
rec_id = null;
}
}
}
It gives me error on this line
ids[0] = Integer.parseInt(content_id);
I tried several things as I said previously , but what should be my code? My full class is here. One more thing I'm working on a Adapter Class.
Log says that it's a NumberFormatException and the String you're trying to convert to int is null. Integer.parseInt(content_id) works only if content_id is not null as well it's a valid integer.
So in your situation, you can add a check to see if the string is null. If the string is not null and still gives a NumberFormatException, then the string is not a valid integer and can be handled with a try catch statement.
if (content_id != null) {
try {
ids[0] = Integer.parseInt(content_id);
} catch(NumberFormatException e) {
// Deal with the situation like
ids[0] = 0;
}
}
You can use TextUtils utility method like this,
if (!TextUtils.isEmpty(content_id) && TextUtils.isDigitsOnly(content_id)) {
ids[0] = Integer.parseInt(content_id);
} else {
ids[0] = 0;
}
and while setting content_id you can set like this, content_id = message.getContentId().toString(); instead of content_id.valueOf(message.getContentId().toString()) ;
Put the statement in try and catch block to handle the exception.
try{
ids[0] = Integer.parseInt(content_id);
}catch(NumberFormatException ex){ // handle your exception
...
}
or simply integer matching-
String input=...;
String pattern ="-?\\d+";
if(input.matches("-?\\d+")){ // any positive or negative integer or not!
...
}
String str = arraylist.get(position); //check your value from Arraylist
if (!TextUtils.isEmpty(str) && TextUtils.isDigitsOnly(str)) {
yourTextview.setText(str);
} else {
yourTextview.setText("Your default value");
}
I'd like to get the string value output from AsyncTask. And store it into a variable on my main thread. How can I do so?
I tried to do store = new ReceiveData().execute().get() however it throws an execution exception error. But anyway, my question is not about the execution exception error. I just need a way to get the string out, please help!
Here is my activity code:
public class MainActivity extends AppCompatActivity { //MAIN ACTIVITIES (REMOTE)
double multiplier;
int seekbarvalue, finallumens;
#Override
protected void onCreate(Bundle savedInstanceState) {
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT); //On orientation change socket will disconnect...
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Toast.makeText(MainActivity.this, LoginActivity.SERVER_IP, Toast.LENGTH_LONG).show();
//================START AFTER DEFAULT ON CREATE=================
SeekBar seekbarbrightness = (SeekBar) findViewById(R.id.seekbarbrightness);
final TextView tblumens, tbvolts, tbamps;
tblumens = (TextView) findViewById(R.id.tblumens);
seekbarvalue = seekbarbrightness.getProgress();
multiplier = (double) seekbarvalue / 100;
finallumens = (int) (multiplier * LoginActivity.enterlumens);
tblumens.setText(String.valueOf(finallumens) + " Lumens");
tbvolts = (TextView) findViewById(R.id.tbvolts);
tbamps = (TextView) findViewById(R.id.tbamps);
seekbarbrightness.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekbarbrightness, int progress, boolean b) {
if (b == true) {
seekbarvalue = seekbarbrightness.getProgress();
multiplier = (double) seekbarvalue / 100;
finallumens = (int) (multiplier * LoginActivity.enterlumens);
tblumens.setText(String.valueOf(finallumens) + " Lumens");
if (LoginActivity.getSocket() != null) {
try {
LoginActivity.getSocket().getOutputStream().write(String.valueOf(multiplier).getBytes());
new ReceiveData().execute();
//infinite loop here to keep receiving volts and amperes.
//Do a split and assign value to volt and amp
//String[] strrecv= store.split("|");
//String volts = strrecv[0];
//String amps = strrecv[1];
//tbvolts.setText("Voltage: " + volts + " V");
//tbamps.setText("Amperes:" + amps + " A");
} catch (IOException e) {
e.printStackTrace();
}
} else {
Toast.makeText(MainActivity.this, "NOT connected To Socket, please disconnect and reconnect!", Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
And in my Asynctask I am doing this.
class ReceiveData extends AsyncTask<Void, Void, String> {
String str;
protected String doInBackground(Void... args) {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(LoginActivity.getSocket().getInputStream()));
str = in.readLine();
return str;
} catch (IOException e) {
e.printStackTrace();
String str = "fail";
return str;
}
}
protected void onPostExecute(String str) {
//super.onPostExecute(str);
}
}
The purpose of AsyncTask is to perform asynchronous task in a separate thread to free the main thread and avoid UX issues. For your purpose, I suggest transferring all of the work inside your try block inside the AsyncTask and update the UI after execution.
Something like this
In MainThread
new ReceiveData().execute();
In AsyncTask
class ReceiveData extends AsyncTask<Void, Void, Boolean> {
String volts;
String amps;
protected Boolean doInBackground(Void... args) {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(LoginActivity.getSocket().getInputStream()));
str = in.readLine();
String[] strrecv= store.split("|");
volts = strrecv[0];
amps = strrecv[1];
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
protected void onPostExecute(Boolean result) {
if (result) {
tbvolts.setText("Voltage: " + volts + " V");
tbamps.setText("Amperes:" + amps + " A");
}
}
}
Note that this only works if your AsyncTask is defined inside your Activity. If not, you need to create an interface from the AsyncTask and implement it in your activity and activate it onPostExecute