Manifest for Android - Allow Permissions

Let’s take the geolocation sample as is. “Run” it with phonegap basic and get the apk. Download the apk onto an Android device. The install says it doesn’t need any special permissions. But we know it does. And when you run the app it fails, as the permission is not set. You can not set the permission on, as it’s not in the “manifest” of the APK as a settable permission.
How do I make that sample project work on Android devices? EG, how do I note the need for the permission in the project?
Or, if I must use the phonegap CLI, then I still need to know how to do this, as it is not discussed anywhere in your docs that I can find, nor answered in this forum.
I see a couple of topics, and one talks of putting a PLUGIN xml definition in the config.xml - but where? I tried it just before the ending widget tag, but it did not ask for permissions on install, etc. Could someone answer this fully, as it looks like I’m not the only one having this problem.

The cordova-plugin-geolocation is used to set the permissions. The plugin now does nothing more than that as the geolocation services are now a part of the html5 spec and included in the webview.

And how do I set the project so that this plug in is enabled? EG: how do I get the project into an APK file that has an appropriate manifest for the geolocation service to work? As just using the sample project in NSbasic (the basic version), does not create an APK file that will allow the app to use geolocation services of the device. Remember, the user always has to agree to allow the app to access location services. This question is not being asked at install - one has to assume it is not in the manifest of the APK to ask for the permission.

This may help - and thanks in advance.
NSB version Developer Edition
Taking APK file from default phonegap account and placing on private server and downloading to device from that server URL.

To clarify what @PPetree said, use the Cordova Geolocation plugin instead of the one built into the browser.

You will then the permission prompt.

Unfortunately, that doesn’t mean a thing to me. The doc that link in npm corresponds to the sample NSB geolocation program. So, I’m confused what you want me to change to make this work. The calls in the sample are:
gps=navigator.geolocation.watchPosition(onGeolocation, errorCallBack, options)

and there are no other references to geolocation = not in the config.xml or manifest.json. So what do I change?

And again, thanks

Most feature sets like the camera etc are accessed with plugins. The plugins do all the heavy lifting for you and present you with a simple JavaScript interface. Geolocation used to be handled with a plugin but now, all it does is handle permissions. In AppStudio, you have to add the geolocation plugin to your project and provide permission strings to be used in prompting the user.

PPetree - thank for your patience with me. I’ve managed to find another post you made where you actually posted what appears to be the config.xml tags to add. I added them just before the last </widget> tag. Here they are for those who would like to know - not sure they are fully correct - PP - can you comment if this is the correct placement and xml content?

 <plugin name="cordova-plugin-geolocation" source="npm"/>
 <edit-config mode="merge" file="*-Info.plist" target="NSLocationWhenInUseUsageDescription">
 <string>need location access to find things nearby</string>

Also, anyone who was using the default account of Phonegap, create your own account. You’ll really want to look at the plugins tab of the app that is only available with a private free account. If the geolocation plugin is not showing, then I’m presuming the app won’t be able to access it.

Adding of the above xml in config.xml got the plugin to appear in PhoneGap. However, the app still claims no permissions needed at install and the geolocation permission is not assigned to the app.

Getting closer :slight_smile: I’m guessing the comment PP made about permission strings is the next hurtle. Thanks again for all the help for an obvious newbee.

Also, you won’t be prompted for permission until you actually try to access the geolocation.

First, I changed the Config.xml to your suggestion in that original post. Which is:

<plugin name="cordova-plugin-geolocation" spec="4.0.1">
     <variable name="GEOLOCATION_USAGE_DESCRIPTION" value="App uses geolocation to determine where you are." />

With either plugin definition, the plugin shows in PhoneGap and they both react the same. The app loads with no permissions requested, and when I push the start button on the app, it presents a dialog saying Geolocation – application does not have sufficient geolocation permissions. with OK only. Pressing ok continues the program which eventually times out.

Okay, I know you’re learning so this is a great opportunity to learn an important lesson… Users screw things up! LOL even if you are granted permission on startup, the user may revoke permission so on the next startup you may NOT have permission. What you do is use “yet another plugin” (get used to that term), the cordova-plugin-device allows you to check a lot of things (like if you’re online) so use that to check if you have permission to access location before you enable that start button. (Having said all that, make sure you have location services turned on else you won’t get prompted.)

Definitely learning this. 57 years of programming, even a little with AppForge in the Palm Pilot days. But mostly desktop visual studio and back in the day, IBM and DEC mainframes.
I can go into the permissions for the app, where the user would allow/block it. And it’s not even given as a permission for the app - eg - as I’ve said, the app is not given the permission to be set as on or off.
I’m guessing it’s a permission that has to be in the manifest of the apk (eg, in the config.xml of NSB). I’m guessing something in this area of the config.xml:

<preference name="permissions" value="none"/>
<!-- sample preference specifications -->
<!-- <preference name="autorotate" value="false" readonly="true"/> -->
<!-- <preference name="orientation" value="default" /> -->
<!-- <preference name="fullscreen" value="true" /> -->

Also, when I run the sample in AppStudio on windows, it starts chrome and when I press the start button, it does ask permission allow/deny for the geoloc data. EG, the app works fine other than on the device.

