Is there any possible solution to "protect" the webview cache from the "Clear Cache" option in the default web browser. Any time I clear the cache completely I lose my app data, I'd like to preserve it.
Is there any possible solution to "protect" the webview cache from the "Clear Cache" option
No. That runs foul on the principal of "users over authors". That means the user controls their data, and not the authors of the web app. If the user wants to delete the data, then its gone. See the W3C's HTML Design Principals, Priority of Constituencies.
I think this is going to be a problem when (1) WebCrypto goes live because it means provisioning information, like keys and certificates provisioned by a bank or organization, and can deleted at any time; and (2) the document you created and edited with your word processor offline web app was accidentally deleted.
For (1), I think WebCrypto intended to try and solve it with some storage specification. But I think they found it was too difficult and offloaded it to another working group (web storage).
(2) is kind of solved with "cloud storage", but that moves data out of your control and into someone else's control. Its not just Apple back dooring their products...
Related
We'd like to have our web app available offline, mainly on mobile devices. We've written code for that, using a service worker. Application data is stored in an IndexedDb and the application code (html, js, css, etc) is stored in the SW cache. So far so good. We are aware that the user can delete the browser cache and our data, that's not a problem. But what about the browser itself wiping the app data ? We haven't found a comprehensive specification for that, the main info we found are:
1) the StorageManager feature that is currently marked as "experimental" (since 2016);
2) a short article from Google here about it (also from 2016).
The code sample is the following:
if (navigator.storage && navigator.storage.persist)
navigator.storage.persist().then(granted => {
if (granted)
alert("Storage will not be cleared except by explicit user action");
else
alert("Storage may be cleared by the UA under storage pressure.");
});
The Google article says:
When storage on the local machine is running tight (“under storage
pressure”), user agents automatically clear storage to make more
available space. Of course, for offline apps, this may be unfortunate,
as they may not have synced their data to the server yet, or they may
be apps that the user expects to just work offline (like a music
player); so the Storage spec defines two different modes for storage
for a given domain - “best effort” and “persistent”. The default mode,
of course, is “best effort”. Storage for a domain that is “best
effort” (aka “not persistent”) can be cleared automatically, without
interrupting or asking the user. However, “persistent” data will not
be automatically cleared. (If the system is still under storage
pressure after clearing all non-persistent data, the user will need to
manually clear any remaining persistent storage.)
...
Beginning with Chrome 55, Chrome will automatically grant the persistence
permission if any of the following are true:
The site is bookmarked (and the user has 5 or less bookmarks)
The site has high site engagement
The site has been added to home screen
The site has push notifications enabled
The permission is automatically denied in all other cases.
The goal is to ensure that users can rely on their favorite web apps
and not find they have suddenly been cleared.
That's for Chrome 55, let's suppose the information is up to date. A first glance, their goal sounds reasonable, but if you take a closer look the implementation is geared for "big" sites (à la Google) and not for niche applications that are more task-oriented.
Indeed, when testing on various Android phones on Chrome 80+, the persistence is always refused, with no user interaction. So, "best effort" it is.
We could have stopped the investigation here and called it a day. After all, current phones and PC are sporting ungodly amount of storage, and we only use a few hundred of KB, so we should be fine. Problem is, we're not: testing on a brand new flagship Android phone with Chrome, our code is erased only with a few seconds of fiddling (closing and opening the page a few times is enough). On other platforms it's different, but Android+Chrome will get the most use.
Oddly, only the code in the SW cache (<100KB) is erased, and the bigger IndexedDb is not. So we tried to also put the code in the IndexedDb, and it seems more "persistent" that way, but the code to manage that is also more involved, so it feels somewhat hackish.
Are we alone with that problem ? If not, how are you people dealing with it ?
Bonus question: is there more up to date documentation on the subject somewhere ?
If I understand you correctly, the main issue is that a Chrome browser on Android keeps emptying the browser cache for a website which does not fulfill the Chrome conditions for automatically granted persistence permission.
Up to now, I have not been in this situation yet, but I observed the behavior, you are quoting from https://developers.google.com/web/updates/2016/06/persistent-storage - I just did not know up to now that it explicitly documented.
I see three ways how some websites enforce persistent user data storage:
Repeatedly ask the user to add the website to the home-screen and / or to enable push-notifications. I observe that this request comes often somehow under false-flag, i.e. something as "Subscribe to notifications to show your appreciation" rather than "Are we allowed to store data persistently". It may even go so far that a "Install our app" essentially means that a full-screen Chrome instance is added to the home screen of a mobile device, rather than a real app from an app store.
Some sites offer a Chrome extension which allows them to store stuff there and even gain more access rights. I personally do not suggest that approach, it somehow creates a strange feeling for security-aware users.
Yet another alternative would be an hybrid approach that you offer a native app which in fact is just a customized browser. Bear me with me a second, if this sounds strange at first glance. This option is in fact quite readily available e.g. in React Native as react-native-webbrowser component. It obviously requires programming effort, but quite a few news sites seem to use as approach.
Option 1 and 2 both stick with Chrome, but clearly do not apply for you, since you just want to avoid bothering the user.
Option 3 is unconventional, but may be an option worth considering. Only users who are programmers might realize that they are being somewhat fooled to install something which is essentially just a browser. Nevertheless it is indeed a clean solution: The app store takes care of access right control and you give the user the full choice what happens with the data.
I'm new to app dev...
I read somewhere in the doc: "...In most cases you want to use SharedPreferences as it is automatically backed up and migrated to new devices..."
On first install my app saves a few settings with SharedPreferences. It works great but if I uninstall the app or install it on another device the preference settings are lost.
How can I have these settings saved online within google somehow to be able to retrieve them if the user changes his phone or similar...
Could someone point me in the right direction ?
I read somewhere in the doc: "...In most cases you want to use SharedPreferences as it is automatically backed up and migrated to new devices..."
Your words "backed up and migrated to new devices" is nowhere written nor its true.
We use SharedPreferences in order to minimise the database operations, its like keeping variables handy.
On first install my app saves a few settings with SharedPreferences. It works great but if I uninstall the app or install it on another device the preference settings are lost.
If you wants to store or remember the device dependent settings, use device id / imei_id and store it on your web server mysql database
Even if user uninstalls app from the device and installs again anytime in future, make a call with async task to server by sending deviceid / imei_id and fetch its settings from mysql database and show it.
How can I have these settings saved online within google somehow to be
able to retrieve them if the user changes his phone or similar...
If user changes device, you can do nothing.
One way is, keep public device_id levels keys on server.
If user changes device and uses that key, then show him a response, this key is assigned to another device, but if you are the same, wait for our support
Call him, confirm he is the same old user with new device and delete his old entry from mysql and assign old key to the new device entry
Or use OTP SMS system to identify already existing customers with unique phone numbers
If OTP authentication code is correct then fetch settings for that user from the server, delete old mysql entry, modify new entry with old key and mobile number
This should be the your direction
Edit : 2 ##
I was hoping an easier solution exist but....
There is no short cuts for developers till the date, and it will be never.
Why, no short cuts / easy ways ?
Any device ( mobile, desktop / laptop / any AI device ) which is operated by a system software, is able to perform the tasks as per it is structured.
Ex : android is java based, obviously you can Make javascript based apps, but it is the extensions to the existing system, Android still has the base of Java virtual machine. ( Dalvic / Malvic like )
So, it is always better to use native java
Yes, Kotlin is best option now a days and better than hybrid approach
Every way has its own advantages, disadvantages
If you are developer, should go with native approach
Now your java code never knows, which version it is running on, so you have to, check android versions programming wise, and decide the flow for above Marshmallow & below marshmallow too, and it is explicitly done by developer by coding.
Ex, once user registers, he never shown please register again screen, it is not the magic, nor google, nor, java, nor android does anything, developer has decided, planned, architectured, designed, coded, tested that.
Even developers needs to take care of exceptions, you need to handle it in order to save your app from crashing.
In short developer is god, who creates his own universe, and everything is pre-planned and verified thats it.
You should use allowBackup = "true" in your manifest file. More details can be found here: AutoBackup
I am in the process of writing a Xamarin.Forms line-of-business application.
The app will be targeting UWP and Android.
I have a requirement of being able to store information and pictures taken, in a shared folder on the local storage. This way, multiple users of the same device at different times can resume work-in-progress of the first user.
I am not sure what my options are, as I am unable to write outside of AppData folder (for UWP).
I read about potentially using a Picker and storing the selected folder in the FutureAccessList for UWP, but I am unsure if it will actually work and seems hacky as I will need to come up with a way of doing the same for Android at a later time.
Any ideas/pointers are greatly appreciated!
There is a special ApplicationData.SharedLocalFolder folder that allows you to share app data across user accounts on a PC. Its main limitation is that it requires appropriate Group Policy:
SharedLocalFolder is only available if the device has the appropriate group policy. If the group policy is not enabled, the device administrator must enable it. From Local Group Policy Editor, navigate to Computer Configuration\Administrative Templates\Windows Components\App Package Deployment, then change the setting "Allow a Windows app to share application data between users" to "Enabled."
I feel that the fact that this is not allowed by default is a great obstacle to the usefulness of this API.
There a publisher cache folder, but this solution is not appropriate for you because of documentation says:
Publisher Cache shares data across apps for the current user
So I would probably really go with the picker-based solution you proposed. Offer the user to select a folder to save the data to using the FolderPicker and then store the selected folder to the FutureAccessList. The future access list is reliable and can even track the changes of the selected item (like when the user moves it to a different location). The abstraction of the selection process in a cross-platform manner may be a bit more complicated, but it should be possible to hide it behind a dependency service implementation. My guess will provide an async method that will initialize the target location. On UWP this will check the FutureAccessList if a location was selected previously and if it was not, it will use the FolderPicker to let the user select it and will store it for future user afterward. On Android, it will work in Android specific manner (I am not sure what are the options there). Then the service will have some file manipulation methods that will abstract the platform-specific manipulation with the folder (I think you cannot use the common System.IO namespace, as you cannot directly access the user selected folder outside of the StorageFolder API)
The app that I'm developing allows the user to enter in a zip code, then the app displays my local businesses that are closest to them. So if someone entered in a New York zip code, all of my franchises located in NY would show up.
It would be ideal if I could see what zip codes are most popular with the usage of this app, and which states receive the most traffic.
Is there a way to record/analyze the entered in zip codes of my users, and have that data sent back to me? Will this become a privacy issue if I gather this data?
Thanks
EDIT
The zip code the user will enter is simply in an EditText.
What you want to do is certainly possible. Since you're posing this question at all, I'm guessing you're app has the available franchises stored locally as opposed to retrieving them from a server.
Where is the data supposed to be sent to? If you have a server, you can use an HttpsURLConnection and POST the requested zipcode to your server when the user presses calculate or however else calculation is kicked off in your app. You will need the internet permission for this to work.
As a word of caution, you should be very up front about that you're doing this to the user, and also give them an option to turn it off, or even have it turned off per default. Personally, this would be the kind of thing that would bother me a great deal if I were to use your app. (Actually, if I couldn't turn it off, I probably wouldn't use it.)
EDIT
I'm not an expert on U.S. privacy laws but I imagine you probably need a formal privacy statement, as well. You certainly do if your app is also available in the European Union (regardless of whether it's useful there or not - whether or not it's available is enough.)
Yes you can easily collect this data and return it to a server. This will require an additional permission for your application 'android.permission.INTERNET' (If not already included.)
Not a lawyer and didn't stay in a Holiday Inn... but I don't see a privacy concern if you're using anonymous data... if you're packaging up user information (Name, Phone #, etc.) and sending it back I would think you'd want to include a "privacy policy" in your app's terms of service.
I have an application that uses the SQLiteDatabase as its database, because each application has its own, custom database (well, custom values), for another app I am making, I want to hose a single SQLiteDatabase that every app will access, for example one app adds a row, while another then reads it at a later time.
Is there anyway to do this? Everything I've found has left me believing there is not, but there has to be.
Any ideas?
Update:
I'm not sure if you've quite understood what I'm trying to do, sorry. The apps accessing this db are all the "same" app, but from different phones, for example, the database could be used to store a user id and their favorite color, so another phone could search their user id, and get the color in db with that user id –
I'm sorry if I did not make that clear enough
Of course there is way to do it! There is always a way!
Anywho, what I think you are looking for is a remote server. These can be done in a few way depending on how much money you have.
(1)If you're broke like me all the time, then you can make an extra computer you have at home act as a server for your app. This can cause a few ( :) hehe few) security issues for your home though. Also you will have a lot of traffic on your home network.
(2)Another option it's to get a domain name and web host. Most of the web hosting services I have seen offer database support. So what you could do is hop on, create your database on the web host server then link your app to your server. The cost on that varies based on your needs.
Really though, is your app interfacing with mulitple people? I can't think of a reason you would want this feature on any other phone (device) than your (relative to us customers) device. I rarely hand my device over to others, and never unless it's locked.
SQLite is serverless. In a situation as described there are no guarantees that it will work properly. Your solution is to create a database server that will cater to multiply Android clients simultaneously.
For more information on SQLite see LinuxForu.com and/or SQLite.org