Android - converting string to long value - android

I am creating a fairly simple android application which is basically a timer, I am trying to make it so that you can set the timer length in the settings and then using preferences retrieve the value and set it as the timer length. I can retrieve the value from the preferences and simply display it.
But when I try to convert the string value (i.e. 1) to a long value using either Long.parseLong(string) or Long.valueOf(String) and Long.valueOf(Int), I don't receive any errors in the code but when I try and start the application, it force closes and the error log says it is caused by NumberFormatException, Here is the the section of code I am using, also if I remove the line that says Long.ParseLong... everything else works fine.
private long interval = 1000 ;
private long startTime = 30000;
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_countdown_timer);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
StringBuilder builder = new StringBuilder();
builder.append("\n"+ prefs.getString("timerLength","NULL"));
startTime = Long.parseLong(builder.toString());
TextView view = (TextView)findViewById(R.id.showTimer);
view.setText(builder.toString());

Pls remove "\n"
StringBuilder builder = new StringBuilder();
builder.append(prefs.getString("timerLength","NULL"));
startTime = Long.parseLong(builder.toString());

The problem is the '\n' character. The string should only contain a long as a String for it to be successfully parsed.

Related

SharedPreferences retrieval stops code

I have a broadcast receiver class that successfully runs when the phone is rebooted. My problem is that when I try to retrieve info from the SharedPreferences, the code stops running and nothing continues. This is the start of the onReceive method:
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
if(sp.getBoolean("alarmRunning", false)) {
Log.d("test", "Fixing alarms1");
String name = sp.getString("currentName", "");
String description = sp.getString("currentDescription", "");
long exactTriggerTime = sp.getLong("exactTriggerTime", 0);
long offsetTriggerTime = sp.getLong("offsetTriggerTime", 0);
String intentNameExtra = sp.getString("intentNameExtra", "");
String intentDescriptionExtra = sp.getString("intentDescriptionExtra", "");
boolean runOnce = sp.getBoolean("runOnce", true);
long interval = sp.getLong("interval", 0);
long totalOffset = sp.getInt("totalOffset", 0);
Log.d("test", "Fixing alarms");
Log.d("test", String.valueOf(runOnce));
When I run it on my phone, I get "Fixing alarms1" returned to me, but not "fixing alarms" or the value of the runOnce variable. Could someone explain this behavior? It shouldn't be that it broke since it couldn't find something, because everything has a default value for it. I have also checked the console with the test filter and without filters, and no error message is being displayed.
EDIT: After further testing, I realized that it didn't like taking an int variable from the SharedPreferences and assigning it to a long. My bad.

UnitTesting for EditText , testing multiple values

Hi I am trying to test the edit Text placing 2 different values but the second test is failing .reasons unknown...below is my code
TestCase1
public void testvalues1() {
// clearing the edit text
mTextView.clearComposingText();
TouchUtils.tapView(this, mTextView);
// sending input as 7
sendKeys("7");
String userInput1;
String expected = "158269.3778";
String parameterFrom1 = "0.0027";
String parameterTo1 = "61.04676";
// getting the input from the mTextView reference
userInput1 = mTextView.getText().toString();
String resultset = UnitCalculation.Converter(parameterFrom1,userInput1,parameterTo1);
assertEquals(resultset, expected);
}
In the above test case iam sending value 7 and output is as expected
TestCase2
public void testvalues2() {
// clearing the edit text
mTextView.clearComposingText();
TouchUtils.tapView(this, mTextView);
// sending input as 23
sendKeys("23");
String userInput1;
String expected = "150.5011";
String parameterFrom1 = "1.092607";
String parameterTo1 = "7.149502";
// getting the input from the mTextView reference
userInput1 = mTextView.getText().toString();
String resultset1 = UnitCalculation.Converter(parameterFrom1,userInput1,parameterTo1);
System.out.println("printing resilt set "+ resultset1);
assertEquals(resultset1, expected);
}
But the method is returning value 0 instead of 150.5011
Iam using the same methos to calculate, When i give User value hardcoded like this String userInput1="23"; it is working, but when is taking the value from edittext its is not working.
can i send multiple values to edit text on the same testfile??
sendKeys with more than one character is what messed it up. See this reference.
To sum up, sendKeys needs a String which contains space separated keys. Your sendKeys("23")is trying to find a key in the soft keyboard called 23, though there isn't. Try using this:
sendKeys("2 3");
As it will send these two key strokes individually, instead of trying to find a key named 23. That's why sending just a 7 worked, because 7 is the key name for "7".

How do I write a random quote generator in Java for Android?

I am very new to Java for Android, and am basically just a noob trying to make a few basic apps for a HTC phone. So far, mainly by copying code, I've written apps that will write "Hello, World", print a random number and display a picture, and these have worked nicely on my phone.
I would now like to combine what I've done and write an app that will generate a random quote from a specified list and print it on the screen. A refresh button would be nice, too.
I looked at these links first as a starting point:
Forrst
Stack Overflow
However, I think I'm going in circles now by trying to combine the two. I started off by making an array of the quotes, generating a random number and assigning it to the quote, then trying to get the tv.setText method to write it.
Any help gratefully received! Thank you!
This is what I have so far:
package com.Me;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import java.util.Random;
public class QuoteActivity extends Activity {
int numQuotes = 10;
String[] quotes = new String[numQuotes] {"John", "Mary", "Bob"};
String randomQuote = quotes[Math.floor(Math.random() * numQuotes)];
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Make a new text view passing Activity object
TextView tv = new TextView(this);
//Set a text into view
tv.setText(randomQuote);
//set the view into activity view container
setContentView(tv);
}
}
Ok, some basic stuff first: you're not assigning numbers to the quotes, you're using the random number to index the quotes array. With that said, something like this would do the trick:
String[] quotes = new String[] {"q1", "q2", "q3"};
String randomQuote = quotes[(int) (Math.random() * quotes.length)];
Please note that you cannot both set the size of an array and initialize it at the same time. I.e. either you do like above, or you do something like:
int numQuotes = 3;
String[] quotes = new String[numQuotes];
quotes[0] = "q1";
quotes[1] = "q2";
quotes[2] = "q3";
I see a couple of errors in your code:
You init an array either by
String[] quotes = new String[]{"1", "2", "3"};
or
String[] quotes = new String[3];
quotes[0] = "1";
quotes[1] = "2";
quotes[2] = "3";
The Math.floor() and Math.random() return double, and you should access array elements with ints. You should cast to int. You don't actually need floor() because random() returns positive value.
You will get an exception if you try to access an array element that is not there. If you have array with 3 elements and math.random()*10 gives you 4 - you will crash.
I suggest:
int randomElemenetIndex = (int) (Math.random() * 10) % 3; //This way you will have 0, 1 or 2
...
tv.setText(quotes[randomElementIndex]);

