I did a major rewrite of my application to support fragment. I also took this opportunity to rewrite a bunch of code to make it more stable, cleaner, more maintainable, etc.
We pushed the new version on the Play Store. Unfortunately, some users complained that they had to clear the cache and the application data for the new version to work. Unfortunately, I don't have more information (as I can't contact these users). Clearing the cache and the data seems to fix the problem. I have no idea if the problem is that the app crash at startup. Or if the app start, but then is stuck in a endless loop.
We use Bugsense to have automatic bug reports. I've looked at them, but I can't seem to find the cause of the problem.
I'm curious as to what is stored and where. My app uses the "context.getExternalCacheDir()" to store images downloaded from the web. I store data in preference files, as well as in the SQL database. Before releasing the app, we had an internal QA to make sure the app upgrade was working perfectly. And most of our users don't have this problem.
What can I do to try to pinpoint the cause of this issue?
Related
I'm trying to use the Firebase Storage for images in my app. What happened was I wanted to change the name of my app as I've changed my mind on what the name will be, and so respectfully I updated the Firebase Console Project.
Corresponding name spaces were updated. After the rename of the app project I wasn't able to download the google.json file anymore. Even after deleting the entire project, and starting from scratch the google.json just wouldn't download kept saying there was a problem with the server.
There is another question with this inquiry, but it didn't have a single issue after upgrading to the new Firebase, and the question that is regarding this is specifically about having been upgraded . It took some learning, and there still isn't as much documentation as I'd like. For example, the FirebaseUI (ListAdapter) and such. Would solve a lot of my current issues in regards to handling data being moved, updated, deleted, etc.
Is there any way to know if this specific bug issue has been reported? Is it a known issue, and is there a possible timeline? I plan to scale the app once I launch and am afraid to do so as once I do. I will be upgrading the plan to the $25 plan for better simultaneous connections.
Any help would be graciously appreciated.
UPDATE
Since a few days ago I was able to download the google.json file. That is great! However, the issue still remains. I cannot use the Storage, and it's giving the same error as the attached image.
Also, I have submitted a ticket with Firebase Support. Communicating with Firebase Support currently via email. Will post updates as I have them.
This is my first questions on SO, but I would first like to thank the community for helping me along the way in creating a few Android apps. I am not a programmer by profession, and most of the stuff I make is just for fun, but one Android app is a real project that I created for a client, and I've run into some real trouble and need some help.
The app I made basically takes in some data, stores it into an SQL database, and when necessary, uses queries to pull various information from the DB, and displays it. If any adjustments need to be made, I make them and just send them another .apk. No problem, until now...
I recently upgraded to Windows 10, doubled my laptop's RAM and replaced my hard drive with an SSD, and did a refresh of the OS. Everything, including Android Studio, runs like a dream now!!! I had a request from my client to make a few adjustments, so I recopied my backed up source code to my projects folder, opened the code, made the modifications, and resent the .apk to my client. They are getting the following message:
"X App not installed.
An existing package by the same name with a conflicting signature is already installed."
The only changes I made to the app were adding a table to the database (and upgrading the DB version number, of course), and modified some layouts and a couple of methods and calculations, etc. Nothing more. I have searched up and down and have even replicated the same error on my tablet and can't find a way around it. My client currently has a few months worth of data input into the app, so they can't just uninstall it and do a new app installation. Is there anything I can do at this point? Also, I never made any custom key signature, just programmed, made .apk, and have sent numerous updates without issue. Any help would be greatly appreciated. (I have all my project folders and .apks backed up for all the different versions that I have sent)
Thank you!
Your best bet at this point, assuming you can't find/get the original key, is to use a backup program (or adb pull worst case) to backup his /data/data/ folder. Then you can uninstall the original app and reinstall the new version. Then you can restore/adb push the old folder's contents to the phone to restore the data files. This may require rooting it.
If possible I would test this on another phone first, to make sure it works, since you only get 1 shot at this. I would also save your key in your source control repo in the future.
I was just wondering the same when try to update from PlayStore.
Generally, say for Windows, when it is updated, downloads the files and patches them. From size perspective, these are significantly small compared to its setup which is around 3.5 GB.
So why its not applicable for ANDROID apps? E.g. any update to WhatsApp is almost equivalent to its original setup file (~18 MB).
Although Play Store calls them updates, you actually download the whole Android app again. In a way, it's still an update because you do actually upgrade to a newer apk version but not quite the way you would've liked. It's taxing on your bandwidth but it's easy.
However, your app's settings (shared preferences) and data (SQLite databases or custom files) survive this update/install process which won't be the case if you manually uninstall & install the app's new version again.
In cases where the app's database schema has evolved between the two versions, Android notifies the app on startup that it wasn't a fresh install by calling a life cycle method onUpgrade() where the app has a chance to upgrade its data left over by the previous version.
When you compare this with Windows, both the OS and the update server are from Microsoft and they must have worked together to figure out what needs to be pushed (.dll, .ini, .sys etc.), update bundle's format/compression and security implications (some sort of encryption to prevent malware injection by any one intercepting the traffic).
No such standard update mechanism has been made available by Google for the Play Store see update and I believe so is the case with every other app store. Obviously, the developers can't roll out one on their own since the updates are handled by Google both at the device and server side.
But, the developers are certainly not unhappy about it. It's much more convenient to test the new apk, see it working and uploading the same rather than fiddling with what changes to push and breaking the app if you miss something. The bandwidth is cheap anyway.
I've just recently discovered that at Google I/O 2012 Google announced that they were working on a Smart Updates technology using some delta encoding algorithm. The idea was to compute the DIFF between two APKs (sort of like we do for text between two source code files), create a patch on the server-side and only send that over the wire.
This feature went live on Play Store later that year as reported by AndroidPolice and TechCrunch.
Developers, Google said at I/O, won’t have to do anything to enable
this feature and according to the folks over at Android Police, this
feature quietly went live late last night or early this morning.
You can see it in action in this video. Notice how the apps start installing once the progress bar hits just 40-50%. This is absolutely brilliant because not only this saves Google terabytes of bandwidth, its pure server-side approach means developers don't have to fiddle with anything. Perhaps, that's the reason it finds no mention on the android developers site and so takes time to get discovered.
With that said, my personal experience seems to coincide with yours. I see most of my app updates download almost the whole of the app. Maybe it's because I don't download very frequently. It's not unusual for me to skip several minor revisions and perhaps the app changes far too much to derive any size benefits out of the patch generated.
There is nothing like an "update" for an Android app. It is always a full app. It is called update, because it is a new version of the app currently installed in a device.
But when it is an "update" the whole app is not fully downloaded. For many years the Google Play downloads just parts of the app and patches the currently installed app with the difference. So in the case of 20MiB the Google Play can download just few megabytes to reconsctruct the new version in a phone. Google calls is Smart App Updates or something like that.
I need to increase the security of my android app. Actually my android app. will not be for Google play Store (which provides some licensing options to protect your app.) it will be used for some local companies that used the same app (Desktop app). However, I want to support two versions for my app. which are:
Demo version: for testing aims (after the given period end, the app will stopped!)
Actual version: this if the user want to pay for the app.
What I need:
To increase the security of my app. from installing it another time or on another device for the same user!
For my code I used ProGuard which is a tool provided by Android that lets you obfuscate (make harder to read) your code during packaging. cause there are many reverse-engineering application that used for unpacking the compiled code and viewing the source code (actually I tried some of them and its really amazing to restore the sourse code from .apk!) ..
I think to use the MAC address of each device the app. installed on and then store it into internal database and generate a number form it (in somehow), then ask user enters it (which I the one who knows this number and provider for it) if it is true, the app run else not. But, it's just idea I do not know how this can happen or even from where I can start or even also if that will help!
I tried also SharedPreferences But this does not help!
Actually I do not need for external database on server to read the username or the password for eligible users for app. I need to do that by my app. itself!
In sum please,
How can I protect my app from installing many times for same user or continuing using after testing period ends, etc. (I mean make it more secure)!
any ideas, any suggestions, any useful examples or sites are also desirable.
Sorry for this long question,
We have an application, that can itself be downloaded for free, but works with paid, licensed data. Some users buy particular version of the data while others buy right to use latest data for some period of time. Now as the application evolves, it eventually stops supporting data older than some date. So obviously users who have those data licensed, but no license for newer data don't want to upgrade. But if we publish new version on the market, they would see it and if they upgrade, they will have trouble downgrading back to version that actually works for them.
So can we somehow instruct the market application not to offer upgrades for particular user or some hack to achieve that end?
We currently use mechanism completely independent on the market to sell and check licenses for the data, but could consider different mechanism (like the android in-app billing support or something) if it could help solving the problem.
The way I see it, you have two options to "disable" upgrades:
Use a different signing key - this will prevent installation without removal of the previous app, but upgrade notifications will still appear (I think)
Use a different package name - this will prevent upgrades since it is a completely separate app so far as the market is concerned, and also has the side-effect that old versions are still available for those users who are licensed for that data version.
The second option may be a better match since you can roll out upgrades if necessary for bug-fixes, but can also ensure that wholly new versions are not detected as an upgrade.
EDIT:
Totally agree that the above options are cumbersome and don't really solve the issue as-is.
As you mentioned however, you could use in-app billing, but given the nature of your requirements, you'd have to use unmanaged purchases which means you'll need some infrastructure to manage authorising purchases and preventing people from buying the same license too many times.
I'm guessing you've already got much of that infrastructure in place to handle distribution of the data though.
Can the data not contain a "format version" number at the start of the file?
Then you can program the app to read version 1 files, a new app needs more fields on the data source, so you create version 2 data, which adds extra fields, version 1 app see's the data needs a newer app, so tells the user to upgrade.
Version 2 app should know how to read version 1 files and version 2 files (perhaps create a reader Interface and implement loaders for the different versions of files.)
You'll have to handle the missing data in v1 / old files in the loader in the v2 app. The loading of older files is the nicest way for the customer as the app shouldn't just stop working after an upgrade.
If you keep a copy of each format's data you can quickly run tests to check the new version's loader can load each file correctly, plus if the app has a bug in there you won't have to fix several app versions, just the current one.
Ok.. I saw one of the posters suggest you have a way to read the old data.
First that's likely the best option but as you say your apps a mess.
You should invest some time in migrating your data reading/writing to an abstraction layer. The pain your having on a (likely less than 4 year old project) is only going to get worse.
Okay.. so here's how I've dealt with it in long lived apps..
Create a migration path.. Create a new class call Migrate.
In it have several functions to convert the version of the file from n to n-1
convert_1_to_2(fileName){check the version and upgrade data.)
convert_2_to_3(fileName)...
I suspect you have your old code, and you could write a method to convert one bit of data to the next..
When you add new features to the data, then you create a new convert.. No knowledge of the earlier ones would be needed, and everything would be nice and self contained.
You could even have sub migrations, so part way along the dev cycle, you could have convert_3a_to_3b.
Now... you could archive the original version of the data in case the user wants to go back.
If the data is accessed remotely, you could have the app include the version, or some hash of itself, when requesting it. And then filter the data provided based upon that information.
If you already have in-app purchasing and the infrastructure to support it, just poll for new data when the app is upgraded. If the user has purchased the license for current data, provide it. Otherwise just continue using the existing data.
I came up with an option that market will contain an installer that will download and install another .apk containing the core of the application locally.
We already have an installer dialog in the application for downloading the data and user has to enter it when using the application for the first time, so it can be made responsible for the application core too.
You can not definitely prevent users to download the new version of a app they already have. You can either register a new app or check the version and user data programatically.