Check if app is opened for the first time in LIBGDX - android

I am trying to check if the app is opened for first time in LIBGDX. I want this logic to be implemented in level selection screen. I want the sprite to get different for the first time. I have implemented the below code,
private static Preferences prefs;
public MenuScreen(MyGame game) {
prefs = Gdx.app.getPreferences("firsttimeopen");
if (prefs.getBoolean("lock",true) ) {
prefs.putBoolean("lock", false);
Gdx.app.log("firsttimeopening" + a, "firsttimeopening" + a);
} else {
Gdx.app.log("secondtimeopening" + a, "secondtimeopening" + a);
}
Here both the condition becomes true when i open the app.I don't know where did I go wrong. I even referred this question stackoverflow and even this question stackoverflowbut nothing helped. Help me. Thanks in advance.

From the wiki:
Your changes to a preferences instance will only get persisted if you explicitly call the flush() method.
Add the line in your code:
prefs.putBoolean("lock", false);
prefs.flush();

Related

Welcome page for Android App

I am new to android development, and developing a small app for practice purposes.
I want the following:
When the user installs the app, he/she is greeted with a set of welcome pages, that give details about the app, and then proceeds to the actual app.
But I don't want that set of pages to appear anytime after the first time the app is opened.
So how do I go about implementing that?
PS: This is my first question posted, excuse typos or brevity if any.
Edit: It seems like there is another question of the same context, but I also want to know how to make such an activity that will load only once after the installation.
You can achieve this result in different way, one of them may be to
store on SharedPreference
isFirstLoad = true
after the user read you intro page then
isFirstLoad = false
in your main activity check for first load to redirect user to correct activity
Intent i = ...// normal activity
if(isFirstLoad){
i = ...// intro activity
}
startActivity(i);
you should use SharedPrefrences for store that it is the first time or not.
you can creat a class for store information like this.
public class prefrence
{
SharedPreferences sharedPreferences;
public prefrence(Context context)
{
sharedPreferences = context.getSharedPreferences("myAppData", 0);
}
public boolean isFirstTime()
{
return sharedPreferences.getBoolean("first", true);
}
public void setFirstTime(boolean b)
{
sharedPreferences.edit().putBoolean("first", b).commit();
}
}
and check that it is first time or not like this:
if (new preference(context).isFirstTime()) {
showSplash();
new preference(context).setFirstTime(false);
}

change default preference on upgrade

In my app, I have the following code that tells me if a feature is enabled by default :
public boolean getFeatureEnabled()
{
return mPrefs.getBoolean("FEATURE_ENABLED", DEFAULT_ENABLED);
}
This preference is overwritten only when the user changes the setting from UI. So by default it draws its value from DEFAULT_ENABLED which is a class variable somewhere.
In the current version, DEFAULT_ENABLED is true but on the next version of my app will be false.
The problem is that after the update, with the above code the old users who did not change the default setting from UI will have their feature disable - and I want to avoid this.
Any advices on how to handle this ?
As I understand, you have a feature that was enabled by default but this default was never written to SharedPreferences unless explicitly changed by the user.
Now you want the feature to be disabled by default but without affecting the behavior for users that already have it enabled.
I can think of 3 options:
Option 1 If you are already saving the last version, you could check that in your migration logic:
private void migratePreferences(Context context) {
SharedPreferences prefs = context.getSharedPreferences("your_preference_file", MODE_PRIVATE);
int lastKnownVersionCode = (prefs.getInt("LAST_INSTALLED_VERSION", BuildConfig.VERSION_CODE);
prefs.edit().putInt("LAST_INSTALLED_VERSION", BuildConfig.VERSION_CODE).apply();
//this is the old featureEnabled check
boolean oldPreferenceValue = prefs.getBoolean("FEATURE_ENABLED", true);
boolean newPreferenceValue;
if (prefs.contains("FEATURE_ENABLED")) {
//the feature was modified by the user so respect their preference
newPreferenceValue = prefs.getBoolean("FEATURE_ENABLED", false);
} else if (lastKnownVersionCode == BUGGY_VERSION_WITH_FEATURE_ENABLED_BY_DEFAULT) {
//the user is updating from the buggy version.
// this check could include a range of versions if you've released several buggy versions.
// this is also where option 2 would be inserted
newPreferenceValue = oldPreferenceValue;
} else {
//the new default that will apply to fresh installs
newPreferenceValue = false;
}
//save the preference
prefs.edit().putBoolean("FEATURE_ENABLED", newPreferenceValue).apply();
}
This, however depends on your already having a call to this method somewhere in your app startup code.
Option 2 In case you don't, there is still hope. You can check if this is your first install using the answers given in this StackOverflow answer
Option 3 You can release an intermediate version of your app that behaves as it does now but saves the unsaved default setting in SharedPreferences. This will keep the feature AS IS for your eager users but you will have to wait until a significant portion of users updates before releasing the desired behavior.
Put another flag "FIRST_TIME" as "true" in your preferences in new build. Check on the very first screen of your app
if(FIRST_TIME==true)
{
//put FEATURE_ENABLED = false;
//put FIRST_TIME = false;
}
By doing this FEATURE_ENABLED will set to false for the first time the user launches the app and will not consider the default value

how to make a screen in android that runs only when the app installs

I am making an Android project. In that project i want a screen to appear only during the app installation and not every time we start the app. For eg. in whatsapp the page in which we put our name appears only during installation. I want exactly that type of a screen. I am fairly new to android programming so any help will be appreciated. Thanks! Cheers!
You can use the SharedPreferences to identify if it is the "First time" the app is launched.
Just use a Boolean variable ("app_first_time") and change its value to false after your task runs for the first time.
final String PREFS_NAME = "PrefsFile";
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
if (settings.getBoolean("app_first_time", true)) {
//here the app is being launched for first time, launch your screen
settings.edit().putBoolean("app_first_time", false).commit();
}

How to handle GoogleApiClient instance upon Activity reconnection in Chromecast App?

I'm writing a simple app to send public photos from Dropbox public folder to Chromecast.
Instead of CastCompanion library I decided to write my own stuff to understand better the API.
According to Google Guidelines:
if the sender application becomes disconnected from the media route, such as when the user or the operating system kills the application without the user first disconnecting from the Cast device, then the application must restore the session with the receiver when the sender application starts again.
It seems to me that the same solution should apply to Activity recreation upon orientation change since it recreates the Activity from scratch.
My first question: Is my assumption correct? Both scenarios, orientation change and system kill, may use the same solution?
Given this assumption I wrote some code to restore session upon Activity restoration.
I'm considering the orientation change scenario, when Activity is recreated from scratch and I am supposed to restore route Id, Session Id and try to reconnect (I'm storing and retrieving both values from shared preferences).
I've been testing with and it's working fine.
That's what I do (based on Google Sender Guidelines code):
After discovering the ongoing Route Id and find the cast device I call this method:
private void connectToDevice(CastDevice castDevice) {
Log.d(TAG, "connecting to " + castDevice);
Cast.CastOptions.Builder apiOptionsBuilder = Cast.CastOptions
.builder(castDevice, new CastListener());
Log.d(TAG, "apiClient is null ? " + (apiClient == null));
apiClient = new GoogleApiClient.Builder(this)
.addApi(Cast.API, apiOptionsBuilder.build())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
Log.d(TAG, "apiClient connected? " + apiClient.isConnected());
Log.d(TAG, "apiClient connecting? " + apiClient.isConnecting());
apiClient.connect();
}
private class CastListener extends Cast.Listener {
#Override
public void onApplicationStatusChanged() {
if (apiClient != null) {
Log.d(TAG, "callback => " + this);
}
}
#Override
public void onVolumeChanged() {
}
#Override
public void onApplicationDisconnected(int errorCode) {
teardown();
}
}
After this method I call Cast.CastApi.joinApplication if I recognize a reconnection.
But once reconnected to Chromecast the log of onApplicationStatusChanged prints one different instance for every phone's rotation. E.g: if I rotate phone 3 times the log prints 3 times with 3 different pointer addresses. That makes me believe it is internally holding all callbacks instances.
How am I supposed to handle this situation since the Activity is being recreated and I need to create another instance of GoogleApiClient keeping the session?
Full source:
https://github.com/ivan-aguirre/chromecast_samples/blob/master/DropboxCast/app/src/main/java/com/dropboxcast/dropboxcast/MainActivity.java
IMHO, I believe the proper way (or at least a better way) to approach this is one of the following:
if you have only one activity and that is all you care about, then use a fragment that persists across configuration changes and put the stuff that you want to persist seamlessly, there. This way, rotation of the phone is not going to cause any disruption in your cast related stuff.
if you have more than a single activity, think about creating an object that lasts across all your activities and put the cast stuff there and then ask that object for the instance of CastApi whenever needed, etc.
In your case, do you really get disconnected when you rotate the phone? Since you are setting up a whole new connection, you might want to disconnect yourself first when configuration changes (assuming you don't want to go with my earlier proposed (1) or (2)).

How to clear android cache onCreate

I'm new to Android development and I've started creating this app where I read an XML feed and list the contents. But even though the feed changes I still get the same data displayed. Although over night the cache seemed to clear itself. I would like to force reading of the feed each time I start my app. I tried the methods described here How to clear cache Android but it didn't help.
My guess is that I would have to do it onCreate in my main activity (at least that's what I have tried so far).
Can anyone point me in the right direction?
Thanks in advance :-)
Here are some code snippets.
From my activity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_game);
deleteCache(this);
new ReadLeagueXml().execute();
}
deleteCache is the method from the other thread I linked to.
Then in my doInBackground I have
InputStream inputStream = new URL(xmlURL).openStream();
if (inputStream != null) {
list = parse(inputStream);
}
And finally in my onPostExecute:
ListView matchListView = (ListView)findViewById(R.id.match_list);
List<String> matchArray = new ArrayList<String>();
for (int i = 0; i < matches.size(); i++) {
matchArray.add(matches.get(i).HomeTeam + " - " + matches.get(i).AwayTeam);
}
matchArray.toArray();
matchesArrayAdapter = new MatchListAdapter(ListGameActivity.this, matches);
matchListView.setAdapter(matchesArrayAdapter);
Your code seems perfectly Fine. Also you do not need to "clear cache".
Now back to the question, If i understand your question correctly, The feed is not getting refreshed. This is because you download the new data on onCreate(). So when you launch the app for the first time the data is downloaded. Then the user goes to another application (remember Android will not close your activity, it will simply pause it). So when the user comes back, If the application is not closed Android will resume it! So your onCreate() will not be called again.
In short,
Update the data in onResume() which is called everytime your activity is shown to the user. Move the new ReadLeagueXml().execute(); to onResume() and new data will be downloaded every time the user opens the app.
You might want to look at the Android Activity Life Cycle here

Categories

Resources