My application is Enter an amount, calculate the amount and display the amount.
I am using Android SDK 16. When i enter the amount and click on the calculate button i am getting the
SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length.
My Activity class is
public class ChapterTwo extends Activity {
public static final String tag = "Chapter 2";
static{
StrictMode.ThreadPolicy policy = new
StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
#SuppressWarnings("unused")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chapter_two);
final EditText mealpricefield = (EditText) findViewById(R.id.mealprice);
final TextView answerfield = (TextView) findViewById(R.id.answer);
final Button button = (Button) findViewById(R.id.calculate);
button.setOnClickListener(new Button.OnClickListener() {
public void onClickView(View v) {
try {
Log.i(tag, "onClick Invoked");
// grab the meal price from UI
String mealprice = mealpricefield.getText().toString();
Log.i(tag, "meal price is [" + mealprice + "]");
String answer = "";
// check to see if meal price contains $
if (mealprice.indexOf("$") == -1) {
mealprice = "$" + mealprice;
}
float fmp = 0.0F;
// get currency formatter;
NumberFormat nf = java.text.NumberFormat
.getCurrencyInstance();
// grab the input meal price
fmp = nf.parse(mealprice).floatValue();
// let's give a nice tip
fmp *= 1.2;
Log.i(tag, " Total meal price Unformatted is [" + fmp + "]");
// format our result
answer = " Full Price, Including the 20% Tip is "
+ nf.format(fmp);
answerfield.setText(answer);
Log.i(tag, " On Click Complete");
} catch (java.text.ParseException e) {
Log.i(tag, "Parse Exception caught");
answerfield.setText("Failed to Parse the Exception");
}
catch (Exception e) {
Log.e(tag, "Failed To calculate the tip" + e.getMessage());
e.printStackTrace();
answerfield.setText(e.getMessage());
}
}
public void onClick(View v) {
// TODO Auto-generated method stub
}
});
}}
My Layout is
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Chapter 2 Android Tip Calculator"
tools:ignore="HardcodedText" />
<EditText
android:id="#+id/mealprice"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="text">
<requestFocus />
</EditText>
<Button
android:id="#+id/calculate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Calculate Tip" />
<EditText
android:id="#+id/answer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10" />
I am getting the following error in the log cat
10-23 20:19:26.232: E/Trace(699): error opening trace file: No such file or directory (2)
10-23 20:19:27.092: D/gralloc_goldfish(699): Emulator without GPU emulation detected.
10-23 20:19:33.262: W/IInputConnectionWrapper(699): showStatusIcon on inactive InputConnection
10-23 20:24:22.106: I/Choreographer(699): Skipped 30 frames! The application may be doing too much work on its main thread.
10-23 20:27:52.824: I/Choreographer(699): Skipped 37 frames! The application may be doing too much work on its main thread.
10-23 20:31:13.323: E/SpannableStringBuilder(699): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
10-23 20:31:13.323: E/SpannableStringBuilder(699): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
10-23 20:31:32.552: I/Choreographer(699): Skipped 35 frames! The application may be doing too much work on its main thread.
10-23 20:39:44.723: I/Choreographer(699): Skipped 63 frames! The application may be doing too much work on its main thread.
You should declare all the views in main class and initialize them in onCreate() method:
public class ChapterTwo extends Activity {
public static final String tag = "Chapter 2";
EditText mealpricefield;
TextView answerfield;
Button button;
.
.
.
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chapter_two);
mealpricefield = (EditText) findViewById(R.id.mealprice);
answerfield = (TextView) findViewById(R.id.answer);
button = (Button) findViewById(R.id.calculate);
.
.
.
}
Also the code that you have placed in onClickView(View v) should be inside onClick(View v) that you have below in your code:
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
Is there more code other than the one you posted?
Here are couple things I noticed:
Your code won't do anything when you press the button since you are not doing anything in the onClick(View v) method as pointed above. You have an onClickView(View v) function, which no one calls. You should move your code from onClickView() to onClick() and just get rid of the onClickView() method (or you can just call onClickView from onClick function).
If you move the code as noted above, your code will work, I even tested it myself just now to double check. (You are missing a </LinearLayout> tag in the copy-paste code above but I assume you had it).
The error log you posted shows an error from SpannableStringBuilder. But you are not using SpannableStringBuilder at all anywhere in your code, so either a) you have some other code or b) this error has nothing to do with your code.
What happens when you press the button? Does the application crash? What values are you using for testing when you see the issue? Is there any other log in the log that has your tag or application name? The log you posted doesn't show any force-close logs or any errors associated with your application.
On second thought, are you saying that your problem is that when you press the Calculate button, nothing happens? So you assumed you had an error and just thought that the error you saw in the log was the reason your code didn't work? If that's the case, all you have to do is just move the code block in onClickView() into onClick() and get rid of onClickView(). The error log is from some other program that has nothing to do with your code.
At a glance, this may be your problem.
Log.i(tag, " Total meal price Unformatted is [" + fmp + "]");
fmp is a float... you are adding it to a string.
comment this line out and see if it works.
Related
I have a button(button) and a textview(text) in my application. Before clicking on the button the textview text will always be "Start Search".But After clicking on the button , a function(scanning()) will be called. For executing the function it takes some times. So I want the texview text to be "Please wait" between the time after clicking the button and before getting the result of the function. And after getting the result of the function the textview text will be change to "Found" or "Not Found".
But problem is ,it never shows "please wait". After clicking on the button it shows "Start search" until getting the result of the function.
How to show "please wait" on the textview until it gets the result from the function after clicking on the button ??
Button button = (Button) findViewById(R.id.search);
TextView text = (TextView) findViewById(R.id.searchR);
text.setText("Start Search");
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
text.setText("Please Wait");
boolean res=scanning();
if(res==true)
text.setText("Found");
else text.setText("Not Found");
}
});
XML Part:
<Button
android:id="#+id/search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="60dp"
android:layout_marginLeft="60dp"
android:layout_marginTop="30dp"
android:text="Search"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/searchR"
android:layout_width="0dp"
android:layout_height="34dp"
android:layout_marginStart="97dp"
android:layout_marginLeft="97dp"
android:layout_marginTop="30dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/search"
app:layout_constraintTop_toTopOf="parent" />
In the scanning part, I did some searching for BLE devices using UUID. If that device is found then I returned true otherwise false;
Introduce a small delay after you change the text to "Please Wait" and before calling scanning().
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
text.setText("Please Wait");
Handler delayHandler = new Handler();
delayHandler.postDelayed(new Runnable() {
#Override
public void run() {
boolean res=scanning();
if(res) {
text.setText("Found");
}
else{
text.setText("Not Found");
}
}
},100);
}
});
Edit: Depending on your code, you may need to declare your variables as static or maybe global for this to work.
I found some mistakes in your code.
You are changing text of Button instead of TextView.
public void onClick(View v) {
text.setText("Please Wait");
boolean res=scanning();
if(res==true)
but1.setText("Found");
else but1.setText("Not Found");
}
Here
but1.setText
should be replaced with
text.setText
Your scanning method is returning result very fast, that's why you will not get Please Wait text.
Write external method for change text,
for example:
public void onClick(View v)
{
changeText("Please Wait");
boolean res = scanning();
if (res) // (res == true) is unnecessary, you can use like this
changeText("Found");
else changeText("Not Found");
}
private void changeText(string s)
{
text.setText(s);
}
I know this has probably been asked a million times, and I have searched. this question originally started from my wanting to have an activity with some buttons and when one was clicked before sending over to the next activity check for null variables and if some where found show a toast. I have since for bug checking removed the null variable checking segment to just show the variables. A very barebones and simplified code of the situation is like so
public Class MyClass extends Activity {
EditText et1;
EditText et2;
Button btn1;
String et1string;
String et2string;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mylayout);
et1 = (EditText) findViewById(R.id.et1);
et2 = (EditText) findViewById(R.id.et2);
btn1 = (Button) findViewById(R.id.btn1);
btn1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
et1string = et1.getText().toString();
et2string = et2.getText().toString();
Log.d(getClass().getName(), "et1string =" + et1string + " and et2string =" + et2string);
Toast.makeText(getApplicationContext(), "et1string =" + et1string + " and et2string =" + et2string, Toast.LENGTH_LONG);
}
});
}
I have tried using the following in place of the Toast.makeText
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "et1string =" + et1string + " and et2string =" + et2string, Toast.LENGTH_LONG);
}
});
Either way there is no toast message that is shown.
I am sure i am doing something easily noticed by a guru, but just has me puzzled. the logcat shows the logd, and this isnt application dependant, I would just like to figure out why i cant get a toast to show up
Also Ive read that notifications can be disabled? idk, but I am programming with the version 23 sdk so if there is a permissions i need to ask for some guidance on that would be great
You have to call show on your toast:
Toast.makeText(getApplicationContext(), "et1string =" + et1string + " and et2string =" + et2string, Toast.LENGTH_LONG).show();
You're missing a call to .show().
This should show up as a warning in Android Studio, but if it isn't, go to your Preferences > Inspections, and make sure that the "Toast created but not shown" inspection is enabled.
add a ".show" at the end.
Toast.makeText(getApplicationContext(), "et1string =" + et1string + " and et2string =" + et2string, Toast.LENGTH_LONG).show;
Your question — solved by calling show() — was already answered, but I feel this is a great opportunity to share Reto Meier's awesome post where he talks about Android Studio's Live Templates and he talks about this very Toast issue.
I am writing code for an inbox-like activity which has a button that leads to the messages. This button has a text field that counts how many messages are in the inbox.
My problem is that the button's text field is not changing when the number of messages changes. It is not a problem of the app not checking for updates, and the code with setText is being called with the correct number to update.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.v("onCreate", "Main");
// Checking if there is login
if (ParseUser.getCurrentUser() == null) {
navigateToLogin();
} else {
// Setting pointers for buttons.
// onClick methods follow.
askButton = (Button) findViewById(R.id.buttonAsk);
ansButton = (Button) findViewById(R.id.buttonAnswer);
inboxButton = (Button) findViewById(R.id.buttonCenter);
mUser = ParseUser.getCurrentUser();
updateInbox();
}
This is the method that checks for new messages and updates the button.
private void updateInbox() {
Log.v(TAG, "Updating inbox");
ParseQuery responses = new ParseQuery(ParseConstants.CLASS_ANSWER);
responses.whereMatches(ParseConstants.KEY_SENDER_ID, mUser.getObjectId());
try {
responsesCount = responses.count();
Log.v("responses count" ,""+responsesCount);
if (responsesCount > 0) {
inboxButton.setText(String.valueOf(responsesCount));
}
Log.v("InboxActivity","Label set to " + responsesCount);
} catch (ParseException e) {
Log.v("InboxActivity", e.getMessage());
}
}
updateInbox gets called correctly and in the correct moments, so I only added its code to make this as clean as possible. Here is the xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0099cc"
tools:context=".MainActivity"
android:clickable="false"
>
<Button
android:layout_width="80sp"
android:layout_height="80sp"
android:id="#+id/buttonCenter"
android:layout_gravity="center"
android:layout_centerInParent="true"
android:textSize="30sp"
android:text=""
android:textColor="#color/black_overlay"
android:background="#drawable/greenbutton"/>
EDIT:
Hi all, thanks for the help. I figured out the problem and posted it as an answer. It was a logical error, nothing to do with Android.
try this:
inboxButton.post(new Runnable(){
#Override
public void run(){
inboxButton.setText(String.valueOf(responsesCount));
}
});
(responsesCount should be final)
Try below code
import android.widget.RemoteViews;
if (responsesCount > 0) {
RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.my_layout); //where my_layout is the layout file where the button resides.
remoteViews.setTextViewText(R.id.button, "Set button text here");// where button is id of the button.
}
findViewById doesn't exist for a widget.
Below code will work for you
runOnUiThread(new Runnable() {
#Override
public void run() {
if (responsesCount > 0) {
inboxButton.setText(String.valueOf(responsesCount));
}
}
});
You may use AsyncTask for smoothness of app flow.
I realized that the text was only getting updated when the number of responses was > 0. The button was updating correctly otherwise so I had to put an else statement to make sure the button always got updated. I edited the question with the correct answer in comments.
responsesCount = responses.count();
Log.v("responses count" ,""+responsesCount);
if (responsesCount > 0) {
inboxButton.setText(String.valueOf(responsesCount));
///////////////////////////////////
// MY EDIT HERE
//} else{
// inboxButton.setText("");
///////////////////////////////////
i have to show some operations in Android,,,
but Im having some noob problem,
public void calculateButtonPressed() {
// TODO Auto-generated method stub
Button button = (Button) findViewById(R.id.result);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Log.d("myTag", "result biatch");
String text=et.getText().toString();
//toast msg
//Toast msg = Toast.makeText(getBaseContext(),text, Toast.LENGTH_LONG);
// msg.show();
//set Text
tv.setText(text);
//result_tv.setText("copao");
int total = 1+2+3;
result_tv.setText(total);
}
});
}
so the app crashes , as im not using the variable correctly??
If I print the result_tv.setText("copao"); it works fine
but on my basic operation the app crashes,
int total = 1+2+3;
result_tv.setText(total);
so what Im I missing?
thanks!
It is assuming your total value as a string resource Id which might not be available in the R class as a valid resource Id, causing the app to crash.
Change:
result_tv.setText(total);
To:
result_tv.setText(String.valueOf(total));
//OR
result_tv.setText(total + ""); //to parse it as string
use
result_tv.setText(total+""); or result_tv.setText(String.valueOf(total));
Quite new to coding for android but this issue has me tearing my hair out because it seems to make no sense at all...
I have an activity with four form elements in the layout: a CheckBox, two EditTexts and a Button.
When the user presses the button, it saves the content of the EditTexts as two preference values.
When the user presses the checkbox, it does the following:
If the checkbox is checked, load the preferences and store them into two variables.
Check if either of those variables contain empty strings after trimming them.
If so, show an error message, otherwise show a success message.
Essentially, the two text fields are used to set a pair of preferences which must not be empty when the checkbox is clicked.
It seems to work fine if I click the checkbox before pressing the button - error message or success message shown as appropriate.
If I press the save button and then click the checkbox, it always shows the success message regardless of the preferences.
Code follows (trimmed from the program as a whole)...
layout.xml
<CheckBox android:id="#+id/cboxActive" android:text="Click me!" android:onClick="toggleActive" android:layout_width="wrap_content" android:layout_height="wrap_content" />
<EditText android:id="#+id/editFrom" android:layout_width="fill_parent" android:layout_height="wrap_content" android:inputType="phone"><requestFocus /></EditText>
<EditText android:id="#+id/editTo" android:layout_width="fill_parent" android:layout_height="wrap_content" android:inputType="phone"></EditText>
<Button android:id="#+id/btnSave" android:onClick="savePrefs" android:text="Save" android:layout_width="120dp" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" />
</LinearLayout>
main class:
public class AutoMessengerActivity extends Activity
{
SharedPreferences settings;
CheckBox cboxActive;
EditText editFrom, editTo;
boolean active;
String from, to;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
editFrom = (EditText) findViewById(R.id.editFrom);
editTo = (EditText) findViewById(R.id.editTo);
showPrefsInUI();
}
private void loadPrefs()
{
//Load preferences
settings = getPreferences(MODE_PRIVATE);
from = settings.getString("from", "");
to = settings.getString("to", "");
}
private void showPrefsInUI()
{
loadPrefs();
//Set UI elements to preference values
editFrom.setText(from);
editTo.setText(to);
}
public void savePrefs(View view)
{
SharedPreferences.Editor editor = settings.edit();
editor.putString("from", editFrom.getText().toString());
editor.putString("to", editTo.getText().toString());
editor.commit();
Toast.makeText(this, "Prefs saved!", Toast.LENGTH_SHORT).show();
}
public void toggleActive(View view)
{
if (cboxActive.isChecked())
{
loadPrefs();
//This toast is for debugging
//It shows the correct data in all circumstances...
Toast.makeText(this, "F: " + from + " T: " + to, Toast.LENGTH_SHORT).show();
//This is the part that seems to fail if you save then click checkbox
if (from.trim() == "" || to.trim() == "")
{
Toast.makeText(this, "Error - Prefs not saved", Toast.LENGTH_LONG).show();
cboxActive.setChecked(false);
}
else
{
Toast.makeText(this, "Success!", Toast.LENGTH_SHORT).show();
}
}
else
{
Toast.makeText(this, "Unchecked!", Toast.LENGTH_SHORT).show();
}
}
}
Hopefully that code gives an idea of the problem and allows it to be replicated...
Oh god, how silly of me - Urban and jcxavier hit the nail on the head... I forgot about that damn annoying quirk of Java! Changed the line to
from.trim().equals("") || to.trim().equals("")
And it works fine!
For what it's worth, that HAD actually crossed my mind briefly, but it was 2am when I tried equals and I got confused about requiring an Object as the parameter and ended up specifying null rather than "" - which didn't work...