Store data periodically in Android - android

I need to record a change in my boolean variable that depends on certain conditions in my code. I have a timertask that runs every second to track any such change. When a change occurs, i.e., when the variable change say from 'true' to 'false', I need to save the time at which this event happened. All of these events need to be able to retrieved from another Activity at a later time. I can implement this task either using SharedPreferences: I was thinking about using the putstring method:
sp_editor.putString("alarm_activated",String.valueOf(System.currentTimeMillis()));
but I realized alarm_activated is overridden each time. But I need all the 'time' values.
I could also change the key each time (key,value) by adding the 'time' to the key itself as below.
sp_editor.putStrng("alarm_activated"+String.valueOf(System.currentTimeMillis(),placeholder);
This looks like a really inefficient way to do it.
Is there any other way I can do this?

The right way to do this is to set up and update an SQLite database your app can use. It will give you maximum flexibility in terms of saving and retrieving data locally without worrying about loosing data if the app gets killed. Here is a good tutorial

Create a singleton class and inside create ListArray where you can save data.
If it data need to be accessible from another App use Android SQLite.

You can create a class like this.
public class TimeKeeper {
private static TimeKeeper instance;
public List<String> timeList = new ArrayList<String>();
public static TimeKeeper getTimeKeeper() {
if (instance == null) {
instance = new TimeKeeper();
}
return instance;
}
}
From your TimerTask you can add time to the list as
TimeKeeper.getTimeKeeper().timeList.add("Your Time");
and from any other activity you can access this same list very easily.
Mark as up if it works for you.
//======= For Saving it permanently you can loop through it and save it into db.
for(Strng time :TimeKeeper.getTimeKeeper().timeList)
{
db.insertTime(time); //call Your method to insert time string into your db
}

Related

RealmResult as RealmObject field

I'm trying to figure out the best way to set up a RealmObject with a RealmResult as one of its fields.
For example, let's say I have two RealmObjects, Goal and Achievement. The Goal object contains fields that define a query of Achievement's the user wants to track (e.g. date range the achievement was created, type of achievement, etc) and has custom methods to extract statistics from those Achievements.
What is the best way for Goal to contain this RealmResult of Achievements? Here are some ways I've thought of doing this:
Have a persisted RealmList field in Goal and update it anytime a field is changed that would change the resulting query. But how would this RealmList get updated if a new Achievement gets added to the realm?
Use #Ignore annotation on a RealmResult<Achievement> field within Goal. Anywhere in Goal where mResult is used, first check if null and requery if needed. This seems like I will be doing a lot of unneccessary querying if I'm using something like a RecyclerView that refetches the object in getItem().
Have a wrapper class that contains a Goal object and the RealmResult<Achievement> as fields. Add a listener to Goal so that anytime a relevant field changes the RealmResult can be requeried.
I'm leaning towards the last one as the cleanest way to keep a valid RealmResult. Am I missing an easier way to accomplish this?
Okay so I'm trying to implement a wrapper class (which I think is similar to the DAO abstraction #EpicPandaForce was mentioning, but I'm not super familiar with that)
public class GoalWrapper {
private RealmResults<Achievements> mResults;
private Goal mGoal;
private Realm mRealm;
public GoalWrapper(Realm realm, Goal goal) {
mRealm = realm;
mGoal = goal;
// TODO: does this need to be removed somewhere? What happens when GoalWrapper gets GC'd?
goal.addChangeListener(new RealmChangeListener<RealmModel>() {
#Override
public void onChange(RealmModel element) {
// rerun the query
findResultForGoal();
}
});
findResultForGoal();
}
/**
* Run a query for the given goal and calculate the result
*/
private void findResultForGoal() {
mResults = mRealm.where(Achievement.class)
.greaterThanOrEqualTo("date", mGoal.getStartDate())
.lessThanOrEqualTo("date", mGoal.getEndDate())
.equalTo("type", mGoal.getAchievementType())
.findAll();
calculateStats();
}
private void calculateStats() {
// Get relevant stats from mResult...
}
}
I haven't tested this code yet but I plan to have a RecyclerView.Adapter with an ArrayList of GoalWrapper objects.
My one concern is that I never remove the listener on mGoal. Do I even need to remove it? What happens in the case that the ArrayList gets GC'ed? I would think that the Goal field and resulting listeners attached to it all get GC'ed as well.

How do I share common functions and data across many activities in a single android application

