Nativescript Android 8.0 READ_CALL_LOG Failed - nativescript

Using Nativescript 5.0.
Below piece of code works well in Android ver 6.0.1
But fails to get permission in Android 8.0
Permission seeking message box does not appear.
Difference observed in both phone's permission details is, in Android 8.0, additional permission is seen as "Dial through contacts" which can not be set manually.
Permissions.requestPermission(android.Manifest.permission.READ_CALL_LOG, "Needed for connectivity status").then(() => {
console.log("refresh - Permission granted!");
this.readCallLog();
alert("in refresh Permission granted");
}).catch(() => {
console.log("Permission is not granted (sadface)");
alert("in refresh Permission NOT granted");
});

Try including READ_PHONE_STATE permission.
But to be precise nothing was changed in Android 8, but Android 9 introduced breaking changes to read call log permission which now requires phone state permission too to work.

While with earlier Android versions you could just request permission READ_CALL_LOG the newer Android versions are introducing some changes in how you could request the user call logs. The idea is to provide more information to the user explaining why you need these permissions.
An explanatory strings values should be provided in the Andorid resources
<string name="permgroupdesc_calllog">read and write phone call log</string>
<string name="permgrouprequest_calllog">Allow <b>%1$s</b> to access your phone call logs?</string>
Also, you will need to ask for a number of permissions and not just READ_CALL_LOG:
CALL_LOG
READ_CALL_LOG
WRITE_CALL_LOG
ROCESS_OUTGOING_CALLS
Details on the above here

Related

Xamarin - Android 13 Notification Permission Prompt

As we know, Android 13 is introducing runtime notification permission. Here's the Android developer documentation on this.
We already have a priming page where we show the notification permission prompt in iOS. We just need to do this for all users on Android 13.
After reading the documentation, i've added the following:
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
However I can't seem to find a way to prompt Android users. Has anyone had any success with this/can point me in the right direction?
Also, we've noticed all of our users who have upgraded to Android 13 have notifications turned off by default. Is there a way we can add a link to the notifications permission in the settings?
I am currently using this to achieve that, in your MainActivity put this
protected override void OnStart()
{
base.OnStart();
const int requestLocationId = 0;
string[] notiPermission =
{
Manifest.Permission.PostNotifications
};
if ((int)Build.VERSION.SdkInt < 33) return;
if (this.CheckSelfPermission(Manifest.Permission.PostNotifications) != Permission.Granted)
{
this.RequestPermissions(notiPermission, requestLocationId);
}
}
From document Notification runtime permission, we know that:
To request the new notification permission from your app, update your
app to target Android 13 and complete a similar process compared to
requesting other runtime permissions.
And from document POST_NOTIFICATIONS, we also find that :
POST_NOTIFICATIONS Added in API level 33
public static final String POST_NOTIFICATIONS Allows an app to post
notifications
Protection level: dangerous
Constant Value: "android.permission.POST_NOTIFICATIONS"
That is the Protection level of POST_NOTIFICATIONS is dangerous, so we need to
add Requesting Runtime Permissions.
For more information, you can check : Requesting Runtime Permissions in Android Marshmallow.
You can also check Permissions In Xamarin.Android here.
And there is a sample here:https://github.com/xamarin/monodroid-samples/tree/main/android-m/RuntimePermissions.

Xamarin-System.UnauthorizedAccessException: Access to the path is denied