How to persist the time and score using shared preferences

I having developing simple application, which has just like game. When I have finished game the gave over page display, which as time and score. Now if i want to play that game again and again. How to store that previous all time and score and current finished.
I want to display, all time and score in to the list according to high to low score, after score button was clicked.
I have done shared preferences in gaveover page and that value get from score page. but why not display when i play third time. second time it is ok. third time and so on.. just replacing upward . I don't have enough idea, how to store that all information in to array and display on list. But I have try to use map, but getting not more idea.
I want to display this type of format in to the score page:
Time .............. Score
1:10 .............. 175
2:05 .............. 145
1:15 .............. 110
2:50 ............... 90
Here I have just started little code but not complete and better,
GaveOver.Java
Where just diplay socre , time and mistakes after finish game.
Score.Java
public class Scores extends Activity {
private static String strTime;
private static int intScore;
public static SharedPreferences settings;
public static final String MY_PREFS_NAME = "PrefName";
#Override
protected void onCreate(Bundle savedInstanceState) {
ImageView back, reset, score_home;
super.onCreate(savedInstanceState);
setContentView(R.layout.score);
// lv = (ListView) findViewById(R.id.listView);
getValuesFromGaveOver();
SharedPreferences pref = this.getSharedPreferences(MY_PREFS_NAME, 0);
String data=pref.getString("DATA", "Nothing");
Log.i("horror", "DATA "+data);
}
private void getValuesFromGaveOver() {
SharedPreferences pref = this.getSharedPreferences(MY_PREFS_NAME, 0);
strTime = pref.getString(TIME, "n/a");
intScore = pref.getInt(SCORE, -1);
Log.i("horror", "From Gave Over "+"Time="+strTime+" "+"Score="+intScore);
}
#Override
protected void onStop() {
super.onStop();
SharedPreferences pref = this.getSharedPreferences(MY_PREFS_NAME, 0);
strTime = pref.getString(TIME, "");
intScore = pref.getInt(SCORE, -1);
savePreferences(intScore, strTime);
}
private void savePreferences(int s, String t) {
SharedPreferences sPref = this.getSharedPreferences(MY_PREFS_NAME, 0);
SharedPreferences.Editor edit = sPref.edit();
edit.putString("DATA", strTime+" "+intScore);
edit.commit();
}
}
please give me the good suggestion, how to do it?
The cleanest way would be to use sqlite databases.
Using SharedPreferences is much easier, especially for beginners.
You could do it like that: You save a 3rd item, the actual entry count as SharedPreference.
Everytime you save a new entry you increment this counter.
Then you append the current counter number to the TIME and SCORE keys.
// Saves a new entry | Attention: code not tested!
save(int score, int time){
SharedPreference pref = ...
SharedPreference.Editor editor = ...
int newEntryID = pref.getInt("numEntries", 0) + 1;
editor.setInt("numEntries", newEntryID);
editor.setInt("score" + newEntryID, score);
editor.setString("time" + newEntryID, time);
editor.commit();
}
Assuming "score" is the SharedPreference-Key for SCORE and same for the time.
Reading would be of the same scheme.
for(int i=0; i<numEntries; ++i){
pref.getInt("score" + i, 0);
...
}
using the shared preference you can store both,
1) first you have to store time, once this is done you have to store score mapped on the given time,
you are doing this way,
edit.putString("DATA", strTime+" "+intScore);
But you can take different approach if you have only one player playing at one time,
edit.putString("TIME", strTime);
edit.putString(strTime, strScore);
1:10 .............. 175
So here first you mapped your time with TIME and then you mapped score 175 with 1:10
Hope this will help you
Good idea would be to define Java bean holding score ( say with 2 Fields, time in seconds / points / maybe date / name / whatrever else fields you like to store). You can easily do following with them:
sort in a list and limit their amount ( you do not like to have 10000 of score entries, 100 will be anough )
marshall this list to / from JSON ( Shameless self advertising: https://github.com/ko5tik/jsonserializer )
store JSON in a shared preference or in a private application file (I store up to 100 local highscore entries, and 1000 all time scores and use files)

How to update Android textviews efficiently?

I am working on an Android app which encounters performance issues.
My goal is to receive strings from an AsyncTask and display them in a TextView. The TextView is initially empty and each time the other process sends a string concatenates it to the current content of the textview.
I currently use a StringBuilder to store the main string and each time I receive a new string, I append it to the StringBuilder and call
myTextView.setText(myStringBuilder.toString())
The problem is that the background process can send up to 100 strings per second, and my method is not efficient enough.
Redrawing the whole TextView everytime is obviously a bad idea (time complexity O(N²)), but I'm not seeing another solution...
Do you know of an alternative to TextView which could do these concatenations in O(N) ?
As long as there is a newline between the strings, you could use a ListView to append the strings and hold the strings themselves in an ArrayList or LinkedList to which you append as the AsyncTask receives the strings.
You might also consider simply invalidating the TextField less frequently; say 10 times a second. This would certainly improve responsiveness. Something like the following could work:
static long lastTimeUpdated = 0;
if( receivedString.size() > 0 )
{
myStringBuilder.append( receivedString );
}
if( (System.currentTimeMillis() - lastTimeUpdated) > 100 )
{
myTextView.setText( myStringBuilder.getChars( 0, myStringBuilder.length() );
}
If the strings come in bursts -- such that you have a delay between bursts greater than, say, a second -- then reset a timer every update that will trigger this code to run again to pick up the trailing portion of the last burst.
I finally found an answer with the help of havexz and Greyson here, and some code here.
As the strings were coming in bursts, I chose to update the UI every 100ms.
For the record, here's what my code looks like:
private static boolean output_upToDate = true;
/* Handles the refresh */
private Handler outputUpdater = new Handler();
/* Adjust this value for your purpose */
public static final long REFRESH_INTERVAL = 100; // in milliseconds
/* This object is used as a lock to avoid data loss in the last refresh */
private static final Object lock = new Object();
private Runnable outputUpdaterTask = new Runnable() {
public void run() {
// takes the lock
synchronized(lock){
if(!output_upToDate){
// updates the outview
outView.setText(new_text);
// notifies that the output is up-to-date
output_upToDate = true;
}
}
outputUpdater.postDelayed(this, REFRESH_INTERVAL);
}
};
and I put this in my onCreate() method:
outputUpdater.post(outputUpdaterTask);
Some explanations: when my app calls its onCreate() method, my outputUpdater Handler receives one request to refresh. But this task (outputUpdaterTask) puts itself a refresh request 100ms later. The lock is shared with the process which send the new strings and sets output_upToDate to false.
Try throttling the update. So instead of updating 100 times per sec as that is the rate of generation. Keep the 100 strings in string builder and then update once per sec.
Code should like:
StringBuilder completeStr = new StringBuilder();
StringBuilder new100Str = new StringBuilder();
int counter = 0;
if(counter < 100) {
new100Str.append(newString);
counter++;
} else {
counter = 0;
completeStr.append(new100Str);
new100Str = new StringBuilder();
myTextView.setText(completeStr.toString());
}
NOTE: Code above is just for illustration so you might have to alter it as per your needs.

Categories

Resources