I am looking for how to share functions and data across multiple activities within a single application. I researched the daylights out of it and find some ideology war between overriding the extend for the application and doing a singleton, neither of which I can find examples sufficient to make me understand. Basically I want to share data and share functions. All activities need the same functions and data so this is not one activity sharing data with another activity. It is all activities needing to have access to the same functions and data.
What I want to know is what is the way to go and how do I do it. I need to see what I need to do in my 34 activities, what the class that is going to be common looks like, and what the Manifest entry needs to be. I also need to be sure the common data area will not be closed by the OS.
This is my first Android - Java program and now find my 15,000 line, 34 activity application needs some structure. I know, should have done things differently but the app works really well with two exceptions. One is that it is structurally a mess. Two is that the fact it is a mess is making it hard to fix one behavior I would like to fix.
This is a GPS based application for racing sailboats. It is timing critical and every activity basically runs a once a second loop inside the location manager onLocationChanged function. That part is fine and I do not want to put the GPS code in one place. The problem is that most activities need to filter the data so a lot of code is copied and pasted to the activities. The filter needs history so it needs to remember a state. There are other functions that are used by several activities so these have been copied as well. Think of a function that averages the last three GPS speed readings. It needs to save some history, do its thing, and give a result. All activities need to do the exact same thing. All this works but the problem is that the averaging starts over every time I switch activities because every activity has its own filter. That gives a glitch in the data that I need to get rid of. I need common place to save the data and hopefully a common place to run the filtering and other functions that are common. If every activity can call the filter function that is using common state data, there will be no glitch across activity changes.
I would appreciate some guidance.
Why you don't just make a Class with only static functions, passing needed Parameters? An example if you want to show an ErrorDialog
public class SharedHelper{
public static Dialog showErrorDialog(Context ctx, String message, String title, DialogInterface.OnClickListener okListener, DialogInterface.OnClickListener cancelListener){
AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
builder.setMessage(message).setTitle(tilte);
if (okListener != null){
builder.setPositiveButton(R.string.button_positive, okListener);
}
if (cancelListener != null){
builder.setNegativeButton(R.string.button_negative, cancelListener);
}
return builder.show();
}
}
Singletons are (from my point of view) one of the uglyest design pattern and will bite you sooner or later. Putting anything in Application requires you to cast it everytime to the Special Application class you designed. A class with only statics however is very flexible in its usage and doesn't need an instance to work.
For the storage-issue:
lookup "SharedPreferences" & "SQLite" and decide afterwards which storage-type suits your needs more.
For the methods-issue:
This question is a bit more complex and there are different ways to do it. For example you could write a parent-class that implements all your globally needed questions and you let all your activity-classes inherit from it.
public class MyParentActivity extends Activity {
public void myMethod() {
}
}
and:
public class Activity1of34 extends MyParentActivity {
myMethod();
}
I think what this comes down to is not an Android problem but an Object-Oriented Programming problem. If I understand the situation correctly, I'm betting the best solution would be to take your shared filter and create a new Filter class that is instantiated within each Activity (this is likely more manageable than a singleton, but not having seen your use case, it's hard to say for sure). If you need to centrally track the averaging, you can simply create a static variable within the Filter class that maintains the same value during the life of the application. If you really want to maintain that average (even past the application's current lifecycle), you can persist it in a database or other local data options. However, I don't see any reason to put everything in a singleton just to maintain that average. Singletons (and all static data structures) can be potentially troublesome if used incorrectly.
I, for one, do not mind the singleton pattern. Of course as everything else it should not be abused.
This is the construction I use for my shared objects. My app is divided into modules this way but can just as well be used in your case.
public class SharedDataObject {
private Context context;
private static SharedDataObject instance;
public static SharedDataObject getInstance() {
if (instance == null) throw new RuntimeException("Reference to SharedDataObject was null");
return instance;
}
public static SharedDataObject createInstance(Context context) {
if (instance != null) {
return instance;
}
return instance = new SharedDataObject(context.getApplicationContext());
}
// notice the constructor is private
private SharedDataObject(Context context) {
this.context = context;
}
...
public void myMethod() {
// do stuff
}
}
Notice that it uses the application context, that means among other things, means that the context owned by SharedDataObject cannot be used for GUI operations. But, the context will live for the entire lifetime of the application, which is nice.
Furthermore I hate having to pass a context everytime I wish to call methods on my SharedDataObject, thus I have a splashscreen calling SharedDataObject.createInstance() on all my modules.
Once an instance is create, I can call:
SharedDataObject.getInstance().myMethod();
Anywhere in my code, regardless of a context being present or not (from the place calling this code that is).

General Android Advice: Global Variables

I was wondering what is the best way to handle global variables for android apps. For example, I'm just trying to create a basic login/register system. I've created a user class (that has various attributes like username, password, etc..), so that when we go to the register activity, the User class constructor is called to create a unique user object once all the fields are filled out. I was then thinking of simply having a global arrayList of type User so that I could just loop through all the users on a login attempt.
So far (due to a combined lack of experience in java, and being very new to this android stuff), I haven't been able to implement this successfully. I have a class which I call "globalStuff" which has a bunch of public static variables (i.e. the list of users and current user), which I thought could be accessed from any activity the user navigates to.
There must be a better way to go about this. I've been reading through a few tutorials and a few posts on here, but none address this very basic idea. So what would be the best way to approach something like this?
Thanks for any help!
It's called a static singleton and it looks like this:
public class Global {
private static Global instance = null;
public static Global getInstance() {
if( instance == null )
instance = new Global();
return instance;
}
// additional methods, members, etc...
}
Then you just refer to it in your code as:
Global.getInstance().getUserList();
etc.

How to store data between activities in android?, shopping cart like

I want to make some data available between some activities, just like a shopping cart on a website would do.
This data would probably be a collection of strings maybe a list, a map or something like that. Each item should have associated a id, quantity, type, and a text note (about last one isn't sure yet)
The point is that it doesn't need to be persistent after session ends, and this data will be deleted and recreated completely many times in a whole session.
The question is :
Is the best choice to use a SharedPreferences?, a database?
Thanks!
Even better choice would be some singleton java collection ( map or list ) located via factory object. Just store your cart there and do not bother with database or preferences at all
In case you decide to use preferences, I can recomment my small databinding library:
https://github.com/ko5tik/andject
the simplest way is to use a class with public static variables declared and jus set them from any activity and the retrieve that saved value in any other activity just by calling through a static refrence i.e MyContantsClass.StaticVar1 like
class MySessionVars
{
public static int MyVar1;
}
In first Activity
{
MySessionVars.NyVar1=10;
}
and from any other activity
{
Var = MySessionVars.NyVar1;
}
this is easiest way and will retain vars untill app is closed
You can use Gson (by Google) to send and receive any data btw activities, even class object.
Send: (FirstActivity)
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
Gson gson = new Gson();
intent.putExtra("CustomClassObject", gson.toJson(object));
startActivity(intent);
Receive: (SecondActivity)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Bundle extras = getIntent().getExtras();
if (extras != null)
{
Gson gson = new Gson();
CustomClass object = gson.fromJson(extras.getString("CustomClassObject"), CustomClass.class);
}
//...
}
SharedPreferences is great for storing simple key/value pairs and small amounts of data, however, I imagine your shopping cart object(s) might be a bit more complicated than that. For that reason I would probably use a SQLite database. If you don't have complicated data though, and you just want to store some simple stuff then Shared Preferences should do.
Use Bundle or Intent.
I wouldn't recommend using database for this purpose. Database needs to be properly opened and closed. Where data is passed around activities, it can get messy which activity should be the last to close the database, and may cause a leak. If you are just passing these data from one Activity to another, create a Bundle, attach it to Intent as you start the next activity.
SharedPreferences are key-value pairs whereas database in Android is SQLite both persists after session. You can do any number of operations on SQLite database and use the same file during next session also.
You can put up comments to my answers if you need more clarifications for your particular use case.
People may talk about making global data or storing values in sharedpreference but according to my experience, the simplest way is to just create a separate class with your variables or arraylists declared as public static then use them throughout your project by just referring to the classname.variable name.
class global
{
public static arrayList<String> my;
}
in any of your activity
global.my
This is the simplest method i found so far!

What is the best way to store a non serializable object instance in android?

i have a class that inherits from BroadcastReceiver and is bound to listen for PHONE_STATE events. inside of the onReceive method, i need an object instance that has to be always the exact same (at least between the state ringing and the next occurrence of ide / offhook). that means i need to store the object somewhere. it can not be serialized nor anyhow be stored in a database or in the SharedPreferences.
i thought about 2 different approaches:
using a static variable. downside: no one knows at which point android is going to delete it.
using a service. downside: the service needs to be started at the first call and then bound. this is an async call and i might have to wait for an uncertain time. also it seems kinda wrong to use a service just to store one single object.
any other, better ideas?
Don't know if it will work in your situation, but I'm usually storing an object's string representation in SharedPreferences. You can override the toString() method, which will create the string representation, and implement a parse() method that will parse the saved string and initialize an object based on its saved state. Hope this helps.
third 3) Use a singleton instance of a custom class, then you may get variable from call to call , but not persistant (if application stop).. But useful from a time to another time in the runtime application life. To avoid as much as possible to have wiped data by android framework you may tie your singleton to a service that is "foreground" see http://developer.android.com/reference/android/app/Service.html#startForeground(int,%20android.app.Notification) by this way you get a higher memory detruction protection .. That is the way I currently use singleton in service.. made long time execution (~2 weeks with normal and heavy load activity) without any trouble ...
here an singleton example
class MyData {
private static MyData mMydata= null; // unique reference ( singleton objet container)
private MyObject myobject = null; // inside the unique object container we have the unique working object to be use by the application
// can't make instance from outside... we want to have single instance
// we want that outside use method "getInstance" to be able to use the object
private MyData() {
}
// retrieve and/or create new unique instance
public static MyData getInstance() {
if (mMydata == null) mMyData = new MyData();
return mMyData;
}
// Works with your memory stored object
// get...
public myObject getMyObject() {
return myobject;
}
// set ...
public void setMyObject(MyObject obj) {
myobject = obj;
}
}
in your application to handle your "working" object your may access it like
// get object
MyObject obj = MyData.getInstance().getMyObject();
// or set a object
MyData.getInstance().setMyObject(obj);

Categories

Resources