We have a Progressive Web App that prompts the user with the "Add to home screen" banner.
Adding to the homescreen works great, but after the user launches the page from the Home Screen it will sometimes still prompt them to install the app again. I'm posting here because all the resources I have found don't talk about this issue or how to solve it.
TL;DR Launching the app from the home screen still asks them to install the app with the "Add to home screen" prompt.
As suggested by #Mr.Rebot, I developed a little piece of code to solve the problem.
This is the result code:
window.addEventListener("beforeinstallprompt", (ev) => {
if (isStandalone()) {
// PWA already installed.
event.preventDefault();
return false;
} else {
// PWA not installed.
}
});
function isStandalone() {
// Check if device supports service workers
if (!('serviceWorker' in window.navigator)) return false;
// Check for Android
if (window.matchMedia('(display-mode: standalone)').matches) return true;
// Check for iOS
if (window.navigator["standalone"] == true) return true;
return false;
}
Related
I have strange behaviour with Ionic 5 Angular 10.
My app have notification feature that allow user to navigate to specific page based on notification type. Unfortunately in Android device i need to separate notification action based on app state (background or foreground). When app is in background the Push Notification shown, but when App running in foreground i modified my function using Local Notification because idk why the Push Notification did’nt work in Android foreground.
Here is my code.
TS
import { NavigationExtras, Router } from ‘#angular/router’;
import { ActionPerformed as LocalNotificationActionPerformed, LocalNotifications } from “#capacitor/local-notifications”;
constructor (private router: Router) {}
LocalNotifications.addListener(‘localNotificationActionPerformed’, (res: LocalNotificationActionPerformed) => {
let params: NavigationExtras = {
queryParams: {chatToEmployeeId: res.notification.extra.employeeId}
}
this.router.navigate([’/friend-list/chat’], params);
})
isDisabled() {
return this.newMsg == ‘’ ? true : false;
}
I have a button with property [disabled] that using function to return true or false based on some condition.
HTML
<ion-textarea placeholder=“Type a message…” id=“newMsg” name=“newMsg” class=“message-input” rows=“1” autoGrow=“true” style=“max-height: 100px;” maxLength=“500” ngModel [(ngModel)]=“newMsg”>
<ion-button id=“sendMsg” [disabled]=“isDisabled()” class=“msg-btn” (click)=“sendMessage()”>
When user tap the notification from Push Notification, it’s working fine. But, when user tap from Local Notification, the button always disabled, idk why, i’ve tried many different ways, but no one works for me.
I try to publish a web page as as PWA app with SAMSUNG internet.
I would like to use a custom "Add to home screen" pop up. For this i have to use the following event and i like to listen to the user choice.
In Chrome the user choice does fire after the user choice...
but in SAMSUNG internet it doesn't react to this...
... can somebody helps me with this?
Thanks
window.addEventListener('beforeinstallprompt', function (e) {
deferredPrompt = e;
deferredPrompt.preventDefault();
deferredPrompt.then((choice) => {
if (choice.outcome === 'accepted') {
console.log('User accepted the A2HS prompt');
} else {
console.log('User dismissed the A2HS prompt');
}
// Clear the saved prompt since it can't be used again
installPromptEvent = null;
});
})
From caniuse Samsung internet does not support the beforeinstallprompt and appinstalled events.
Ref: https://caniuse.com/#feat=web-app-manifest
So you won't be able to use it this way at all.
caniuse screenshot as of 2020-04-13
I want to close my app when user force close.
Any event arise for force close in ionic application ?
Any plugin for force close event handling in ionic app ?
example:
A common piece of functionality for native mobile applications is the ability to logged out if the user closes the application(force stop/force close).
How can this be achieved for a Cordova / Ionic / PhoneGap ?
Put the following code accordingly to your angular.run configuration, and that's it. You can even add some checks, for example using a boolean value in a Service or a check to the current state to decide if prompt to the user the closing app notice or not.
.run(function($ionicPlatform, $ionicPopup) {
$ionicPlatform.onHardwareBackButton(function () {
if(true) { // your check here
$ionicPopup.confirm({
title: 'System warning',
template: 'are you sure you want to exit?'
}).then(function(res){
if( res ){
navigator.app.exitApp();
}
})
}
})
});
More...
I have searched all over the web and found different ways of closing a PhoneGap App. I tested all of them and none work. At least on Android.
Question:
Is it possible (By Feb 2014) to have a close button in a PhoneGap App on Android?
Thanks
This doesn't work:
function CloseApp() {
if (confirm('Close this App?')){
if (navigator.app) {
navigator.app.exitApp();
}else if (navigator.device) {
navigator.device.exitApp();
}
}
}
Is
navigator.app.exitApp()
really killing/closing the android app with phonegap?
I use cordova and have the same issue. Above mentioned code is just putting the app into background - I checked the running tasks (android task manager) after above code got executed by the app.
I am confused on why you want a button to close the app. Android already has a back button when clicked enough times will take the user back to the phone's main screen. There is also a home button that takes the user out of an app. Once, out of the app the user can "kill" the app through a task manager.
navigator.app.exitApp()
works and I use it in all my cordova apps. Check the rest of your code.
As ejwill said, having a "close" button is a bad idea. On Android I call exitApp when the user is the home page of my app and he presses the backbutton:
function onDeviceReady() {
document.addEventListener("backbutton", onBackKey, false);
}
function onBackKey( event ) {
var l = window.location.toString();
var parts = l.split('#/'); // this works only if you are using angularjs
var page = parts[1];
if (page == 'home') {
navigator.app.exitApp();
} else {
// do something else... one option is:
navigator.app.backHistory();
}
}
My 2c.
there a lot of q&a about how users can rate my app within the app,
but i need just a direct link to review\rate my app to send the user by mail and not to my app page in the market because there he need to cilck review then login and then write the review and this is exhausting and not user friendly.
tnx
In order not to disturb the user with annoying forms you can add a menu item that let the user rate the application through your application site in google play. After the user click in this option, this should not been showed again (even if the user did not rate the app at the end). This solution is quite user friendly, in my opinion.
Add a menu item like this (in res\menu[menu].xml):
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
(other options...)
<item android:id="#+id/MenuRateApp" android:title="#string/menu_Rate_app"
android:icon="#drawable/ic_menu_star"></item>
</menu>
In your main activity add the following in order to hide the option once the user has already rated your app:
#Override
public boolean onPrepareOptionsMenu(Menu menu)
{
MenuItem register = menu.findItem(R.id.MenuRateApp);
if(fApp.isRated()) {
register.setVisible(false);
}
return true;
}
Change the fApp.isRated() for a method or variable that keep a boolean saying if the user already rated the app (write and read this value using the sharedPreferences mechanism).
The code to redirect the user to your app site in Google Play could be like the following:
private boolean MyStartActivity(Intent aIntent) {
try {
startActivity(aIntent);
return true;
} catch (ActivityNotFoundException e) {
return false;
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
(other options code...)
if (item.getItemId() == R.id.MenuRateApp) {
//Try Google play
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("market://details?id="+getPackageName()));
if (MyStartActivity(intent) == false) {
//Market (Google play) app seems not installed, let's try to open a webbrowser
intent.setData(Uri.parse("https://play.google.com/store/apps/details?id="+getPackageName()));
if (MyStartActivity(intent) == false) {
//Well if this also fails, we have run out of options, inform the user.
Toast.makeText(this, this.getString(R.string.error_no_google_play), Toast.LENGTH_LONG).show();
}
}
//Do not disturb again (even if the user did not rated the app in the end)
fApp.setRated(true);
}
return super.onOptionsItemSelected(item);
}
Hope this solution feets your requirements.
Note: part of the code has been borrowed from this site:
http://martin.cubeactive.com/android-how-to-create-a-rank-this-app-button/
Example:
The premise from where you start, saying that rating an app is exhausting and not user friendly is not applicable because the user should only rate your app when he is willing to "donate" 30 seconds of his life to rate your app. There is a minimal responsibility involved when rating other people work.
The farthest I'd go, since there are also ethics involved, is providing a button in the About section of my app with a link to the Market app screen containing my app, using an Intent to the market (search StackOverflow). Other apps constantly ask a user to rate... I find it bothersome, but at least they are not pushing me right into the Edit and star Views of the Market.
The question you need to ask yourself: do you need to disrupt the user experience of your app by automatically stopping the activity and displaying this "oh-my-gosh-rate-my-app" view in the Market app?
You don't need to push the user into that situation... chances are you will end up with more low ratings than good ratings. I'd take one star just because of that. :-)
Personally, I wouldn't do it and leave the way it is. My 2 cents, of course.
Based on a similar question I posted, the desired answer I was looking for was
https://play.google.com/store/apps/details?id= + your.package.name
This should be what you're looking for if a link is what you have in mind. The first part is the default starter, and the second part will be your package name.