How can I know if the user has ever used my Android app on this device
before?
You can create these methods to manipulate SharedPreferences:
Keep in mind, there is no way to stop the user from clearing the app data and therefore deleting the SharedPreference.
public boolean hasUsed()
{
SharedPreferences sp = getSharedPreferences("hasUsed",0);
boolean b = sp.getBoolean("hasUsed",false); // default value is false
return b;
}
public void writeUsed(boolean b)
{
SharedPreferences.Editor editor = getSharedPreferences("hasUsed",0).edit();
editor.putBoolean("hasUsed", b).commit();
}
Call them like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// if user hasn't used the app, write to the preference that they have.
if (!hasUsed()) writeUsed(true);
// later in code:
if (hasUsed()) // if the user has used the app
{
// do something
}
}
Links for explanation of code:
How to store User name and password details in strings.xml
How to save app settings?
How to keep information about an app in Android?
If you store anything regarding it in your app,user is Owner of his device . he can clear it anytime.
Kindly store this information on either your server or use some analytics integration.
But I would prefer to store on server because in your case,analytics might be overhead for you as you just want to identify the existing users.
Explaination:
When your app starts, send device's unique id to your server, so that when user starts the app for next time,it will again send unique id and at that time your server can perform check in database for existance of recently received unique id.
In such a manner you can identify that the user has already used your app or not and then you can modify your business logic accordingly.
I hope it will be helpful !!
Check this : The Google Analytics SDK for Android makes it easy for native Android developers to collect user engagement data from their applications.
You can do things like :
The number of active users are using their applications.
From where in the world the application is being used.
Adoption and usage of specific features.
Crashes and exceptions.
In-app purchases and transactions.
https://developers.google.com/analytics/devguides/collection/android/
You can create a shared preference and can update a count value every time the user opens the app, like
SharedPreferences myPrefs = this.getSharedPreferences("myPrefs", MODE_WORLD_READABLE);
SharedPreferences.Editor prefsEditor = myPrefs.edit();
prefsEditor.putString("Count",Integer.valueof(myPrefs.getString("Count", null))+1) );
the code may have errors but the logic is right
Related
I am developing an android application. It has two types of users, a teacher and a student. I was hoping to use Shared Preferences to communicate between the two users.
Basically, I have a teach screen which has four TextViews on it with different messages. The TextView text is set to "" when the toggle value is 1 (which is the default value).
On the student screen, they have 4 Buttons. Upon hitting each button, the toggle value is changed to 0 and then the message is displayed on the teacher's view. This works when I log in as a student, click the button, then log in as a teacher. However, I want it to work on two different devices, so that when the student clicks the button the teacher sees the message.
Here are some code snippets:
Firstly, the student activity:
Assistance.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
toggleAssistance(view);
}
});
public void toggleAssistance(View view){
SharedPreferences sharedPreferences = getSharedPreferences("requestToggles", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt("assistanceToggle", 0);
editor.apply();
}
Secondly, the teacher activity:
asstToggle = sharedPreferences.getInt("assistanceToggle", 1);
if(asstToggle==1){
Assistance.setText("");
clearAssistance.setVisibility(View.GONE);
}
Clear assistance is just a button that basically does the reverse of toggleAssistance (it sets the value to 1). No need for this button to be displayed when the message isn't.
Can anyone provide assistance or advice in to how I can make this work between devices? Thanks!
No, you cannot use shared preferences to communicate between devices, your preferences values are stored locally on the device. You should use a remote data storage system like Firebase to implement a solution where two different devices are interacting with each other.
In the real professional world, What you develop in the android environment is considered a Front End.
To create a communication between 2 users(2 different android environments/machines), you need a back-end environment.
If you want to store data that can be accessed by 2 or more android users of different machines, you need the data stored in The "Back End". The most popular database system at the moment is MySQL.
I am writing an android app and I retrieve a balance for the user from a webservice and the user is able to log in and out of my app.
When the app starts I check the shared preferences to see if the user is logged in or out. On correct log in I update the shared pref boolean to true and set it to false when the user logs out.
I need to know the balance in several fragments and I need to remember it when I am navigating thru the fragments in my app. When I return to the "My Account" fragment balance value is lost and I have to call my web service again to check it.
It the best way to use a string shared pref and update it any time the app starts or when there is a change in the balance. Or am I better to use a static variable in my main activity that can be referenced when the user navigates to the My Account fragment.
Is it possible to overuse shared preferences?
A simple and elegant solution is to use a very simple library TinyDB in android, which is nothing but an abstraction over the Shared Preferences.
You can initialise it in your activity's onCreate() method like this:
TinyDB tinydb = new TinyDB(this);
In fragment, just replace this with getActivity.
And then use it like this:
tinydb.putString("userName", "john");
String currentUser = tinydb.getString("userName");
Hope it helps.
For a single value such as balance or username you should definitely use SharedPrefereneces and OnSharedPreferenceChangeListener.
For structured data such as balance operations you should definitely use a database:
SQLite
Realm (noSQL)
StorIO (SQLite wrapper)
or some ORM.
There is 3 way to store you login details .
Using Shared Preference
Store Data in a File
Using Sqlite.
This tutorial will give you the ideas for storing login details.
You should store data in SharedPreferences rather than global variables because when app crashes, the data updated in static global variables at different times is lost and the default data in it remains.
I'm trying to figure out when to use a saved instance state versus loading information from a shared preferences file. I have two variables that I wish to save, time and score. I want to make sure that if the user returns to the game screen that their score and time is saved and restored regardless if it's from onPause state or onStop.
I have three keys:
public static final String ARG_SCORE = "score";
public static final String ARG_TIME = "time";
public static final String SHARED_PREFS = "shared_preferences";
If the game is paused and a dialog is shown, when the user returns should I do
public void onRestoreInstanceState(Bundle savedInstanceState){
int score = savedInstanceState.getInt(ARG_SCORE);
}
or should I do something like:
protected void onResume(){
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
int score = sharedPref.getInt(getString(R.string.saved_high_score));
}
Overall, I need help understanding the lifecycle and when to store vital information such as time and score of the game. I simply need to avoid the user having to restart in cases they weren't able to finish the game.
Lastly, I'm assumed that the sharedPrefs saves to an xml file. Is this correct? Does anyone have a sample xml for how my sharedPrefs should appear? Do keys which are saved to bundles of savedInstanceState get stored in xml files as well? If so, any examples? If not, where is the information stored?
THANKS!
edits:
ok cool beans. Thanks! One more question, when defining a key for a key-value pair stored into sharedPreferences such as
public static final String ARG_SCORE = "score";
why is the "score" string stored? When would this ever be used? I've always placed a value into the key_value pair using something like
args.putInt(ARG_TIMER, timerINT);
and retrieved using
scoreINT=savedInstanceState.getInt(ARG_SCORE);
Why is a name needed for the key ARG_SCORE? When would I need the name? Does it have to stay type String?
use saveInstanceState when you are frequently moving back and forth between activities and use SharedPreferences when you want to keep information for long time and yes sharedpreferences stored in an xml file. you can view using DDMS in eclipse.
Remeber, in saveInstanceState, when you close app mean it get removes from memory, information will also lost. And in SharedPreferences, information will remain there if you close your app.
It will depend on how you want to manage the data. Both options (and more) are feasible:
If you want to fill once and keep the data even if the app gets
killed, use SharedPreferences.
If it's volatile data that will have to be reentered differently some
other time (i.e., days later), then use onSavedInstanceState.
If you want to keep multiple datasets on the same device, then use a
SQLiteDatabase
You usually want to use SharedPreferences when you want to persist some information between different app session. Imagine you want to store information that you want to retrieve also after the user closes the app.
SavedInstanceState is used to keep some information while user is using the app and allow you to track temporary state of your activity or fragments.
Hope it helps.
when you press home button then still your activity remains in background. since there is some memory constraints in android , there is always chance some other application can take your memory. so to resume application from same point where we have left we use saveInstanceState.
we use sharedprefrence when we have to save small info(normally primitive type) like game high score in any game.
In the Android documentation says how to relate SharedPreferences to XML but there's no need to use SharedPreferences if you don't want the data to be stored forever, you can store the game's state using the Activitys lifecycle methods with no problem, but for example, if the user turns off it's phone or presses the back button to finish your Activity, then the savedInstanceState won't work and you will lose your data.
It's your call, if you want the game to be saved even if the user turns off his phone (I think this would be kinda radical, but if it's your requirement go ahead) then use SharedPreferences or a DB if it's complex data. If you want the game to be saved only when the user navigates in and out to your app, then it's safe to use the savedInstanceState.
I have created a service that writes some information about a widget once a user places it on home screen(the info is picked up from the confutation activity)..i also write down the number of widgets the user has set up.
Once the user removes the widget i delete that info in the shared preferences.
What i have experienced is that if user places for example 2 widgets, then removes one, then places one again, doing all those actions fast, the shared preferences file gets inconsistent values in it. Sometimes it works ok but most of the time i get stuck with wrong values in it.
I am using apply(), i've tried with commit but same thing happens.
The values i store in the shared preferences are crucial for the system to work, without it the widgets are useless since they are backed up by info from internet based on the user configuration which is written in preferences.
Is switching to a database solution more reliable or any other viable solution which will fix this "race condition"? (maybe forcing my own mechanism of synchronization, but as far as i've understood from docs, apply() is already synchronized, and the read/write should first go to RAM which should make it fast and i shouldnt be experiencing any problems like this since the user cant physically manage to delete a widget and place a new one faster then 2-3 seconds top!)
Try using the synchronized keyword in working with the SharedPreferences itself. For example, here is a method that could be used when setting an application String in the SharedPreferences of an Android app:
public synchronized static void setAppString(Context context, String pref,
String val) {
SharedPreferences sp = context.getSharedPreferences(
APP_PREFS_UNIQUE_ID, Context.MODE_PRIVATE);
Editor editor = sp.edit();
editor.putString(pref, val);
editor.commit();
}
For few/simple key-value pairs, you might not need the overhead of a database paradigm.
I would like to know if and how it is possible to detect if my application have run in the past on a given android device. I would like every time the phone reboots to be able to check if my application has run on the past and retrieve some private data. If not just create those data.
You could store a simple value in the SharedPreference of the application.
insert this into your onCreate() in your Main Activity
SharedPreferences shared = getSharedPreferences("config", 0);
if (shared.getBoolean("hasRunBefore", false))
{
// have run before.
}
else
{
SharedPreferences.Editor editor = shared.edit();
editor.putBoolean("hasRunBefore", true);
editor.commit();
// have not run before
}
As others have said, the easiest way to read and write this information is in the SharedPreferences. However, you said you want to do this every time the phone reboots. The way to go about that is to implement a BroadcastReceiver and register to receive ACTION_BOOT_COMPLETED message, and make sure to add a permission to your manifest for RECEIVE_BOOT_COMPLETED.
http://developer.android.com/guide/appendix/faq/commontasks.html#broadcastreceivers
http://developer.android.com/reference/android/content/Intent.html#ACTION_BOOT_COMPLETED
http://developer.android.com/reference/android/Manifest.permission.html#RECEIVE_BOOT_COMPLETED
Check if this data exists ? Or put something in the default PreferenceManager of your application
You'd save everything using SharedPreferences. This will create a file readable by your app that will be created when first written to.
See the following:
Tutorial
Documentation