I need to recognize first launch of my application or activity.
At this time I need to get some information from server create local database and save info to it. What is the best way to do this?
Create any preferences for example FirstLaunch and set true \ false to it.
Check whether my database exists or not.
Something else?
PS. All server calls must be into one transaction. Ormlite supports transactions?
Thanks.
For the "create database at first run"-purpose, you should use an SQLiteOpenHelper, which offers you the onCreate()-method that is called when:
[...] the database is created for the first time.
The Database-file itself will be created for you (you don't have to do this manually). In this method, you can then perform actions like populating your database with standard entry's.
If you want to populate the database with informations you get from your server, there might be a problem when there is no Internet-connection available.
In this case, I would check if there is a connection available:
If there is, get your informations.
If not, show a Toast or some other notification to inform the user.
To determine if your Database has be populated with the standard entry's, you can use the database-version which is also provided by the SQLiteDatabase-class:
When you first create your Database-object, you call
SQLiteOpenHelpers constructor and pass it 0 as the Database
version.
If you successfully populated your database, you use
setVersion()-method to alter it to 1.
Later in the onOpen()-method, which is called when the
database is opened, you can check if the database was populated by
using the getVersion()-method.
If it is populated, call the super-method to open it.
If not, try populating it.
Further more, the getReadableDatabase() / getWritableDatabase()-methods should be called off the main-thread anyways because:
Database upgrade may take a long time, you should not call this method
from the application main thread, including from
ContentProvider.onCreate().
So getting the informations from the Internet can take place in the onCreate() and in the onOpen()-method (if it wasn't successful at the first try). You can (for example) use a Service to do this.
If you want to solve this problem with database:
Create database with MyDatabasaVersion table and store your version in a single row, for example db_version default value is 0. First time when the application starts you check the db_version if 0 you need to start the syncronisation, after it is finishing set the db_version to 1.
The easiest way should be sharedpreferences. you can call it everywhere form the application context and you can put boolean values in it.
Here are all Android storages.
you should try first option Create any preferences for example FirstLaunch and set true \ false to it.
Related
I'm trying to use Realm to store a local database of objects. The app checks if the current session is first load and if so populates the local database with an api call. But, if the database is not empty, I would like to use the data already available. To do this, I need to know whether the database is empty or not.
I found this issue on github, but they dont provide a workaround:
https://github.com/realm/realm-java/issues/766
So how should this be done?
If you scroll down that issue page, you can see Realm.isEmpty() is added. :)
Add a realm.isEmpty() method that returns true if there is no objects
in the Realm. It is just a utility method, but fits nicely with the
Realm object store abstraction.
use realm.isEmpty()
I used
if(realmResults.isEmpty()) {action...}
or
if(realmResults.isNullOrEmpty()) {action...]
there's false but action..
What's wrong!? ...T0T
I have build an android application where I call the method insertSampleData()
from the onCreate() method of main activity.
The problem is that onCreate() method is called every-time the app is launched,
this results in filling my database with a lot of sample data.
I want to provide sample data only once when the application is installed. Can anyone please tell me how to do it ? Thanks a lot !
P.S: The method insertSampleData() is used to insert sample data into Sq-lite database.
2 ways of doing this:
Either save if the data was inserted once (e.g. to the SharedPreferences)
Or check if any sample data is already in your database before adding it (but may lead to problems if the user can erase the data)
You could create a check in your Application class, in its onCreate() similar to this one:
SharedPreferences preferences = getSharedPreferences("prefs", Context.MODE_PRIVATE);
boolean firstRun = preferences.getBoolean("firstRun", false);
if(firstRun) {
insertSampleData();
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("firstRun", true);
editor.commit();
}
While other answers are correct, there is a built-in way to achieve what you want: onCreate and onUpgrade methods of SqliteOpenHelper.
About onCreate() and onUpgrade()
onCreate(..) is called whenever the app is freshly installed.
onUpgrade is called whenever the app is upgraded and launched and the
database version is not the same.
As written here: https://stackoverflow.com/a/8133640/5349594
I would add that if you are using some orm library, most of them support something similar to this.
In your insertSampleData() method, before inserting the data, check the row count in yout table.
If it's 0, execute the INSERTs.
No else statement is needed: proceed to exit.
Note: The sample data will be re-inserted on next run, if not found.
Because insertSampleData() is called in onCreate().
And it will insert the sample data, if no data is found.
Therefore, the table will never be empty on start.
As Hrundi said in comments, you can use if statement, but probably better choice would be to use custom DatabaseHelper class wihic extends SQLiteOpenHelper.
Inside SQLiteOpenHelper you have onCreate method which is called when the database is created for the first time. This is where the creation of tables and the initial population of the tables should happen.
You can google this and you will find a lot of examples.
I wonder if it is possible to create a SQLite database when the app got run the first time and already save some data in it.
I don't want to save it every time the app gets started. Just after Installation.
Is this possible?
Just override onCreate() method in class which extends from SQLiteOpenHelper and insert there some data.
Called when the database is created for the first time. This is where
the creation of tables and the initial population of the tables should
happen.
http://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html#onCreate(android.database.sqlite.SQLiteDatabase) .
For my apps I do the simple trick as in Splash check preference of available Data variable, first time its default is false. Then I read from Database and check is there any items If No then insert data and set preference available data variable to true.
and when you come next time splash it will check again and in your available data variable will get true so you don't need to do anything and continue your flow.
I hope this will help you too :)
SQLiteOpenHelper.onUpgrade should do the trick, simply compare oldVersion with newVersion
I've done my homework; I know all the ways to query an SQLite db from an Activity.
The problem is that all the examples ASSUME that i want to "load" data from the db onto the FIRST Activity screen.
But when my app's FIRST Activity is loaded I DON'T WANT TO GET ANY DATA FROM THE DB; i just want to:
(1) Check if the db file has already been created (if the setup routines have already run).
(2) If the db exists, load the SECOND Activity (with ContentProvider/Loaders, etc.) so the user can start adding data.
OR
(2) If the db DOESN'T exist, WHILE STILL IN THE FIRST ACTIVITY run the setup routines (create the db/tables from an *.sql file & INSERT the dummy data where needed)...then load the SECOND Activity (with ContentProvider/ Loaders, etc.) so the user can start adding data.
To me, the simple operation of creating the db/tables shouldn't require all the OVERHEAD of a ContentProvider and a bunch of Cursors and Loaders.
Is there anybody who could point me to a SIMPLE solution? Thanks!
Yaqub's link was helpful...
...what i did was create public static final String arrays in a DBConstants class containing the commands to create the Database on first run.
somehow I don't understand the working concept of the query parameter CALLER_IS_SYNCADAPTER. Its default value is false, if set, the DIRTY flag is not automatically set. So what does it actually mean? Out from my understanding, each change on a contact results in setting the dirty flag to 1. After a sync adapter finished the job, using insert/update/delete with the CALLER_IS_SYNCADAPTER the inserted/updated and deleted records should have a dirty flag of 0, is that right?
However if I invoke queries with that optional parameter, the entries remain with the flag 1.
Is there something else I have to do, or is my understanding how it should work wrong? Or is there something to tell the system the sync has been finished successfully to set the flags?
Does anybody have a sample or some advices for further reading?
CALLER_IS_SYNCADAPTER doesn't necessarily affect what's stored in the database row, it depends on the command performed. It shouldn't have an effect on queries. Do not use it from a user application on the device.
Now... Why does it exist?
It is provided to help with notifyChange() / ContentObservers / ContentResolver / Syncadapter integration. There are two use cases for changing a row in the database.
Local user edits from an application.
Changes come from the network (via SyncAdapter)
Either change requires the UI to update, if it's onscreen. Therefore ContentResolver.notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) gets called. This updates ContentObservers and tells them to go fetch the newest data from the ContentProvider DB. That last parameter in the call is your clue.
ContentResolver itself is a ContentObserver. When it sees the database change, it considers starting up your SyncAdapter to push the change up to the network. This is great in case 1. In case 2, it's redundant. The change came from the network, there's no reason at all to start up a sync to send the change back.
Calendar.CALLER_IS_SYNCADAPTER is a cue used within the update() performed by the SyncAdapter. When it's true, ContentProvider sets syncToNetwork as false, ensuring a redundant second sync is not performed
A second example is as veljko mentioned. The cleanest way to delete a thing from the server is to set the delete flag, and then perform a sync. When the CALLER_IS_SYNCADAPTER flag is false (user app) a call to delete() sets the flag. When the flag is true (sync is happening), a call to delete() pushes the deletion up to the server and removes the row from the local DB. There's only one delete() call, this flag allows the ContentProvider to know which task it's supposed to do.
You can add to your existing Uri:
myUri=calendarUri.buildUpon().appendQueryParameter(Calendar.CALLER_IS_SYNCADAPTER, "true").build();
Here is from Javadoc:
/**
* An optional insert, update or delete URI parameter that allows the caller
* to specify that it is a sync adapter. The default value is false. If true
* the dirty flag is not automatically set and the "syncToNetwork" parameter
* is set to false when calling
* {#link ContentResolver#notifyChange(android.net.Uri, android.database.ContentObserver, boolean)}.
*/
.
The invocation of resolver.delete(...), does not immediately delete a raw contacts row. Instead, it sets the DELETED flag on the raw contact and removes the raw contact from its aggregate contact. The sync adapter then deletes the raw contact from the server and finalizes phone-side deletion by calling resolver.delete(...) again and passing the CALLER_IS_SYNCADAPTER query parameter.