How to do an operation when an android application on first launch - java

When my application installs and is opened for the first time(when there is an internet connection) i want the phone to download some information from my server and insert it into the database.
if the information does not download fully or download at all, this activity should occur untill it fully downloads?
How would i go about doing this?

Use the preferences
in your Activity :
private boolean isFirstLaunch() {
// Restore preferences
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
boolean isFirstLaunch = settings.getBoolean("isFirstLaunch", true);
Log.i(TAG + ".isFirstLaunch", "sharedPreferences ");
return isFirstLaunch;
}
and from the onCreate call
if (isFirstLaunch()) {
Intent firstLaunchIntent = new Intent(this,
GetStartedActivity.class);
firstLaunchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(firstLaunchIntent);
// set the bool to false in next activity !
finish();
}

Add a flag in your database, shared preferences or a file that indicates that you've downloaded the data. In onResume, check that flag and whether the device has connectivity. If the flag is false and you have connectivity, attempt to download the data.
If that was successful, update the flag.

Use SharedPreference for this. Create a boolean variable and change it once your operation is complete. In onCreate of your Main/Launcher activity check for this variable and perform operation accordingly. Some psuedo-code.
if (!sharedpreferences.getBoolean("isOpComplete", false)) {
// perform my operation
performOperation();
}
performOperation() {
// Operation complete
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putBoolean("isOpComplete", true);
editor.commit();
}

Related

I am expecting my boolean to be saved in shared preferences as true, however it always saves as false

I am trying to save a boolean into shared preferences with a value of true but when I log it I keeping seeing it returning a false value. Please see the code below and also bear in mind that this code is within a fragment.
SharedPreferences AppPreferences = getActivity().getSharedPreferences("myPrefs", Activity.MODE_PRIVATE);
boolean propertyManagerLoggedIn = AppPreferences.getBoolean(PROPERTYMANAGER_LOGGEDIN, false);
if(!propertyManagerLoggedIn)
{
SharedPreferences.Editor editor = AppPreferences.edit();
transitionInterface.showDashboardIcons();
AppPreferences.edit().putBoolean("PROPERTYMANAGER_LOGGEDIN", true);
editor.commit();
//boolean vlaue = prefs.getbooleanflag(context, false);
Log.d("tag",""+propertyManagerLoggedIn);
}
else
{
Log.d("tag",""+propertyManagerLoggedIn);
}
and below is the relevant lines of code from my AppPreferences class
public final static String PROPERTYMANAGER_LOGGEDIN = "PROPERTYMANAGER_LOGGEDIN";
public static boolean propertyManagerLoggedn(Context context)
{
TinyDB settings = new TinyDB(context);
return settings.getBoolean(AppPreferences.PROPERTYMANAGER_LOGGEDIN);
}
every time you call edit() a new Editor is being returned to you. Accordingly to the documentation
Create a new Editor for these preferences, through which you can make
modifications to the data in the preferences and atomically commit
those changes back to the SharedPreferences object.
so you can either do
AppPreferences.edit().putBoolean("PROPERTYMANAGER_LOGGEDIN", true).commit();
or
editor.putBoolean("PROPERTYMANAGER_LOGGEDIN", true);
editor.commit();
but calling putBoolean on an instance and commit on an other won't probably help
You are calling commit on a different instance.
Basically AppPreferences.edit() will give you a new instance.
AppPreferences.edit().putBoolean("PROPERTYMANAGER_LOGGEDIN", true);
This is another instance in which you are putting the boolean value.
Use the same instance which you have created.
Your code should look like this:
SharedPreferences.Editor editor = AppPreferences.edit();
transitionInterface.showDashboardIcons();
editor.putBoolean("PROPERTYMANAGER_LOGGEDIN", true);
editor.commit();

unable to find data in sharedpreferences