Thanks again Phil

Tried adding these, but PhoneGap says the config.xml is malformed when I do.

 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

There are several of us around here who’re older than coal. My first language was 8086 assembler, then C on the original windows sdk and on and on.

This is definitely a learning curve. The tool chain “compiling” the apps is quite fragile. There’s tons of plugin conflicts (plugin A has a bug and the later version that plugin fixes that bug but requires a CLI version that breaks other plugins - we call it plugin hell). It can get frustrating but if you stay patient, you’ll figure it all out.

So, adding uses-permission obviously won’t work. The CLI (command line interface) which builds the apps is quite particular about what and how it accepts information and parameters. Since this is working in chrome, try posting your entire config.xml (scrub out any sensitive info) and let us look at it.

config.xml - direct from sample for basic - I made no changes except as noted below

<?xml version="1.0" encoding="UTF-8"?>
xmlns = ""
xmlns:gap = ""
id = "com.nsbasic.{id}"
versionCode = "1"
version = "{version}">

<preference name="phonegap-version" value="{phoneGapVersion}" />

<!-- Icons -->
<icon src='{icon}' />

<platform name = 'android'>
    <icon src='icons/android/ldpi.png' platform='android' qualifier='ldpi' />
    <icon src='icons/android/mdpi.png' platform='android' qualifier='mdpi' />
    <icon src='icons/android/hdpi.png' platform='android' qualifier='hdpi' />
    <icon src='icons/android/xhdpi.png' platform='android' qualifier='xhdpi' />
    <icon src='icons/android/xxhdpi.png' platform='android' qualifier='xxhdpi' />

<platform name = 'ios'>
    <icon src='icons/ios/icon-40.png' platform='ios' width='40' height='40' />
    <icon src='icons/ios/icon-40@2x.png' platform='ios' width='80' height='80' />
    <icon src='icons/ios/icon-50.png' platform='ios' width='50' height='50' />
    <icon src='icons/ios/icon-50@2x.png' platform='ios' width='100' height='100' />
    <icon src='icons/ios/icon-60.png' platform='ios' width='60' height='60' />
    <icon src='icons/ios/icon-60@2x.png' platform='ios' width='120' height='120' />
    <icon src='icons/ios/icon-60@3x.png' platform='ios' width='180' height='180' />
    <icon src='icons/ios/icon-72@.png' platform='ios' width='72' height='72' />
    <icon src='icons/ios/icon-72@2x.png' platform='ios' width='144' height='144' />
    <icon src='icons/ios/icon-72@3x.png' platform='ios' width='216' height='216' />
    <icon src='icons/ios/icon-76.png' platform='ios' width='76' height='76' />
    <icon src='icons/ios/icon-76@2x.png' platform='ios' width='152' height='152' />
    <icon src='icons/ios/icon-small.png' platform='ios' width='29' height='29' />
    <icon src='icons/ios/icon-small@2x.png' platform='ios' width='58' height='58' />
    <icon src='icons/ios/icon.png' platform='ios' width='57' height='57' />
    <icon src='icons/ios/icon@2x.png' platform='ios' width='114' height='114' />
    <icon src='icons/ios/icon-1024.png' platform='ios' width='1024' height='1024' />

<!-- Splash Screens -->
<preference name='SplashScreenDelay' value='2000' />
<preference name='AutoHideSplashScreen' value='true' />
<splash src='{splashscreen}'/>
<plugin name='cordova-plugin-splashscreen' source='npm' />

<platform name='android'>
    <splash src='splash/android/res-long-land-hdpi/splash.png' qualifier='long-land-hdpi' />
    <splash src='splash/android/res-long-land-ldpi/splash.png' qualifier='long-land-ldpi' />
    <splash src='splash/android/res-long-land-mdpi/splash.png' qualifier='long-land-mdpi' />
    <splash src='splash/android/res-long-land-xhdpi/splash.png' qualifier='long-land-xhdpi' />
    <splash src='splash/android/res-long-land-xxhdpi/splash.png' qualifier='long-land-xxhdpi' />
    <splash src='splash/android/res-long-land-xxxhdpi/splash.png' qualifier='long-land-xxxhdpi' />
    <splash src='splash/android/res-long-port-hdpi/splash.png' qualifier='long-port-hdpi' />
    <splash src='splash/android/res-long-port-ldpi/splash.png' qualifier='long-port-ldpi' />
    <splash src='splash/android/res-long-port-mdpi/splash.png' qualifier='long-port-mdpi' />
    <splash src='splash/android/res-long-port-xhdpi/splash.png' qualifier='long-port-xhdpi' />
    <splash src='splash/android/res-long-port-xxhdpi/splash.png' qualifier='long-port-xxhdpi' />
    <splash src='splash/android/res-long-port-xxxhdpi/splash.png' qualifier='long-port-xxxhdpi' />
    <splash src='splash/android/res-notlong-land-hdpi/splash.png' qualifier='notlong-land-hdpi' />
    <splash src='splash/android/res-notlong-land-ldpi/splash.png' qualifier='notlong-land-ldpi' />
    <splash src='splash/android/res-notlong-land-mdpi/splash.png' qualifier='notlong-land-mdpi' />
    <splash src='splash/android/res-notlong-land-xhdpi/splash.png' qualifier='notlong-land-xhdpi' />
    <splash src='splash/android/res-notlong-land-xxhdpi/splash.png' qualifier='notlong-land-xxhdpi' />
    <splash src='splash/android/res-notlong-land-xxxhdpi/splash.png' qualifier='notlong-land-xxxhdpi' />
    <splash src='splash/android/res-notlong-port-hdpi/splash.png' qualifier='notlong-port-hdpi' />
    <splash src='splash/android/res-notlong-port-ldpi/splash.png' qualifier='notlong-port-ldpi' />
    <splash src='splash/android/res-notlong-port-mdpi/splash.png' qualifier='notlong-port-mdpi' />
    <splash src='splash/android/res-notlong-port-xhdpi/splash.png' qualifier='notlong-port-xhdpi' />
    <splash src='splash/android/res-notlong-port-xxhdpi/splash.png' qualifier='notlong-port-xxhdpi' />
    <splash src='splash/android/res-notlong-port-xxxhdpi/splash.png' qualifier='notlong-port-xxxhdpi' />