I'm trying to download a file and I'm getting System.UnauthorizedAccessException: Access to the path "/storage/emulated/0/Download/test.pdf" is denied. I have set required permission in Android Manifest file.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Download Path:
Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads)
If i use the below path as my download path i can able to download the file. But i cant able to share the PDF file to google drive, drop box or any other System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal)
I am using Xamarin.Forms v2.4.0.282 and Xamarin.Android.Support packages v25.4.0.2.
Note: The code was woking fine when use Xamarin.Forms version 2.3.5.256-pre2 and Xamarin.Android.Support packages v23.3.0
Please suggest your ideas to resolve the issue.
Thanks in Advance.
Depending on the version of Android you are using even with the permissions added in the manifest in 6.0 or up the user has to explicitly enable the permission when the app runs and on lower versions permission is asked during install. For example, on startup of the app I created a method to check if it is enabled and request permission if it's not.
private void CheckAppPermissions()
{
if ((int)Build.VERSION.SdkInt < 23)
{
return;
}
else
{
if (PackageManager.CheckPermission(Manifest.Permission.ReadExternalStorage, PackageName) != Permission.Granted
&& PackageManager.CheckPermission(Manifest.Permission.WriteExternalStorage, PackageName) != Permission.Granted)
{
var permissions = new string[] { Manifest.Permission.ReadExternalStorage, Manifest.Permission.WriteExternalStorage };
RequestPermissions(permissions, 1);
}
}
}
You can also use the support library to do this, which is simpler and allows you to not have to check the Android version. For more info check out google's documentation.
If targeting API 29+, you will get the error even if you request the permission and user grants it, because they changed how storage works.
The correct solution is to look how it should be done on API 29+ and do it.
But if you are like me, tired of Android making things more complicated every day, just add android:requestLegacyExternalStorage="true" to your manifest <application> tag and you are saved until you start targeting API 30.
Those of you who are facing this issue after your app is Targeting API29 or higher, please go to this link and check LandLu's Answer:
https://forums.xamarin.com/discussion/171039/saving-files-to-external-storage
Earlier I was accessing Folder path using
return Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
But using this line solved my problem:
return Android.App.Application.Context.GetExternalFilesDir("").AbsolutePath;
You need user's permission on run time even you have mentioned them in your manifest file if you are running Android api level 23 or greater. Check and if user has not yet granted granted READ_EXTERNAL_STORAGE & WRITE_EXTERNAL_STORAGE, use the bellow code;
var permissions = new string[] { Manifest.Permission.ReadExternalStorage, Manifest.Permission.WriteExternalStorage };
RequestPermissions(permissions, 77);
If i use the below path as my download path i can able to download the
file. But i cant able to share the PDF file to google drive, drop box
or any other
System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal)
You are storing files on app's private storage. All files saved to the internal storage are private to your application and other applications ( google drive, drop box or any other ) cannot access them (nor can the user). You can use any public folder for that purpose;
var finalPath = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads);
replace
Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
with
Android.App.Application.Context.GetExternalFilesDir("").AbsolutePath;

Parse FB SDK Login Application Transport Security errors on device but not on simulator XCode 7.1 Swift IOS 9 FBSDK 4.7

Although I have seen similar questions posted here, I have not been able to resolve my issue via plist settings. Any other ideas? Here is where I am:
Adding FB Login to a simple IOS app using the Parse framework
All versions are up-to-date as of today. XCode 7.1, IOS 9, Parse latest, FB SDK latest (4.7)
I have added the specified IOS 9 settings for the FB SDK in my plist. I even combined the lists to include the extra setting required for FB SDK 4.7.
The mystery:
last night I could not get this to run on my simulator, but after
re-adding the plist settings and re-importing all the libraries, I
finally got the FB login screens to show up on the iphone 6 (has been
upgraded to IOS 9). I couldn't get it to run on the simulator but i
left it at that.
now today i tried it on the iphone again and i keep getting the ATS-looking errors.
On the iphone the error is:
Cannot Verify Server Identity. The identity of "m.facebook.com" cannot be verified by Safari. Review the certificate details to continue.
In the XCode console the error is:
FBSDKLog: WARNING: FBSDK secure network request failed. Please verify you have configured your app for Application Transport Security compatibility described at https://developers.facebook.com/docs/ios/ios9
It seems to me that the plist fix is allowing the FB Login to work in my simulator, but why wouldn't it also work on the iphone? Could this have anything to do with Parse? Below is my login code:
class LoginViewController: UIViewController, PFLogInViewControllerDelegate, PFSignUpViewControllerDelegate, UITextFieldDelegate {
#IBAction func FBLoginButtonPressed(sender: AnyObject) {
// Set permissions required from the facebook user account
var permissionsArray : [String]?
permissionsArray = ["user_about_me"]
var userBlock : PFUserResultBlock?
// Login PFUser using Facebook
PFFacebookUtils.logInInBackgroundWithReadPermissions(permissionsArray, block: userBlock)
PFFacebookUtils.logInInBackgroundWithReadPermissions(permissionsArray) {
(user: PFUser?, error: NSError?) -> Void in
if let user = user {
if user.isNew {
print("User signed up and logged in through Facebook!")
} else {
print("User logged in through Facebook!")
}
self.performSegueWithIdentifier(self.tableViewSegue, sender: nil)
} else {
print("Uh oh. The user cancelled the Facebook login.")
}
if let e = error {
print(error)
}
}
print(userBlock.debugDescription)
}
picture of plist
Okay, the mystery has been solved. Parents of teens may be able to relate.
It turns out that last night when the login was working on my teen's iphone, it was set to use mobile data ON PURPOSE to bypass the content filtering settings on our network! The reason I didn't realize this today was because the FB app seemed to be working on the iphone (upon later scrutiny I see that there was just some cached content), and my mac is set to bypass the content filtering. So this is why it worked on the simulator but not on the iphone (when the iphone was set to use wifi and not mobile data).
So the FB error was a red herring. I just wasn't looking down that path...

