Problem: my PWA is already installed on many clients, Android and iOS, and I want to update the launch icon and splash screen.
Android: according to Google documentation:
When the PWA is launched, Chrome determines the last time the local
manifest was checked for changes. If the manifest hasn't been checked
in the last 24 hours, Chrome will schedule a network request for the
manifest, then compare it against the local copy.
If select properties in the manifest have changed (see list below),
Chrome queues the new manifest, and after all windows of the PWA have
been closed, the device is plugged in, and connected to WiFi, Chrome
requests an updated WebAPK from the server. Once updated, all fields
from the new manifest are used.
Which properties will trigger an update? background_color, display, orientation, scope, shortcuts, start_url, theme_color, web_share_target
In my tests, when I update one of these fields in the manifest (I am updating background_color for Chrome to pick up the change and the images specified in icons\src with the new icon), it will indeed be picked up after some time (I can see it by navigating to chrome://webapks) but the launch icon will NOT be updated. I have tried changing the icon name in addition to the icon content but that does not help.
Notes:
if I follow the instructions in Testing manifest updates then the icon will indeed be updated after some time, but obviously, I can't ask this to my users...
My PWA is listed in the installed apps in Android's settings
iOS: here the icon is specified in an HTML tag apple-touch-icon and I could not find anything except this very old answer on SO:
In newer iterations of iOS, the Apple Touch Icon that is displayed on
the home screen is cached just like any other piece of content from the
website. By simply changing the name of the image, it will force the
home screen shortcut to refresh the icon the next time the shortcut is
launched.
<link rel="apple-touch-icon" href=".\icon.ico">
Again this is not what I am seeing, the icon will not change even if I modify the name of the referenced image.
What am I missing???
Related
According to “People and conversations”, one of the prerequisites for a conversation notification on Android 11 is the following:
The notification is associated with a valid long-lived dynamic or cached sharing shortcut. The notification can set this association by calling setShortcutId() or setShortcutInfo().
But I can only have 5 shortcuts. Does this mean that I can't make conversations notifications for more than 5 people?
It appears that you can actually publish more than 5 shortcuts. You can make notifications which would rank lower than all others by setting rank to a high number, and publish them using shortcutManager.pushDynamicShortcut().
In case you don't have any launcher shortcuts, the above action will create one. If you don't want that, it's recommended to... simply remove the shortcut you just created:
Q: Will my shortcuts appear in the long press app launcher context menu?
A: They can depending on their rank, but if you prefer not having shortcuts appear on launcher you can remove the shortcut with ShortcutManager#removeDynamicShortcuts() or #removeAllDynamicShortcuts() after sending the notification. You can also rank other app shortcuts with higher ranking, so only those dynamic shortcuts appear on launcher.
Some thoughts follow below. It appears that shortcuts on a regular phone will appear in three places:
launcher— either by long pressing app icon, or pinned;
direct share;
conversation notifications.
These shortcuts all come from the same pool. It makes sense, but as there is only a single rank for every shortcut this means that the launcher list and the direct share list are the same. This is something you might not want; you might be sharing more to one conversation but opening another one more often. In my app, I solved this in the following way:
I maintain statistics of when the user shares to a contact / opens a chat with a contact
Whenever the list of top used/top shared contacts change, I update the shortcut using shortcutManager.pushDynamicShortcut(); if a shortcut with the same id already exists, it is updated. I use the old details from shortcutManager.getShortcuts().
depending on whether a shortcut becomes or ceases to become a direct share target, I set or unset a category
specifying rank allows reordering shortcuts in the launcher
Whenever I need to push a notification, I check if I already have a shortcut for the conversation. If not, I simply create a new one with a rank of 10000.
This allows having completely different launcher & direct share shortcuts, and to publish many a conversation notification.
Some random observations:
Adding a shortcut id to a conversation notification also adds its icon to the notification, even if you don't set one explicitly.
shortcutManager.maxShortcutCountPerActivity actually returns 15 (!) on my device (LineageOS), even though the launcher & direct share only show the regular 4 icons.
If you update a shortcut name and/or icon, most of the time it will instantly update in launcher. This includes pinned shortcuts.
Use IconCompat.createWithAdaptiveBitmap() to create icons that work well for various icon shapes. The system will keep a hold of the image, you don't need to keep it. See the documentation for that method.
There are two other methods to be aware of:
IconCompat.createWithAdaptiveBitmapContentUri() is the same as the above but will work with content URIs. This is good for creating Person for notifications, as this allows not keeping the icons in memory. However, there is seemingly no way to pass URI permissions to shortcut manager, so this method can't be used. (Please correct me if I'm wrong here!)
Edit: if you cancel the notification after inline (direct) reply, the system might decide to add your reply to it instead of actually cancelling it. Apparently it might lose URI permissions at this point. Calling this workaround on URIs seems to be helping:
fun Uri.grantReadPermissionToSystem() {
applicationContext.grantUriPermission("com.android.systemui", this,
Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
IconCompat.createWithData() creates memory efficient icons from compressed image data (PNG/JPEG). It's not adaptive, however. And, icons made with it don't work with ShortcutManager at all.
Also don't forget to check out the readme of the People sample app.
I have tried with different launchers (Apex, Microsoft, envie...) the behaviour is the same. I install a launchers on a user account and set it as default launcher. When I restart my phone and switch back to that user the default launcher is used. When I check the settings the new launcher is still set as default but somehow it's not working. For the main user (owner) it works and when the launcher is set, it is triggered after rebooting but not for the other users. Ther default launcher comes always back. I am using android 8.1 with EMUI 8.2. Any help? ty
My App has the "Dynamic Services URL" set to true.
This is because we have several Application Servers and, also, the URL might change depending on the network we are connected to.
Android:
The App gets a menu on the AppBar (upper-right corner) with a "Settings" option in it.
The App startup invokes an Authentication procedure, that requires access to the Application Server.
Q1: If the last Application Server is unavailable (eg, device connected to a different network) the App will return a "Error: Connect time out" and will not give the Settings Menu, not allowing me to change the URL.
Even if i go to the device settings and Clear the app data, still, the app will try to reconect to the last / default Services URL.
It seems impossible to use the App again, until the previous Application Server becomes available so I can have access to the Settings Menu.
Is there any other way to change the Service URL?
Q2: I will have to create my own "settings" screen for the App (where user can select a default theme, default nº of rows, etc).
Can I add a new option into the menu that genexus creates (so I don't have 2 Settings menus)?
The fist point is officially recognized as a bug. See this SAC
The second point: I have no clue on how to achieve that (unify the 2 settings screens or create a custom edit box for setting the dynamic services URL). If there is a way, it may be programming an external object.
I am trying to build a sort of launcher.
I would like to have the possibility to present to the user the apps he uses most.
Is there any way to determine which Apps are launched more often by the user?
I am not aware of any system "counter" that does that, and I have found nothing in the documentation and in SO.
There is no way to get this information from the OS, because of privacy concerns. You can start collecting this information when people install your launcher and start using to launch apps, because you'll know which apps they start, but you have to start with some common list of apps initially, which likely will be useless to your users. You can also import their current home screen from the Launcher (and TouchWiz, and HTC Sense), but that does not scale easily for all possible launchers people might be currently using (Nova, GO Launcher, Facebook Home, and so on).
If you are creating an Android launcher, then you are responsible for displaying the android Applications installed and while clicking on the application icon that you listed, you are the one who is opening up the clicked app. So you can keep the count whenever you open a particular app and do accordingly.
Whenever you open an application, just save an open counter against the application package name of the app that you opened.
I have a web app and on the Android I would like to display an alert describing how to add my app to the home screen. (Add it to "Bookmarks" and then "Add it to home screen" or "Add to shortcut in Home"). Then a icon will be displayed on the screen that opens my app.
But off course I only want this to show if the app is not added to the home screen.
Does anybody know how to do this?
Any input appreciated, thanks.
Yes, you can.
While technically a page open in Chrome browser tab can't directly check whether a home screen shortcut exists, the page's local data (localStorage, IndexedDB) is shared between home screen instance and browser tabs, so this can be used to communicate the existence of the home screen version.
Detect if the app is running from home screen
If it's ran from home screen, save this fact to localStorage
Profit! (by reading this from localStorage in any tab)
When the app is in standalone view (which is possible only when launched from home screen), the CSS media query (display-mode: standalone) will match. In Javascript you can read it using:
matchMedia('(display-mode: standalone)').matches
(BTW: the non-standard iOS equivalent of this is navigator.standalone, but iOS doesn't share state between home screen and Safari, so you're out of luck there).
However, instead of custom instructions I suggest meeting Chrome's criteria for "progressive web app" and let Chrome do the prompting for you.
You can't check a web app if its added to home screen on android. At least for now. (Chrome 67)
But you can tell if the app is running in standalone mode using display-mode media query.
Add this inside your <style> tag.
#media all and (display-mode: standalone) {
body {
background-color: yellow;
}
}
Then in your <script> tag.
if (window.matchMedia('(display-mode: standalone)').matches) {
console.log('display-mode is standalone');
}
Or this
if (window.navigator.standalone === true) {
console.log('display-mode is standalone');
}
You can check more from here.
The short answer is: from a Web Site you can't.
The longer answer is: from a Web site you might be able to get a hint in Chrome.
Chrome on Android two new features 1) Web App Manifest that describes what should be launched from the home screen and how it should look on the homescreen, and 2) Chrome now has an beforeinstallprompt event that will trigger for Web apps that we think are app-like and can be installed to the homescreen.
There are a number of criteria for the onbeforeinstallprompt event to fire which might make it an "ok" heuristic (although I suspect not).
The event only fires if:
The site has a manifest, is on https and has a service worker. (this can be quite a stretch).
The user has engaged with the site multiple times (right now, twice within at least 5 minutes).
The user has not already added your site to the home-screen.
So, in summary it is complex and full of false positives and false negatives. However if all you want to do is detect if you should display a banner to prompt the user to add your web-app to the homescreen then Chrome already has a solution for you.
We also have a full range of samples on our samples site.
I think you can do it. Simply add query string to start_url in manifest.json and in your javascript check if start url is having that query string. If query string is found then yeah app is installed.
first you get the list of apps on the device
List<ApplicationInfo> packs = pm.getInstalledApplications(0);
then you use getLaunchIntentForPackage()
Now that you've got the list of packages installed on your device,
iterate through them and call getLaunchIntentForPackage() on each
item.
If a valid intent is returned, it exists on the Launcher, else if null
is returned, the package does not launch from the Launcher screen.
Note that Home screen shortcuts are a subset of the Launcher apps.