Android: How to reset FirstRun SharedPreferences when my app is updated? - android

My app copies files over from res/raw to the sdcard on first run. I want it to update those files on every subsequent app update. How can i have it reset the firstrun preference to true on every app update?
Here is the relevant code:
/**
* get if this is the first run
*
* #return returns true, if this is the first run
*/
public boolean getFirstRun() {
return mPrefs.getBoolean("firstRun", true);
}
/**
* store the first run
*/
public void setRunned() {
SharedPreferences.Editor edit = mPrefs.edit();
edit.putBoolean("firstRun", false);
edit.commit();
}
SharedPreferences mPrefs;
/**
* setting up preferences storage
*/
public void firstRunPreferences() {
Context mContext = this.getApplicationContext();
mPrefs = mContext.getSharedPreferences("myAppPrefs", 0); //0 = mode private. only this app can read these preferences
}
public void setStatus(String statustext) {
SharedPreferences.Editor edit = mPrefs.edit();
edit.putString("status", statustext);
edit.commit();
}
}

In my app, I save in my shared preferences the version code of the app. At every startup, I check to see if the saved version code is lower than my current version code. If it is, I show a "what's new" dialog.
Give this code a whirl - I use it in my main activity's onCreate:
PackageInfo pInfo;
try {
pInfo = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_META_DATA);
if ( prefs.getLong( "lastRunVersionCode", 0) < pInfo.versionCode ) {
// TODO: Handle your first-run situation here
Editor editor = prefs.edit();
editor.putLong("lastRunVersionCode", pInfo.versionCode);
editor.commit();
}
} catch (NameNotFoundException e) {
// TODO Something pretty serious went wrong if you got here...
e.printStackTrace();
}
prefs is a private SharedPreferences object. This works if it's truly the first run, and for upgrades. At the end of the first-run code, the editor.putLong updates your shared preferences with the current version code of your app so the next run doesn't trigger your first-run code.
This also benefits from the fact that your version code must increase for the app to be seen as an upgrade by the market, so you don't need to remember to change a separate value to detect the first-run.

You could mimic what's done on the database side, with version numbers. Instead of having just a firstRun variable, have a couple with firstRun and versionNumber, and put a static version number field in your app, that you increment at each release. This way, you'll be able to check if the app has been updated, and do your operation on each update.

I'm create class for this; download in https://gist.github.com/2509913
Example Use:
long versionInstalled = App.getVersionInstalled(this);
long current_v = App.getVersion(this);
if( versionInstalled != current_v ){
Log.w("TAG", "Veresion not valid");
}

Run this in the MainActivity's OnCreate
public void onUpdateFirstRun () {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
PackageInfo pInfo;
try {
pInfo = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_META_DATA);
Log.d("VersionCode", pInfo.versionCode + " ");
if (prefs.getLong(LAST_RUN_VERSION_CODE_KEY, 0) < pInfo.versionCode) {
if (!isInitializedInSP(KEY)) {
editor.putString(KEY, "");
}
//Finalize and Save
editor.putLong(LAST_RUN_VERSION_CODE_KEY, pInfo.versionCode);
editor.apply();
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
}
Use method to check if you had already initialized it in previous version
public static boolean isInitializedInSP (String key) {
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContex());
Object o = mPrefs.getAll().get(key);
if (o != null) {
return true;
}
else {
return false;
}
}

Related

Run Service only when on Wifi if user wants to