Here's what I have done.
public void addToFavorites2(View view) {
//ImageButton button = (ImageButton)findViewById(R.id.imageButton);
//button.setImageResource(R.mipmap.star_clicked_button);
int movieId = favoriteMovieId;
SharedPreferences settings = getSharedPreferences("FavoritesIdKey", MODE_PRIVATE);
Log.v("tessssst", String.valueOf(settings.contains(favoriteMovieTitle)));
SharedPreferences.Editor editor = settings.edit();
editor.putString(favoriteMovieTitle, String.valueOf(movieId));
editor.commit();
}
public boolean movieIsInFavorites()
{
Log.v("method check","is working");
SharedPreferences settings = getSharedPreferences("FavoritesIdKey", MODE_PRIVATE);
Log.v("tezzzzzt", String.valueOf(settings.contains(favoriteMovieTitle)));
if(settings.contains(String.valueOf(favoriteMovieId)))
{
Log.v("truth test","true");
return true;
}
Log.v("truth test","false");
return false;
}
In the given code I have created two methods. in the first method when I call
SharedPreferences settings = getSharedPreferences("FavoritesIdKey", MODE_PRIVATE);
settings.contains(FavoriteMovieTitle);
the data is found and returns true.
when I call the same
SharedPreferences settings = getSharedPreferences("FavoritesIdKey", MODE_PRIVATE);
settings.contains(FavoriteMovieTitle);
In the second method, it does not return true. is there a fundamental thing about shared preferences that I am missing? if more information is needed i apologize. both methods are next to each other without anything between them.
edit- I will add that the first method is called when i press a button on the details screen(details screen is already finished setup and showing).
the second method i was calling in the onCreateView attempting to check if the movie is already in the favorites list apon start up.
The first method is called when you press a button and the second method is called in the onCreateView. So the second method is called before the first method. However, you insert favoriteMovieTitle into xml in the first method so when the second method was called, favoriteMovieTitle had not been in xml and it would return false.
To Store/Obtain shared preferences, use the following method In your activity
SharedPreferences settings = this.getSharedPreferences("FavoritesIdKey",
Context.MODE_PRIVATE);
To store value in SharedPreferences
SharedPreferences.Editor editor = settings.edit();
editor.putString(favoriteMovieTitle, String.valueOf(movieId));
To read SharedPreferences in other class write this line if same class
then no need to write this direct use getString
SharedPreferences settings = this.getSharedPreferences("FavoritesIdKey",
Context.MODE_PRIVATE);
If your are in same class the above line not need to write again.
String myvalueInPref = settings.getString(favoriteMovieTitle, "defaultValue");

Android WearableListenerService isn't detecting if peer connect or disconnect

I created class "CommunicationService" it extends WearableListenerService. I modify my manifest and added service with this action:
android:name="com.google.android.gms.wearable.BIND_LISTENER"
I overrided onPeerDisconnected and onPeerConnected method like this:
#Override
public void onPeerDisconnected(Node peer) {
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean(ON_PEER_CONNECT, false);
editor.commit();
super.onPeerDisconnected(peer);
}
#Override
public void onPeerConnected(Node peer) {
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean(ON_PEER_CONNECT, true);
editor.commit();
super.onPeerConnected(peer);
}
I store true on connect and false on disconnect to my sharedpreferences.
In other classes I call methods from this service like this.
if (prefs.getBoolean(CommunicationService.ON_PEER_CONNECT, false))
CommunicationService.sendDataToWearable();
else
Toast.makeText(context, "There is no connection to wearable. Please, try reconnecting!", Toast.LENGTH_SHORT).show();
So the problem is that when I am running my app and I am connected to the watch everything is working, when I manualy disable bluetooth and try again everything is working like it should, so Toast is displayed warning about connection error.
But when I walk away from the watch and come back to it (I lost connection and then I got it back when I am close enough) it's displays Toast warrning about connection error, but in Android Wear app it says that wearable is connected to handheld.
So I guess something is wrong with my service and it does not update my sharedpreferences the right way.
Also I don't get what should I do onCreate method in service. Should I check if there are any nodes connected with this:
List<Node> connectedNodes =
Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await().getNodes();
And then just update my sharedpreferences?

