[Android] Removing unused permissions added at build time #5886

Open
lucidrains opened this Issue Feb 12, 2016 · 64 comments

Comments

Projects
None yet
@lucidrains

lucidrains commented Feb 12, 2016

edit: see https://medium.com/@applification/fixing-react-native-android-permissions-9e78996e9865 for a workaround -@hramos

It seems like Read/Write external storage and Read phone state permissions are automatically added to the manifest on building the android apk. Are these necessary for all React Native android apps? Is there any way to remove these permissions?

android:uses-permission#android.permission.READ_EXTERNAL_STORAGE
android:uses-permission#android.permission.WRITE_EXTERNAL_STORAGE

It feels weird that I'll see these permissions being requested if I install the app from the Play store if I'm not using them.

@facebook-github-bot

This comment has been minimized.

Show comment
Hide comment
@facebook-github-bot

facebook-github-bot Feb 12, 2016

Hey lucidrains, thanks for reporting this issue!

React Native, as you've probably heard, is getting really popular and truth is we're getting a bit overwhelmed by the activity surrounding it. There are just too many issues for us to manage properly.

  • If you don't know how to do something or something is not working as you expect but not sure it's a bug, please ask on StackOverflow with the tag react-native or for more real time interactions, ask on Discord in the #react-native channel.
  • If this is a feature request or a bug that you would like to be fixed, please report it on Product Pains. It has a ranking feature that lets us focus on the most important issues the community is experiencing.
  • We welcome clear issues and PRs that are ready for in-depth discussion. Please provide screenshots where appropriate and always mention the version of React Native you're using. Thank you for your contributions!

Hey lucidrains, thanks for reporting this issue!

React Native, as you've probably heard, is getting really popular and truth is we're getting a bit overwhelmed by the activity surrounding it. There are just too many issues for us to manage properly.

  • If you don't know how to do something or something is not working as you expect but not sure it's a bug, please ask on StackOverflow with the tag react-native or for more real time interactions, ask on Discord in the #react-native channel.
  • If this is a feature request or a bug that you would like to be fixed, please report it on Product Pains. It has a ranking feature that lets us focus on the most important issues the community is experiencing.
  • We welcome clear issues and PRs that are ready for in-depth discussion. Please provide screenshots where appropriate and always mention the version of React Native you're using. Thank you for your contributions!
@mkonicek

This comment has been minimized.

Show comment
Hide comment
@mkonicek

mkonicek Feb 13, 2016

Contributor

Just remove them from your AndroidManifest.xml if you don't need them. I believe these are for AsyncStorage.

Contributor

mkonicek commented Feb 13, 2016

Just remove them from your AndroidManifest.xml if you don't need them. I believe these are for AsyncStorage.

@mkonicek

This comment has been minimized.

Show comment
Hide comment
@mkonicek

mkonicek Feb 13, 2016

Contributor

There's an awesome place to post code / ask question first before filing an issue: StackOverflow. It's the best system for Q&A. Many people from the community hang out there and will be able to see and answer your question. This lets us use the github bug tracker for bugs.

I'm posting this here because github issues haven't been working very well for us and because StackOverflow is so much better. Thanks for reading! :)

Contributor

mkonicek commented Feb 13, 2016

There's an awesome place to post code / ask question first before filing an issue: StackOverflow. It's the best system for Q&A. Many people from the community hang out there and will be able to see and answer your question. This lets us use the github bug tracker for bugs.

I'm posting this here because github issues haven't been working very well for us and because StackOverflow is so much better. Thanks for reading! :)

@mkonicek mkonicek closed this Feb 13, 2016

@satya164

This comment has been minimized.

Show comment
Hide comment
@satya164

satya164 Feb 14, 2016

Collaborator

@mkonicek aren't they added at build time? In that case it's not easy to remove them

Collaborator

satya164 commented Feb 14, 2016

@mkonicek aren't they added at build time? In that case it's not easy to remove them

@kevinejohn

This comment has been minimized.

Show comment
Hide comment
@kevinejohn

kevinejohn Feb 17, 2016

Contributor

+1

Even when you don't have the READ and WRITE permissions in your AndroidManifest they still show up on build. Do you just have to remove AsyncStorage completely?

Contributor

kevinejohn commented Feb 17, 2016

+1

Even when you don't have the READ and WRITE permissions in your AndroidManifest they still show up on build. Do you just have to remove AsyncStorage completely?

@vshy108

This comment has been minimized.

Show comment
Hide comment
@vshy108

vshy108 Feb 28, 2016

I have similar problem when I generated release apk.

Before install, it asked for permissions:

  • Photos/Media/Files

  • Device ID & call information

    but I confirmed I removed AsyncStorage completely and only have

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

in my AndroidManifest

vshy108 commented Feb 28, 2016

I have similar problem when I generated release apk.

Before install, it asked for permissions:

  • Photos/Media/Files

  • Device ID & call information

    but I confirmed I removed AsyncStorage completely and only have

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

in my AndroidManifest

@Bhullnatik

This comment has been minimized.

Show comment
Hide comment
@Bhullnatik

Bhullnatik Mar 24, 2016

Contributor

@mkonicek @satya164 @bestander Could this issue be re-opened please? I digged around a bit, I couldn't find where those permissions were added. So far there are :

<android:uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<android:uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<android:uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