<platform name = 'ios'>
  <splash src='splash/ios/Default.png' width='320' height='480' />
  <splash src='splash/ios/Default@2x.png' width='640' height='960' />
  <splash src='splash/ios/Default-568h@2x.png' width='640' height='1136' />
  <splash src='splash/ios/Default-667h@2x.png' width='750' height='1334' />
  <splash src='splash/ios/Default-Portrait.png' width='768' height='1024' />
  <splash src='splash/ios/Default-Landscape.png' width='1024' height='768' />
  <splash src='splash/ios/Default-Portrait@2x.png' width='1536' height='2048' />
  <splash src='splash/ios/Default-Landscape@2x.png' width='2048' height='1536' />
  <splash src='splash/ios/Default-Portrait-736h@3x.png' width='1242' height='2208' />
  <splash src='splash/ios/Default-Landscape-736h@3x.png' width='2208' height='1242' />

<preference name="permissions" value="none"/>
<!-- sample preference specifications -->
<!-- <preference name="autorotate" value="false" readonly="true"/> -->
<!-- <preference name="orientation" value="default" /> -->
<!-- <preference name="fullscreen" value="true" /> -->

<!-- Platforms: Customize as needed. -->
   <gap:platform name="android" />
   <gap:platform name="ios" />
   <gap:platform name="winphone" />

<plugin name="cordova-plugin-statusbar" source="npm" />
  <preference name="StatusBarOverlaysWebView" value="{phoneGapStatusBarOverlay}" />
  <preference name="StatusBarBackgroundColor" value="{phoneGapStatusBarColor}" />
  <preference name="StatusBarStyle" value="{phoneGapStatusBarStyle}" />

<plugin name="cordova-plugin-whitelist" source="npm" />
  <allow-navigation href="*" />
  <access origin="*" />
  <allow-intent href="*" />

Then I successfully added before the ending widget tag:

<plugin name="cordova-plugin-geolocation" spec="4.0.1">
        <variable name="GEOLOCATION_USAGE_DESCRIPTION" value="App uses geolocation to determine where you are." />

   <platform name="android">
        <uses-permission name="android.permission.ACCESS_COARSE_LOCATION" />
        <uses-permission name="android.permission.ACCESS_FINE_LOCATION" />
        <uses-permission name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />


The plugin shows in PhoneGap, but the permissions are not in the andriodmanifest.xml in the APK file, just the normal NETWORK and INTERNET permissions.

Phil, did you see this?? Thanks in advance.

Sorry, no, I had missed this one.

First, some observations:

  1. All of these permissions are set by the plugin.
  2. I’m not aware of any plugin commands or HTML5 spec commands that actually use the EXTRA_COMMANDS and only one native command)
  3. If you ask for FINE_LOCATION you typically don’t need COARSE. COARSE will get you within a block, FINE if you’re drawing a pin on a map.
  4. Using direct Android permissions like you added requires an addition to the widget definition. Specifically you need:

So here are my questions:

  1. What minimum SDK are you setting for Android? (minimum should be 19)
  2. What is the target SDK? (minimum should be 23)
  3. What CLI version are you specifying? (8.1.1 seems to be working reliably)
  4. Are there any compile errors in the log (hint: you can get an APK generated with compile errors - grep the log file using terms like permissions and geolocation and navigator)

To start, I’d add the widget command, remove the permissions you’re setting, verify your min and target sdk settings. Add in the diagnostic plugin and use the isLocationAuthorized() to see what the device says.

Phil - thanks -
I’m not using the CLI, but the menu item “Make Native App with PhoneGap Build”. If you look back at the original post, I ask if I need to use CLI to set plugins/permissions.
Since I’m not using CLI, there’s no SDK versions to set that I’m aware of.
No compile errors.
I’ll look at your suggestions and get back on that.

I sent you a PM.

Is an email reply to a PM a PM?