Android: Logout system and the android lifecycle

on the weekend I started to build my first android app. As I need to ask the user of my app for user credentials [which are used for further webservice usage] I want to simulate a "login system". On the start of my app the user should be told to enter his credentials. When the user is inactive for too long I want to dismiss the entered credentials and to "log out" the user.
While coding and afterwards while testing I realized that the way I thought I could go doesn't work. After reading the docu and several SO-questions again and again I question myself more and more if I have understand the app / activity life cycle and its possibilites fully. So I wanted to ask for help in understand the life cycle and its linked influences on my app. So yes this might be several questions in one :/
For the moment my app consists of the following activities:
a search activity (which is opened once the app is started)
a settings acitivy (which can be accessed from the search dialog and has a link back to the search dialog)
After the user has entered an ID in the search dialog I want to open an activity regarding to the search result (NYI).
When starting to implement the user auth, my idea was the following:
Everytime onResume() of an activity is called I need to check a) if user credentials are already stored and b) if the last action of the user is less then X minutes ago. If one these fails I want to show a "log in panel" where the user can enter his credentials, which are then stored in the SharedPreferences. For that I did the following:
I first build an parent activity which has the check and a reference for the SharedPreferences in it
public class AppFragmentActivity extends FragmentActivity {
protected SharedPreferences sharedPref;
protected SharedPreferences.Editor editor;
protected String WebServiceUsername;
protected String WebServicePassword;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_appfragmentactivity);
}
#Override
protected void onResume () {
super.onResume();
// Check if user is "logged in".
// Meaning: Are there given user credentials and are they valid of was the user inactive for too long?
// We only do this "onResume" because this callback is the only one, which is called everytime an user
// starts/restarts/resumes an application
checkForUserCredentials();
// Set new "last action" now "now"
setLastAction(new Date().getTime());
}
#Override
protected void onStart () {
// Fill content
super.onStart();
// Set global sharedPreferences
sharedPref = this.getSharedPreferences(getString(R.string.FILE_settings_file), Context.MODE_PRIVATE);
}
/*
* Checks if user credentials are valid meaning if they are set and not too old
*/
private void checkForUserCredentials() {
long TimeLastAction = sharedPref.getLong(getString(R.string.SETTINGS_USER_LAST_ACTION), 0);
long TimeNow = new Date().getTime();
// Ask for User credentials when last action is too long ago
if(TimeLastAction < (TimeNow - 1800)) {
// Inactive for too long
// Set back credentials
setUsernameAndPassword("", "");
}
else
{
WebServiceUsername = sharedPref.getString(getString(R.string.SETTINGS_USER_USERNAME), "");
WebServicePassword = sharedPref.getString(getString(R.string.SETTINGS_USER_PASSWORD), "");
}
}
/*
* Saves the given last action in the sharedPreferences
* #param long LastAction - Time of the last action
*/
private void setLastAction(long LastAction) {
editor = sharedPref.edit();
editor.putLong(getString(R.string.SETTINGS_USER_LAST_ACTION), LastAction);
editor.commit();
}
/*
* Saves the given username and userpassword sharedPreferences
* #param String username
* #param String password
*/
private void setUsernameAndPassword(String username, String password) {
editor = sharedPref.edit();
editor.putString(getString(R.string.SETTINGS_USER_USERNAME), username);
editor.putString(getString(R.string.SETTINGS_USER_PASSWORD), password);
editor.commit();
WebServiceUsername = username;
WebServicePassword = password;
}
/*
* Method called when pressing the OK-Button
*/
public void ClickBtnOK(View view) {
// Save User-Creentials
EditText dfsUsername = (EditText) findViewById(R.id.dfsUsername);
String lvsUsername = dfsUsername.getText().toString();
EditText dfsPassword = (EditText) findViewById(R.id.dfsPassword);
String lvsPassword = dfsPassword.getText().toString();
if(lvsUsername.equals("") || lvsPassword.equals("")) {
TextView txtError = (TextView) findViewById(R.id.txtError);
txtError.setText(getString(R.string.ERR_Name_or_Password_empty));
}
else
{
// Save credentials
setUsernameAndPassword(lvsUsername, lvsPassword);
setLastAction(new Date().getTime());
// open Searchactivity
Intent intent = new Intent(this, SearchActivity.class);
startActivity(intent);
}
}
The "log in mask" is setContentView(R.layout.activity_appfragmentactivity);.
The two other activites I created are then extending this parent class. This is one of it:
public class SearchActivity extends AppFragmentActivity {
SearchFragment searchfragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
}
#Override
protected void onResume() {
super.onResume();
if(WebServiceUsername.equals("") && WebServicePassword.equals("")) {
// Username not set. Re"login".
Intent intent = new Intent(this, AppFragmentActivity.class);
startActivity(intent);
}
}
#Override
protected void onStart() {
super.onStart();
}
// ...
}
As far as I understand the lifecycle now this should work as the following: When my app starts (the SearchActivity is set for LAUNCH) the app should step into the onResume() of my parent class. There it sees that the credentials are not yet stored and opens the layout of the AppFragmentActivity which is the login. When entered, the user is redirected to the SearchActivity which now sees "ok credentials are there, lets move forward". But this doesnt't happen as the login is not shown up. So I think my onResume() might be wrong. Perhaps my full idea is bad? Up to here I thought I also understand the life cycle, but obviosly I don't?
I then had a look around on SO for similar problems. One thing I saw here was a comment to an user which wanted to build a similar "logout" mechanism as mine, that he has to implement this in every activity. I thought about that and ask myself "Why do I have to override the onResume() in every of my activites, when they are all from the same parent? When theres no onResume() in the child, the one of the parent should be called". The user in the SO-question was advised to use services as background threads to count down a timer in there for the logout. I then read the services article in the docu and then fully got disoriented:
There are two types of services: Started and bounded ones. A started service is once started by an activity and then runs in the background until hell freezes when it doesn't get stoped. So it's fully independed of any app, but the programmer has to / should stop it when it's not longer needed. A bounded services is bounded to one or many app components and stops when all bounded components end. I thought this might be a good alternative for me, but when I thought further I ask myself how: If one of my starts it (let's say the login dialog) and then is closed the service is stoped and the other activites always start there own ones which can't be the sense of it. So this service must be bounded not to any component but to my app. But whats the life cycle of an android app? How can I keep information "global" inside my app. I know I can switch data between actitivites using 'Intents'.
This more and more "foggy cloud" lead to ask myself: "Shall I use only one activity and try to switch in/out everything using fragments?"
So my questions are (I think that's all of them, but I'm not sure anymore):
Does my idea of writing an parent class which does the checks for all extended childs ok or bad AND does it work as I understood it?
Do I have to override every onResume() in the childs just to call the parent one for the checks?
Can you give me a tip why my "login systems" doesn't work?
What's the life cycle of an android app and how can I interact with it?
Shall I only use one activity and switch in/out everything using fragments or is it a good way to have several activities and some of them use fragments (to reuse often used parts)?
Thanks in advise
What I've done in the end is the following:
I removed the "login" thing from the parent class into a stand alone activity. This activity is called when the credentials are not valid together with an finish() of the calling one. So I don't build a loop and drop unused activites.