Which I'm not sure what they do, but I don't think there are actually used because it wouldn't work on Android 6.+ (run-time permissions). Also it seems strange to force permissions to use a module since in NetInfoModule on Android, React-native requires YOU to add the needed permission to your manifest (See NetInfoModule.java#L38).
Anyway it's not for AsyncStorage as it uses a SQLite DB under the hood, which doesn't require any permission. Even if it used another method of storage like SharedPreferences or the internal storage to store files, it shouldn't require any permission (See Storage Options).

I'm sure this is coming from React-native, I tried on a fresh project with no other permission, and there were here once the APK generated. I also looked at every Android app in the showcase and every app has those permissions, except one which doesn't have READ_PHONE_STATE at least : Facebook Ads manager (See Permissions: View details at the bottom).

Also not completely related, but this is a permission too:

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

This permission (Draw over other apps) is needed in debug mode to show the error redbox, but is still present
in release mode, which is quite scary for the user (even though it is not used). I could probably submit a PR for that (have 2 different manifests for debug and release, only uses the permission in the debug one).

Sorry for the long post, but my company is in the process of releasing our new Android app, and we would really like to ship it without un-needed permissions since that's not some the Android community really likes.

Thanks for your attention.

Contributor

Bhullnatik commented Mar 24, 2016

@mkonicek @satya164 @bestander Could this issue be re-opened please? I digged around a bit, I couldn't find where those permissions were added. So far there are :

<android:uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<android:uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<android:uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

Which I'm not sure what they do, but I don't think there are actually used because it wouldn't work on Android 6.+ (run-time permissions). Also it seems strange to force permissions to use a module since in NetInfoModule on Android, React-native requires YOU to add the needed permission to your manifest (See NetInfoModule.java#L38).
Anyway it's not for AsyncStorage as it uses a SQLite DB under the hood, which doesn't require any permission. Even if it used another method of storage like SharedPreferences or the internal storage to store files, it shouldn't require any permission (See Storage Options).

I'm sure this is coming from React-native, I tried on a fresh project with no other permission, and there were here once the APK generated. I also looked at every Android app in the showcase and every app has those permissions, except one which doesn't have READ_PHONE_STATE at least : Facebook Ads manager (See Permissions: View details at the bottom).

Also not completely related, but this is a permission too:

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

This permission (Draw over other apps) is needed in debug mode to show the error redbox, but is still present
in release mode, which is quite scary for the user (even though it is not used). I could probably submit a PR for that (have 2 different manifests for debug and release, only uses the permission in the debug one).

Sorry for the long post, but my company is in the process of releasing our new Android app, and we would really like to ship it without un-needed permissions since that's not some the Android community really likes.

Thanks for your attention.

@bestander

This comment has been minimized.

Show comment
Hide comment
@bestander

bestander Mar 24, 2016

Contributor

Maybe gradle does that?
I can't find any string with READ_PHONE_STATE in the code.
I don't mind reopening this but could you help us investigating this?

Contributor

bestander commented Mar 24, 2016

Maybe gradle does that?
I can't find any string with READ_PHONE_STATE in the code.
I don't mind reopening this but could you help us investigating this?

@bestander

This comment has been minimized.

Show comment
Hide comment
Contributor

bestander commented Mar 24, 2016

@facebook-github-bot reopen

@facebook-github-bot

This comment has been minimized.

Show comment
Hide comment
@facebook-github-bot

facebook-github-bot Mar 24, 2016

Okay, reopening this issue.

Okay, reopening this issue.

@Bhullnatik

This comment has been minimized.

Show comment
Hide comment
@Bhullnatik

Bhullnatik Mar 24, 2016

Contributor

@bestander Yeah I think it's added automatically by Android/gradle since I couldn't find any mention of them in the code, but I'm really not sure why. I'll try to investigate quickly and get back to you/submit a PR as soon as I find something.

Contributor

Bhullnatik commented Mar 24, 2016

@bestander Yeah I think it's added automatically by Android/gradle since I couldn't find any mention of them in the code, but I'm really not sure why. I'll try to investigate quickly and get back to you/submit a PR as soon as I find something.

@Bhullnatik

This comment has been minimized.

Show comment
Hide comment
@Bhullnatik

Bhullnatik Mar 24, 2016

Contributor

I forgot to check the manifest merger log... Turns out the problem is quite obvious:

IMPLIED from /Users/mayouk/Dev/tmp/AwesomeProject/android/app/src/main/AndroidManifest.xml:1:1-23:12 reason: org.webkit.android_jsc has a targetSdkVersion < 4
android:uses-permission#android.permission.READ_PHONE_STATE
IMPLIED from /Users/mayouk/Dev/tmp/AwesomeProject/android/app/src/main/AndroidManifest.xml:1:1-23:12 reason: org.webkit.android_jsc has a targetSdkVersion < 4
android:uses-permission#android.permission.READ_EXTERNAL_STORAGE
IMPLIED from /Users/mayouk/Dev/tmp/AwesomeProject/android/app/src/main/AndroidManifest.xml:1:1-23:12 reason: org.webkit.android_jsc requested WRITE_EXTERNAL_STORAGE

Because android-jsc doesn't provide a targetSdkVersion, the manifest merger added the permissions for various reasons (See Implicit permissions). Apparently @astuetz already fixed this in facebook/android-jsc#12 but either the new version of android-jsc wasn't published or it isn't used in React-native currently. If you can contact the maintainers of android-jsc to solve this, that would be fantastic!

Contributor

Bhullnatik commented Mar 24, 2016

