I have a situation where I use this method to call a dialog for the In-App Review, but the dialog does not appear either when the test version is an app, or when the app is live in the Play store. However, LogCat Info shows that the method is called properly when the code is called. Can anyone help with advice or suggestion, thanks.
https://developer.android.com/guide/playcore/in-app-review
Gradle
implementation 'com.google.android.play:core:1.8.0'
onCreate
Log.i("rate", "CALL MANAGER");
askRatings();
Code
void askRatings() {
ReviewManager manager = ReviewManagerFactory.create(this);
com.google.android.play.core.tasks.Task<ReviewInfo> request = manager.requestReviewFlow();
request.addOnCompleteListener(task -> {
if (task.isSuccessful()) {
// We can get the ReviewInfo object
ReviewInfo reviewInfo = task.getResult();
Log.i("rate", "SUCCESS FLOW");
com.google.android.play.core.tasks.Task<Void> flow = manager.launchReviewFlow(this, reviewInfo);
flow.addOnCompleteListener(task2 -> {
// The flow has finished. The API does not indicate whether the user
// reviewed or not, or even whether the review dialog was shown. Thus, no
// matter the result, we continue our app flow.
});
} else {
Log.i("rate", "NOT A SUCCESS FLOW");
}
});
}
Log
2020-08-18 11:17:03.641 13328-13328/my.app I/rate: CALL MANAGER
2020-08-18 11:17:03.764 13328-13328/my.app I/rate: SUCCESS FLOW
I had to use the Internal App Sharing and an Android 10 emulator to see the dialog. In Android 9 and previous I see the same logs as you do, but no review pops up. Anyway, I do see a glitch with the android virtual buttons menu appearing for a second, so I believe that means the flow is working.
Related
I have an android native application using MSAL library to authenticate. We are facing issues to logout from application after login. While logout, it displays a screen where the already logged in email displays, tapping on that allows the user to login to the application with out a password. The application is configured as MultiAccount mode. Below is the code for logout.
removeAccountButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (mMultipleAccountApp == null) {
return;
}
/**
* Removes the selected account and cached tokens from this app (or device, if the device is in shared mode).
*/
mMultipleAccountApp.removeAccount(accountList.get(accountListSpinner.getSelectedItemPosition()),
new IMultipleAccountPublicClientApplication.RemoveAccountCallback() {
#Override
public void onRemoved() {
Toast.makeText(getContext(), "Account removed.", Toast.LENGTH_SHORT)
.show();
/* Reload account asynchronously to get the up-to-date list. */
loadAccounts();
}
#Override
public void onError(#NonNull MsalException exception) {
displayError(exception);
}
});
}
});
It always display the toast "Account removed", but it is actually not. Any help is appreciated!
Edit 1 - 12/12/2022
#Tinjzz This Answer is almost your exact scenario.
Question Description
"accounts are removed successfully, but when signing in again and the microsoft sign in intent is opened, the accounts can just be clicked to sign in without password"
#Rutha answer "This is happening because MSAL automatically refreshes your token after expiration. When user opens your app it checks if that token is already present and valid."
"you need to remove the cache as well to remove the account from the cache, find the account that need to be removed and then call PublicClientApplication.removeAccount()"
In a later answer, #Rutha notes "On Android we basically don't have any control on the cookies" "If you want the user to enter the password again then you should do this: AcquireTokenInteractive(scopes).WithPrompt(Prompt.ForceLogin);
Old Response
From the code posted, it looks like you are using an approach similar to this site with a separate loadAccounts() method. "Step 5.2: Load accounts"
However, in the MS MSAL Single and Multi-Account page, it notes:
"If your app is configured to use a broker, and a broker is installed on the device, the account won't be removed from the broker when you call removeAccount. Only tokens associated with your client are removed."
MS specifically recommends using "Call getAccounts to get a list of accounts currently known to the app."
So, the current setup may be using loadAccounts() per the first link, yet MS actually recommends getAccounts that specifically addresses only the internal MSAL token system.
Firestore call onComplete etc events only online. How do know about write status offline.
db.collection("col").document(id).set(obj)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (task.isSuccessful()) {
//Ok finish activity <----
finish();
} else {
Toast toast = Toast.makeText(getApplicationContext(),
"Error try again", Toast.LENGTH_SHORT);
toast.show();
}
}
});
The code above doesn't works offline, and i can write multiple times. onComplete will not called until i connect to internet. Ho do i implement this feature(closing activity when success).
onComplete will not be called until I connect to the internet.
That's normal behavior. The OnCompleteListener is called only when the data has been written or rejected by the Firebase servers.
A listener will never fire for local write operations. If the local write operation were to fail, the client will raise a regular exception. The Firestore client is designed to continue working even if offline. So writing some data to the database while offline will never produce an error.
Ho do I implement this feature(closing activity when success).
There is no way you can add a completion listener to know when the data is written to the cache and this is because this operation is happening instantly. There is nothing you should worry about in this situation.
What you can in such cases is to check the internet connection. If you are offline, it means that all data is added to the local cache.
Offline writes are considered to be written immediately. There is no completion status for that.
You'll notice that if you have a listener set up for the document that's being written, that listener will trigger immediately, while offline, with the updated document values. You can tell from the document snapshot delivered to the listener if the write has completed or not. If you call snapshot.getMetadata().hasPendingWrites(), it will tell you whether or not the updated document has actually been sent. This is the best possible information you can receive about the status of offline writes.
I have been trying to fix this for weeks and have no clue what is causing the issue. In my project I am utilizing the Android Webview's evaluateJavascript() method like this:
this.runOnUiThread(new Runnable() {
#Override
public void run() {
webView.evaluateJavascript(command, new ValueCallback<String>() {
#Override
public void onReceiveValue(String value) {
//Parsing and taking action here
Log.d("Response", value);
}
});
}
});
A sample string of the javascript I am sending would be:
document.getElementById("message").value="Stuff worked!";
or
document.getElementById("some-awesome-button").click();
While 9 times out of 10 these calls return a value in the onReceiveValue() method, once in a while I just straight never receive a response at all.
This lack of a response has made chaining events a nightmare and I have no clue why this would be happening.
Some more data to head off any additional questions:
The minimum SDK for this project is 21 and I am targeting 28.
I am not utilizing any javascriptInterfaces at this point in time and don't intend to for this project for a few business-related reasons.
When I do get a response fro the webview in the onReceiveValue() method it is usually the value I had just set or 'null' if it was a click event. Regardless, the issue isn't that I am sometimes receiving nulls or other values, but the distinct lack of a response sometimes.
As shown in the code sample, I am definitely running this on the UI Thread as per the documentation.
I had the server dev add in some code to console log whenever I am hitting the button and when I get back a successful value in the onReceiveValue() method the console logs are working and responding but when I am in the situation where I do not get back a response, the web console logs never fire and it never detects an interaction with the button.
I have also tried adding in a timer with logic that listens for a response from the webview and if it does not receive it, attempts to make the same call again up to 10x. When the first call fails, none of the subsequent attempts work.
These are the settings for my webview:
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setAllowFileAccess(true);
It almost seems like the issue is with the Javascript Bridge but I cannot be certain.
The summary question I have is, what could cause the Android WebView's evaluateJavascript() call to not trigger a callback nor return a value in the onReceiveValue() method?
Happened to me because I was trying to call webView.evaluateJavascript(...) from a background thread.
I solved it by wrapping it using View#post() :
webView.post(() -> webView.evaluateJavascript(...));
I did eventually figure out what happened here.
The shorter version is, this can happen when you have a memory leak and an object that is utilizing a semi-destroyed webview will fire off commands, but the newly-initialized webview will not receive a response because it is going to a dead listener.
If you want to prevent this from occurring, just make sure that all objects that maintain an application Context are properly disposed of or correctly reset if the activity restarts, else you have all objects that use the same Application-level context, but are using new views and callbacks entirely.
I am trying to clear a data from within the app and my app is device owner, hence I am getting and error
java.lang.SecurityExeception :Clearing DeviceOwner data is forbidden.
Code I am using is
public void onClearData(View view) {
try {
boolean isCleared = ((ActivityManager) getSystemService(ACTIVITY_SERVICE)).clearApplicationUserData();
if (!isCleared) {
Toast.makeText(this, "Not able to clear the data", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
Now, my question is that how it will be possible to clear a data of device owner app from within the app? Would appreciate a help.
The way you're doing it is how it's done, according to the docs.
But since you're getting that security exception, your app is probably set as a device owner app, and you're not allowed to deactivate it, remove its data nor uninstall it while it is on this state.
If that's really the case I'd suggest you to unset it as a Device Owner App. Try to use dpm remove-active-admin for that.
Take a look at those questions for more info:
How to make my app a device owner?
How to remove set-device-owner in Android DPM?
Disable a device owner app from android terminal
I have added a local notifications so when my app gets a push while opening there is still a popup and a sound.
It's working fine on Android, but on iOS the local notification doesn't appear at all.
The push notifications are working fine on both platforms.
This is my code in the push callback that should trigger the notification (if the app is open):
if(Display.getInstance().getCurrent() != null) {
LocalNotification n = new LocalNotification();
n.setId(value);
n.setAlertBody(value);
n.setAlertTitle({app name});
n.setBadgeNumber(1);
Display.getInstance().scheduleLocalNotification(n, System.currentTimeMillis() + 1000, LocalNotification.REPEAT_NONE);
}
Local notifications don't fire while the app is open in the foreground. You should use a different mechanism to make a sound while the app is running. Eg Display.vibrate()
- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo
{
[[NSNotificationCenter defaultCenter] postNotificationName:#"DriverNotification" object:nil userInfo:userInfo];
// [[NSNotificationCenter defaultCenter] postNotificationName:#"UserNotification" object:nil userInfo:userInfo];
NSLog(#"%#",userInfo);
}
Put This Code in Your View Controller
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(receiveNotification:) name:#"DriverNotification" object:nil
];
Did you call registerUserNotificationSettings to register the fact that your app uses local notifications? If you don't do that, your request to post a local notification will be ignored.
See this text from the description of that method:
If your app displays alerts, play sounds, or badges its icon, you must
call this method during your launch cycle to request permission to
alert the user in these ways. (You must also make this request if you
want to set the applicationIconBadgeNumber property directly.)
Typically, you make this request if your app uses local or remote
notifications to alert the user to new information involving your app.
The first time your app launches and calls this method, the system
asks the user whether your app should be allowed to deliver
notifications and stores the response. Thereafter, the system uses the
stored response to determine the actual types of notifications you may
use.
After calling this method, the app calls the
application:didRegisterUserNotificationSettings: method of its app
delegate to report the results. You can use that method to determine
if your request was granted or denied by the user.
It is recommended that you call this method before you schedule any
local notifications or register with the push notification service.
Calling this method with a new user settings object replaces the
previous settings request. Apps that support custom actions must
include all of their supported actions in the notificationSettings
object.
you need to add below code in didFinishLaunchingWithOptions method of AppDelegate.m file for register local notification
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if ([[UIApplication sharedApplication] respondsToSelector:#selector(registerUserNotificationSettings:)])
{
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
else
{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:
(UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert)];
}
}