I am creating multiple apps and every app has same package so if I install one then it should overwrite the other, i.e. one of these apps can only be installed in the phone. This may sound weird but this is the way apps need to be. I have all the apps ready but I have this issue that I want to drop the table of database on every install, so if I install second app it overwrites the first one but the database is not deleted. I cannot change the VersionCode as I won't be able to overwrite with the older version so all apps have same package and same version code.
Basically it should ask for a password on every first run of the app, then I create a table and store it there that this user is authenticated, so for every new app this has to be done again but on update the table remains there which results in no prompt for password. Now how do i detect and drop the table from database. Even if I use sharedpreferences instead of database, they remain there on the update and I can't even detect if the app is updated as version code is same.
I will really appreciate if anyone can give me a solution or a hint.
Thank you,
Hamza Manzoor
You could store a seperate version value of the apps in the SharedPreferences and check the value in it against a list or numerical value and decide depending on the result.
You could also use Android's built-in version (not the nummrical value but the string value).
If you go for the SharedPreferences solution, you can use a kind of algorithm for the version value. Let's say one app is numbered "A", another "B" and yet another "C". You then append the app's real version to that, i.e. "A1.0" or "B2.4", ... (you get the idea). This way Android has no idea of what app is curretly being installed.
Whenever you start an app just check for the first value. If that is different from the app's normal value you know, it has been replaced. Otherwise check for the version value and see, whether you need to update the database or not.
// May I add:
Of course this is a possible source for bugs but if you are careful this should work. If someone has a better solution, please post.
Your app will not be overwritten\upgraded via Google Play mechanism in case they will have the same versionCode. Only via "adb install -rd" or some root-enabled side-loader.
IMHO, the right way to act is
increase versionCode and DB SCHEMA_VERSION on each upgrade as usual
in your DB class (which extends SQLiteOpenHelper) in onUpgrade() method you should check DB version and set some variable in Prefs accordingly, later in Activity you'll be able to fire a password dialog (open DB on onCreate(), check prefs on onResume()).
Related
I’m building app which consists on a test. It can be done only once, so I’d like to create a system which checks if the app has been opened before and if the answer is yes then it prevents to open it again. I was thinking to write a file inside the app as soon as the user open it the first time, so on the next startup I can check if it exists or not, but if the user deletes and reinstall the app it doesn’t work anymore. How can I improve this method?
Are you constrained to using local storage? Or can you use a cloud based solution?
If you can use the internet, you could just store device IDs or some other form of unique identification that is checked every time the application is opened. If the ID already exists in your remote store, don't open the app etc.
I am developing application for testing another application, in this application I am inserting/editing songs/playlists in android media storage. After many inserts/deletes app gets such error:
SQLiteConstraintException: UNIQUE constraint failed: files._id (code
1555)
...
Application is trying to remove all data (now it just removes all songs/playlists) from media storage before any insert, but seems that android saves some data in media storage (all songs/playlists are removed, seems it is some meta information with specified ID in different table), so I cannot add new song with specified ID (please do not ask why I am specifying ID of entities before inserting, it is needed for testing), only
adb shell pm clear com.android.providers.media
helps here. I tried to call adb shell pm clear com.android.providers.media on rooted devices directly from application, but unfortunately it is allowed only after user approves it in dialog, but this app should work automatically, so this way does not help.
Does anybody know a way to clear media storage from application at least on rooted devices?
If you are using Android Studio, then Tools/Android/Android Device Monitor, then click on File Explorer Tab. Could be easier.
I assume that you are aware that some app data is stored with the app in Data/Data/. This can be cleared via Settings/App//Clear Data. However, this would make it as though you have reinstalled the app, which is probably not what you want. I am pretty sure that the database would have it's data stored here by default (although I do believe that you can override this).
If you haven't you could perhaps look at some database managers Stetho for Chrome is perhaps one.
The UNIQUE constraints is saying something along the lines of. The files table has an issue when trying to add/insert a row and that is because the _id column is not unique. I think the norm is to allow the system to generate the id, perhaps the app isn't following this and is inserting with a calculated _id and it happens that the calculation method has a flaw.
Is it perhaps that deleting the underlying files has somehow caused the index number(s) to be re-used?
I have got a suggestion to restrict an Android application to be installed a limited number of times, let's suppose three times for a given user account. I have already inserted a form at the start of the application which checks for username and password from our database, and returns whether its valid or not.
Next I have to apply a trick to prevent this application from being installed more than three times by each user. I hope it clears what I am trying to do. Any ideas what to do and how to proceed?
By no means you can restrict user to not to install your application from google play.
Have a install_count column in the user table in your database. Each time the user fills out form, check for the install_count value, if it is equal to 3, then don't allow the application to continue, you can show a message like "max installs exceeded" and exit the app. Otherwise, increment the install_count value in the db for that user.
PS: As Zoombie said, you can't stop the user from installing the app, but you can restrict the user from running the application if installation limit exceeds.
Also you need to be aware, there are many apps which take a back up of the installed app and data that can be restored back anytime. More over, if the user changes his device more than thrice, he won't be able to run your application. So consider the drawbacks of this limitation.
Technically this isn't a very difficult problem but the issue of user relations will be difficult to manage. You should provide a simple and easy mechanism for your users to "reset" their install count. Additionally you need to inform your users of this restriction BEFORE they pay for your app.
Restrictions like this will result in problems in a few cases I can think of:
What happens if a user factory resets their phone and then re-installs the app?
What if the user installs a custom ROM or gets a new phone?
Are you going to deny a paying customer the ability to install an application that they paid for? Poorly enforcing a policy like this will only hurt you in the long run as it will result in
very bad reviews of your app
piracy of your app with the checks removed
Remember people are downloading/buying your app because it provides something to them and with that they assume that they'll always have access to your app. As soon as you start denying functionality or violating their assumptions you're going to start alienating your customers.
In the newer versions of Android (> 3.0) there is an onscreen button that
will display a list of the recent apps with their names and snapshots.
Even though my app itself is password protected, this overview might
show sensitive data in that snapshot. So is there any way to force a
certain image (like a logo) to be shown rather than let the OS decide?
It seems to be impossible for now. There's a method called onCreateThumbnail but it is not used currently by the system I guess, since it is not called. I see two possible solutions:
1. To disable thumbnail on the activity containing sensitive data by adding FLAG_SECURE to your window: getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
2. To exclude your activities from recent apps, set android:excludeFromRecents attribute to true for activities in AndroidManifest.xml
The solution provided by Azat continues to be valid also in Lollipop.
Just a note, if you want to continue to not see snapshots in recent list for the entire app, ALL the implemented activities should specify in the onCreate() method the flag getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE);
before setContentView();
Otherwise a snapshot in the recent list will show the first activity without the flag if the user navigated through it.
There is an approach to archive this requirement besides using that flag is HardwareKeyWatcher but it can not cover all of the cases due to fragmented device configurations and custom ROMs, then we have to fulfill missing cases with other approaches.
To ease the way of implementation, we had built a lib for Recent Apps thumbnail hiding mechanism, which supports implement a custom layout to show an empty screen with the app's logo when the app is going to Recents Screen.
I would like to upgrade my app to android market and some users have the old version of the app. What I want to do is in my new app, I want to run some codes to change a bit on the app database when the user do the update of my app, so how can I check if the user has the older version of my app in their mobile?
You should use a SQLiteOpenHelper-class to manage your Database (tutorial).
In your new App's version, you simple increase the version-number of the Database so the onUpgrade()-method gets called and you do your work on the Database.
I'd do the transformation the first time your code is run after the update: there's no need to do it any earlier.
And then I'd take the usual approach to this: once you've done the update, write some field to the database that indicates the current version. And when that field equals the current version then you know that no update needs to be done.
Well, if it's only the database you want to change take a look at SQLiteDatabase.onUpgrade. For more information look at IE http://www.barebonescoder.com/2010/05/android-development-database-management/
If it's not just the database I would use Preferences to keep a reference on which version the user has and if the user has run the latest update routine.