My app has this appearance
It seems to be a TableLayout with several TableRows. In my activity, each TableRow has 3 views: ImageView, TextView and a Button.
The user is the one who sets the content of the ImageView and the TestView by entering the text he wants and pressing a button.
I store this data in stringArray variables and works fine if the phone is not restarted or the app is not closed (forceClose)
If one of these two situations happen, i lose all my data.
I've been trying to store my StringArrays by SharedPreferences but I don't know when i should load the preferences, whether it's in OnCreate() or OnResume() or OnStart methods().
Another question is how to define the arrays. I use this:
String[] titulo = new String[500];
I don't know if this string is created each time i start the activity. Because what i want is to load the previous String (from SharedPreferences) and add some more entries not to create new ones every time the phone is rebooted, for example.
Do you think i need a SQL database or it's OK with this StringArrays.
Thank you.
You should probably switch to using a database, seeing as you have an array of size 500, which could possibly increase in the future.
However, if you want to continue using SharedPreferences, you should write the data in onPause() and onStop() methods, and use an if else statement to see if your data is null before running an operation on it. If the data is null, the read it from the SharedPreferences before continuing.
Related
My Activity has 6 default CardViews, each cardview contains a Constraint layout and the constraint layout contains a couple of Text views
my problem is, I wanted to add an "ADD" which would take you through some steps and eventually create a new cardview, but how would I save that view created by the user so when they close the app and enter again it would still be there? (Users could add multiple cardviews)
I'm familiar with SharedPreferences but i don't think it would be possible in this case because it requires me to save the data in a declared string and the user simply doesn't have access to that
What i want to do is something similar to Alarm apps, when you can add multiple alarms, delete alarms etc and it would be there even if you restart the Alarm app
What you need is not saving the view itself, but rather save info or state of each object after user modifies it. And you are right about SharedPreferences, it wouldn't be the best option for this...
So, I would recommend two things:
Saving & getting your Cardviews data should be from a custom class (for ex: Alarm) that has properties.
package my.app.example;
class Alarm{
long time;
boolean isOn;
String label;
public Alarm(long time, boolean isOn, String label){
this .time = time;
this .isOn = isOn;
this .label = label;
}
}
And you can use it as follows:
long timeFromDatabase = ...;//get time value from database
boolean isOnFromDatabase= ...;//get isOn value from database
String labelFromDatabase= ...;//get label value from database
Alarm alarm1 = new Alarm(timeFromDatabase, isOnFromDatabase, labelFromDatabase);
After, you can add each Alarm object to a List, and then pass it to your Adapter
A database (I recommend Sqlite or Json) to which you will save each Alarm data (time, isOn, ...)
Remark Alarm is just an example! Feel free to use whatever name and properties that suit your project
See this tutorial it's way is similar to what I suggested: https://www.javatpoint.com/android-sqlite-tutorial, he saves contacts to an sqlite offline database and get them later.
I have a screen with an EditText and a ListView. As you type into the EditText, an AsyncTask is launched (any existing AsyncTask is cancelled and tossed) to query locally for some data to display in the ListView. If the EditText is empty of text, all data is queried for and displayed. Essentially, the EditText is a filter of the data on the screen. This is easy to do. In the addTextChangedListener, simply cancel your previous AsyncTask, launch a new one, and pass to it s.toString().
When the user hits the backspace to erase some text in the EditText, I want the default behavior (where all data populates the list). This works with my current implementation of addTextChangedListener.
However, I also have an X button on the right side of my EditText. This is intended to clear out the EditText (EditText.setText("");). This is a special case. In this case, I do not want the query to happen. The problem is, addTextChangedListener does not seem intelligent enough to know this. It gets triggered because the text has changed and all data is queried for.
How do I prevent this?
Use a boolean ignoreNextTextChangeKThxBye data member, setting/clearing that boolean as appropriate and using an if() statement to avoid doing the query.
Everything I've read about Intents talks about using them to push data, or to start one Activity from another Activity. I want to pull data from an Activity that's already running.
The Tab Layout tutorial at http://developer.android.com/resources/tutorials/views/hello-tabwidget.html illustrates what I want to do. (My app is doing some engineering calculations instead, but the tutorial code provides a good analogy to my app.) The tutorial creates an app with three tabs, and each tab hosts a separate activity.
To expand on the example in the tutorial, suppose I select an artist in the Artists tab/activity. I want to be able to select the Albums tab/activity and have it display all the albums featuring that artist.
It seems to me that I need to use an Intent to do this. All of the tutorials I've found assume that I would create a "See albums" Button in the Artists tab/activity, and that pressing the Button would execute an Intent that starts the Albums activity and passes artistName.
I DO NOT want to create that Button. Real estate on the Artists layout is precious, and I have a perfectly good Albums tab, AND the HelloTabWidget activity already contains an intent to create the Albums tab.
Besides, a user will want to skip back and forth between Album and Artist in order to change artist selections, and the tabs are a perfectly good way to do this. There's no need to complicate the UI with another button.
So how can I have the Albums activity PULL artistName from the Artists activity when the Albums tab is selected (or the Albums layout is displayed), rather than have the Artists activity START Albums and PUSH the artistName?
Equivalents I can think of from other programming worlds:
Global variables. Discouraged in Android devt, right? And if they do exist, what are they called?
A getter, like artistName = Artists.getArtistName(); . I get the feeling that it's not that easy.
Writing to, and reading from, a file - that is, mass storage or non-volatile memory. I don't need the artistName value to be permanent. It will be reset to null every time the user launches the application.
So how is it done in the Android world? Do I use an Intent - and if so, how?
Global variables were the right answer.
I thought Java discouraged their use, but a couple of links that appeared in the "Related" links on the right margin of this window mentioned them directly. One was "Android: How to declare global variables?" and the other was "how to pass value betweeen two tab in android". Both pointed to the Application Class as the place to define global variables and methods. Armed with this new knowledge, I found an article called "Android Application Class" on the Xoriant blog that expanded on the StackOverflow answers.
It's best to review those three links first. I need to add some tips to what those authors have said.
Your Application class has to be in its own separate file. (That might be a "duh" to some people, but not to everybody.) Here's a good framework for an example called Something.java:
public class Something extends Application {
// Put application wide (global) variables here
// Constants are final, so they don't have to be private
// But other variables should be declared private;
// use getters/setters to access them
public final boolean FEET = false;
public final boolean METERS = true;
private boolean units = FEET;
#Override
public void onCreate() {
super.onCreate();
// Put any application wide (global) initialization here
}
// Put application wide (global) methods here
public boolean getUnits() {
return units;
}
public void setUnits(boolean whichOne) {
units = whichOne;
}
}
I'm using Eclipse with the ADT plug-in, in Windows XP. Eclipse doesn't always behave properly if you edit XML code directly, so it's best to open AndroidManifest.xml, then select the Application tab and enter your application name in the Name field. You don't need to put a dot or period in front of the name. Just type in the name of your class, like "Globals" or "MyApplication" or whatever. (Note that this is the default application in your Manifest. You don't have to create a separate <application></application> tag.
This step may not be necessary on an actual Android device, but it was necessary for the emulator: you need to use the getApplicationContext() command in every onCreate() and every method that will be accessing the global variables and methods. I tried to put it outside of onCreate() with the rest of my activity wide variables, and it didn't work. Putting it inside every method seems wasteful, but both the emulator and the Android device work fine with it that way. Here's a sample showing how I used it:
public void fooBar() {
// Access to global variables and methods
final Something s = (Something)getApplicationContext();
// ...
// This next line demonstrates both a global method and a global variable
if (s.getUnits() == s.FEET) {
// do something with feet
} else {
// do something with meters instead
}
// ...
}
Those were the only hiccups I encountered. The three references that I have listed, taken together, are otherwise pretty complete.
Is it possible to use a preference screen as a simple interface to read and write values to a database?
Basically, I like the way the preference screen looks and operates, but preferences aren't a suitable way to store all the data I have.
I know how to get it to display correctly, but I'm unsure on how to access the values represented on the screen, and how to keep it from writing a preference file.
Is this even a good idea?
Thanks.
Just to follow this up for anyone that is interested. I got it working by using a Preference.OnPreferenceChangeListener() to store the value as a int or string or whatever. For example:
et_model.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener(){
public boolean onPreferenceChange(Preference preference, Object newValue) {
String val = (String) newValue;
preference.setSummary(val);
model = val;
return true;
}
});
Then once the user presses done, I add the data to the database in the usual way with my SQLight database helper class.
When I load the values from the database, I simply use Preference.SetText(String), and Preference.SetSummary(String).
I guess it is still writing a preference file because if I don't set the preference's text it will load with whatever was set last, but I don't think this is a problem. I could also delete the preference file when I close the activity or something...
If you want a good example, just look at the source for the AlarmClock (now DeskClock) Look at SetAlarm.java and set_alarm.xml for the layout(Save and cancel keys) and alarm_prefs.xml for the actual preference layout.
I don't think that is such a hot idea, especially if you plan on having a tone of data in your database. How ever if you did want to do it, I would just extend the Preference widgets that you will use and have them interface with the database. For example, lets say you have 10 items in a table and you want to select one item (row in the database), you would override the ListPreference and fill it with the content of the applicable database row.
OK, so I'm playing around with an android app.
The 90% use case is that users want to go straight to the primary list screen to find what they're looking for. That's what I want as my default screen.
The first time a user loads the app however, some configuration is required before their list screen is of any value to them.
So my question, is how I can go about displaying the configuration activity the first time the app is opened up, and then the list screen for future openings.
I also want to put a demo button on the configuration screen, so I suppose more than just detecting that it's the first time, I specifically want to detect whether the user has performed certain configurations within the first screen.
After the first time the user has loaded the app you could store the details of whether user has performed the configurations in SharedPreferences.
protected void storeSharedPrefs(String value) {
/*
* Storing in Shared Preferences
*/
editor.putString("first", value);
editor.commit(); //Commiting changes
}
Check each on time application is loaded, whether its the first time and configuration details has been entered correctly by checking SharedPreferences
private boolean first_time_check() {
/*
* Checking Shared Preferences if the user had pressed
* the remember me button last time he logged in
* */
String first = uPreferences.getString("first", null);
if((first == null)){
return false;
}
else
return true;
}
i like dweebsonduty's method. a similar way to do this is to save their configuration information in files on the SD card. your app could start out by checking for those files and loading the information. if the load is successful, it moves on to the next activity, if not it starts the appropriate activity to prompt the user for input.
I have done this same thing, but instead of swiching activities i just switch views until i have all the info i need, and then move on.
Many applications actually store the current version in SharedPreferences, and check against it for if an update has been installed. Its a clever way of achieving a "what's changed" popup, or making sure that some settings get set (I would be wary of just having a boolean flag because if you ever want to add an additional setting, you will need a second flag and it gets messy after the third, etc.).
String VersionValue = "v.1.0";
final String PREFS_NAME = "MyPrefsFile";
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
if (settings.getBoolean(VersionValue, true)) {
//the app is being launched for first time, do something
NewDialogFragment newFragment = new NewDialogFragment();
newFragment.show(getFragmentManager(), "New");
// record the fact that the app has been started at least once
settings.edit().putBoolean(VersionValue, false).commit();
}
You could do it this way and still get the same result I tried it its a small workaround if u do not fully understand how to check if the app is updated. Instead with this code you can just simply change the String VersoinValue to your current app version and android will think the app is a new first time app and will only display the code u wrote once until you change VersionValue on your next update. (:
How will you be storing the configuration?
If it is in SQLlite you could just create a table called firstuse and put a field in there called hasbeenused and make it null. Then when the app is used you can put a 1 in there. Then you can read it each time your app loads and if that field = 1 then go to your next activity.