I forgot to check the manifest merger log... Turns out the problem is quite obvious:

IMPLIED from /Users/mayouk/Dev/tmp/AwesomeProject/android/app/src/main/AndroidManifest.xml:1:1-23:12 reason: org.webkit.android_jsc has a targetSdkVersion < 4
android:uses-permission#android.permission.READ_PHONE_STATE
IMPLIED from /Users/mayouk/Dev/tmp/AwesomeProject/android/app/src/main/AndroidManifest.xml:1:1-23:12 reason: org.webkit.android_jsc has a targetSdkVersion < 4
android:uses-permission#android.permission.READ_EXTERNAL_STORAGE
IMPLIED from /Users/mayouk/Dev/tmp/AwesomeProject/android/app/src/main/AndroidManifest.xml:1:1-23:12 reason: org.webkit.android_jsc requested WRITE_EXTERNAL_STORAGE

Because android-jsc doesn't provide a targetSdkVersion, the manifest merger added the permissions for various reasons (See Implicit permissions). Apparently @astuetz already fixed this in facebook/android-jsc#12 but either the new version of android-jsc wasn't published or it isn't used in React-native currently. If you can contact the maintainers of android-jsc to solve this, that would be fantastic!

@bestander

This comment has been minimized.

Show comment
Hide comment
@bestander

bestander Mar 24, 2016

Contributor

@brentvatne ping, is it possible to publish new android-jsc?

Contributor

bestander commented Mar 24, 2016

@brentvatne ping, is it possible to publish new android-jsc?

@astuetz

This comment has been minimized.

Show comment
Hide comment
@astuetz

astuetz Mar 24, 2016

Contributor

@Bhullnatik what we're doing until a new version of android-jsc will be released is just stripping away the unwanted permissions in our apps' manifest like this:

<uses-permission
  android:name="android.permission.READ_PHONE_STATE"
  tools:node="remove"/>
Contributor

astuetz commented Mar 24, 2016

@Bhullnatik what we're doing until a new version of android-jsc will be released is just stripping away the unwanted permissions in our apps' manifest like this:

<uses-permission
  android:name="android.permission.READ_PHONE_STATE"
  tools:node="remove"/>
@Bhullnatik

This comment has been minimized.

Show comment
Hide comment
@Bhullnatik

Bhullnatik Mar 24, 2016

Contributor

@astuetz I was looking at the manifest merger on how to fix this until it gets solved, thanks for the heads-up 😄

Contributor

Bhullnatik commented Mar 24, 2016

@astuetz I was looking at the manifest merger on how to fix this until it gets solved, thanks for the heads-up 😄

@brentvatne

This comment has been minimized.

Show comment
Hide comment
@brentvatne

brentvatne Mar 25, 2016

Collaborator

@bestander - sure I can do that, we might also want to update to r189384 as well @kmagiera?

Collaborator

brentvatne commented Mar 25, 2016

@bestander - sure I can do that, we might also want to update to r189384 as well @kmagiera?

@mouneyrac

This comment has been minimized.

Show comment
Hide comment
@mouneyrac

mouneyrac Apr 13, 2016

@astuetz thanks, it helped me, justto add to this info I had to declare the tools attribut in

 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.bepaw.esportninja">. 

By default there is only xmlns:android, no xmlns:tools

@astuetz thanks, it helped me, justto add to this info I had to declare the tools attribut in

 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.bepaw.esportninja">. 

By default there is only xmlns:android, no xmlns:tools

@Bhullnatik

This comment has been minimized.

Show comment
Hide comment
@Bhullnatik

Bhullnatik Apr 25, 2016

Contributor

@bestander @brentvatne Hey! Any update on this?

Contributor

Bhullnatik commented Apr 25, 2016

@bestander @brentvatne Hey! Any update on this?

@danleveille

This comment has been minimized.

Show comment
Hide comment
@danleveille

danleveille May 12, 2016

👍 +1 for this.

👍 +1 for this.

@marcshilling

This comment has been minimized.

Show comment
Hide comment
@marcshilling

marcshilling Jun 7, 2016

I feel like the removal of SYSTEM_ALERT_WINDOW from release builds is far more critical than the other permissions being discussed.

I feel like the removal of SYSTEM_ALERT_WINDOW from release builds is far more critical than the other permissions being discussed.

@Bhullnatik

This comment has been minimized.

Show comment
Hide comment
@Bhullnatik

Bhullnatik Jun 7, 2016

Contributor

@marcshilling It's all equally important to remove them in my opinion, but this one is a little more tricky. The easiest way to remove it is to remove it in the release AndroidManifest.xml, but the configuration is a little bit heavy to include in every React Native project.
The other way would be to remove the usage, thus not needing the permission anymore. For that I'm not sure where/for what it is used, but I didn't see any particular need that couldn't be fulfilled with something else. I could be wrong though.

Contributor

Bhullnatik commented Jun 7, 2016

@marcshilling It's all equally important to remove them in my opinion, but this one is a little more tricky. The easiest way to remove it is to remove it in the release AndroidManifest.xml, but the configuration is a little bit heavy to include in every React Native project.
The other way would be to remove the usage, thus not needing the permission anymore. For that I'm not sure where/for what it is used, but I didn't see any particular need that couldn't be fulfilled with something else. I could be wrong though.

@marcshilling

This comment has been minimized.

Show comment
Hide comment
@marcshilling

marcshilling Jun 7, 2016