I made an app whos purpose is to download and set wallpaper in set intervals.
User can choose to do that only when connected to wifi or not.
Relevant code:
mWallpaperButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mSwitchWifi.isChecked()) {
mConnectivity = mConnectionDetector.isConnectedToWifi();
} else {
mConnectivity = mConnectionDetector.isConnectedToInternet();
}
if (mConnectivity) {
my code here
}
The code above works fine for setting the wallpaper the first time.
My problem is, I need the Service to check if the user wants to update wallpaper only over WIFI before doing so. At the moment, wallpaper is updated regardless of mSwitchWifi state. (which is bad, because it can use mobile data and user sometimes doesn't want that.)
I tried running similar Switch code in Service but I can't because it must be called in a UI Thread.
I also tried couple of workarounds and Intent.putExtra but I get exception:
NullPointerException: Attempt to invoke virtual method on a null object reference
Any idea how to check network state in service?
My service code atm:
public static class Service extends IntentService {
public Service() {
super("wallpaperchanger-download");
}
#Override
protected void onHandleIntent(Intent intent) {
if (url == null) {
SharedPreferences sharedPreferences = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
String getUrl = sharedPreferences.getString(pref_urlKey, null);
if (getUrl != null) {
url = getUrl;
}
}
wm = WallpaperManager.getInstance(this);
try {
InputStream input = new URL(url).openStream();
Log.v(TAG, url);
wm.setStream(input);
input.close();
} catch (Exception e) {
e.printStackTrace();
}
loading = false;
Log.v(TAG, "Service Running Url " + url);
}
}
If you question is how to access the user selection inside a service/runnable/thread then you can use shared preferences to achieve this. So in your case when the user selects the choice for the first time you want to do something like this:
if(mSwitchWifi.isChecked()) { // i guess this is no wifi
SharedPreferences sharedPreferences = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
Editor editor = sharedPeredences.edit()
editor.putBoolean("isWifi", false)
} else { // guessing this is wifi
SharedPreferences sharedPreferences = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
Editor editor = sharedPeredences.edit()
editor.putBoolean("isWifi", true)
}
This is this code to check if it is true or false:
mWallpaperButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Boolean isWifi = isWifi()
if (!isWifi) { // i guess this is if not wifi
mConnectivity = mConnectionDetector.isConnectedToWifi();
} else if (isWifi) { // guessing this is wifi
mConnectivity = mConnectionDetector.isConnectedToInternet();
}
}
}
public Boolean isWifi() { // you can call this inside your service
SharedPreferences sharedPreferences = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
Boolean wifiState = sharedPreferences.getBoolean("isWifi", true)
return wifiState;
}
This is just a very rough implementation to give an idea of how you can do it, you can improve this many ways. For example you could put the if statement thats inside the onClickListener in the isWifi() function and just call isWifi() inside your runnable/thread...
you can set list preferences to auto update functions based on the network ....
You can create separate class to check the connectivity and from that class you can select the preferences like auto update only on wifi or when connected to network or do not auto update ....

Create a function that fires only once after app is installed on phone

I'm developing a mobile app using ApacheCordova/Phonegap.
I need a function that sends a SMS to me once per install. If I put my function on "DeviceReady" it will be run each time the app opens.
Is there any solution for a function to be run when app is installed OR when it runs for first time?
Any suggestion would be appreciated.
Check if it is the first time with a method and then perform the action if that method determines that it is the first time.
Ex:
isFirstTime() Method
private boolean isFirstTime()
{
SharedPreferences preferences = getPreferences(MODE_PRIVATE);
boolean ranBefore = preferences.getBoolean("RanBefore", false);
if (!ranBefore) {
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("RanBefore", true);
editor.commit();
// Send the SMS
}
return ranBefore;
}
You may want to add it to your onCreate()
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
topLevelLayout = findViewById(R.id.top_layout);
if (isFirstTime()) {
topLevelLayout.setVisibility(View.INVISIBLE);
}
I added a field to the localstorage and on startup just check if that field exists. So something like this:
if (window.localStorage.getItem("installed") == undefined) {
/* run function */
window.localStorage.setItem("installed", true);
}
Edit: The reason I prefer this over the other methods is that this works on iOS, WP, etc as well, and not only on android
This should be what u are searching for:
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
if(!prefs.getBoolean("firstTime", false))
{
// run your one time code
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("firstTime", true);
editor.commit();
}
Use some boolean value if its true don't call that function other wise call that function example is here
if(smssent!=true)
{
//call sms sending method
}
else
{
//just leave blank or else notify user using some toast message
}
Note:-the boolean value store in some database like sharedprefernce or sqllite, files....

Get previous version code of app when installing new version programatically in android?