Apple AirLocation demo App ranging not shows beacons

I have3 Estimote beacons that can be seen with the App store Estimate App.
Now I am trying to run the Apple demo app AirLocation AirLocate
I have changed the UUID in the APLDefaults.m file to the default Estimote UUID _supportedProximityUUIDs = #[[[NSUUID alloc] initWithUUIDString:#"B9407F30-F5F8-466E-AFF9-25556B57FE6D"]];
I have enabled the Region to start startMonitoringForRegion as this stackoverflow says.
But they are not showing up, have you seen this ? Or am I missing some Estimate specific.
Regards
The problem is that AirLocate was written for iOS7, and in iOS8, the permissions model for iBeacons and other location operations has changed. In order to get the program to work on iOS 8 when compiled from XCode 6, you need to add code that requests permission in your AppDelegate. Like this:
if([self.locationManager respondsToSelector:#selector(requestAlwaysAuthorization)]) {
[self.locationManager requestAlwaysAuthorization];
}
This will prompt the user to authorize location operations including beacons. You also need to edit the info.plist for the app, and add a new string key called NSLocationAlwaysUsageDescription with a value like "This app needs access to location services" so the OS can prompt the user for this permission.
After you run your app, you can check in settings to see if this permission has been granted properly.
Another problem I have noticed in iOS 9 is that the calibration sometimes does not work. Seems to be an NSNumber conversion issue. The following edit in APLCalibrationCalculator.m fixed it:-
//measuredPower = [[sample valueForKeyPath:#"#avg.rssi"] integerValue];
measuredPower = [[sample valueForKeyPath:#"#avg.rssi"] intValue];

Issue in Titanium Appcelerator

I am trying to import a project and run it onto iPhone Simulator on Appcelerator, but I am getting a message on console that says,
[WARN] : The Ti.Geolocation.purpose property must be set.
[INFO] : {"source":{"cache":false},"type":"error"}
I have spent more than 2 hours on trying to eradicate the issue.
Also, Please share useful resources about appcelerator app lifecycle.
It says "The Ti.Geolocation.purpose property must be set."
I would try something like
Ti.Geolocation.purpose = "Find restaurants near you";
iOS want to let the user know why your App wants to know his location. The user must allow this Geolocation permission. Thats why you should surround your location requests with an if-statement:
if (Titanium.Geolocation.locationServicesEnabled){
Titanium.Geolocation.getCurrentPosition(function(e){
Ti.API.info(e.coords);
}
}else{
Titanium.UI.createAlertDialog({title:'Location Service', message:'Please turn on your location services.'}).show();
}
The parameters to be sent to the Call, were wrong.

Resources