Won't load values from SharedPreferences - when using them in a calculation, they appear to be blank

when testing an activity in my app I see that it's not using the values I've set using the PreferenceActivity.
I can confirm that the values are corretly set in the PrefsActivity (at least "locally"), because every time I open it, the settings are exactly like they were when I closed it the last time...
Do I have to specify in my PreferenceActivity which preference file to store the settings into, or is it a problem with the methods I'm using to import those values for use in my activity?
It feels like I've searched all over the web without ever finding a clear answer to that question...
This is where my activity is supposed to load the preferences, does it look right?
I know that's the only thing missing, because the calculation works just fine when I run it in debug mode and manually input the values to use...
public void OnStart() {
// Loads the values for the calculator to use
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
bodymass = settings.getInt(getString(R.string.pref_key_user_mass).toString(), 0);
gender = settings.getString(getString(R.string.pref_key_user_gender).toString(), "");
Also, does this following code look right to you?
(I would also be grateful if someone told me how to make an 'if' statement comparing several variables at once - e.g. if (one out of three fields are empty) {do something})
//Checks defined user gender and sets value to be used by calc accordingly
if (gender == "male") {
genderValue = 0.7;
}
else if (gender == "female") {
genderValue = 0.6;
}
else if (gender == "") {
settingsAlert();
}
It never seems to trigger the settingsAlert()-function, even when all app data is wiped (it should then spawn an alert message, prompting the user to go set the preferences before using, but nothing happens)
Here's the code that's supposed to spawn the alert:
public void settingsAlert() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("#string/dialog_setPrefs_text")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent gotoSettings = new Intent(ActivityCalc.this, ActivitySettings.class);
startActivity(gotoSettings);
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
}
})
.create();
}
--UPDATE--
I have now managed to get the alert dialog spawn like it should, I figured I'd post the code lines that made it happen, so others with the same problem can watch and learn... :)
The problem appeared to be that the alert was indeed created correctly, but never actually called to display - therefore everything worked perfectly once I added that little .show() after the .create() in the last line.
Alternatively, you can define it as an AlertDialog object, and just call it whenever you feel like it:
AlertDialog alert = builder.create();
alert.show();
I'm posting the contents of my PreferenceActivity class here for you to see
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// This line will import the preferences to display in the settings activity
addPreferencesFromResource(R.xml.settings);
}
To see how to build the preference resource file, look at this article
I've no longer included the string for specifying the name of the shared prefs to use, as I changed the get-method to use DefaultSharedPreferences instead:
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
I have now only defined and initialized the variables required to be persistent for the rest of the activity:
private double genderValue = 0;
private String gender = "";
private int bodymass = 0;
The app now works exactly like it should - not crashing, and correctly loading the preferences as set in the PreferenceActivity.
You need to use equals for the IF-ELSE sentences
if (gender.equals("male")) { //equals
genderValue = 0.7;
}
else if (gender.equalsIgnoreCase("female")) { //Here the equalsIgnorecase one
genderValue = 0.6;
}
else if (gender == "") {
settingsAlert();
} else {
settingsAlert(); //Probably it always comes here.
}
Another thing.. did you saved the preferences correctly with 'commit' ?
settings.edit().putString(getString(R.string.pref_key_user_gender).toString(), gender).commit();
--After 3rd comment---
Never tried. One for each works fine. But if you check 'duanhong169' comment, there're 2 following putString and the last commited, so.. make a try :)
Anyway you can just do:
SharedPreferences.Editor editor = settings.edit();
editor.putString("gender", genderValue);
editor.putInt("bodymass", bodymassValue);
editor.commit();
And answering your other question.. you need the 'edit' to save a prefference, is how it works. you can use it at onpause, onrestart, or just after you've the data you need (inside a method).
Ie if you need a login data, once after you checked the login is correct, and if you've a different login-pass value stored (different user), you can edit.putString to save the new value inside onResult confirmation.
The better thing you can do is try different methods of saving to prefferences with different tags and then creare a Log and do getString() from each tag, so you'll know which one works, and then you can choose the better/easier for your case.
-- UPDATE 2 --
As far as I know.. (i've never tried that, and like you, i'm really new in android) your preferences.xml should be placed at res/xml and then:
public class PreferencesFromXml extends PreferenceActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
}
}
and to get the data:
PreferenceManager.setDefaultValues(this, R.xml.prefer, false);
SharedPreferences p = PreferenceManager.getDefaultSharedPreferences(this);
p.getString("key", "value_default")

Categories

Resources