I want to get the previous version code of an application when new version of the application is being installed.
What i tryied:
I have implemented following class and it will get run when new version is being installed.
But i can only get the new version code.
public class VersionContraller extends BroadcastReceiver {
#Override public void onReceive(Context context, Intent intent) {
if(Intent.ACTION_PACKAGE_REPLACED.equals(intent.getAction())) {
if(intent.getData().getSchemeSpecificPart().equals(context.getPackageName())) {
try {
PackageInfo pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
int newVersion=pInfo.versionCode;
//I want to do some logic hear with older and new version of the application
} catch (NameNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
How can i get the previous version of the application inside above class?
AFAIK you can't do this very easely. You can use SharedPreferences in your code, like this:
String newVersion;
try {
PackageInfo pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
int intVersion = pInfo.versionCode;
newVersion = "" + intVersion;
} catch (NameNotFoundException e) {
// Put a version you want if exception is launched
newVersion = "something you want";
e.printStackTrace();
}
SharedPreferences sharedPrefs = this.getSharedPreferences("your.package.app", Context.MODE_PRIVATE);
String savedVersion = "your.package.app.savedVersion";
String versionOnSP = sharedPrefs.getString(savedVersion, "previous");
if (versionOnSP.equalsIgnoreCase("previous") && newVersion.equalsIgnoreCase("versionTarget")) {
// Your version is old; do some logic here with older version of the application
...
} else {
// Your version is new, do whatever you want
}
// After that, save your current version
sharedPrefs.edit().putString(savedVersion, newVersion).commit();
In this way, at the first launch after update you will be able to do some operation because you haven't save a version on SharedPreferences in previous release.
But it is not 100% safe, because user can delete data of your app, and after a re-launch of the app you will go directly on first if. Maybe my idea need an improvement.
EDIT (after bgse comments)
My code must be placed into the first if:
public class VersionContraller extends BroadcastReceiver {
#Override public void onReceive(Context context, Intent intent) {
if(Intent.ACTION_PACKAGE_REPLACED.equals(intent.getAction())) {
// My code here
}
}
}

SharedPreferences lost on force quit?

I've added the SharedPreferences functionality to my App to launch a specific activity once the App starts after it has been quited.
I use the following code to save the string:
final SharedPreferences pref1 = getSharedPreferences("myapp", MODE_PRIVATE);
SharedPreferences.Editor editor = pref1.edit();
editor.putString("Stringval", "view1");
editor.commit();
Then the following to load the last used activity, this code is below OnCreate
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final SharedPreferences pref1 = getSharedPreferences("myapp", MODE_PRIVATE);
String str1= pref1.getString("Stringval", null);
if(str1 == "view0")
{
setContentView(R.layout.activity_view0);
}
else if(str1 == "view1")
{
setContentView(R.layout.activity_view1);
}
else
{
setContentView(R.layout.activity_no_setup);
}
}
The code works if the user just quits the App, then relaunches it (Only tested it in the Simulator so far) but whenever I use the task manager to force quit the app like this:
The App just relaunches without using the SharedPreferences.
What's the reason for the App to not load the SharedPreferences or is this just a simulator bug?
You can write
if(str1 != null && str1.equals("view0"))
{
setContentView(R.layout.activity_view0);
}
else if(str1 != null && str1.equals("view1"))
{
setContentView(R.layout.activity_view1);
}
else
{
setContentView(R.layout.activity_no_setup);
}
try this, May be helpful for you......

Android: Update Dialog with share preferences

I'm trying to set up a dialog that will popup after the users updates or installs the application for the first time. I can't figure out how to exactly do this. Currently I have tried to use the package manager to get the users version and compare it to see if its the most recent. I'm uncertain if this will work as its hard to test for something that relies on a package update. Here is my code:
public void firstrun() {
String version = "";
String currenver = "3.9";
// update function
try {
PackageInfo manager = getPackageManager().getPackageInfo(
getPackageName(), 0);
version = manager.versionName;
} catch (NameNotFoundException e) {
// Handle exception
}
getSharedPreferences("PREFERENCE", MODE_PRIVATE).edit()
.putString(version, version).commit();
boolean firstrun = getSharedPreferences("PREFERENCE", MODE_PRIVATE)
.getBoolean("firstrun", true);
if (version.matches(currenver)) {
// Save the state
getSharedPreferences("PREFERENCE", MODE_PRIVATE).edit()
.putBoolean("firstrun", false).commit();
} else {
// Save the state
getSharedPreferences("PREFERENCE", MODE_PRIVATE).edit()
.putBoolean("firstrun", true).commit();
}
if (firstrun == true) {
new AlertDialog.Builder(this)
.setTitle("Welcome!")
.setIcon(R.drawable.icondialog)
.setMessage("UpdateText")
.setNeutralButton("OK", null).show();
}
}
I think you are on the right track, there are many solutions here and here that may give you ideas.
In addition you could create a database table that contains a flag to prompt or not. By default it would be set to a value to prompt, and then once the user launches and acknowledges the dialog you could change the flag. Then in your onUpgrade() method of your SQLiteOpenHelper you could flip the flag again, and thus your application would prompt on installation of a new version.

Categories

Resources