I'm working on a demo app for android that needs to get information about the phone, the SIM, the network, etc.. I put all the code in a plugin and my Java function that that retrieves the SIM info looks like this:
private boolean getSIMInfo(CallbackContext cbc) throws JSONException {
// tm is a TelephonyManager instantiated in initialize
JSONObject res = new JSONObject()
.put("carrierID", tm.getSimCarrierId())
.put("carrierName", tm.getSimCarrierIdName())
.put("countryIso", tm.getSimCountryIso())
.put("operator", tm.getSimOperator())
.put("operatorName", tm.getSimOperatorName())
.put("state", tm.getSimState())
.put("msisdn", tm.getLine1Number()) // <== Requires permission
;
cbc.success(res);
return true;
}
As long as I dont call getLine1Number() everything goes fine.
getLine1Number() requires either android.permission.READ_PHONE_STATE or a.p.READ_SMS or a.p.READ_PHONE_NUMBERS to be set. I first declared a.p.READ_PHONE_STATE in plugin's plugin.xml and I checked it was injected into AndroidManifest.xml.
The platform part of the plugin.xml looks like this:
<platform name="android">
<config-file target="res/xml/config.xml" parent="/*">
<feature name="TelPlugin">
<param name="android-package" value="org.buguigny.CordovaPlugin.TelPlugin"/>
</feature>
</config-file>
<config-file parent="/*" target="AndroidManifest.xml" />
<config-file target="AndroidManifest.xml" parent="/*">
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
</config-file>
<source-file src="src/TelPlugin.java" target-dir="src/org/buguigny/CordovaPlugin/TelPlugin" />
</platform>`
Upon execution I get the error:
getLine1NumberForDisplay: Neither user 10190 nor current process has
android.permission.READ_PHONE_STATE, android.permission.READ_SMS, or
android.permission.READ_PHONE_NUMBERS
I tried with the other permissions: same error.
Any idea what I'm doing wrong ?
On Android >=6.0, Android app should request permission runtime.
So in Cordova, you can use the permission plugin like following
permissions.requestPermission(permissions.READ_PHONE_STATE, success, error);
function error() {
console.warn('Camera permission is not turned on');
}
function success( status ) {
if( !status.hasPermission ) error();
}
Related
I made a cordova plugin for Android applications, but unlike other plugins, this one only uses an Application (App.java) and not a CordovaPlugin class.
When I try to install it for the first time using cordova plugin add, it works fine. When I try to remove it using cordova plugin rm, it doesn't remove the folder from node_modules and keeps the plugin dependency name in the package.json. Besides, it removes some code from the manifest that belongs to another plugin (I've seen this is a consecuence of the edit-file in the plugin.xml, I need to add the Application name to the manifest) and if I try to install it again I will get an error (because it's still holding the node_modules dependency) unless I update the version of the plugin.
Here's my plugin.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android" id="com.test.plugin.applicationTest" version="1.0.0" platform = "Android">
<name>codova-app-plugin</name>
<description>Test</description>
<author>test</author>
<license>Apache 2.0</license>
<keywords>cordova, application</keywords>
<platform name="android">
<config-file parent="/*" target="res/xml/config.xml">
<feature name="applicationTest">
<param name="android-package" value="com.test.plugin.applicationTest" />
</feature>
</config-file>
<source-file src="src/android/App.java" target-dir="src/com/test/plugin/applicationTest" />
<config-file target="AndroidManifest.xml" parent="/*">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</config-file>
<edit-config file="AndroidManifest.xml" target="/manifest/application" mode="merge">
<application android:name="com.test.plugin.applicationTest.App"/>
</edit-config>
</platform>
</plugin>
Why it isn't removing the node_modules? and what can I do to avoid the deletion of the AndroidManifest tags ?
Edit:
If I remove the edit-config and instead use a hook, I won't delete the AndroidManifest tags, but they won't get executed or throw EACCESS error. Besides, it keeps the node_modules dependencies.
<hook type="after_plugin_install" src="scripts/nameManifest.js" /> -- won't execcute
<hook type="before_plugin_uninstall" src="scripts/uninstallPackage.sh" /> -- EACCESS error
For now, the best I can do is to remove that edit-config and create hooks for the edition of the application name and the execution of npm uninstall
I am developing a cordova plugin and I want to publish now. However, I need to invoke some third party plugins in my plugin, such as cordova-plugin-camera and cordova-plugin-googlemaps. Currently I'm merging everything and given source path in plugin.xml manually, which is a poor code management. I want to know if I can add the dependencies in plugin.xml and free my work.
Actually, I'm helping my friends to solve his problem. Read this Doc of plugin.xml. And specifically:
The <dependency> tag allows you to specify other plugins on which
the current plugin depends. The plugins are referenced by their unique
npm ids or by github url.
Therefore, what you should do is simple:
<dependency id="cordova-plugin-camera" version="^1.1.1" />
but be careful when you dealing with feature and permission in manifest.xml, if you still have those issues after addinig those dependencies, you need add them in plugin.xml as well:
<config-file target="res/xml/config.xml" parent="/*">
<feature name="Camera">
<param name="android-package" value="org.apache.cordova.camera.CameraLauncher"/>
</feature>
</config-file>
<config-file target="AndroidManifest.xml" parent="/*">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</config-file>
Hopefully it will solve your problem.
I am writing a Cordova plugin for Android, and it is not registering a JavaScript object to window and I would like to know why.
In the plugin's plugin.xml, I am using <js-module> to register the js object to window object:
<platform name="android">
<js-module src="www/Loading.js" name="loader">
<clobbers target="loader" />
</js-module>
<config-file target="res/xml/config.xml" parent="/*">
<feature name="Loading">
<param name="android-package" value="org.apache.cordova.loader.Loading" />
<param name="onload" value="true" />
</feature>
</config-file>
...
</platform>
The plugin compiles, but when I do window.loader in Chrome debugger, it is undefined. I tried changing the value of target in <clobbers> to window.loader to no avail.
www/Loading.js file is exporting a JavaScript object using module.exports:
function Loading() {
...
}
module.exports = new Loading();
Any suggestions?
Resolved. This is a very specific case for my app. I am copying everything from the sandboxed environment to an internal path and booting the app from the internal path. Turns out the app was not copying the www/Loader.js file.
A plugin I am using to access the AccountManager in android through phonegap requires some permissions. I am using PhoneGap 3.4.0. In the config.xml in my www folder there is a tag
<preference name="permissions" value="none"/>
I am having the hardest time figuring out how I add permissions to this config.xml file. All the other questions I've found say to alter the manifest file, but that feels wrong with me setting so many things in this config.xml file.
How do I add the permissions in the config.xml file? Comma separated list in the tag referenced above?
Here are the permissions I have added to my manifest file:
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
Please check you have declared the following.
<feature name="NetworkStatus">
<param name="android-package" value="CDVConnection" />
</feature>
Network status will be the feature name and value will be your class name.
In Android Manifest,
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
Aso check cordova_plugin.js
cordova.define('cordova/plugin_list', function(require, exports, module) {
module.exports = [{
"file": "plugins/org.apache.cordova.dialogs/www/notification.js",
"id": "org.apache.cordova.dialogs.notification",
"merges": ["navigator.notification"]
}, {
"file": "plugins/org.apache.cordova.network-information/www/network.js",
"id": "org.apache.cordova.network-information.network",
"clobbers": ["navigator.connection", "navigator.network.connection"]
}];
module.exports.metadata = // TOP OF METADATA
{
"org.apache.cordova.device": "0.2.8",
"org.apache.cordova.network-information": "0.2.7"
}
});
These are some permission types.
Thanks.
I'm writting an android and iphone app using phonegap 3.0.
So far I have been only compiling the apps remotely using phonegap build.
Now I'm trying to add the geolocation plugin to my app, and in iphone was easy, since I only had to modify the config.xml file.
<feature name="Geolocation">
<param name="ios-package" value="CDVLocation" />
</feature>
So far so good, the problem was that when adding geolocation to android, the documentation indicates that I have set the following configuration:
(in app/res/xml/config.xml)
<feature name="Geolocation">
<param name="android-package" value="org.apache.cordova.GeoBroker" />
</feature>
(in app/AndroidManifest.xml)
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
But I don't have an AndroidManifest.xml file. I could generate the complete android app using:
cordoba platform add android
But I'm not sure if this is what I should do.
Is is what I should be doing? or there is a way to add geolocation without generating the entire android project?
I am a bit confused because you say you are using phonegap 3.0 and you also mention phonegap-build (highest is 2.9). If you are in fact using phonegap-build, the only thing you need is in your config.xml:
<feature name="http://api.phonegap.com/1.0/geolocation"/>
I had the same problem. My geolocation worked on IOS but not on Android. So I Added to config.xml
<feature name="http://api.phonegap.com/1.0/geolocation"/>
As explained by Dom.This was not sufficient. I wanted to share what I did step by step because I lost about 18h of dev time looking for the solution.
This however did not reslove the problem. So I added the plugin using my IDE.
This added the following to the config:
<plugin name="cordova-plugin-geolocation" version="2.2.0" />
I then went inside the plugin.xml under the plugin directorty.
And looked if the following was added.
<!-- android -->
<platform name="android">
<config-file target="AndroidManifest.xml" parent="/*">
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</config-file>
...
It was, so I rebooted the device. (on the Ionic forum they say, it might help)
When reinstalling the app I checked for the permission. And it was added. So for the bad Q of the last pic but I took a pic with my cam for it. Hope this helps