For those who want to exclude SYSTEM_ALERT_WINDOW from release builds without separate Manifest files:

In your manifest:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" tools:remove="${excludeSystemAlertWindowPermission}"/>

In app/build.gradle:

    buildTypes {
        debug {
            manifestPlaceholders = [excludeSystemAlertWindowPermission: "false"]
        }
        release {
            manifestPlaceholders = [excludeSystemAlertWindowPermission: "true"]
        }
    }

Seems to work well.

marcshilling commented Jun 7, 2016

For those who want to exclude SYSTEM_ALERT_WINDOW from release builds without separate Manifest files:

In your manifest:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" tools:remove="${excludeSystemAlertWindowPermission}"/>

In app/build.gradle:

    buildTypes {
        debug {
            manifestPlaceholders = [excludeSystemAlertWindowPermission: "false"]
        }
        release {
            manifestPlaceholders = [excludeSystemAlertWindowPermission: "true"]
        }
    }

Seems to work well.

@danleveille

This comment has been minimized.

Show comment
Hide comment
@danleveille

danleveille Jun 7, 2016

@marcshilling Perfect! Thank you! It's been kind of embarrassing to have to explain that to users because I couldn't figure out how to remove it. 😕

@marcshilling Perfect! Thank you! It's been kind of embarrassing to have to explain that to users because I couldn't figure out how to remove it. 😕

@jbrodriguez

This comment has been minimized.

Show comment
Hide comment
@jbrodriguez

jbrodriguez Jul 5, 2016

Hi, I've been alerted about READ_PHONE_STATE by a user of one of my apps.

I'm getting the same reason in the build log

reason: org.webkit.android_jsc has a targetSdkVersion < 4

Hopefully it gets solved in a future release.

For the time being, I'm using the permission removal workarounds mentioned here
astuetz - READ_PHONE_STATE - #5886 (comment)
marcshilling - SYSTEM_ALERT_WINDOW - #5886 (comment)

