Cordova adds unwanted permission to AndroidManifest.xml when building from CLI

10,548

Solution 1

In your project, edit the file plugins/org.apache.cordova.media/plugin.xml You'll see the android specific configuration

   <platform name="android">
        <config-file target="res/xml/config.xml" parent="/*">
            <feature name="Media" >
                <param name="android-package" value="org.apache.cordova.media.AudioHandler"/>
            </feature>
        </config-file>

        <config-file target="AndroidManifest.xml" parent="/*">
            <uses-permission android:name="android.permission.RECORD_AUDIO" />
            <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
            <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
            <uses-permission android:name="android.permission.READ_PHONE_STATE" />
        </config-file>
...

remove the line <uses-permission android:name="android.permission.RECORD_AUDIO" />like this the permission will not be added each time you build.

As the permission has already been added to AndroidManifest.xml, you'll have to remove it manually and then it should not come back next time you build.

Solution 2

To keep plugins from re-adding unnecessary permissions edit platforms/android/android.json.

Locate these lines and remove them:

{
    "xml": "<uses-permission android:name=\"android.permission.RECORD_AUDIO\" />",
    "count": 1
}

Please note that this is a "dirty" solution. After adding/updating plugins, you'll probably have to repeat this.

Solution 3

I have tried the suggestions above (from QuickFix and leuk98743) but the manifest file kept getting re-generated. So I created a hook to modify the manifest file during the build.

  1. Add the content below into a file in your project: hooks/after_prepare/030_remove_permissions.js
  2. If you're on Linux, make that file executable.
  3. Modify the file to set the permissions you want to remove. There are 3 listed in my example but you should add/remove as appropriate.
#!/usr/bin/env node
//
// This hook removes specific permissions from the AndroidManifest.xml
// The AndroidManifest is re-generated during the prepare stage,
// so this must be run on the "after_prepare" hook.
//


// Configure the permissions to be forcefully removed.
// NOTE: These permissions will be removed regardless of how many plugins
//       require the permission. You can check the permission is only required
//       by the plugin you *think* needs it, by looking at the "count" shown in
//       your /plugins/android.json file.
//       If the count is more than 1, you should search through
//       the /plugins/&lt;plugin-name&gt;/plugin.xml files for &lt;uses-permission&gt; tags.

var permissionsToRemove = [ "RECORD_AUDIO", "MODIFY_AUDIO_SETTINGS", "READ_PHONE_STATE" ];


var fs = require('fs');
var path = require('path');
var rootdir = process.argv[2];
var manifestFile = path.join(rootdir, "platforms/android/AndroidManifest.xml");

fs.readFile( manifestFile, "utf8", function( err, data )
{
    if (err)
        return console.log( err );

    var result = data;
    for (var i=0; i<permissionsToRemove.length; i++)
        result = result.replace( "&lt;uses-permission android:name=\"android.permission." + permissionsToRemove[i] + "\" /&gt;", "" );

    fs.writeFile( manifestFile, result, "utf8", function( err )
    {
        if (err)
            return console.log( err );
    } );
} );

Solution 4

I have done below:

  1. Removed permission entries from below 2 files:

myapp\platforms\android\app\src\main\AndroidManifest.xml myapp\platforms\android\android.json

  1. Rebuilt the apk in release mode.

It worked, removed permission entries dint come back in manifest file.
Successfully uploaded apk to Play console.

Solution 5

A clone of Steve-e-b's answer for those who are more comfortable with python. It assumes the file will be located under something like hooks/after_prepare/123_remove_permissions.py and be executable.

#!/usr/bin/env python
import os

script_dir = os.path.dirname(os.path.abspath(__file__))
project_dir = os.path.abspath(os.path.join(script_dir, '../..'))

bad_permissions = [
    'WRITE_EXTERNAL_STORAGE',
    'RECORD_AUDIO',
    'MODIFY_AUDIO_SETTINGS',
]

android_manifest = os.path.join(project_dir, 'platforms/android/app/src/main/AndroidManifest.xml')

with open(android_manifest, 'r') as fr:
    lines = fr.readlines()

new_lines = [line for line in lines if not [perm for perm in bad_permissions if perm in line]]

with open(android_manifest, 'w') as fw:
    fw.writelines(new_lines)
Share:
10,548
mrbay
Author by

mrbay

Updated on June 12, 2022

Comments

  • mrbay
    mrbay almost 2 years

    I use CLI to build my Cordova app, and I have added the Media plugin.

    'cordova build' automatically adds the android.permission.RECORD_AUDIO to my AndroidManifest.xml even though I don't use that permission.

    So how do I remove it? Each time I build to release, the permission is added to the apk.

  • mrbay
    mrbay over 9 years
    I thought that too. But it still adds the four permissions. This is the flow: 1. Create app and add Android platform 2. Add media plugin 3. Remove the permissions from AndroidManifest.xml 4. Remove the permissions from plugins/org.apache.cordova.media/plugin.xml 5. Build 6. The AndroidManifest.xml now contain the permissions again. Even if I uninstall the media plugin from cli and remove the permissions from manifest, and then build again, the permissions are put back in...
  • mrbay
    mrbay over 9 years
    I forked the plugin, removed the permissions from plugin.xml on github and installed from there. That did the trick.
  • mrbay
    mrbay over 9 years
    Thanks. I was unaware that this file also contained uses-permission information. I will try that next time.
  • Mirko
    Mirko over 9 years
    Best thing is to fork the plugin repository though
  • Joel Malone
    Joel Malone almost 7 years
    Nice idea because it's automatic. The code sample seems to have been mangled, though!
  • Steve-e-b
    Steve-e-b almost 7 years
    Thanks for letting me know. I have fixed the code sample.
  • MStoner
    MStoner almost 7 years
    Thanks this solved my issue however: 1) the hooks directory is now deprecated so I specified the hook in config.xml 2) I'm using VS2015 TACO and the script was initially failing with ENOENT (although the build succeeded) because the platforms directory is in the project root rather than build\. The fix for this was to set rootdir=''; in the above sample
  • Ricky Levi
    Ricky Levi over 6 years
    there's nothing in my plugins/android.json but found such under platforms/android/android.json ( using Ionic 2 )
  • Grego
    Grego about 5 years
    I forgot about android.json, that saved me!
  • Manohar Reddy Poreddy
    Manohar Reddy Poreddy about 5 years
    Happy to know it was useful.