How do I find the last time when any application was used in Android. Which means last >access time for any app?
Perhaps you could use the Calendar class to save an instance when the onCreate or onDestroy executes for your app. You could then save the time into a private app file using a OutputStreamWriter and just read it's contents using an InputStreamWriter whenever you need it.
As i know there are no instances which records this. You can easily make it yourself by adding a Database and Record every Start with timestamp or calender instances. Then you COUNT(*) it and there you go.
I found the answer my self:
IUsageStats mUsageStatsService = IUsageStats.Stub.asInterface(ServiceManager.getService("usagestats"));
PkgUsageStats[] stats = mUsageStatsService.getAllPkgUsageStats();
Pull out the map from the desired array index. This map contains the last time the app was accessed.
Related
Context
I'm working on an offline first app, and I'm basically working on a screen that is supposed to show a list of store offers - discounts, coupons, things like that - I'm trying to rely on Realm queries via Flowables to fetch the data, and I want the app to be 100% honest with what we have on the Realm DB. I mean, that if something changes in the database the app should immediately refresh the UI, that's why I'm using Flowables.
Problem
This approach has been working fine so far, but I've stumbled across this specific situation where things are a bit tricky. I need to display this list of store offers like this:
private val offersFlowable: Flowable<RealmResults<RealmOffer>>
get() {
val realm = Realm.getDefaultInstance()
return realm.where(RealmOffer::class.java)
.equalTo("userId", CredentialManager.getInstance().getUserId())
.and()
.beginGroup()
.isNotNull("expiryDate").and().greaterThan("expiryDate", Date())
.endGroup()
.findAll()
.asFlowable()
}
The query itself works perfectly, I fetch the user's offers which haven't expired yet. The only problem is that it seems I need to recreate this query every time I want to refresh the data. Why? Because of the Date(). I open the Activity that renders this RecyclerView list of store offers, I instantiate the query and start listening for the changes - so far so good - but if I have a store offer that is about to expire in a minute or so, wait that full minute and do a Pull To Refresh, the expire offer doesn't go away. Again, because of the Date() because the current date was instantiated a minute ago and it is still that date.
If I kill the app or instantiate the Activity from scratch, everything works as expected because I'm instantiating the query again, therefore getting an up to date Date().
What I've tried so far
Instead of hardcoding that Date() arg there, having a currentDate property in my ViewModel - the place where this Flowable lives - I was kinda hoping that if the date arg was a reference to a computed Kotlin property that would do the trick, but it didn't work.
Same thing as above but I changed the expiryDate field to millis instead of a Date.
The Workaround
So, the only thing that works right now is just re-instantiating the Flowable query every time I do a PTR, that way I pass an up to date Date() arg and the query works as expected.
My Question
Is there any way to fix this without having to re-instantiate the query all the time?
Thanks! Appreciate all feedback! 🙇
I hope that I have understood your problem right, I would like to put a suggestion may be that help you. The current work around for sure is not a good option because of requesting the database again and again. so what in my opinion would be better for this situation is,
Before rendering the data on the RecyclerView, Do the following;
1 - get the expiry date & time of each item.
2 - get current date & time.
3 - Compare both of them and get the difference.
Now, if the difference is -ve value, it means the item is expired and you don't have to show it in recyclerView. Of course the item is available in ArrayList/List but it is not being rendered on recyclerView.
Otherwise Second Option
At the time of adding the store offers data to the database, just register a PendingIntent for every offer along with an AlarmManager and set the Expriy-time as the alarm time for the PendingIntent.
This way, when the offer expires, it will throw an alarm. So, here you could do the magic, when the PendingIntent get trigger, just update your database and recyclerview from there. This way you can handle every offer automatically.
Let me know if it helps.
Happy coding :)
I have an Android App that uses an SQLite database. The problem is that the database has gotten to be quite large (41.6 MB) and I'm starting to wonder if I am correctly loading it into the app.
Right now what I'm doing is in the onCreate() method of my app's splash screen I'm opening the database, querying it, saving the data as objects, then closing the database. It takes a noticeable amount of time on a cold launch. Ideally I want to do all of this on the first launch and save the data somewhere on the device to speed up future launches. Is there a way I can do that?
I have same problem before.Probably thats the same case. Mine one because I pinging too many times of the Backend API and there is one more problem where you insert into your Object. probably when you insert it, The data that should just insert once, you insert it too many times on the for loop if there are many object that you are going to insert. Probably you can put your code when inserting it. lots of dev doesn't care about that but actually thats really annoying to user.
in my case because of this :
manager.removeAllStop();
manager.removeAllUpload(); //--> remove the data before insert the new one
for (Stop stop : SomeStopsList) { //--> when I want to loop through and want to add it to other object
**manager.insertAppTourStopList(appTourStopList);** //--> PROBLEM HERE !!!! THIS COULD BE OUTSIDE FROM THE LIST BECAUSE YOU WANT THIS TO BE ADDED ONCE ONLY
ArrayList<Upload> uploadList = new ArrayList<Upload>(); // --> new object
for (Upload uploadData : stopList.uploads) { //--> get the list and loop
Upload upload = new Upload(); //--> create new object
upload.setStopId(stopList.getId()); //--> insert it
}
}
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 am creating a multiple choice quiz game where there is an option to continue the game from where the user has left. Example, if user stopped the application at Question Number 4, then by pressing the continue option will resume the quiz game from Question Number 4 itself. I am not able to understand how should I move ahead by coding way? What is the right way to continue a multiple choice quiz game? Any help would be appreciated.
As an example, you could use JDOM. Just include the .jar file in your projects build path and then you'll have access to the JDOM library methods.
An example of using the JDOM libraries:
// Create a new XML document in memory
Document doc = new Document();
Element root = new Element("child");
doc.setRootElement(root); // set ^ above element as the root element
root.addContent(new Element( "childname" )); // add a data element to the root
root.getChild("childname").setText("SOME INFO"); // give some data to the element <childname>
// Save the XML file
FileWriter writer = new FileWriter("FILENAME.xml");
XMLOutputter outputter = new XMLOutputter();
outputter.setFormat(Format.getPrettyFormat()); // sets correct tabbing/format in the file
outputter.output(doc, writer);
This would make something like:
<child>
<childname>SOME INFO</childname>
</child>
You can then access the information stored in the XML file by using some JDOM methods like:
root.getChild("SOME CHILD").getText();
Of course JDOM isn't the only option here. It's whatever seems easiest for you, not me.
Where are you getting your questions from? Try to build a sqlite db around your game. Get your questions from there. Then when the player goes out save state of the quiz in a db table, and when he comes back resume the game. Also you can store his previous performances, current performance in seperate tables. Seems like a good way to go about it.
Its a simple solution actually. A sql read will always result in the same sequence of read when you make a select call. So if you have 100 rows, and you select 10 rows of them and choose the first one, it will always be the same. Practically tested and it works. Now, you can create a "played" flag in your table and flag your quiz played. This way you will always get the same question in the same sequence as you reset.
If you want to randomize, I suggest you code that. There is no automatic way to do it.
Now for question, you should use shared preferences to save current question being played. This way you can just read that one row when you restart your application.
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.