The docs state:
As mentioned previously, next to the main sourceSet is the androidTest sourceSet, located by default in src/androidTest/
....
The sourceSet should not contain an AndroidManifest.xml as it is automatically generated.
So, if I want to add extra permissions for the tests, what is the correct way to do it?
As of version 0.13.0 (released 2014/09/18) of the Android Gradle plugin it is now possible to have a custom manifest for Android tests.
It is now possible to provide a manifest for test apps (src/androidTest/AndroidManifest.xml)
Source: https://sites.google.com/a/android.com/tools/tech-docs/new-build-system
For more information see the sample "gradle_examples_0.14.4/tree/master/androidManifestInTest" - although it seems to me that there's no special configuration needed.
Related
In order to build different versions of my app, I added the applicationPackage property to the build file:
jfxmobile {
javafxportsVersion = '8.60.6'
android {
manifest = 'src/android/AndroidManifest.xml'
applicationPackage = 'com.myapp.lite'
}
}
But the generated apk file is still named after the package property in the AndroidManifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.myapp"
android:versionCode="1"
android:versionName="1.0.0" >
What's the proper way to change the package name if you want to build different flavors of your app like "Lite" and "Full" ?
Currently, when you use the Gluon plugin to create a Mobile project, the jfxmobile plugin builds the default AndroidManifest.xml file, based on your input (main class, package name). After that, any modification you make on your project (like refactoring the main class name or the package name) won't be updated on the Android manifest file, so you have to do it manually yourself.
If you have a look at the source code of the plugin, there is a way to force recreating the manifest every time you run the android task: Just delete the file under src/android/AndroidManifest.xml, and remove the manifest property in the build.gradle file. When you run android or androidIntall, a new default Android manifest will be created under build/javafxports/tmp/android, taking into account your applicationPackage property.
Notice this won't allow any custom change in the manifest, like adding or removing permissions or changing the version numbers. So clearly it is not a complete solution.
Another approach will be creating a custom task that recreates the AndroidManifest file based on your own settings, based on the way the plugin does it itself.
You can file an issue under javafxports repo if you think a more dynamic solution is required to build the apk. For instance, allowing the use of the same approach as in Android, where a strings.xml file is used to set some metadata (#string).
I am currently trying to remove all unneeded permissions from my AndroidManifest, and my first thought was to remove all permissions to see if it would give me an error at build or at run time. When I removed all of them I didn't get failure at build or run time.
Looking a bit deeper I found the generated manifest generated at build at /app/build/intermediates/manifest/full/debug/AndroidManifest. The manifest surprisingly had almost all of the permissions that I had removed.
EDIT
I am trying to ask if it is an acceptable practice for me to leave permissions out of my AndroidManifest that I know will be merged from my gradle dependencies at build.
If manifest merging in gradle is enabled, then you will get all the activities, permissions, and other manifest tags from your dependencies (https://developer.android.com/tools/building/manifest-merge.html). You will need to add only the ones that your app explicitly requires. It is a good practice to add to the app manifest the permissions your app relies on, even if they are duplicated, since your app dependencies might remove those permissions on future versions.
I am trying to ask if it is an acceptable practice for me to leave permissions out of my AndroidManifest that I know will be merged from my gradle dependencies at build.
Technically it would work and there's nothing really bad with it now, but the same way you do not keep i.e. unused assets in your app res/drawables folders, your manifest should list only these permissions your code requires.
I'm trying to test using the following directory structure (which was setup by Android Studio):
I can run some tests just fine, and even the AllTests.java runs fine without the AndroidManifest.xml file even being there. The thing is, for one of my new tests, I need the android.permission.INTERNET permission. So, I added the following to the AndroidManifest.xml file located within the androidTest directory:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.core"
android:versionCode="2"
android:versionName="2.0" >
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
Unfortunately, this doesn't work. I'm still getting the following error when I run one of my tests:
E/RestAPIRequestTest﹕ Permission denied (missing INTERNET permission?)
I've tried setting the package to be com.example.core.test in my AndroidManifest.xml file (since that is what it shows up as in my Settings->Apps list), but with no joy.
I'm thinking it's not even recognizing the AndroidManifest.xml file, since the version number doesn't show in the Settings for the test app, either.
How can I inject the correct permissions for my test project?
I needed to do something similar. I created a folder named "debug" next to androidTest, which corresponds to the debug variant of the app, and put an AndroidManifest.xml with the permission in that folder. Then the permission works under test since the test app uses the debug variant. It's not ideal because it blurs the line between test and debug, which aren't quite the same thing.
I think what's happening is that the permissions in androidTest/AndroidManifest.xml are going to the test app, not the target app, although it's not 100% clear to me if there are actually two different APKs or what.
In older versions of Android Studio and the Android Gradle plugin the androidTest/AndroidManifest.xml file was ignored. This was documented at the tools.android.com site at the time.
With the Android Studio 1.0+ and Android Gradle 1.0+ plugin launch in December 2014 the AndroidManifest.xml file should now be merged with the normal main/AndroidManifest.xml files (in addition to the debug and release manifest files if they exist). More details regarding the manifest merging rules are here.
If you still run into issues or are just debugging manifest related testing issues try this
(Adapt this slightly for Windows):
Drop to a terminal
change to to your project directory
cd MyApplication
Build your project, assuming 'debug' is the build type you want to test with, but you could also be testing with 'release' or a build script defined one.
./gradlew assembleDebugTest
Then inspect your test APK manifest:
ls app/build/intermediates/manifests/test/debug/AndroidManifest.xml
View your application APK manifest:
ls app/build/intermediates/manifests/full/debug/AndroidManifest.xml
A merge output log can be found detailing the manifest merging process:
ls app/build/outputs/apk/manifest-merger-debug-report.txt
A couple of extra notes:
An instrumentation element is automatically added to your test APK's AndroidManifest.xml so you should only be adding extra activities, permissions, etc that your test APK needs.
If testing with mock locations your application APK will need the ACCESS_MOCK_LOCATION permission. You can add the permission to your debug/AndroidManifest.xml file or you can define that the test APK and the application APK should use the same userId when deployed (sharedUserId attribute in your AndroidManifest.xml).
This is a known problem.
Currently (AGP <= 3.4.X) is not supporting AndroidManifest test merging.
This is reported here: https://issuetracker.google.com/issues/127986458
and here there is the issue created by one of the Roboelectric maintainers.
The workaround as described here its near the same proposed by user3286293 and currently is the only way to have the manifest merged for testing purposes.
Hope to see a fix for AGP 3.5 or 3.6
As specified here, during instrumented tests, there are generated two .apk files. If you take a look, the smaller one it's most probably the one named app-debug-androidTest-unaligned.apk and it actually does include the provided permissions.
Inspecting the file with aapt d permissions <apk_file_path>.apk can be useful to see a list of all of them.
Now, there might be an issue with the context itself where the permission is requested. I had a similar problem, trying to write some screenshots on SD card (thus needing the WRITE_EXTERNAL_STORAGE permission).
This answer helped me to fix the problem, although I cannot fully understand why it's necessary.
In few words, you'll need to declare the same android:sharedUserId in both manifests, in order to merge the permissions when both apks are installed on the same device - that happens when tests are running.
This helped me to separate permissions needed just for testing from the one in production.
You need to define that in build.gradle file:
android {
sourceSets {
androidTest.manifest.srcFile "src/androidTest/AndroidManifest.xml"
}
}
One solution would be like build main apk and test apk in single run.
Example: ./gradlew clean :main:assembleDebug :main:assembleDebugAndroidTest.
This will create a new instrumented main application which has all extra permissions required for test application.
I have a gradle flavor of my android app that uses the AdMarvel SDK. The app is trying to launch an activity using
com.myapp.flavour1/com.admarvel.android.ads.AdMarvelActivity, which results in an ActivityNotFoundException.
I believe that it needs to call com.myapp.main/com.admarvel.android.ads.AdMarvelActivity.
Is this something that can be fixed in a manifest / gradle config?
Is it caused by using the wrong context in my parameters?
Or is it just a bug in the library?
Any help would be appreciated.
Thanks.
You will have to create a separate manifest xml for the given flavor, and in that manifest, declare the activity from the AdMarvel library. There is a SO question about the latter part.
As for the flavor-specific manifest, you need to put in under src/flavor_name/res/AndroidManifest.xml - this is described here.
I'd like to know if there is a way to add certain permissions (or anything) to an android manifest file, but so that its only used during test runs - not production. I'm looking for something programmatic, not cutting and pasting when I'm testing.
Here's the context:
I'm reading this article: http://developer.android.com/training/location/location-testing.html, the best practice for test running an app used to be creating a 'test-app' however with android studio we now are not meant to create a new app - all testing should be done through the app. (Thank you gradle)
The issue is that this article is written with a testing permission (ACCESS_MOCK_LOCATION) in it, and I don't want that sitting in my app - and if there's a good way of doing it, I'd like to do that.
UPDATE: The reason I had this problem was because of a misunderstanding of the set up of android studio architecture since the migration to Gradle.
I didn't realize that the build types shared the 'androidTest' and 'main' source folders. And so when testing or running the unfinished app, it takes the debug files (if any) and adds all the production stuff to it. So in my case, I added a empty manifest file in debug and simply added the two permissions to it. When I run or test, gradle adds all of my apps things from its other manifest to it this skeletal file (or vice versa, I'm uncertain).
So in the end we don't need to modify the androidTest folder (in fact I don't think we are allowed to add a manifest here) as its completely generated based off of whether a user is running on debug or deployment. Cheers! :-)
Let's say you use the default debug and release build types and you run your tests against the debug build type.
In this case you can create a src/debug/AndroidManifest.xml and add the additional permissions you need in your debug builds:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="your.package">
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"/>
</manifest>
If your project does not follow the default folder hierarchy and you want to add permissions to the debug build add the following block.
sourceSets {
debug {
manifest.srcFile '<your folder>/AndroidManifest.xml'
}
}