I am trying to log installs of my app using Firebase with this simple code below:
firebaseAnalytics.logEvent("foo", bundle);
However, I am not sure where to put this code. Does any one know of an "onInstall" method in the Application class?
Or is there another, easier way to log installs with Firebase?
Thank you!
You could determine if the user launches the application for the first time, and log that event.
public class MyActivity extends Activity {
SharedPreferences prefs = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Perhaps set content view here
prefs = getSharedPreferences("com.mycompany.myAppName", MODE_PRIVATE);
}
#Override
protected void onResume() {
super.onResume();
if (prefs.getBoolean("firstrun", true)) {
firebaseAnalytics.logEvent("foo", bundle);
prefs.edit().putBoolean("firstrun", false).commit();
}
}
}
Code referenced from this SO answer.
There's another answer in that same SO question that explained how to differentiate between first run and subsequent upgrades, I'll just link that SO answer here for your reference.
The cleanest method would be to have a remote server that holds a unique ID for each user.
Also, you could theoretically write a file directly on the device. But then, you'd need to get the write permission and it's most definitely not a good idea to create and leave a file on the device.
P.S - To answer the actual question, No, Android doesn't have an onInstall method.
Related
So I followed Google's first Android app sample. If I tapped the send button, it opened up the DisplayMessageActivity. But upon tapped the back button (left arrow) from the DisplayMessageActivity, the onCreate(Bundle savedInstanceState) of the MainActivity got called again. It looks like it created a new instance of MainActivity. I could verify this by setting a bool value in onCreate of MainActivity and it was not retained.
How do you go back to the previous instance of MainActivity (the caller)?
You should have a look at Androids Activity Lifecycle.
If you want to access the state of the activity again, I would suggest to use the method
public void onSaveInstanceState(Bundle outState)
to save the current state.
Retrieve the previously saved values in this method:
public void onRestoreInstanceState(Bundle savedInstanceState)`
An example can be found here
You can call finish() in the onClickListener of the back arrow view. It will finish the DisplayMessageActivity and you will return to the caller activity (MainActivity in your case).
Something like:
backArrow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
It looks like it created a new instance of MainActivity.
Yes, I think, that was quite a normal behavior.
Basically, Android OS would keep only one Activity at once so that free as many memory resources as possible.
You should design your application with understanding about such lifecycle concepts.
You can save some of the states of your Activity in certain manners (Parcelable, Bundle or SharedPreferences, etc.).
I know there must be douzens of answers to this question out there, but either i cant't find them or I don't understand them.
The Question:
How do I get my app to exactly start as it was left?
F.e. dynamicly added checkBoxes shouldn't dissapear!
There is no "out of the box" way of doing it. You could save the current state of your Activity in some way (More on persistence)
Then you need to be able to rebuild the desired state of the persisted state in your Activity lifecycle
You could save and load with the shared preferences for example:
public void saveState(YourState state) {
SharedPreferences sharedPreferences = app.getSharedPreferences(R.string.preference_file_key, Context.MODE_PRIVATE)
sharedPreferences.edit()
.putString("CustomAtt", state.getCustomAtt())
}
public YourState loadState() {
SharedPreferences sharedPreferences = app.getSharedPreferences(R.string.preference_file_key, Context.MODE_PRIVATE)
String customAtt = sharedPreferences.getString("CustomAtt", "DefaultValue")
return new YoutState(customAtt)
}
And use it like this
#Override
protected void onCreate(Bundle savedInstanceState) {
YourState state = loadState();
// Rebuild your activity based on state
someView.setText(state.getCustomAtt())
}
You can store such values in SharedPreferences.
https://developer.android.com/training/basics/data-storage/shared-preferences.html
It is using key-value approach for saving. So you can save some values and read it from SharedPreferences whenever you want to.
This is the best approach for small data, that can be used on the app launch. So you can quit your app and the data is still present - so can be read on the next app launch.
Or save the condition of your program to a text file, so that the program can "translate" it back into conditions before it stops, or what I do not recommend, it saves every object created with ObjectOutputStream.
I searched a lot but i did not find my answer. I have developed an android application where on the very first lunch user will be shown a welcome screen made of viewpager. The problem is i don't know which place is the best to put the welcome activity code in my application.
The simplest way it could be that in the main activity at the very fist line even before super.onCreate(), inside onCreate method where i try to get the shared preference value and then evaluate whether it is fist lunch. If it is, then i start the welcome activity as shown below
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
boolean welcome = sharedPreferences.getBoolean(getString(R.string.key_welcome), true);
if (welcome) {
// go and start welcoming activity
Intent intent = new Intent(this, WelcomeSlideActivity.class);
startActivity(intent);
}
super.onCreate();
}
}
But i found another approach to deal with it. It is Application class. Since Application class is the first one, which runs even before any other codes in my application. So i thought, i would be nice to do it there as shown below
public class App extends Application {
#Override
public void onCreate() {
super.onCreate();
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
boolean welcome = sharedPreferences.getBoolean(getString(R.string.key_welcome), true);
if (welcome) {
// go and start welcoming activity
Intent intent = new Intent(this, WelcomeSlideActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}
}
So i am in dilemma, which one would be the best option to choose. And i am even not sure if i am doing it in the right way since there is no such documentation in android developer website or anywhere.
Have a look at how to create splash screens the correct way. https://www.bignerdranch.com/blog/splash-screens-the-right-way/
As for using the Application class - this is primarily used for Application-wide configuration for maintaining a global application state. Hence starting an activity from here does not make much sense as it's purpose has changed into becoming an entry point into the application rather than providing state for the app as a whole.
Furthermore, why not make the WelcomeSlideActivity the first 'launcher' activity? Then in there, you can create the logic of whether to launch the next activity without history or whether to show the current view.
Ideally, you should create a splash screen activity, which determines whether to show the WelcomeSlideActivity Or the MainActivity. The advantage of this is that while he app determines which Activity to launch, the user is presented with a splash screen that informs the user that the app has started
I have an android app that simply just toggles a value in the settings. For this app when clicked I DON'T want to show a layout, just a Toast and then kill itself. I have this already:
public class Test extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
Toast.makeText(this, "MESSAGE", Toast.LENGTH_LONG).show();
android.os.Process.killProcess(android.os.Process.myPid());
}
}
Is there a possibility to disable the layout at all?
It sounds like a Service will be much more appropriate in this case.
Services run in the background, but can still perform some limited UI tasks such as showing Toasts.
Activities are not designed to be used without a UI.
Simple, just comment out one line looks like:
//setContentView(R.layout.activity_main);
oh, to kill self, you may simply call finish by the end of onCreate.
I am trying to detect if my app has been run before, by using this code:
(This is in my default Android activity)
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
Log.w("activity", "first time");
setContentView(R.layout.activity_clean_weather);
} else {
Log.w("activity", "second time");
setContentView(R.layout.activity_clean_weather);
}
}
When I first run the app it says first time, when I run it a second time, first time, and a third, first time....
I am using an actual Android device and I am not using the run button each time. I run the app once with the Eclipse run button, then I close the app and press on its icon on my phone.
Is there something wrong with my code?
savedInstanceState is more for switching between states, like pausing/resuming, that kind of thing. It must always be created by you, also.
What you want in this case is SharedPreferences.
Something like this:
public static final String PREFS_NAME = "MyPrefsFile"; // Name of prefs file; don't change this after it's saved something
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0); // Get preferences file (0 = no option flags set)
boolean firstRun = settings.getBoolean("firstRun", true); // Is it first run? If not specified, use "true"
if (firstRun) {
Log.w("activity", "first time");
setContentView(R.layout.activity_clean_weather);
SharedPreferences.Editor editor = settings.edit(); // Open the editor for our settings
editor.putBoolean("firstRun", false); // It is no longer the first run
editor.commit(); // Save all changed settings
} else {
Log.w("activity", "second time");
setContentView(R.layout.activity_clean_weather);
}
}
I basically took this code directly from the documentation for Storage Options and applied it to your situation. It's a good concept to learn early.
You may use a self-defined shared preference to archive your goal.
The fact is that savedInstanceState holds persistent data across activities. As such if you restart the app, savedInstanceState will be null across runs. You should either use a Preference or some data base entry to keep track of your first run. I myself use a SharedPreference for this purpose.
savedInstanceState will be null if the app is not already loaded in memory. If you want to detect whether the app has run for the very first time, you have to apply different technique, such as using sharedPrefs / DB to store a property for the first run.
i.e. Check sharedPrefs for property "firstRun"
if exists, then it is not a first run
else it is the first run
set the firstRun property to true