As well as adding the namespace as explained by mouneyrac (#5886 (comment))

jbrodriguez commented Jul 5, 2016

Hi, I've been alerted about READ_PHONE_STATE by a user of one of my apps.

I'm getting the same reason in the build log

reason: org.webkit.android_jsc has a targetSdkVersion < 4

Hopefully it gets solved in a future release.

For the time being, I'm using the permission removal workarounds mentioned here
astuetz - READ_PHONE_STATE - #5886 (comment)
marcshilling - SYSTEM_ALERT_WINDOW - #5886 (comment)

As well as adding the namespace as explained by mouneyrac (#5886 (comment))

@jbrodriguez

This comment has been minimized.

Show comment
Hide comment
@jbrodriguez

jbrodriguez Jul 5, 2016

So, I wasn't being able to remove SYSTEM_ALERT_WINDOW with the solution above.

Had to resort to a hack (after much prodding and poking).

in AndroidManifest.xml

    <uses-permission android:name="${permissionName}" tools:node="remove"/>

in app/build.gradle

    buildTypes {
        debug {
            manifestPlaceholders = [permissionName: "android.permission.ACCESS_FINE_LOCATION"]
            ...
        }    
        release {
            manifestPlaceholders = [permissionName: "android.permission.SYSTEM_ALERT_WINDOW"]
            ...
        }
    }

In debug mode, I remove ACCESS_FINE_LOCATION, since I don't use (neither in dev nor in prod). Any other non-essential permission could be used (BIND_TV_INPUT?).

In release mode, I remove SYSTEM_ALERT_WINDOW. If you don't forcibly remove it, it will get merged in.

Hacky, but effective 😂

So, I wasn't being able to remove SYSTEM_ALERT_WINDOW with the solution above.

Had to resort to a hack (after much prodding and poking).

in AndroidManifest.xml

    <uses-permission android:name="${permissionName}" tools:node="remove"/>

in app/build.gradle

    buildTypes {
        debug {
            manifestPlaceholders = [permissionName: "android.permission.ACCESS_FINE_LOCATION"]
            ...
        }    
        release {
            manifestPlaceholders = [permissionName: "android.permission.SYSTEM_ALERT_WINDOW"]
            ...
        }
    }

In debug mode, I remove ACCESS_FINE_LOCATION, since I don't use (neither in dev nor in prod). Any other non-essential permission could be used (BIND_TV_INPUT?).

In release mode, I remove SYSTEM_ALERT_WINDOW. If you don't forcibly remove it, it will get merged in.

Hacky, but effective 😂

@Jeiwan

This comment has been minimized.

Show comment
Hide comment
@Jeiwan

Jeiwan Jul 12, 2016

If you use this solution #5886 (comment), don't forget to add xmlns:tools as described here: #5886 (comment)

Jeiwan commented Jul 12, 2016

If you use this solution #5886 (comment), don't forget to add xmlns:tools as described here: #5886 (comment)

@satya164

This comment has been minimized.

Show comment
Hide comment
@satya164

satya164 Jul 12, 2016

Collaborator

@marcshilling I think this is something we can have in the generator template by default.

Collaborator

satya164 commented Jul 12, 2016

@marcshilling I think this is something we can have in the generator template by default.

@astuetz

This comment has been minimized.

Show comment
Hide comment
@astuetz

astuetz Jul 20, 2016

Contributor

@marcshilling Your solution didn't work for me as well but the one from @jbrodriguez did.

One thing I noticed was that instead of using a real permission which will be removed, you can also use a non-existing permission name like REMOVE_ME.

Contributor

astuetz commented Jul 20, 2016

@marcshilling Your solution didn't work for me as well but the one from @jbrodriguez did.

One thing I noticed was that instead of using a real permission which will be removed, you can also use a non-existing permission name like REMOVE_ME.

tgaff added a commit to tgaff/rNpMoves that referenced this issue Aug 30, 2016

@tgaff

This comment has been minimized.

Show comment
Hide comment
@tgaff

tgaff Sep 6, 2016

Quick comment: after updating from 0.30 to 0.32 it seems react-native now suddenly adds the permission com.google.android.c2dm.permission.RECEIVE I've seen this in two apps now. I doubt it needs this new permission either.

tgaff commented Sep 6, 2016

Quick comment: after updating from 0.30 to 0.32 it seems react-native now suddenly adds the permission com.google.android.c2dm.permission.RECEIVE I've seen this in two apps now. I doubt it needs this new permission either.

@mikelambert

This comment has been minimized.

Show comment
Hide comment
@mikelambert

mikelambert Oct 6, 2016

Contributor

The use of @marcshilling 's tools:remove doesn't work for me either.

My solution to avoid unnecessary permissions (a mix of the above) is:
In the app/src/main/AndroidManifest.xml, I added:

<uses-permission tools:node="remove" android:name="android.permission.READ_PHONE_STATE" />

And in a newly-created app/src/release/AndroidManifest.xml, I put:

<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    >

    <!-- These are added by React Native for debug mode, but actually aren't needed in releasemode -->
    <uses-permission tools:node="remove" android:name="android.permission.SYSTEM_ALERT_WINDOW" />
</manifest>

Variable substitution inside a tools:node doesn't work for me, so something like tools:node="${someManifestPlaceholder}" wouldn't work. So the above approach of multiple AndroidManifest.xml files that merge together seems like a better method of adding/removing certain permissions on a debug vs release basis (or the default main).

Contributor

mikelambert commented Oct 6, 2016

The use of @marcshilling 's tools:remove doesn't work for me either.

My solution to avoid unnecessary permissions (a mix of the above) is:
In the app/src/main/AndroidManifest.xml, I added:

<uses-permission tools:node="remove" android:name="android.permission.READ_PHONE_STATE" />

And in a newly-created app/src/release/AndroidManifest.xml, I put:

<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    >

    <!-- These are added by React Native for debug mode, but actually aren't needed in releasemode -->
    <uses-permission tools:node="remove" android:name="android.permission.SYSTEM_ALERT_WINDOW" />
</manifest>

Variable substitution inside a tools:node doesn't work for me, so something like tools:node="${someManifestPlaceholder}" wouldn't work. So the above approach of multiple AndroidManifest.xml files that merge together seems like a better method of adding/removing certain permissions on a debug vs release basis (or the default main).

@goldylucks

This comment has been minimized.

Show comment
Hide comment
@goldylucks

goldylucks Nov 29, 2016

@marcshilling your solution didn't work for me, so I've used @jbrodriguez's combined with @astuetz's

u guys think it's worth creating a script to automate this?

maybe create a npm package that makes this on install and then remove itself?
Never done something like that tho I believe it is possible.

@mikelambert, regarding your approach, is anything else needed to make it work?

does gradle automagically merges app/src/release/AndroidManifest.xml into app/src/main/AndroidManifest.xml?

that seems like the cleaner approach to me

Thoughts and comments appreciated! :)

@marcshilling your solution didn't work for me, so I've used @jbrodriguez's combined with @astuetz's

u guys think it's worth creating a script to automate this?

maybe create a npm package that makes this on install and then remove itself?
Never done something like that tho I believe it is possible.

@mikelambert, regarding your approach, is anything else needed to make it work?

does gradle automagically merges app/src/release/AndroidManifest.xml into app/src/main/AndroidManifest.xml?

that seems like the cleaner approach to me

Thoughts and comments appreciated! :)

@mikelambert

This comment has been minimized.

Show comment
Hide comment
@mikelambert

mikelambert Nov 29, 2016

Contributor

Yes, it automatically merges the AndroidManifest.xml files. I believe it's all that was necessary to make it work for me, but let me know if I've missed anything!

Contributor

mikelambert commented Nov 29, 2016

Yes, it automatically merges the AndroidManifest.xml files. I believe it's all that was necessary to make it work for me, but let me know if I've missed anything!

@freakinruben

This comment has been minimized.

Show comment
Hide comment
@freakinruben

freakinruben Nov 29, 2016

@mikelambert also worked for me. I've got multiple release buildTypes though, so I needed release{X}/AndroidManifest.xml for each build-type in order to get it working.

Not sure how you could capture something like that in a npm package..

@mikelambert also worked for me. I've got multiple release buildTypes though, so I needed release{X}/AndroidManifest.xml for each build-type in order to get it working.

Not sure how you could capture something like that in a npm package..

@iegik

This comment has been minimized.

Show comment
Hide comment
@iegik

iegik Jun 2, 2017

build.gradle

        classpath 'com.android.tools.build:gradle:1.2.3' // For Android 5.1

Following rule craches on 5.1:

    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" tools:node="remove"/>
