In my Android application for my school project I want to make it such that:
Every day, when you first open the application, it will start an activity. However, if you open the application again even after closing it from the multitasking view, it will not start the activity again.
I want it to be much like Elevate (https://www.elevateapp.com/) where on first startup it will say "Your training session for the day is ready" but never display this again if you open the app at another time in the day.
This is a screenshot of the activity:
I have tried using AlarmManager in this link Alarm Manager Example and searching for answers but it did not work for me and I couldn't find any.
Is there a way to make it possible? Thanks in advance.
We can use SharedPreferences to store the system date when the app is launched and verify if it is the same date or a different one every time the app s run.
If the date is different, store the new date into the SharedPreferences handle that you used.
To understand how to use SharedPreference to store data you can look at my answer here for an example.
First declare this two method on global level
public static void commitPref(String key, String value, Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = prefs.edit();
editor.putString(key, value);
editor.commit();
}
public static String readPref(String key, Context context) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
return preferences.getString(key, null);
}
now maintain your logic..
if (!readPref("CHECK_IF_RUN_TODAY", getApplicationContext()).equals(new SimpleDateFormat("yyyy-MM-dd", Locale.US).format(new Date()))){
//YOUR LOGIC
commitPref("CHECK_IF_RUN_TODAY", new SimpleDateFormat("yyyy-MM-dd", Locale.US).format(new Date()), getApplicationContext());
}
but dont forget to upadte your prefrence after your logic
Hope this helps..
Related
I am new in Android Development. I am trying my hands on developing an alarm app. When I set the alarm, I use a TextView to show the time for which the alarm in set up(initially empty). But when I close or minimize the app and start it again the TextView is again empty. How to get rid of this?
I looked for its solution in android app development manual, but still couldn't find my way out.
Particularly visiting developer.android.com will help you to get started with android development. Anyways you can either use any of the following to save your data:
SharedPreferences
Sqlite Database
File (Pertaining to your app's location)
And when you are reopening your application you can retrieve the information from this methods.
Saving data can be done easily with the SharedPreferences.
private final String SAVED_ALARM_TIME_KEY = "SavedAlarmTime"
private final String ALARM_PREFERENCES = "AlarmPreferences"
private void saveAlarmTime(Context context, long alarmTimestamp) {
SharedPreferences sharedPref = context.getSharedPreferences(ALARM_PREFERENCES, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putLong(SAVED_ALARM_TIME, alarmTimestamp);
editor.commit();
}
private long getAlarmTime(Context context) {
SharedPreferences sharedPref = context.getSharedPreferences(ALARM_PREFERENCES, Context.MODE_PRIVATE);
return sharedPref.getLong(SAVED_ALARM_TIME, 0);
}
This is great for something like user settings in the application. But I imagine you will later want to add multiple alarms to your application. In this case it would be better if you used a database. It will provide you with more options to scale the implementation. For instance you wish to add a functionality for repeating alarms at certain days the database will come in very handy.
You can refer to the documentation: https://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html
I have asked a question before 2 days about daily notification and i put my code and i didn't get any useful answer so i need someone write a code that show notification every 1 hour .
caution (i have write a code doing that but i was have a problem that is every time i open the activity it gives me a notification i don't need that i just want it give a notification at the first time i run app or press a button to start it then the service runs to give notification every 1 hour ) .
Hope anyone can help me .
Thanks.
Well this seems like a two part question, for one the effect that you want to wait and be able to check to start the notifications and to save that value. SharedPrefence's can do this, you could save a boolean value to see whether or not a alarm should be set. Easy enough to access.
public boolean saveSharedBoolValue(String key, Boolean value, Context localContext) {
SharedPreferences sp = localContext.getSharedPreferences("FILE_NAME", 0);
Editor edit = sp.edit();
edit.putBoolean(key, value);
return edit.commit();
}
public Boolean getSharedBoolValue(String key, Context localContext)
{
SharedPreferences sharedPreferences = localContext.getSharedPreferences("FILE_NAME", 0);
Boolean value = sharedPreferences.getBoolean(key, false);
return value;
}
Something like this. With alarm notifications, that start on startup I had this similar issue. What I noticed was that I was creating an alert for earlier than my present time and it created a single notification automatically.
That may not be your issue though,
calendar.setTimeInMillis(System.currentTimeMillis() +5*1000);
this line from your code. Isn't it essentially creating an alarm just right after it starts? 5000 milli seconds aren't much after present time.
Im trying to use androids sharedpreferences, I´ve logged everything and the code below really commits the string set. The problem is when I force close the app and start again, the settings.getStringSet returns an empty set. No errormessages anywhere.
I´ve tried PreferenceManager.getDefaultSharedPreferences but that does not work for me either.
Thanks for you time.
public static final String PREFS_NAME = "MyPrefsFile";
private static final String FOLLOWED_ROUTES = "followedRoutes";
and later on when saved is called:
public void onFollowClicked(View view){
SharedPreferences settings = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
Set<String> follows = settings.getStringSet(FOLLOWED_ROUTES, new HashSet<String>());
follows.add(routeId);
editor.putStringSet(FOLLOWED_ROUTES, follows);
editor.commit();
}
You can also work around the bug mentioned by g00dy this way:
Get the set from sharedPreferences and save it in a variable.
Then just delete the set in sharedpreferences before adding it again when saving.
SharedPreferences.Editor editor= sharedPref.edit();
editor.remove("mSet");
editor.apply();
editor.putStringSet("mSet", mSet);
editor.apply();
Make sure to use apply() or commit() twice.
Alternatively, if you are working in Kotlin simply :
PreferenceManager.getDefaultSharedPreferences(applicationContext)
.edit {
this.remove("mSet")
this.apply()
this.putStringSet("mSet", mSet)
}
Take a look here.
Also for refference:
SharedPreferences
SharedPreferences.Editor
EDIT:
There's actually a bug with this one, see here. An extract from there:
This problem is still present on the 17 API level.
It is caused because the getStringSet() method of the
SharedPreferences class doesn't return a copy of the Set object: it
returns the entire object and, when you add new elements to it, the
commitToMemory method of the SharedPrefencesImpl.EditorImpl class see
that the existing value is equal to the previous one stored.
The ways to workaround this issue is to make a copy of the Set
returned by SharedPreferences.getStringSet or force the write to
memory using other preference that always change (for example, a
property that stores the size of the set each time)
EDIT2:
There might be a solution here, take a look.
I'm trying to write a file on users mobile following this example
Storage Options [data-storage]
I want to create that file the first time users run my app.
After the first time users run my app, I want FIRST read the file, and THEN write something in it (if i need).
Following the example above i'm using FileInputStream stream= openFileInput(FILENAME),
Is there a way to know if the file i put in FileInputStream exists by checking the fIleInpuStream itself?
Thank everybody for your help.
Maybe the best way to do what i want to do was suggested by #Durairaj P.
I used Preferences.
But i'm still wondering if it's suitable and appropriate for what i want to do. I want to keep track of the points that users earn while playing my game; when users re-open my app, i have to show all the points they earned since they installed my app. I'm just wondering if Preferences are suitable and appropriatefor this, or if i should use something else.
Anyway i post my code, it might help someone
public class managePreferences{
Context context;
managePreferences(Context context){
this.context = context;
}
public String readPreference(String fieldName, String defaultValue){
SharedPreferences prefs = context.getSharedPreferences("MY_PREFERENCES", Context.MODE_PRIVATE);
String value = prefs.getString(fieldName, defaultValue);
return value ;
}
public void writePreference(String fieldName, String value){
SharedPreferences prefs = context.getSharedPreferences("MY_PREFERENCES", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putString(fieldName, value);
editor.commit();
}
}
I would use
context.fileList();
and test if my file is somewhere. (quickest way is to make a List of it and use contains()) :
Arrays.asList(context.fileList()).contains(FILENAME);
I am trying to update the values of SharedPreferences, here is my code:
edit = PreferenceManager.getDefaultSharedPreferences(this).edit();
edit.putString(Settings.PREF_USERNAME+"",txtuser);
edit.putString(Settings.PREF_PASSWORD+"",txtpass);
edit.commit();"
The problem is that when I am accessing this values, it is not returning updated values, it gives me a value of SharedPreferences.
But when I am confirming the data in XML file ,the data updated in that.
And after restarting my application I am getting that updated values. So it requires me to restart the application to get updated values.
So, how to get those updated values once it changes?
Thanks in advance
Here is my whole code:
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
ctx=this;
status=PreferenceManager.getDefaultSharedPreferences(this).getString(Settings.PREF_STATUS, Settings.DEFAULT_STATUS);// get old value
submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
on(ctx,true);// function will call and value is updated
}
}});
status=PreferenceManager.getDefaultSharedPreferences(this).getString(Settings.PREF_STATUS, Settings.DEFAULT_STATUS);// this should give me a updated value but gives old value
}
public static boolean on(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context).getBoolean(Settings.PREF_ON, Settings.DEFAULT_ON);
}
public static void on(Context context,boolean on) {
if (on) Receiver.engine(context).isRegistered(); //
}
**********in reciver file***********
public void isRegistered ) {
Editor edit = PreferenceManager.getDefaultSharedPreferences(Receiver.mContext).edit();
edit.putString(Settings.PREF_STATUS+"","0");
edit.commit();
}
Instead of using edit.commit();, you should use edit.apply();. Apply will update the preference object instantly and will save the new values asynchronously, so allowing you to read the latest values.
commit()
Commit your preferences changes back from this Editor to the
SharedPreferences object it is editing. This atomically performs the
requested modifications, replacing whatever is currently in the
SharedPreferences.
Note that when two editors are modifying preferences at the same time,
the last one to call commit wins.
If you don't care about the return value and you're using this from
your application's main thread, consider using apply() instead.
apply()
Unlike commit(), which writes its preferences out to persistent
storage synchronously, apply() commits its changes to the in-memory
SharedPreferences immediately but starts an asynchronous commit to
disk and you won't be notified of any failures. If another editor on
this SharedPreferences does a regular commit() while a apply() is
still outstanding, the commit() will block until all async commits are
completed as well as the commit itself.
As SharedPreferences instances are singletons within a process, it's
safe to replace any instance of commit() with apply() if you were
already ignoring the return value.
You don't need to worry about Android component lifecycles and their
interaction with apply() writing to disk. The framework makes sure
in-flight disk writes from apply() complete before switching states.
Well, even if my answer came 3 years after the question, I hope it will help. The problem don't seem to came from commit or apply but from the code structure.
Let's explain: on a smartphone, you run an APP but you don't quit the APP as we do on computers.
This mean when you come back to the menu of the smartphone, the APP is still "running". When you "click" again on the APP icon, you don't re-run the APP but just awake it.
In juned code, we can see he calls getDefaultSharedPreferences inside his Create function.
So he calls getDefaultSharedPreferences when he runs first time the APP. But when he sets the APP on background and then awakes the APP, the call is not done.
I've had the same problem:
I check if I have SharedPreference for my APP. If not, I prompt a form to ask value to the user.
If yes, I check the date of the preferences. If too old, I prompt the form.
After the form, I save the preferences with the current date.
What I noticed is that the test about the existence of the SharedPreference (which was set at the same location than the one of juned) was done only at first run of the APP but not when I awake the APP. This mean that I was unable to check the time limite of my SharedPreferences!
How to solve that?
Just add:
#Override
public void onResume(){
super.onResume();
// And put the SharedPreferences test here
}
This code will be called at first run of the APP but also each time the user awake it.
hope it will help you..
SharedPreferences mypref = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor prefsEditr = mypref.edit();
prefsEditr.putString("Userid", UserId);
prefsEditr.commit();
String task1 = mypref.getString("Userid", "");
Try this code:
SharedPreferences edit = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor1 = edit.edit();
editor.putString(Settings.PREF_USERNAME + "", txtuser);
editor.putString(Settings.PREF_PASSWORD + "", entered_name);
editor.commit();
Try like this,
public SharedPreferences prefs;
SharedPreferences.Editor editor = prefs.edit();
editor.putString(Settings.PREF_USERNAME+"", txtuser);
editor.putString(Settings.PREF_PASSWORD+"", entered_name);
editor.apply()
Try like this,
public SharedPreferences prefs;
SharedPreferences.Editor editor = prefs.edit();
editor.putString(Settings.PREF_USERNAME+"", txtuser);
editor.putString(Settings.PREF_PASSWORD+"", entered_name);
editor.commit();