During my activity I'm sending an intent to the browser in order to display a webpage :
Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("http://ww.mywebpage.com");
startActivity(i);
I need to make sure that before sending the intent the browser cache and history are cleared so that the page get loaded from server directly and not from phone.
So far I've found the 2 following but I'm not sure they are used correctly :
Browser.clearHistory(getContentResolver());
Browser.clearSearches(getContentResolver());
Also with that cache is not cleared.
Do you know how to do that ?
First, you are assuming there is only one Web browser for Android. You are mistaken, and will be increasingly mistaken over time. Steel, Dolphin, Opera, etc. are already in production for Android, and Mozilla's Fennec is coming along nicely. This solution will not help you with other browsers.
Second, if a browser is incorrectly caching your data, your problem is probably on the server (i.e., not sending proper cache control headers). I'd try to fix it there, so that it will behave properly across all browsers.
Third, wiping the user's entire history and searches, to satisfy your requirements, is rather unprofessional. How would you like some desktop app wiping out your desktop browser's history and searches?
Fourth, you cannot clear the browser's cache programmatically.
Yes... and if you must assert more control on the client side rather than fixing it at the server, you'll need to display the content with a webview inside your application where you have full control, rather than delegating to the browser (which is a separate application running under a separate user id and separate security context that you can't mess with).
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 developing a django web-project and I'm going to develop its IOS and Android API.
Is there a way to avoid using hardcoded url addresses in the app code?Something like django url name system
The following problem faces me if there isn't any solution to my question:
If I want to change some of my urls, I should change the app code and also all the previous installed apps on peoples' devices won't work and should be updated.
The way I see it, you probably have two options:
a) Code very generic forwarding links into your app, such as:
http://www.example.com?linkid=1
http://www.example.com?linkid=2
You can then, from your side, forward these on to where you need them to go by using the query string ID number.
b) Write a web service to push updated URLs to your app, maybe on load so you're not polling the service all the time.
How often are the URLs likely to change?
I'm doing an android application much like the gmail app for android. I can see the app is very fast and very responsive.
I'm sure gmail uses local caching for better performance. But I wonder how does gmail does the following use cases.
Lets say i login for first time and the app loads all email and put in sql lite or any other caching.
use case1
every time i delete or add a star it makes an asyncronous server req to server. this is fine.
use case 2.
how does the app get notified in case the user makes changes from another client. (from a browser).
To download the entire mails will be costly. Lets assume a case in which the user adds a star to a already cached email.
How can we implement the api in such a way that to get only updates which made from other clients. Updates like new email, deleted email, star added, etc. I'm considering the scenario when the user doesn't use the background sync.
This is been bothering me for a long time. Request you guys to let me know some tutorials or links to understand the secret behind the gmail app.
Why don't you look at the gmail web app. That will be using the same/similar design principals (gmail web app is also very fast for me). Then you can apply the same principals. With the web app you can look at the web requests using something like firebug with firefox. Under the Net tab it will show the json of what is being sent across the network. It will also show you the way the request was structured. You wont be able to see how they go about optimally returning the data, but that should be fairly trivial.
I would recommend for returning data that you do the following:
1) create a cache for the most recent page of emails.
2) Updates of new emails will be immediately prefetched into the cache.
3) setup a cache for the next page and previous page of emails.
Essentially what I am saying is:
1) You can look at googles web version which is very visible to plain snooping.
2) You can optimize based on statistical usage of how the user would want to see their emails. This can suggest cache improvements.
What you are asking for in terms of links is harder because your question relates to many general concepts and proriatary software.
This is what I need to do:
I have an app running in the background. Now when the user is browsing and comes across an 'interesting' URL, he can make a gesture and send the URL to the external app. The app then processes it.
I can think of two way of doing this(though I am not sure if either is possible)
1. Program something like a hook that senses the particular gesture or key press and sends the URL to the app
Write something like an add on to the browser.
My question is, is any of this possible. If yes, could you give me a few hints so that I can go ahead. If not, then is there any other way to do it?
Thanks,
Sandip
Short answer : You can't use the android browser like this.
Long answer : The android browser is an application. The only way you can interact with it is to call it with an argument (a URL). And... that's all. You can't write an extension to the browser like you can do in Chrome.
If you want to control the browser, use a webview, but even in that case, you won't have the ability to detect gesture.
What you're trying to do is not possible.
Take a look at WebViewClient.shouldOverrideUrlLoading. It should allow you to be notified when a new URL is loaded.
http://developer.android.com/reference/android/webkit/WebViewClient.html#shouldOverrideUrlLoading%28android.webkit.WebView,%20java.lang.String%29
I'm looking for a way to find out which browsers are installed on the Android Smartphone and their package names.
Why do I need it?
Well basically, my App reacts on certain URLs, i.e. http://bit.ly, so when the click such an he will get an choice in which App to open it. So far everything is working as intended.
If the user sets up this app as default for this kind of links, it will always open in this one without further asking the user. So far so good too. But by doing this, he will be completely unable to open this links in his browser.
So I need a way to send this intent directly to the browser, but to do so I have to know which app the user has set to be default for http/https scheme for example (as user can change it if there is more than 1 browser installed).
Sending the intend with
intent.setComponent(new ComponentName("com.android.browser", "com.android.browser.BrowserActivity"));
should't be a problem I think. The problem is, I can't send a standard intent für URLs, because my App would catch it again if set as default by the user.
should't be a problem I think
Hardwiring in the package and class names of code that is not yours is always a problem.
So I need a way to send this intent directly to the browser, but to do so I have to know which app the user
has set to be default for http/https scheme for example (as user can change it if there is more than 1
browser installed).
Use PackageManager and queryIntentActivityOptions() to filter your activity out and get a list of other activities that the user can choose from.