I have developed an application which makes use of a toggle button to decide the enabling/disabling of my app. I store the toggle button state as a static variable so that it retains it value on stop and resume. However on a reboot, the static variables will be reinitialised into its default state. Is there any way I can get my app to resume its state even after a reboot?
Specifically, what my app does is that on toggle On it enables a "Service". SO I want that service to be started automatically on a phone reboot. Is that possible?
Thanks
save the variables in SharedPreferences
see how it works, http://developer.android.com/reference/android/content/SharedPreferences.html
then on start of your activity just restore them
not so important but if youre using toggle you may save boolean
tutorial: http://www.vogella.com/tutorials/AndroidFileBasedPersistence/article.html
GL
EDIT: on other Q about services, well dont really know what you made so far but maybe this: Android -Starting Service at Boot Time can help, if not provide some code what you made.
Well,that's possible when you your app starts as the phone reboots.Service will be called via main activity.
You can start the app as soon as the phone boots via a broadcastrecievir which looks like this .:-
public class BootUpReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
This needs to be added in AndroidManifest as :-
<receiver
android:name="com.example.xyz.BootUpReceiver"
android:enabled="true" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
Store your variable into SQLite or SharedPreferences. Then restore it's state on Activity restart.
You can store your variables into sharedpreferences, this will be much easier
http://developer.android.com/reference/android/content/SharedPreferences.html
// to save it
SharedPreferences.Editor editor = getPreferences(MODE_PRIVATE).edit();
editor.putString("your_key", "your_value");
editor.commit();
//to retrieve it back
SharedPreferences prefs = getPreferences(MODE_PRIVATE);
String your_value= prefs.getString("your_key", null);
Related
I need to clear(equivalent to Clear Data in App Settings) all the old data in the app programmatically when the user updates the app from Google Play Store or any other sources. This is because I don't need any of the existing data from the old app since I have changed everything in the new app compared to the old one.
I thought of implementing a version check at the app startup, but I can't find a way to get the app's previous versionCode or versionName. The only way I figured out to clear the data is to check the lastUpdateTime at the time of publishing the app. But it's not reliable since the user has other ways or sources of getting the app (like sharing it with a friend or if the user had a backup of the old app).
Any Suggestions?
You can store versionCode in SharedPreferences and compare with current versionCode
For clear all data you just need to clear all value of SharedPreferences, Local Database and all local files which you have store.
public void clearData()
{
try {
PackageInfo pInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
int mCurrentVersion = pInfo.versionCode;
SharedPreferences mSharedPreferences = getSharedPreferences("app_name", Context.MODE_PRIVATE);
SharedPreferences.Editor mEditor = mSharedPreferences.edit();
mEditor.apply();
int last_version = mSharedPreferences.getInt("last_version", -1);
if(last_version != mCurrentVersion)
{
//clear all your data like database, share preference, local file
//Note : Don't delete last_version value in share preference
}
mEditor.putInt("last_version", mCurrentVersion);
mEditor.commit();
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
Note : Don't delete last_version value in share preference.
You can simply use a PACKAGE_REPLACED receiver which gets fired whenever a package is replaced in your phone (also happens when updating an app). Declare it in your manifest:
<receiver android:name=".UpdateReciever">
<intent-filter>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
<data android:scheme="package" android:path="com.my.app" />
</intent-filter>
</receiver>
And add your receiver class. onReceive will get called when the app is updated:
public class UpdateReciever extends BroadcastReceiver {
#Override
public void onReceive(Context con, Intent intent) {
}
}
EDIT: you don't need to filter the package. Use MY_PACKAGE_REPLACED instead which will fire only for your app.
You can listen to a system broadcast with following intent and filter in onReceive with your package name to see if your app is updated.
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REPLACED" />
<data android:scheme="package" />
</intent-filter>
What I originally had: a launcher activity with a button which would launch my main activity. The launcher activity had shared preferences so it would only show up once. However, I have added a new activity that when the user clicks the button on the launcher activity, a introduction page is to appear. However due to shared preferences on my launcher activity, that introduction page does not show up.
So is there any way to clear the user's data on update? Just for this update, When a user updates my app, I want this to run:
SharedPreferences settings = getActivity().getSharedPreferences("cda-preferences", Context.MODE_PRIVATE);
settings.edit().clear().commit();
Is this possible?
Yes, you can define a BroadcastReceiver for the MY_PACKAGE_REPLACED action. In this receiver's onReceive method you should clear the flag in the shared Preferences. (API12+)
<receiver
android:name=".OnUpgradeReceiver"
android:enabled="true" >
<intent-filter>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>
</receiver>
Or you should save the version of your app (to the shared prefs). When the user launches the app you should check what was the previous one and if its newer, show the introduction page.
I'm developing an Android app which requires the user to be logged in (actually, at the moment they just need to supply a username as no authentication is required... this will change in the future though).
I've managed to implement this, but I'm not sure if it's the best way. I have a LoginActivity which I have declared in the manifest using android:noHistory="true" and:
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
In LoginActivity's onCreate method, I check for a Boolean value isFirstStart stored in SharedPreferences. If the value does not exist, it must be the first start of the app, so I let LoginActivity set everything up, perform the login, and then launch MainActivity using:
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
intent.putExtra(MainActivity.EXTRA_ISFIRSTSTART, isFirstStart);
startActivity(intent);
I use the extra so that I can open the navigation drawer in my main activity if it is the first start. At this stage I also store the Boolean value as false in SharedPreferences.
If isFirstStart already exists as false, I perform the launch of MainActivity straight away using the same method.
To me, this somehow doesn't seem like the most efficient method - launching LoginActivity on every startup even though it will not be used most of the time.
Any thoughts?
I need my android app to be in background mode after a phone restart/power on.
Currently I am using the following code, so that my app successfully gets launched after a phone restart/power on.
AndroidManifest.xml:
<receiver android:enabled="true" android:name="my_package.BootUpReceiver" android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
BootUpReceiver.java:
public class BootUpReceiver extends BroadcastReceiver
{
private static SharedPreferences aSharedSettings;
#Override
public void onReceive(Context context, Intent intent)
{
aSharedSettings = context.getSharedPreferences("MyPreferences", Context.MODE_PRIVATE);
boolean isUserLoggedIn = aSharedSettings.getBoolean(Key.AUTHENTICATED, false);
if(isUserLoggedIn)
{
Intent aServiceIntent = new Intent(context, MyHomeView.class);
aServiceIntent.addCategory(Intent.CATEGORY_HOME);
aServiceIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(aServiceIntent);
}
}
}
As I said above, my app successfully gets launched after a phone restart/power on.
However, after the phone restart/power on, my app was in foreground mode. But I need my app to be in background mode.
Can anyone please say, how to make an app to be in background mode after a phone restart or power on.
I even tried by changing the intent category to
<category android:name="android.intent.category.HOME" />
But no use in it. Can anyone please help me?
Thanks.
I need my app to be just running in background after the phone restart, so that users can select from the minimized app
I think your approach is wrong. All you are trying to do now is to add icon of your app to recent apps list. Your app won't run in background and I think you don't really want it. Am I right?
Recent apps list managed by android and IMHO forcing your app to be in recent apps list is not a very good idea. User will start you app when he wants from launcher or icon on his desktop.
If your broadcast receiver is working fine and app is starting successfully then you can use the below code in your MyHomeView activity's onCreate method to go to the home screen.
Trick is to click HOME button programmatically when app starts.
Intent startMain = new Intent(Intent.ACTION_MAIN);
startMain.addCategory(Intent.CATEGORY_HOME);
startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startMain);
you can pass some variable from the BroadcastReceiver to differentiate a normal request and BroadcastReceiver's request to make the above code conditional.
But if you want to execute it always in background then it would be better to use Service.
It is recommended to change your code to the service to run it in background.
The suggestion which Leonidos replied is correct.
However, Just a workaround for this:
In my BootUpReceiver, I had a seperate boolean flag for this! (Its a bad way. but just a workaround)
SharedPreferences.Editor aPrefEditor = aSharedSettings.edit();
aPrefEditor.putBoolean(Key.IS_DEVICE_RESTARTED, true);
aPrefEditor.commit();
In Oncreate method of MyHomeView:
boolean isDeviceRestarted = aSharedSettings.getBoolean(Key.IS_DEVICE_RESTARTED, false);
if(isDeviceRestarted)
{
SharedPreferences.Editor aPrefEditor = aSharedSettings.edit();
aPrefEditor.putBoolean(MamaBearKey.IS_DEVICE_RESTARTED, false);
aPrefEditor.commit();
moveTaskToBack(true);
}
Thanks
I want to create a new file in sdcard when the apk is installing...
How or where should I code?
Thanks in advance!
You definitely can not do that. That would introduce all kinds of security concerns. As Ken Y -N said in his answer, the best thing to do would be to detect the first time that your app is opened, and do something there.
Here's an activity class to do this:
public class StartupChoiceActivity extends Activity {
private static final String TAG = StartupChoiceActivity.class.getSimpleName();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences mPrefs = getSharedPreferences("prefs", Context.MODE_PRIVATE);
if(!mPrefs.getBoolean("has_started_before", false)) {
// Do what ever you want to do the first time the app is run
} else {
//Remember our choice for next time
mPrefs.edit().putBoolean("has_started_before", true).commit();
Log.i(TAG, "We've already started the app at least once");
}
//Do what ever we want to do on a normal startup. This is pretty much always mean starting a new activity
startActivity(new Intent(this, MyNormalFirstActivity.class);
finish();
}
}
The only other thing you need to do is make sure this activity is set as your 'Startup' activity in the AndroidManifest.xml. You can do this by putting this code inside your application tag:
<activity android:name=".StartupChoiceActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
You cannot do that; such a feature would be a good way of getting trojans to propagate, for instance.
Just check for the first run of your program and do the initialisation there.