I have an Android Library, in its manifest there are a set of permissions declared and used. This library needs to be bundled with different apps. When installing, it says duplicate permission declared across apps. The apps would be of different signature.
In order to use the same permission across apps, can we prefix the permission name in the library with packageName (like ${applicationId})?
When I try to prefix permissions with ${applicationId}, it gets substituted with the library's packageName. Is there a way to replace it in the top level apk or any other way out?
Related
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.
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"/>
In my Android library manifest file I have set sharedUserId property.
I have referenced to this lib project in my app1 and app2.
I have added manifestmerger.enabled=true to project.properties files of both apps.
However sharedUserId does not work (note: it works ok if I set thisproperty to app manifest file directly).
While looking app/bin/AndroidManifest I dont see this property - so looks like merge didn't happen.
I am using Eclipse ADT build22.3.0
Any idea what is the problem?
Basically what I want is to have ability to expose propery from my jar library.
This is not intended to work.
From the inline documentation of the ManifestMerger class
- root manifest: attributes ignored, warn if defined.
The Android Manifest documentation lists android:sharedUserId under the root element of the Manifest file, so it will be in the group of things which cannot be merged in from a library.
You may of course have additional issues preventing merging from working in general but even after those are corrected it should not work for sharedUserId (and other root level attributes) in specific.
I'm developing an application, with another project as my library.
What properties are merged in the manifest files?
Example - If the permissions are already specified in the Library's manifest file, do they need to be specified again in the applications manifest?
Also, if there is a service in the Library project, do I need to specify again manually in the Applications manifest too (additional to library's manifest).
Thanks
There is a section of this page: http://developer.android.com/tools/projects/projects-eclipse.html#SettingUpLibraryProject that says you must (re)declare all of the bits of the library project that your application will be using in the manifest file.
Declaring library components in the manifest file
In the manifest file of the application project, you must add
declarations of all components that the application will use that are
imported from a library project. For example, you must declare activity, service, receiver, provider, and so on, as well as permission, uses-library, and similar elements.
Declarations should reference the library components by their
fully-qualified package names, where appropriate.
Personally, this seems redundant, but it may be because the app doesn't need to use all of the components of the library project, and the app shouldn't assume it will.
It's all pretty much in the title. Although I see <uses-sdk> specified in all the example library project's AndroidManifest.xml I've seen, I have a feeling it's irrelevant.
In fact, I suspect that <uses-permission> is also irrelevant, as are all of the attributes of <manifest>, other than package.
Can anyone confirm?
As of ADT r20 preview 3
Library manifests can be merged with the main application manifest. This is enabled in an ant build by specifying the property
manifestmerger.enabled=true
[I'm not sure how to enable it in other (e.g. maven) builds; please comment here if you figure it out. I'm guessing it translates into an aapt command line argument.]
A variety of rules govern conflicts and overriding behavior.
Relative to the specific questions raised here (merging of <uses-sdk> and <uses-permission>), the rules for <uses-sdk> are:
minSdkVersion: error if destination manifest contains a value less than the lib value; leave destination value it is same or greater than lib value, store lib value in destination only if none was specified there (defaulting to 1 if not specified in either).
targetSdkVersion: warning if destination manifest contains a value less than the lib value; leave destination value it is same or greater than lib value, store lib value in destination only if none was specified there (defaulting to merged minSdkVersion value if not specified in either).
The rule for <uses-permission> is: add library permissions to destination if they are not already present there. It's OK if the same permission is in both.
If you are using ADT r20 preview 2 or earlier, the following applies:
I created a little test library project and a test app that uses it, in order to get to the bottom of this myself. I provided a <uses-sdk> and a <uses-permission> in the library project's manifest, and omitted both of them from the application's manifest.
The result was that the library project's <uses-sdk> and <uses-permission> values were NOT merged into the application at build time, as evidenced by examining the installed app on my device using the AppXplore tool.
My test code is available at https://github.com/adennie/android-library-project-manifest-test.
My conclusion is that specifying <uses-sdk> and <uses-permission> in an Android Library Project's manifest has no effect on the merged manifest of the consuming application.
possible uses of the manifest in library projects:
have you tried lint? it can warn you if your project is using too-new classes/methods which cannot work on the min-sdk that you've set on the manifest.
wanna check it out? just press the V-checkbox button near the sdk manager , as shown here:
http://tools.android.com/tips/lint/lint-toolbar.png?attredirects=0
the manifest could give a clue for other people of what is required for the project to be used.
you can also add some test activities inside which could allow you to quickly toggle the project from library project to normal project , and do some testing on it.
as google has suggested in the past , library projects might have some use of the manifest in the future by being merged with all of those that use the library project.
in short , the manifest is not meaningless . it can help you a lot .
If your library project doesn't depend on Specific android version then you can omit this tag.
Because uses-sdk will define the sdk version etc..
As per the documentation, It says for <uses-sdk>
The attribute android:minSdkVersion is surely required and if you don't pass any then it will take 1 meaning - App will support all api versions of android and then you will have to make your app support all of them if you dont pass any statically.
Caution: If you do not declare this attribute, the system assumes a
default value of "1", which indicates that your application is
compatible with all versions of Android. If your application is not
compatible with all versions (for instance, it uses APIs introduced in
API Level 3) and you have not declared the proper minSdkVersion, then
when installed on a system with an API Level less than 3, the
application will crash during runtime when attempting to access the
unavailable APIs. For this reason, be certain to declare the
appropriate API Level in the minSdkVersion attribute.
The attribute android:maxSdkVersion is little bit tricky to understand..doc says,
Warning: Declaring this attribute is not recommended. First, there is
no need to set the attribute as means of blocking deployment of your
application onto new versions of the Android platform as they are
released. By design, new versions of the platform are fully
backward-compatible. Your application should work properly on new
versions, provided it uses only standard APIs and follows development
best practices. Second, note that in some cases, declaring the
attribute can result in your application being removed from users'
devices after a system update to a higher API Level. Most devices on
which your application is likely to be installed will receive periodic
system updates over the air, so you should consider their effect on
your application before setting this attribute.
And,
Future versions of Android (beyond Android 2.0.1) will no longer check
or enforce the maxSdkVersion attribute during installation or
re-validation. Google Play will continue to use the attribute as a
filter, however, when presenting users with applications available for
download.
That warning is to indicate Negative points that can happen if you declare that attributes But as you look into other side If you are developing anything that supports some specific Android Version then The ATTRIBUTE is most useful to you.
The step taken to remove that attribute is to encourage developer to make their app supportive to all different(newer) version.
Only if you developing with the version 2.0.1^ then you can say Its not needed to write that but If you write that Google paly will use that as filter for presenting user
So My Conclusion and Advice
use the element <uses-sdk> with atleast one attribute android:minSdkVersion