06-02 15:06:54.102: E/AndroidRuntime(18353): android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@f03a0a2 -- permission denied for this window type
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at android.view.ViewRootImpl.setView(ViewRootImpl.java:704)
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:289)
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at android.app.Dialog.show(Dialog.java:311)
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at com.facebook.react.devsupport.DevSupportManagerImpl.showProgressDialog(DevSupportManagerImpl.java:762)
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at com.facebook.react.devsupport.DevSupportManagerImpl.reloadJSFromServer(DevSupportManagerImpl.java:767)
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at com.facebook.react.devsupport.DevSupportManagerImpl.handleReloadJS(DevSupportManagerImpl.java:658)
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at com.facebook.react.XReactInstanceManagerImpl$3$1.run(XReactInstanceManagerImpl.java:412)
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at android.os.Handler.handleCallback(Handler.java:815)
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at android.os.Handler.dispatchMessage(Handler.java:104)
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at android.os.Looper.loop(Looper.java:194)
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at android.app.ActivityThread.main(ActivityThread.java:5631)
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at java.lang.reflect.Method.invoke(Native Method)
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at java.lang.reflect.Method.invoke(Method.java:372)
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:959)
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:754)

Solution is to remove:

tools:node="remove

iegik commented Jun 2, 2017

build.gradle

        classpath 'com.android.tools.build:gradle:1.2.3' // For Android 5.1

Following rule craches on 5.1:

    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" tools:node="remove"/>
06-02 15:06:54.102: E/AndroidRuntime(18353): android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@f03a0a2 -- permission denied for this window type
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at android.view.ViewRootImpl.setView(ViewRootImpl.java:704)
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:289)
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at android.app.Dialog.show(Dialog.java:311)
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at com.facebook.react.devsupport.DevSupportManagerImpl.showProgressDialog(DevSupportManagerImpl.java:762)
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at com.facebook.react.devsupport.DevSupportManagerImpl.reloadJSFromServer(DevSupportManagerImpl.java:767)
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at com.facebook.react.devsupport.DevSupportManagerImpl.handleReloadJS(DevSupportManagerImpl.java:658)
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at com.facebook.react.XReactInstanceManagerImpl$3$1.run(XReactInstanceManagerImpl.java:412)
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at android.os.Handler.handleCallback(Handler.java:815)
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at android.os.Handler.dispatchMessage(Handler.java:104)
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at android.os.Looper.loop(Looper.java:194)
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at android.app.ActivityThread.main(ActivityThread.java:5631)
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at java.lang.reflect.Method.invoke(Native Method)
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at java.lang.reflect.Method.invoke(Method.java:372)
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:959)
06-02 15:06:54.102: E/AndroidRuntime(18353): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:754)

Solution is to remove:

tools:node="remove
@mikelambert

This comment has been minimized.

Show comment
Hide comment
@mikelambert

mikelambert Jun 2, 2017

Contributor

@iegik , I'm not sure whose solution/code you were trying, but adding a SYSTEM_ALERT_WINDOW permission to release builds is not a solution I would recommend to others.

Please try my suggestion above, if you don't want to require that permission in your release builds.

Contributor

mikelambert commented Jun 2, 2017

@iegik , I'm not sure whose solution/code you were trying, but adding a SYSTEM_ALERT_WINDOW permission to release builds is not a solution I would recommend to others.

Please try my suggestion above, if you don't want to require that permission in your release builds.

@joshfriend

This comment has been minimized.

Show comment
Hide comment
@joshfriend

joshfriend Jun 2, 2017

@a-koka it's already been explained above several times

joshfriend commented Jun 2, 2017

@a-koka it's already been explained above several times

@iegik

This comment has been minimized.

Show comment
Hide comment
@iegik

iegik Jun 5, 2017

