As I found out in Why are permissions being automatically added to my AndroidManifest when including Google Play Services library, various Google Play Services components implicitly add permissions to your app starting in Google Play Services 7.5. But obviously not all components require the same permissions - for instance, play-services-games:7.8.0 doesn't require any.
Is there an easy way to tell what permissions will be added by a particular Google Play Services component?
Visit $ANDROID_SDK/extras/google/m2repository/com/google/gms. In there, choose your desired artifact (e.g., play-services-maps) and version (e.g., 8.1.0). Open up the AAR in your favorite ZIP utility, and look at the AndroidManifest.xml file published in there, to see if there are <uses-permission> elements. Then, open up the POM file, see what dependencies there are, and repeat the process for the AARs for those dependencies.
As described in this excellent article, you can see the final manifest file created during the build process here;
app/build/intermediates/manifests/full/debug/AndroidManifest.xml
You can also see a report that shows where every permission comes from;
app/build/outputs/logs/manifest-merger-debug-report.txt
You can use a line like this in your manifest to remove any extra permissions you want (but be careful! you might break functionality);
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="remove"/>
Related
In this page: https://developer.android.com/studio/projects/android-library.html#Considerations
It states that:
You can develop a library module that depends on an external library. (for example, the Maps external library). In this case, the dependent app must build against a target that includes the external library (for example, the Google APIs Add-On). Note also that both the library module and the dependent app must declare the external library in their manifest files, in a element.
So I tried to do what the paragraph says above.
1- I created a module that has this in its gradle:
compile 'com.twitter.sdk.android:twitter-core:3.0.0'
compile 'com.twitter.sdk.android:tweet-ui:3.0.0'
2- and I added this in my manifest.xml
<uses-library
android:name="com.twitter.sdk"
android:required="true"/>
3- I imported my .aar file to my main app.
4- I added the same code into my main app manifest.xml
<uses-library
android:name="com.twitter.sdk"
android:required="true"/>
But of-course it shows an error:
Delete <uses-library> from your manifest. It it only for cases where you are trying to use a "library" that is part of a device's firmware. The "Maps" example that they cite is from the long-obsolete Google Maps V1 for Android implementation.
I am not aware of any device manufacturer that has advised its developers to add <uses-library> elements to their manifest for com.twitter.sdk.
One of my projects has multiple third party libraries and one of those libraries is requesting a permission that I don't have defined in my Manifest. How can I find out which of the libraries is requesting the permission?
If I perform the command:
adb shell dumpsys package [mypackagename]
then I see the permission as "requested", but as I mentioned it doesn't exist in my project. There are a lot of third party libraries.
you can find your final permission in merged manifest file at
app/build/intermediates/manifests/full/debug/AndroidManifest.xml
You can get rid of this with
Just declare the incriminated permission in your main Manifest with the
tools:node="remove"
like:
<uses-permission android:name=”android.permission.RECORD_AUDIO” tools:node=”remove” />
Even if another third party library is asking for this specific permission, the build will be forced to not merge it in your final Manifest file.
With Android 6's dynamic permissions, is it possible to get all the permissions an APK requires from a compiled apk?
The problem is that in our project, we sometimes add third party libraries to our project, and sometimes they require more permissions than our app initially required. I would like to be able to detect such situations at the CI build stage.
"Dynamic permissions" (a.k.a., runtime permissions) do not change anything. They all still have <uses-permission> elements in the manifest. aapt dump permissions, or reading in the merged manifest, will tell you what is requested by your current manifest.
This does not help with libraries that do not publish a manifest in their AARs that contain the <uses-permission> elements required by the library. Hopefully, the authors of such a library document what they are expecting and you are adding the <uses-permission> elements to your own manifest.
I am making an AAR for licensing functionality. I plan to use it in multiple applications.
As per documentation, licensing implementation needs a permission in manifest file: "com.android.vending.CHECK_LICENSE"
I am not sure where should this permission be kept,in application's manifest file or library project's manifest file.
All your library related permissions/metadata/activities relevant info should be declared in your library manifest file
If you find yourself writing a big Android application that depends on many different libraries (which I would recommend instead of reinventing the wheel) it is very likely that you have already come across the 65k method limit of the Dalvik executable file classes.dex. Furthermore, if you depend on large libraries like the Google Play Services SDK which itself in already contained more than 20k methods in version 5.0 you are forced to use tricks like stripping packages or multidex support to avoid errors while packaging. With Android's new runtime ART which is publicly available since Android Lollipop multiple dex files are easier to handle, but currently developers are still forced to do method counting.
What is the simplest way to reduce your application`s method count while using Google Play Services?
The biggest change for developers that came with the 6.5 release of the Google Play Services was probably the Granular Dependency Management. Google managed to split up it's library to allow developers to depend only on certain components which they really need for their apps.
Since version 6.5 developers are no longer forced to implement the complete Google Play Services library in their app, but can selectively depend on components like this:
compile 'com.google.android.gms:play-services-fitness:6.5.+'
compile 'com.google.android.gms:play-services-wearable:6.5.+'
compile 'com.gogole.android.gms:play-services-maps:6.5.+'
...
If you want to compile the complete library into your app, you can still do so:
compile 'com.google.android.gms:play-services:6.5.+'
A complete list of available packages can be found on the Android Developers site.
For someone who do not use Android Studio w/gradle or don't want to implement ProGuard to you project.
It's possible to avoid 65k while using google-play-services
by keeping some packages that you really want to use by using jarjar. For example, in my project I want to implement only google map and google location I lean my google-play-services.jar like this.
Download jarjar HERE
Create new file call 'services.rules'
edit it as follow
keep com.google.android.gms.maps.*
keep com.google.android.gms.location.*
Copy your original google-play-services.jar / jarjar-1.4.jar / services.rules into the same folder
start command prompt and type..
java -jar jarjar-1.4.jar process services.rules google-play-services.jar google-lean.jar
That's it you will get a new .jar that size was reduce a lot (method also)
use it instaed of google-play-services.jar and dex over 56k will gone.
Here is .jar that was lean already as mention above.
I know this question is old but for those of you who face this issue while working on eclipse and cannot use the above answer
please follow the steps
if you don't want to download android studio to get the lib projects
you can download lib files from here
https://www.dropbox.com/s/1pf73czcn7pyqgi/com.google.android.gms.rar?dl=0
and skip to step 4
1 - first of all you still need android studio to download your dependencies
you can download it from here
https://developer.android.com/sdk/index.html
2 - then in your build.gradle inside your app add the below lines
dependencies {
compile 'com.google.android.gms:play-services-maps:7.5.0'
//map , gcm or any specific api for a hole list visit the below link
//https://developers.google.com/android/guides/setup
}
and then hit sync project with gradle file
after that you will get to lib projects
play-services-base
play-services-maps
right click on them to get their path
4 - create project inside eclipse delete the generate files inside src folder
, res folder and manifest
5- copy res and manifest from play-services-base to your project
6 - copy file inside play-services-base/jars to the libs folder of your project
normally named classes.jar (please rename it to any other name so it won't conflict with other project)
7- add this jar to build paths then right click on project / properties / java build path / order and export tab check the added jar
8- right click on project / properties / android / check is lib
9- make the same steps for play-services-maps
10 - now you got to lib projects one is called googleBase and the other is called googleMaps (or any other name)
11 - add them to your project as libraries
now add the following lines to your manifest
<!-- Include required permissions for Google Maps API to run-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-feature
android:glEsVersion="0x00020000"
android:required="true"/>
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="" />
for a complete tutorial with images please refer to below link
http://androidninja.quora.com/Prevent-65-K-Methods-Count-When-Using-Google-Lib-on-Android-with-eclipse-adt