As far as I know, there is no system API for me to get user idle time. When I say user idle time, I mean user have some interaction on the touch screen within my app. Therefore, I want to track it by my self. The way come up to my mind is to extends Activity and override onuserinteraction method to save the last user active time.
But the challenge is that my app have multiple processes. I am not sure the following way is the correct and efficient way.
I want to use SharedPreference with MODE_WORLD_WRITEABLE flag to store the user last active time. To avoid the performance issue, I also cache the last active time within the activity in each activity. And I only save the new time to SharedPrefernces if the diff time > 1 second.
Is this way efficient compared to using aidl? Actually, is aidl also share variable using file? If yes, I think the two ways should have similar performance, right? Thanks.
Instead writing it down every time, from everywhere, make this a global function in your App:
public class MyApp extends Application {
private static SharedPreferences sPreference;
private static final long MIN_SAVE_TIME = 1000;
private static final String PREF_KEY_LAST_ACTIVE = "last_active";
private static final String PREF_ID_TIME_TRACK = "time_track";
public static void saveTimeStamp(){
if(getElapsedTime() > MIN_SAVE_TIME){
sPreference.edit().putLong(PREF_KEY_LAST_ACTIVE, timeNow()).commit();
}
}
public static long getElapsedTime(){
return timeNow() - sPreference.getLong(PREF_KEY_LAST_ACTIVE,0);
}
private static long timeNow(){
return Calendar.getInstance().getTimeInMillis();
}
#Override
public void onCreate() {
super.onCreate();
sPreference = getSharedPreferences(PREF_ID_TIME_TRACK,MODE_PRIVATE);
}
}
Add Application class to manifest: <application android:name="com.example.MyApp"
Place saving functionality in an abstract Activity class:
public abstract class TimedActivity extends Activity {
#Override
public void onUserInteraction() {
super.onUserInteraction();
MyApp.saveTimeStamp();
}
public long getElapsed(){
return MyApp.getElapsedTime();
}
}
Now, extend all your activities from this class, all of them will be auto-save time, and will be able to use getElapsed().
Related
I need to create a session and change it at times. In a specific activity should recover it and compare it to a different variable and modify the value of this session. I tried to create a class for this, but the change of activity, the value back to null. I need it to remain until the application is closed.
below:
import android.app.Application;
public class Util extends Application {
private static String idCorrente;
public void onCreate() {
super.onCreate();
idCorrente="0";
}
public static String getIdCorrente() {
return idCorrente;
}
public static void setIdCorrente(String id) {
Util.idCorrente = id;
}
}
I do not know exactly the right way to do it.
You need to store the data on the device somehow. I would recommend reading the Storage Options page of the Android Developers Guide.
Specifically, I think you will find SharedPreferences well-suited for your application.
The problem is that when accessing TaskTimerApplication.TEST from the activity, it is still "Creation", but in the service it is "Modification" like it should be. I have already made 100% sure that my service is executing its code before the activity is accessing the data. Below is a simple test scenario that presents the problem in a more obvious way.
Application code:
public class TaskTimerApplication extends Application {
// Static properties
private static final String TAG = "Application";
public static final boolean DEBUG = true;
public static String TEST = "Declaration";
#Override
public void onCreate() {
super.onCreate();
TEST = "Creation";
Log.v(TAG, "Created");
}
}
Service code:
public class TaskService extends Service {
public static final String TAG = "TaskService";
#Override
public void onCreate() {
TaskTimerApplication.TEST = "Modification";
Log.d(TAG, TaskTimerApplication.TEST);
}
}
My full, non-test code can be seen at my GitHub project. In the full code, the TASKS ArrayList stays empty in the activity, but is properly filled in the service.
Your problem lies in your manifest:
<service android:description="#string/service_description" android:name=".TaskService" android:label="#string/service_label" android:process=":TaskService"></service>
There is usually no good reason to waste RAM and CPU by putting your service in a separate process. Moreover, if you do put the service in a separate process, then your activity and your service will not be in the same process and therefore will not share a common Application object instance.
My recommendation is to drop the android:process attribute.
I have a settings menu in my app which controls the units used throughout the app - metric or US units. So when the user selects one of these in the options in the menu, I want my app to use the chosen units throughout in display and calculations.
I plan to do this by storing a boolean in sharedpreferences, then check the value of the boolean every time an activity is opened, and then make the appropriate changes.
Is there a better method to go about doing this?
Thanks
Yes you can extends Applications class and store your data over there using Getter and setter.
So that your data will be retained throughout the Application.
public class SocketManager extends Application {
private static SocketManager singleton;
public int mBluetoothState;
public synchronized static SocketManager getInstance(Context context) {
if (null == singleton) {
singleton = new SocketManager();
}
return singleton;
}
public synchronized void setState(int state) {
mBluetoothState = state;
}
public synchronized int getState() {
return mBluetoothState;
}
}
Access it in Activity like :
SocketManager socketManager = SocketManager.getInstance(this);
socketManager.setState(10);
socketManager.getState();
Add your Application to Maanifest file like this :
<application
android:name=".SocketManager"
android:icon="#drawable/first_aid"
android:label="#string/app_name" >
<activity .... />
</application>
Edit :
You should add your class name that extends Application into Application Tag not on Activity Tag
For further refrence check this link
You can have a look at Android Storage options: http://developer.android.com/guide/topics/data/data-storage.html
However, it seems like for your case SharedPreferences is OK
For just a boolean? If its just a single activity calling SharedPreferencesand assigning it would be fine.
If you have multiple activities in an application you could call it once and load it into a static class and call it that way or subclass the Application class.
But even then it's just a boolean and you should do whatever is most convenient for you.
So my problem is as follows: I have 2 services running in different processes and would like to keep it this way. One is busing data from databases to bound applications and the second is polling for incoming data through sockets. I feel keeping these in independent process would be better. The problem is that I would like to have a shared preferences between the two services and would like to implement OnSharedPreferenceChangeListener to update setting needed for polling and busing data. I can't implement OnSharedPreferenceChangeListener in the services since they run on different processes. I could implement this on the PreferenceActivity but how do I communicate to the services for immediate update? I do not want to use AIDL and worry about binding. There is the possibility of creating broadcast receivers and sending out intents but these seems like a big work around if the settings menu grows. Any other great ideas out there?
all right here is your answer...
for the preference of this example lets take 3 classes - 2 services service A and B (href A,B) and Settings(preferenceActivity)
initialize the two services as
public class ServiceA/B extends serice implements OnSharedPreferenceChangeListener{
#Overside
public void onCreate(....){
Settings.getPrefs(this).registerOnSharedPreferenceChangeListener(this);
}
#Override
protected void onResume() {
super.onResume();
Settings.getPrefs(this).registerOnSharedPreferenceChangeListener(this);
}
#Override
protected void onPause() {
super.onPause();
// Unregister the listener whenever a key changes
Settings.getPrefs(this)
.unregisterOnSharedPreferenceChangeListener(this);
}
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
System.out.println("++"+key+"++");
if(key == "KEYA"||key == "KEYC")
Do_what_ever_you_want();
if (key == "KEYB")
do_anything();
}
do_anything(){}
Do_what_ever_you_want();
}
Shared preference Part.
public class Settings extends PreferenceActivity implements
OnSharedPreferenceChangeListener{
public static final String PREFS_PRIVATE = "PREFS_PRIVATE";
public static final String MASTERKEY = "!##$%^&*";
public static final String KEYA = "KEYA";
public static final String KEYB = "KEYB";
public static final String KEYC = "KEYC";
--- the create and get methods for getting and sharing data in the prefs... .....
// get them from just a google search.
}
I have this system implemented in one of my applicaiton... and deployed... so fiddle around these basics and let me know how it is goes...
Rajesh...
I've created a simple SharedPreferences based on ContentProvider, which can be used accross processes, you can find them from my bitbucket https://bitbucket.org/ABitNo/zi/src/783b6b451ba1/src/me/abitno/zi/provider/preference
If I initialize some static objects in an activity and then call finish(), do those objects still exist elsewhere in the application? Like say I want to access them later on in a service.
If not, are there any other solutions where I could initialize some static objects one time that other classes will have access to?
Yes, doing that is possible. But for the static objects to continue to exist, there should be at least one Activity/Service in the application to be running. What I normally do for such variables is to create a class to hold static methods and variables. Something like this:
public class Utils
{
public static String s;
public static int i;
public static initStatics()
{
s = "";
i = 0;
}
}
This you can call from your other Activity/Service like this:
public class CustomService extends Service
{
#Override
public void onStart()
{
Utils.initStatics();
}
}
So, these variables will be available as long as your app is running. Hope that helped. Good luck!
For things of that nature you can use static member variables on the Application object. You will have to clean up manually (since onDestroy is never called), and you will need to make sure there is at least one Activity/Service in the application running to prevent the app's process from being destroyed by the OS.