My expo react native application comunicates with a zebra printer via a HTTP post request this works just fine in web , however on android and I suspect also iOS this isnt the case, from what i gather i need to add something along the lines of :
<uses-permission android:name="android.permission.INTERNET" />
Into androidmanifest.xml however expo doesnt give you direct access to that file , so i need to make a expo plugin that puts the permission into androidmanifest via expo.
I found this post teaching how to remove permissions however my current case requires me to add permissions ill still link the code from the post down here:
const { withAndroidManifest } = require("#expo/config-plugins")
module.exports = function androiManifestPlugin(config) {
return withAndroidManifest(config, async config => {
let androidManifest = config.modResults.manifest
// add the tools to apply permission remove
androidManifest.$ = {
...androidManifest.$,
"xmlns:tools": "http://schemas.android.com/tools",
}
// add remove property to the audio record permission
androidManifest["uses-permission"] = androidManifest["uses-permission"].map(
perm => {
if (perm.$["android:name"] === "android.permission.RECORD_AUDIO") {
perm.$["tools:node"] = "remove"
}
return perm
}
)
return config
})
}
Does anyone know how to add http permissions to my expo app? Thanks.
To add permissions you do not need expo-plugins.
You simply need to add the permission in your app.json (or app.config.js if you have dynamic configuration)
On Android, permissions are little bit simpler than iOS. In the managed workflow, permissions are controlled via the android.permissions property in your app.json file.
https://docs.expo.dev/guides/permissions/
Related
Hi I'm working on a react native app and I'm using expo-media-library to get user's photos but, only on android, when I try to ask for permissions using the following command I get the status as never_ask_again even if it's the first time I'm asking for permissions and I don't event refuse them because the popup didn't show up.
MediaLibrary.requestPermissionsAsync()
Then I tried to manually give permissions to the app, through settings, but when expo try to access to media library, here's the error that occurs.
Error: Missing MEDIA_LIBRARY permissions.
I also tried to use react-native-permissions to ask for permissions, but the result is the same.
Maybe someone has had this problem before and can help me, thanks.
=> Do you add this in your manifest file or not..?
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
const permission = await Permissions.getAsync(Permissions.CAMERA_ROLL);
if (permission.status !== 'granted') {
const newPermission = await Permissions.askAsync(Permissions.CAMERA_ROLL);
if (newPermission.status === 'granted') {
//its granted.
}
} else {
....your code
}
I'm making an app using flutter that uses the contacts(using contact_services plugin) from user's phone. Thus it needs as well to give the ability to add a new contact using the system default add contact page. However there isn't such functionality in contacts_services. What is the way using plugin or existing contact_services plugin to open the add new contact page?
void openAddContacts() async{
if (Platform.isAndroid) {
final AndroidIntent intent = AndroidIntent(
action: 'ContactsContract.Intents.Insert.ACTION',
category: 'ContactsContract.RawContacts.CONTENT_TYPE',
);
await intent.launch();
}
}
This may help you : https://github.com/differenz-system/Addressbook.Flutter
Or if you xant to dive deeper and want to understand the mechanism under the hood, I suggestion you to use Platform Channel to communicate with native codes. Here is an example proposed by Google for address-book : https://developers.google.com/protocol-buffers/docs/darttutorial
if you use this plugin https://pub.dev/packages/contacts_service you can look full working example here https://github.com/lukasgit/flutter_contacts/blob/master/example/lib/main.dart
Add permissions
Android #
Add the following permissions to your AndroidManifest.xml:
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
iOS #
Set the NSContactsUsageDescription in your Info.plist file
<key>NSContactsUsageDescription</key>
<string>This app requires contacts access to function properly.</string>
And after you can use code from the example by link above.
My question is that, if it is possible to get a variable from a .properties or .txt file. I need that in order to save the endPoint, the server IP address. That way, every time that the IP address is changed, all you need to do is change the IP on the file, instead of compile the code again and build the apk, and install it again on the device. Any tips will be welcome.
UPDATE
I've been trying to use this plugin :File , but with no sucess. I want to use readAsText(path,file) but all i get is undefined
import { File } from '#ionic-native/file/ngx';
constructor(
....
private file : File,
....
) { }
async test(){
this.promise = this.file.readAsText('file:///data/','ipAddress.txt');
await this.promise.then(value => {
console.log(value)
}).catch(error=> console.log("nao existe"))
}
And i'm getting the following error:
ERROR Error: Uncaught (in promise): FileError: {"code":1,"message":"NOT_FOUND_ERR"}
UPDATE
Problem Solved. I was trying to acess to the internal storage, and the document was on the external storage. Make sure you use URI, path on android are different from computer. You need URI.
file:///storage/emulated/0/Android/data/
I called the method right on, when device's ready on app.component.ts
ngOnInit() {
.....
this.initializeApp();
}
initializeApp() {
this.platform.ready().then(() => {
this.api.getURL();
.....
});
}
Hope i can help the next with the same problem I had.
I am using a real android device (version 5.1)
I am able to determine my position using react-native-maps (correct blue point position on map inside my app ) + I am able use google maps app and go to my position (GPS works).
I am using a big timeout, toggling enableHighAccuracy to true and false, remove options ... etc . all failed to get navigator.geolocation to get data.
Here is my code:
var options = {
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0
};
function success(pos) {
var crd = pos.coords;
console.log('Your current position is:');
console.log(`Latitude : ${crd.latitude}`);
console.log(`Longitude: ${crd.longitude}`);
console.log(`More or less ${crd.accuracy} meters.`);
};
function error(err) {
console.warn(`ERROR(${err.code}): ${err.message}`);
};
navigator.geolocation.getCurrentPosition(success, error, options);
I am getting : ERROR(3): Location request timed out
I know it's too late, but it can help someone else.
Geolocation has been extracted from react native .60 version. If you need an alternative solution
Install react-native-community/geolocation :
npm install #react-native-community/geolocation --save
react-native link #react-native-community/geolocation
Then, to request access to location, you need to add the following line to your app's AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Usage :
import Geolocation from '#react-native-community/geolocation';
Geolocation.getCurrentPosition(info => console.log(info));
Two things.
1) That is actually not a high timeout for a high accuracy response if the coordinates are not cached
2) Some devices have problems with the highAccuracy setting.
Try putting 30000 ms as timeout and remove the high accuracy until you find one setting that works.
Edit: I found the long bug I was remembering form React Native: https://github.com/facebook/react-native/issues/7495
So, try this:
1) Remove maximumAge property
2) If that does not work, remove the third parameter and use the default values from the native module. Meaning, don't send the options object. That should work.
Removing maximumAge solved the issue here! Just in case someone is still having this problem in 2019 or later
To request access to location, you need to add the following line to your app's AndroidManifest.xml: <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />.
For an android with API >= 23 you need to require an additional step to check for: you need to request the ACCESS_FINE_LOCATION permission using the PermissionsAndroid API.
PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
{
title: "Location Accessing Permission",
message: "App needs access to your location"
}
);
And only after that run navigator.geolocation.getCurrentPosition(success, error, options);
I used this and it works fine: {enableHighAccuracy: false, timeout: 50000}
async watchPosition() {
console.log('watchPosition');
await navigator.geolocation.getCurrentPosition(
(position) => {
console.log('Position -> ',position);
},
(error) => console.log(error)
{enableHighAccuracy: false, timeout: 50000}
);
}
Let me start by saying I've found several proposed solutions online, but none of them seem to work for me.
Issue:
I have a meteor app I'm trying to run on android. For this, I've deployed the app on Heroku and I call the run android-device command using the --mobile-server https://myapp.heroku.com parameter.
I permanently receive the error
"XMLHttpRequest cannot load https://myapp.heroku.com/sockjs/... . No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:12848' is therefore not allowed access. The response had HTTP status code 404.", source: http://localhost:12848/ (0)
Here is what I've tried so far:
I set ROOT URL at meteor startup:
process.env.ROOT_URL = "https://myapp.heroku.com";
I tried setting the Access Control like this, server-side at meteor startup:
WebApp.connectHandlers.use(function(req, res, next) {
res.setHeader("Access-Control-Allow-Origin", "*");
res.header('Access-Control-Allow-Methods', 'GET, PUT, POST, DELETE, OPTIONS');
res.header('Access-Control-Allow-Origin', 'http://localhost:3000');
res.header('Access-Control-Allow-Origin', 'https://myapp.heroku.com');
res.header('Access-Control-Allow-Origin', 'http://localhost:12848');
res.header('Access-Control-Allow-Origin', 'http://meteor.local');
res.header("Access-Control-Allow-Headers", "Content-type,Accept,X-Custom-Header");
return next();
});
I tried to use the browser-policy package, like this, server-side at meteor startup:
BrowserPolicy.content.allowSameOriginForAll();
BrowserPolicy.content.allowOriginForAll('*');
BrowserPolicy.content.allowOriginForAll('http://meteor.local');
BrowserPolicy.content.allowOriginForAll('https://myapp.heroku.com');
BrowserPolicy.content.allowOriginForAll('https://*.myapp.heroku.com');
BrowserPolicy.content.allowEval();
I tried adding access rules to "mobile-config.js":
App.accessRule("*");
I made sure the name in the "package.json" file under root is identical to the App name under "mobile-config.js"
What else am I missing?
Edit:
I've also tried adding the express and cors packages to whitelist local host:
var whitelist = [
'http://localhost:3000',
'http://localhost:12848',
'https://myapp.heroku.com'
];
var corsOptions = {
origin: function(origin, callback){
var originIsWhitelisted = whitelist.indexOf(origin) !== -1;
callback(null, originIsWhitelisted);
},
credentials: true
};
app.use(cors(corsOptions));
Also tried to enable pre-flight, like this:
app.options('*', cors())
This is probably the stupidest problem I ever ran into. Trying to run the app using the --mobile-server https://myapp.heroku.com parameter was wrong. Instead, it should be https://myapp.herokuapp.com
That was it. That was the problem all along...
Adding '*' to whitelist should do the job. The ultimate solution lies within config.xml, this should be helpful: https://stackoverflow.com/a/36124935/8056323