I am using SharedPreferences to know if the user has selected something in the ViewPager and passing it onto the relevant fragment.
e.g. if there is a selection then variable isPassed = 1
if there is no selection as of yet isPassed = 0
The problem:
As SharedPreferences persists the data and the value isPassed = 1 is present throughout, which is disturbing my current flow inside the application. So I tried to assign isPassed=0 in onDestory in my ViewPager class, but it didn't work.
Could someone suggest any improvements on this ? Or at least suggest me a way to store values until the user is inside the application, and once the user exits the application, all the values are reset. Please do help.
Rather then using shared preference make a class and use setter and getter method to set and get the value. Once you exit the application your value also ll be destroyed.
If you don't want your information to be persisted outside of the application scope, then SharedPreferences is really not the good place.
Why won't you try to store it in the instance of your Application class ? This instance will be destroyed rapidly by the system after your user has exited the application.
Use
public static int isPassed=0;
It will store value until the user is inside the application, and once the user exits the application, it will reset.
You can use it in another class by Classname.isPassed=1;
If all you are looking for is a flag you could just create an empty file.
Several ways to create file
File myFile =new File(directory.getAbsolutePath() + File.separator + "myFile.txt");
try
{
new_file.createNewFile();
}
catch (IOException e)
{
}
Check if it exists
File myFile = context.getFileStreamPath(FILE_NAME);
if(file.exists())
Delete it
File myFile = new File(selectedFilePath);
boolean deleted = file.delete();
Related
I am coding using Xamarin and have a question about application settings.
Is it possible to have application wide settings? I will give you an example:
I have a map application. I have a ListView where the user can select if the map is using the Street View, Satellite View or default view.
Depending on the item that is selected in the ListView depends of the map view that is shown.
Where and how can I save this selection such that this value is visible throughout the application and when the user exits the application, this setting can be remembered for when the user starts the application up again?
Thanks in advance
Yes, it's possible and also very easy. Usually you save simple application settings using SharedPreferences. They can be read from anywhere in the app.
For writing.
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
Editor editor = sp.edit();
editor.putBoolean("someBoolean", true);
editor.putString("someString", "string");
editor.commit();
For reading
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
boolean someBoolean = sp.getBoolean("someBoolean", false);
boolean someString = sp.getString("someString", null);
I suppose you are familiar to Java I/O and android basic concepts. So here I go:
For data persistance in Android, you have two main solutions:
SQLite database
File system
I recommend you to use file system, as you don't really need to organize your data with relational constraints and you will probably not have to make a lot of data persist.
Android documentation is very clear on how to save files:
http://developer.android.com/training/basics/data-storage/files.html
I recommend you to create a Setting class that contains a HashMap attribute:
public class Settings implements Parcelable{
public static HashMap<String,String> settings;
public static void readSettings(){
//Here you read your settings file and you fill your hashmap
}
public static void writeSettings(){
//Here you iterate through your hashmap and you write your setting files
}
}
Every activities will have access to the settings, as the attribute/methods are static. Settings will also be synchronized through every activities (if you change a setting in one activity, every other activities will notice).
If you need some clarifications, leave a comment below.
I am trying to develop an app that requires certain values to be set by the users at the app's first startup only, because i don't wanna bother them frequently inputting the values everytime they launch the app. My app has a single activity main and uses certain values that are inputted by the users at first startup. How can I make this possible.
Please explain me elaborately . :-)
You should use SharedPreferences to keep a track of the first use.
In the onCreate Method of your Activity (Startup activity), you could do something like this,
SharedPreferences userPrefs = getSharedPreferences("UserPrefs", 0);
Boolean firstUse = userPrefs.getBoolean("firstUse", true);
if(firstUse){
//this implies it is the first use of the app
//also once you are done implementing the logic for first use you need to put firstUse as true
SharedPreferences.Editor editor = userPrefs.edit();
editor.putBoolean("firstUse", false);
editor.commit();
}
else{
//take the user directly inside the app
}
Also, if you plan to save user information in the first use, look at different ways of storing data here.
show the alert initially and after getting the input values keep it in preference and next time check whether the required values existing or not. If it is already there avoid popup
For getting more information about shared preference check this link http://www.vogella.com/tutorials/AndroidFileBasedPersistence/article.html
preferences_statusFirst.getString("boot", "");
if (status.length() <= 0)
{
showDialog(DIALOG_birth);
editor_boot.putString("boot", "1");
editor_boot.commit();
}
else
{
}
}
I'd like to ask the logic for first asking the user to fill up a profile form so it is filled, and then directed to the main activity. After closing the app and then re open it again, the profile activity should not be first launched but now the main activity. How can I do this? I'm in need of help. Thanks.
This is what I have tried so far:
private void doThread(){
Thread timer = new Thread(){
public void run(){
try{
sleep(5000); // sleeps/delays for 3 seconds
} // end try
catch(InterruptedException e){
e.printStackTrace();
}finally{
// this is going to create new intent activity for
// based on the action name (com.fps.ihealthfirst.IHEALTHFIRSACTIVITY)
boolean firstTime = mPreferences.getBoolean("user_prefs", true);
if (firstTime) {
Intent myProfile = new Intent( Disclaimer.this, Profile_Pref.class );
startActivity(myProfile);
}
else{
Intent openIHealthFirst = new Intent( "com.fps.iHealthFirst.IHEALTHFIRSTACTIVITY" );
startActivity( openIHealthFirst );
finish();
}
}// end finally
} // end run method
}; // end thread
timer.start();
}
Depending on your choice, you can choose to save the information collected from the Profile Form in either a Database or a SharedPreferences file. This part is rather subjective and if you are already employing a Database in your application, you might consider it.
Here are a few suggestions on handling the logic / flow after the user has setup / entered his Profile details:
First: If you aren't already employing a Splash Screen, you must consider creating one. This will give you a small buffer time to check if the user has already entered his profile details.
Second: If he hasn't, you can open the Profile Form Activity. If, after checking either of the Database or SharedPreferences file, you find data indicating a filled form, you can display the main activity directly.
I personally, would be more inclined towards using SharedPreferences for this task.
Here are a few tutorials to get started with SharedPreferences:
http://android-er.blogspot.in/2011/01/example-of-using-sharedpreferencesedito.html
http://saigeethamn.blogspot.in/2009/10/shared-preferences-android-developer.html
http://myandroidsolutions.blogspot.in/2012/06/android-store-persistent-data-using.html
http://moorandroid.blogspot.in/p/shared-preferences-on-android.html
They may not be specific to your question, but will give you the logic to save values. Retrieving the saved values would be fairly simple.
Hope any of this helps.
One way is to save the form information on to SD card, then load and check for the information, if the information is present there, then you can move to next activity. Check this answer for explanation to it.
Can I have an android activity run only on the first time an application is opened?
The other is to check for a specific shared preference in the main activity, if that shared preference is missing, then launch the single run activity again. Check the following answer for an explanation to it.
How to launch activity only once when app is opened for first time?
Determine if android app is the first time used
You can use SharedPreferences.I had this same question with a good answer here. Check it out.
I have a ListActivity to let user pick photo(s) to be upload
For upload, I'll put photos inside a static ArrayList called PhotoList
After that, I'll start a Service to upload those photos
Now, user may switch to another activity to do some other things
Later, user will back to this ListActivity to check upload status. Also in here they can pick more photos to be upload.
So, my PhotoList is actually a kind of Queue, but it also a data to be display at ListActivity.
My problem is, when the Service is running, and user picked more photo(s), I would like put those photo(s) inside the PhotoList.
(I don't want to start Service again since the service is already running...)
Now I just get stuck here.
okey I will try to give you a solution based on my understanding to your problem :
You have a list with photos and you want the user to be eligible to upload those images and update it the user of it status ( uploaded/ uploading / upload/failed) and you dont want to start the Service every time you upload .
a Simple working solution is to use an IntnetService i will be running only if there is tasks assigned to it and will atomically shut down when finish the work and of course the job will be in a sperate thread when working with IntentService
step 1
make a database table contains data about the images
_id integer
_image_uri
_image_status :
_image_status will hold one of these values ( 1-uploaded : finish_uploaded , 2- uploading: service is uploading the image , 3-upload : the user can upload the image 4-failed: failed to upload you can retry )
step2
now in the UploadIntentService try to upload the image to server and when if the upload competes successfully or an error happened while upload update the database
public class UploadIntentService extends IntentService {
private static final String TAG = UploadIntentService.class.getSimpleName();
private static final int STATUS_UPLOAD = 0x01; //can be uploaded
public static final int STATUS_FAILED_TO_UPLOAD = 0x02; // tried to upload but failed
public static final int STATUS_UPLOADING = 0x03; // self explanied
public static final int STATUS_SUCCESSFULLY_UPLOADED = 0x04; // the image uploaded to server
public UploadIntentService() {
super(TAG);
}
#Override
protected void onHandleIntent(Intent intent) {
int status = intent.getIntExtra("status", -1);
String imageUri = intent.getStringExtra("image_path");
long imageDatabaseid = intent.getLongExtra("image_db_address",-1);
if(status != STATUS_SUCCESSFULLY_UPLOADED && status != STATUS_UPLOADING){
try{
//update _image_status column with value of STATUS_UPLOADING with the image_id = imageDatabaseid;
//upload code
//successfully uploaded
//update _image_status column with value of STATUS_SUCCESSFULLY_UPLOADED with the image_id = imageDatabaseid;
}catch(Exception ex){
ex.printStackTrace();
//update _image_status column with value of STATUS_FAILED_TO_UPLOAD with the image_id = imageDatabaseid;
}
}
}
}
......
step3
and you ListActivity if you want to upload any image use this code
Intent intent = new Intent(context, UploadIntentService.class);
Bundle uploadExtras = new Bundle(3);
uploadExtras.putLong("image_db_address", PUT HERE THE IMAGE DATABASE ID );
uploadExtras.putInt("status", PUT HERE THE IMAGE STATUS );
uploadExtras.putString("image_path", PUT HERE THE IMAGE PATH IN FILE SYSTEM);
intent.putExtras(uploadExtras);
context.startService(intent);
.......
step 4
make sure you declare the Service in the manifest.xml , and enjoy.
Your Service should override the onResume() function. onResume() is called whenever the user does other tasks, opens other activities etc and finally returns back to your application's activity. That is just the gist.
You can learn more about Runtime Changes . The concepts that apply for Activity apply for Service also, in that Service is just not "shown" to the user.
In the above link, you will learn when an activity is recreated, and when it is actually resumed by calling onResume(). You also need to override onSaveInstanceState() and onRestoreInstanceState() so as to pass state objects between your old Activity instance and the new one.
What you can do is, when the user goes leaves your activity, in your onSaveInstanceState(), you should save your state variables eg. your list of selected photos, in a Bundle. And pass this Bundle to onRestoreInstanceState()
Question: Are you actually starting your service as a valid Service ? I mean, are you extending the Service class? I've used Service for my projects, and they always resumed where they left without overriding anything. The reason: Services run in background, resources are not released until the service is done doing it's job. So if you have not used Service , then I recommend you do that. Your problems will be taken care of.
You can make a BlockingQueue in which you will store photos to upload. This BlockingQueue is your PhotoList. In Service, in loop, you will look into this BlockingQueue. Two cases are possible:
There is some photo. Take it and upload.
Queue is empty. So the thread will go to sleep, BlockingQueue assures this.
You can use this :
Copy On Write Array List
This will be a thread-safe random-access list.
Check this link for good explanation and example.
Difference between ArrayList and CopyOnWriteArrayList
Iterators of this list never throw ConcurrentModificationException. When an iterator is created, it keeps a copy of the list's contents. It is always safe to iterate this list.
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.