@mikelambert I have to request SYSTEM_ALERT_WINDOW permission from users, because our app crashes somewhere on getting permissions :(

iegik commented Jun 5, 2017

@mikelambert I have to request SYSTEM_ALERT_WINDOW permission from users, because our app crashes somewhere on getting permissions :(

@mikelambert

This comment has been minimized.

Show comment
Hide comment
@mikelambert

mikelambert Jun 5, 2017

Contributor

@iegik From what I understand, normal release-mode apps shouldn't need SYSTEM_ALERT_WINDOW, and it's only useful for development-mode apps. Do you have a log of said crash, that show where this "somewhere" is?

Of course, you're welcome to do that if it suits your needs and isn't worth debugging for you... I just didn't want future readers of this thread to think they need to request that permission too, since this thread is about how to not request unnecessary permissions. :)

Contributor

mikelambert commented Jun 5, 2017

@iegik From what I understand, normal release-mode apps shouldn't need SYSTEM_ALERT_WINDOW, and it's only useful for development-mode apps. Do you have a log of said crash, that show where this "somewhere" is?

Of course, you're welcome to do that if it suits your needs and isn't worth debugging for you... I just didn't want future readers of this thread to think they need to request that permission too, since this thread is about how to not request unnecessary permissions. :)

@npaez

This comment has been minimized.

Show comment
Hide comment
@npaez

npaez Jul 1, 2017

Adding this line, makes my app crash.
<uses-permission android:name="android.permission.READ_PHONE_STATE" tools:node="remove" />

npaez commented Jul 1, 2017

Adding this line, makes my app crash.
<uses-permission android:name="android.permission.READ_PHONE_STATE" tools:node="remove" />

davidyuk added a commit to davidyuk/locator-mobile that referenced this issue Jul 16, 2017

@Crash-- Crash-- referenced this issue in vault-development/react-native-svg-uri Aug 11, 2017

Closed

Need "Draw over other apps" permission on Android #69

@iegik

This comment has been minimized.

Show comment
Hide comment
@iegik

iegik Aug 25, 2017

@npaez, thats right

thats not what node="remove " is doing. Its removing the permission from the generated manifest, because other libraries, for example, can add permissions. This makes sure the permission will definitely not be there.
— Heron at Discord

iegik commented Aug 25, 2017

@npaez, thats right

thats not what node="remove " is doing. Its removing the permission from the generated manifest, because other libraries, for example, can add permissions. This makes sure the permission will definitely not be there.
— Heron at Discord

@muhammedbasilsk

This comment has been minimized.

Show comment
Hide comment

@marcshilling 's method worked. (y)

@johnculviner

This comment has been minimized.

Show comment
Hide comment
@johnculviner

johnculviner Nov 7, 2017

This should not be closed as RN is still adding this permission implicitly:

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

which is a super nasty I have your phone number and IMEI if you install my app sort of permission. I wouldn't want to install any apps that request this...

This should not be closed as RN is still adding this permission implicitly:

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

which is a super nasty I have your phone number and IMEI if you install my app sort of permission. I wouldn't want to install any apps that request this...

@koswarabilly

This comment has been minimized.

Show comment
Hide comment
@koswarabilly

koswarabilly Nov 9, 2017

@johnculviner by the way, does it work when you try to retrieve IMEI? because i tried using react-native-device-info and it is not working, i tried using react-native-Imei which has been deprecated since RN 0.47 give me error of not override or implemented method, do you have any solution for my problem?

@johnculviner by the way, does it work when you try to retrieve IMEI? because i tried using react-native-device-info and it is not working, i tried using react-native-Imei which has been deprecated since RN 0.47 give me error of not override or implemented method, do you have any solution for my problem?

@johnculviner

This comment has been minimized.

Show comment
Hide comment
@johnculviner

johnculviner Nov 9, 2017

@koswarabilly I'm pretty sure the above permission is one of the requirements for IMEI which definitely is a pretty elevated thing to request given it uniquely identifies the phone forever

@koswarabilly I'm pretty sure the above permission is one of the requirements for IMEI which definitely is a pretty elevated thing to request given it uniquely identifies the phone forever

@koswarabilly

This comment has been minimized.

Show comment
Hide comment
@koswarabilly

koswarabilly Nov 9, 2017

@johnculviner i know the permission give me access to the device info , i have tried to get the imei through react-native-imei package but when i run-android it prompt me saying error override or not implemented method, have you ever successfully get IMEI number of your device
Or have anyone successfully retrieve imei number here? Because i believe that it is a possible task

koswarabilly commented Nov 9, 2017

@johnculviner i know the permission give me access to the device info , i have tried to get the imei through react-native-imei package but when i run-android it prompt me saying error override or not implemented method, have you ever successfully get IMEI number of your device
Or have anyone successfully retrieve imei number here? Because i believe that it is a possible task

@sahil290791

This comment has been minimized.

Show comment
Hide comment
@sahil290791

sahil290791 Dec 13, 2017

I am using React Native v0.44.0 and tried upgrading to SDK 26, but android system doesn't allow SYSTEM_ALERT_WINDOW to be used anymore even in debug mode. SYSTEM_ALERT_WINDOW can only be used by system level apps in Oreo. Any ideas on how I can make this work?

I am using React Native v0.44.0 and tried upgrading to SDK 26, but android system doesn't allow SYSTEM_ALERT_WINDOW to be used anymore even in debug mode. SYSTEM_ALERT_WINDOW can only be used by system level apps in Oreo. Any ideas on how I can make this work?

@emaLorenzo

This comment has been minimized.

Show comment
Hide comment
@emaLorenzo

emaLorenzo Jan 8, 2018

For anyone trying to solve this, in this post the guy use the solution listed here but very well explained.
https://medium.com/@applification/fixing-react-native-android-permissions-9e78996e9865

For anyone trying to solve this, in this post the guy use the solution listed here but very well explained.
https://medium.com/@applification/fixing-react-native-android-permissions-9e78996e9865

@baona95

This comment has been minimized.

Show comment
Hide comment
@baona95

baona95 Feb 27, 2018

@mikelambert Thanks, your solution works perfectly

baona95 commented Feb 27, 2018

@mikelambert Thanks, your solution works perfectly

@hramos hramos changed the title from React native is adding an unnecessary user permission to [Android] Removing unused permissions added at build time Mar 5, 2018

@janicduplessis janicduplessis removed the Android label Mar 18, 2018

@ulfgebhardt

This comment has been minimized.

Show comment
Hide comment
@ulfgebhardt

ulfgebhardt Mar 23, 2018

The Solution for me was to modify the
./android/app/src/main/AndroidManifest.xml

I had to add the following lines

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
// Added this
    xmlns:tools="http://schemas.android.com/tools"
    package="de.democracydeutschland.app"
    android:versionCode="1"
    android:versionName="1.0">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
// Added tools:node="remove"
    <uses-permission android:name="android.permission.READ_PHONE_STATE" tools:node="remove"/>
// Added READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE both with tools:node="remove"
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" tools:node="remove" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="remove" />

    <uses-sdk
        android:minSdkVersion="16"
        android:targetSdkVersion="22" />

    ...

For Debug Purposes: ./android/app/build/outputs/logs/manifest-merger-***-report.txt

Rel: https://github.com/demokratie-live/democracy-client/blob/master/android/app/src/main/AndroidManifest.xml

This removes the App-Permission Dialog when installing via PlayStore

The one thing I dont get:

Why do I have to add rights to remove them while the app itself does not even require permission?

Grüße Ulf

<3

ulfgebhardt commented Mar 23, 2018

The Solution for me was to modify the
./android/app/src/main/AndroidManifest.xml

I had to add the following lines

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
// Added this
    xmlns:tools="http://schemas.android.com/tools"
    package="de.democracydeutschland.app"
    android:versionCode="1"
    android:versionName="1.0">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
// Added tools:node="remove"
    <uses-permission android:name="android.permission.READ_PHONE_STATE" tools:node="remove"/>
// Added READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE both with tools:node="remove"
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" tools:node="remove" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="remove" />

    <uses-sdk
        android:minSdkVersion="16"
        android:targetSdkVersion="22" />

    ...

For Debug Purposes: ./android/app/build/outputs/logs/manifest-merger-***-report.txt

Rel: https://github.com/demokratie-live/democracy-client/blob/master/android/app/src/main/AndroidManifest.xml

This removes the App-Permission Dialog when installing via PlayStore

The one thing I dont get:

Why do I have to add rights to remove them while the app itself does not even require permission?

Grüße Ulf

<3

@ishigamii

This comment has been minimized.

Show comment
Hide comment
@ishigamii

ishigamii Mar 29, 2018

The "correction" will be added in any next version of React-native ?

ishigamii commented Mar 29, 2018

The "correction" will be added in any next version of React-native ?

@sladek-jan

This comment has been minimized.

Show comment
Hide comment
@sladek-jan

sladek-jan Apr 17, 2018

Our app has multiple build types (4 as of now), and we wanted to remove SYSTEM_ALERT_WINDOW permissions from all of them EXCEPT debug.
I didn't want to hack up permission names through manifest placeholders, nor create 3 extra AndroidManifests with equal content.
So, in the end I remove the permission in main/AndroidManifest.xml using:

<manifest xmlns:tools="http://schemas.android.com/tools" ...>
<uses-permission tools:node="remove" android:name="android.permission.SYSTEM_ALERT_WINDOW" />
...

and then in a separate debug/AndroidManifest.xml, I add it back:

<manifest xmlns:tools="http://schemas.android.com/tools" ...>
<uses-permission tools:node="merge" android:name="android.permission.SYSTEM_ALERT_WINDOW" />
...

Because the debug AndroidManifest has a higher priority than the main one (see Merge Priorities), it will override the removal and add the permission.

Sounds strange, but seems to work well (judging from the output of aapt d permissions <apk file>).

sladek-jan commented Apr 17, 2018

Our app has multiple build types (4 as of now), and we wanted to remove SYSTEM_ALERT_WINDOW permissions from all of them EXCEPT debug.
I didn't want to hack up permission names through manifest placeholders, nor create 3 extra AndroidManifests with equal content.
So, in the end I remove the permission in main/AndroidManifest.xml using:

<manifest xmlns:tools="http://schemas.android.com/tools" ...>
<uses-permission tools:node="remove" android:name="android.permission.SYSTEM_ALERT_WINDOW" />
...

and then in a separate debug/AndroidManifest.xml, I add it back:

<manifest xmlns:tools="http://schemas.android.com/tools" ...>
<uses-permission tools:node="merge" android:name="android.permission.SYSTEM_ALERT_WINDOW" />
...

Because the debug AndroidManifest has a higher priority than the main one (see Merge Priorities), it will override the removal and add the permission.

Sounds strange, but seems to work well (judging from the output of aapt d permissions <apk file>).

@nkov

This comment has been minimized.

Show comment
Hide comment
@nkov

nkov Apr 19, 2018

Congress should have asked Zuck what's up with these permissions.

nkov commented Apr 19, 2018

Congress should have asked Zuck what's up with these permissions.

@anhtuank7c

This comment has been minimized.

Show comment
Hide comment
@anhtuank7c

anhtuank7c May 3, 2018

I think the solution is create another android/app/src/release/AndroidManifest.xml like this:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.facebook.react.demo">

    <uses-permission
        android:name="android.permission.SYSTEM_ALERT_WINDOW"
        tools:node="remove" />

    <uses-permission
        android:name="android.permission.READ_PHONE_STATE"
        tools:node="remove" />

    <application>

    </application>

</manifest>

And edit android/app/build.gradle like this:

android {
    ...
    sourceSets.release {
        manifest.srcFile 'release/AndroidManifest.xml'
    }
}

https://code.videolan.org/videolan/vlc-android/blob/923bbada6687ecab31addc1dfd3f90619976ccdf/vlc-android/build.gradle#L169

anhtuank7c commented May 3, 2018

I think the solution is create another android/app/src/release/AndroidManifest.xml like this:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.facebook.react.demo">

    <uses-permission
        android:name="android.permission.SYSTEM_ALERT_WINDOW"
        tools:node="remove" />

    <uses-permission
        android:name="android.permission.READ_PHONE_STATE"
        tools:node="remove" />

    <application>

    </application>

</manifest>

And edit android/app/build.gradle like this:

android {
    ...
    sourceSets.release {
        manifest.srcFile 'release/AndroidManifest.xml'
    }
}

https://code.videolan.org/videolan/vlc-android/blob/923bbada6687ecab31addc1dfd3f90619976ccdf/vlc-android/build.gradle#L169

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment