App notification setting access in EXPO sdk39 - android

Problem started when i realize that Permissions.askAsync not working as expected.
I find Permissions.askAsync not working as expected and it`s cool solution for ios, but i need it for android! So, i add some extra code for this:
Alert.alert(
'No Notification Permission',
'please go to settings and enable notifications permissions manually',
[
{ text: 'cancel', onPress: () => console.log('cancel') },
{
text: 'Allow',
onPress: async () => {
if (Platform.OS === 'android') {
await IntentLauncher.startActivityAsync(
IntentLauncher.ACTION_APP_NOTIFICATION_SETTINGS,
{
data: `package:${Application.applicationId}`,
}
);
}
if (Platform.OS === 'ios') {
Linking.openURL('app-settings:');
}
},
},
],
{ cancelable: false },
);
UPD. construction below works great, but i want to access directly to the APP_NOTIFICATION_SETTINGS.
onPress={() => {
IntentLauncher.startActivityAsync(
IntentLauncher.ACTION_APPLICATION_DETAILS_SETTINGS,
{
data: `package:${Application.applicationId}`,
}
);
}}
Related issue in expo forums https://forums.expo.io/t/opening-device-settings-on-android-using-linking/2059/14
I try to access to the APP_NOTIFICATION_SETTINGS but for some reason i'm getting error like "The app wasn't found in the list of installed apps". Tried it on published project and on standalone (apk) and got the same result. Anyone knows what is the problem?

I realize this is a bit late, but the suggested answer didn't work for me. This is what worked on my device using Android Version 29:
const pkg = Constants.manifest.releaseChannel
? Constants.manifest.android.package
: 'host.exp.exponent';
IntentLauncher.startActivityAsync(
IntentLauncher.ACTION_APP_NOTIFICATION_SETTINGS,
{
extra: { 'android.provider.extra.APP_PACKAGE': pkg }
},
);
TL;DR: The key change here being android.provider.extra.APP_PACKAGE as the extra key name.

Solution:
const pkg = Constants.manifest.releaseChannel
? Constants.manifest.android.package // When published, considered as using standalone build
: 'host.exp.exponent'; // In expo client mode
onPress: () => {
if (Platform.OS === 'android') {
if (Platform.Version >= 26) {
IntentLauncher.startActivityAsync(
IntentLauncher.ACTION_APP_NOTIFICATION_SETTINGS,
{
data: `package:${pkg}`,
},
);
} else {
IntentLauncher.startActivityAsync(
IntentLauncher.ACTION_APPLICATION_DETAILS_SETTINGS,
{
data: `package:${pkg}`,
},
);
}
}
if (Platform.OS === 'ios') {
Linking.openURL('app-settings:');
}
},
Solution description: https://forums.expo.io/t/api-to-open-app-settings/5290/18

Related

How to request to Android for Activity Recognition permission using Expo?

I would like to permit my application to use Activity Recognition and how is it possible? I've tried something like this.
In my app.json, I added below based on Expo docs
"permissions": [
"com.google.android.gms.permission.ACTIVITY_RECOGNITION",
"ACTIVITY_RECOGNITION"
],
Then I am trying to make it appear by:
import { PermissionsAndroid } from 'react-native';
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACTIVITY_RECOGNITION,
{
title: "testtitle",
message:"testmessage",
buttonNeutral: "testbtn1",
buttonNegative: "testbtn2",
buttonPositive: "testbtn3",
}
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log("success");
} else {
console.log("denied");
}
} catch (err) {
console.warn(err);
}
Doing the above method doesn't work. How can I prompt it to the user? Thanks in advance.

how to solve [CoreBluetooth] XPC connection invalid react native?

I'm trying to enable the bluetooth when its off using react native by this code
when its turned on the modal asking permission using bluetooth is showed up, but i want to show modal alert again when the bluetooth turned off. So how to show the modal it can be redirect to settings on both android and ios ?
this.setState({ isEnabledSwitch: !this.state.isEnabledSwitch })
const bluetoothPermission = Platform.OS === 'ios' ? PERMISSIONS.IOS.BLUETOOTH_PERIPHERAL : PERMISSIONS.ANDROID.BLUETOOTH_PERIPHERAL;
request(bluetoothPermission).then((result) => {
console.log('result', result);
const title = '“Wynn Resorts” would like to use Bluetooth';
const description = 'Wynn Resorts needs your Bluetooth enabled to use Digital Key features to access your room with your phone. Please go to Settings > Wynn Resorts and turn on Bluetooth in order to allow access.';
Alert.alert(
title,
description,
[
{
text: 'Cancel',
onPress: () => {
this.isDialogShown = false;
// this.gotoWayfinding();
}
},
{
text: 'Settings',
onPress: () => {
this.isDialogShown = false;
if (Platform.OS === 'ios') {
Linking.openURL('app-settings:')
} else {
this.props.navigation.goBack();
NativeModules.OpenSettings.openNetworkSettings(data => {/*This is intentional*/ });
}
}
}
],
{ cancelable: true }
);
}).catch((error) => {/*This is intentional*/ })
}
but when i try in real device the xcode show logs of
2022-03-14 19:19:05.493649+0700 appsTrial[657:117152] [CoreBluetooth] XPC connection invalid
how to solve this problem?

How to mock PermissionAndroid from react native

I'm building an android app using React-native and using PermissionsAndroid from react-native to get user permission.
import {PermissionsAndroid} from 'react-native'
Now i'm writing unit test and i need to verify the component behaviour based on the Permission.
hence i need to mock PermissionsAndroid.
Is there a way to do this?
jest.mock('react-native//Libraries/PermissionsAndroid/PermissionsAndroid', () => {
const PermissionsAndroid = jest.requireActual(
'react-native//Libraries/PermissionsAndroid/PermissionsAndroid',
);
console.log(PermissionsAndroid);
return {
...PermissionsAndroid,
check: jest.fn(() => new Promise(resolve => resolve(true))),
request: jest.fn(() => new Promise(resolve => resolve(true))),
};
});
This worked for me in 2022
jest.mock('react-
native//Libraries/PermissionsAndroid/PermissionsAndroid', () => {
return {
...jest.requireActual('react- native//Libraries/PermissionsAndroid/PermissionsAndroid'),
request: jest.fn(() => new Promise(resolve => resolve('granted')))
}
})
Because it is async you have to later on await it e.g. with react testing library const element = await findByText(...)
Simply mocking
jest.doMock('react-native', () => ({ PermissionsAndroid: {... did not work for me. Here is how I got it to work specifically mocking requestMultiple and check.
let fineLocationPermissionResult: String = PermissionsAndroid.RESULTS.GRANTED;
let courseLocationPermissionResult: String = PermissionsAndroid.RESULTS.GRANTED;
let fineLocationPermissionGranted = true;
let coarseLocationPermissionGranted = true;
const permissionsAndroidModule = jest.requireActual('react-native/Libraries/PermissionsAndroid/PermissionsAndroid.js');
jest.doMock('react-native/Libraries/PermissionsAndroid/PermissionsAndroid', () => ({
...permissionsAndroidModule,
requestMultiple: () => {
return {
[PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION]: fineLocationPermissionResult,
[PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION]: courseLocationPermissionResult,
};
},
check: () => {
return fineLocationPermissionGranted && coarseLocationPermissionGranted;
},
}));
I've included some of the variables I used in my tests to manipulate the results of the mock but essentially you need to mock the entire module path ('react-native/Libraries/PermissionsAndroid/PermissionsAndroid') and then include the rest of the module that you are not mocking via jest.requireActual.
Solution below:
jest.mock(
'react-native//Libraries/PermissionsAndroid/PermissionsAndroid',
() => ({
PermissionsAndroid: {
request: () => {
true;
},
check: () => {
true;
},
},
})
);
You can mock this from react-native directly, just like:
jest.doMock('react-native', () => ({
PermissionsAndroid: {
request: (permission: string) => {
//whatever you want
},
},
}))
Notice that you might see some issues with the components you are using for that unit test, i.e. it might show an error if you are using <View> from React Native and not mocking it. Given that case, you have to import <View> and then include it in your mock.
import { View } from 'react-native'
...
jest.doMock('react-native', () => ({
View,
PermissionsAndroid: {
request: (permission: string) => {
//whatever you want
},
},
}))

deviceNotReady error : "Registration failed" react-native-twilio-programmable-voice

I am working on react native application and want to integrate the Phone masking feature like Uber do. I have choosen Twilio Phone Masking for this. I have used react-native-twilio-programmable-voice package.
I have integrated this using this link:: https://medium.com/#edzh1/create-a-twilio-voip-calls-in-a-react-native-app-35a729a9613d
I have done server setup successfully, using php. But getting error deviceNotReady error : "Registration failed". I have no idea what I am doing wrong here.
This is initial function I am calling here::
initTwilio = async () => {
const token = await this.getAuthToken();
if (Platform.OS === 'android') {
await this.getMicrophonePermission();
}
const success = await TwilioVoice.initWithToken(token);
if (success.initialized) {
TwilioVoice.addEventListener('deviceReady', () => {
this.setState({ twilioInited: true });
});
TwilioVoice.addEventListener('deviceNotReady', function (data) {
console.log('data', data) // getting error here
});
if (Platform.OS === 'ios') { //required for ios
TwilioVoice.configureCallKit({
appName: 'ReactNativeTwilioExampleApp',
});
}
}
};
getAuthToken = () => {
return fetch('https://myurl/accessToken.php', {
method: 'get',
})
.then(response => response.text())
.catch((error) => console.error(error));
}
Please help, and suggest me what I am doing wrong here.

React native geolocation getCurrentPosition no reponse (android)

I have read and tested a lot of issues but I still can not get geolocation on Android.
I use navigator.geolocation.getCurrentPosition, on iOS everything works fine, but on Android I have no answer to this function, either success or error.
I have installed react-native-permissions to make sure that the user has activated the permissions but it does not change anything because it says that everything is "authorized".
I noticed that it came from GPS of the device. If I activate it manually, everyting works fine. However, I can not find a way to activate it for the user. On iOS, if GPS is not activated, I fall in the error callback and tell user to activate it, but on android, nothing is happennig.
I don't understand why I can't get geolocation only with getCurrentPosition (I have ACCESS_COARSE_LOCATION and ACCESS_FINE_LOCATION in manifest).
Here a part of my code:
componentDidMount() {
navigator.geolocation.getCurrentPosition(
(position) => {
//do my stuff with position value
},
(error) => {
Permissions.getPermissionStatus('location')
.then((response) => {
if (response !== "authorized") {
Alert.alert(
"Error",
"We need to access to your location",
[
{
text: "Cancel",
onPress: () => {
// do my stuff
}, style: 'cancel'
},
{
text: "Open Settings",
onPress: () => Permissions.openSettings()
}
]
);
} else {
// do my stuff
}
});
},
{ enableHighAccuracy: true, timeout: 2000, maximumAge: 1000 }
);
}
Does anyone have any idea ?
Thank you
You should need to enable GPS on android
For enabling location/gps on Android I can recommend this module:
https://github.com/Richou/react-native-android-location-enabler
It is using the standard Android dialog for location:
like this
import React, { Component } from "react";
import { Text, StyleSheet, View, Platform } from "react-native";
import RNAndroidLocationEnabler from "react-native-android-location-enabler";
export default class index extends Component {
componentDidMount() {
this.getLocation();
}
onLocationEnablePressed = () => {
if (Platform.OS === "android") {
RNAndroidLocationEnabler.promptForEnableLocationIfNeeded({
interval: 10000,
fastInterval: 5000,
})
.then((data) => {
this.getLocation();
})
.catch((err) => {
alert("Error " + err.message + ", Code : " + err.code);
});
}
};
getLocation = () => {
try {
navigator.geolocation.getCurrentPosition(
(position) => {
//do my stuff with position value
},
(error) => {
Permissions.getPermissionStatus("location").then((response) => {
if (response !== "authorized") {
Alert.alert("Error", "We need to access to your location", [
{
text: "Cancel",
onPress: () => {
// do my stuff
},
style: "cancel",
},
{
text: "Open Settings",
onPress: () => Permissions.openSettings(),
},
]);
} else {
// do my stuff
}
});
},
{ enableHighAccuracy: true, timeout: 2000, maximumAge: 1000 }
);
} catch (error) {
this.onLocationEnablePressed();
}
};
}

Categories

Resources