I have an app uses clearText between Android-client and server using Retrofit, and in Android 9+ it's not allowed to use clearText.
To ignore that I added android:usesCleartextTraffic="true" in Manifest but it warns: tools:ignore="GoogleAppIndexingWarning" and suggests to add tools:targetApi="m".
It's a bit confusing:
Is the tools:targetApi="m" means that any attributes with tools: is for Marshmallow and higher?
Is it for using this version of Manifest or something else? Is this making unwanted mistake in my app?
My Manifest:
...
<application
android:name=".ApplicationClass"
android:allowBackup="true"
android:fullBackupContent="false"
android:hardwareAccelerated="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="false"
android:theme="#style/AppTheme.NoActionBar"
android:usesCleartextTraffic="true"
tools:ignore="GoogleAppIndexingWarning"
tools:targetApi="m">
...
From the docs you can read:
Indicates that Lint should treat this type as targeting a given API level, no matter what the project target is
This means it will affect only the annotated one.
Other attributes with tools won't be affected. tools is a namespace, from which you can get attributes, an attribute won't affect the entire namespace.
By adding tools:targetApi="m" to an element you tell the lint that the element won't be used on API level below 23 (M). See the attribute documentation.
This tells the tools that you believe this element (and any children) will be used only on the specified API level or higher. This stops lint from warning you if that element or its attributes are not available on the API level you specify as your minSdkVersion.
In this particular case <application> uses android:usesCleartextTraffic attribute which is available starting from API 23 but the app minSdkVersion is less then 23 so lint warns you. Despite specifying tools:targetApi removes the warning in this case it isn't a right solution because the <application> can be used on older API levels if minSdkVersion allows it. But such a trick won't harm because android:usesCleartextTraffic will be ignored if it isn't supported, see this answer for more details.
What about tools namespace in general, it contains attributes which used by build tools and won't affect runtime behavior. See the docs for more details.
Android Studio supports a variety of XML attributes in the tools namespace that enable design-time features (such as which layout to show in a fragment) or compile-time behaviors (such as which shrinking mode to apply to your XML resources). When you build your app, the build tools remove these attributes so there is no effect on your APK size or runtime behavior.
Related
When I create an Android library, by default it would give me the below in the Manifest file
<application android:allowBackup="true"
android:label="#string/app_name"
android:supportsRtl="true"/>
After post it as a library on Bintray and used by others, just realise if an application that include this library has the below in its Manifest
android:supportsRtl="false"
It will post the error as below during gradle sync or compilation.
Error:Execution failed for task ':app:processProductionDebugManifest'.
> Manifest merger failed : Attribute application#supportsRtl value=(false) from AndroidManifest.xml:23:9-36
is also present at [com.mylibrarypackage:mylibrary:1.0.0] AndroidManifest.xml:14:9-35 value=(true).
Suggestion: add 'tools:replace="android:supportsRtl"' to <application> element at AndroidManifest.xml:18:5-67:19 to override.
To fix it, I think I would need to remove the android:supportsRtl="true" from my library Manifest.
Just wonder why did Android have this as default its library manifest? Would there be any potential problem if I remove android:supportsRtl="true" from my library Manifest?
tools:replace=”x, y”
Replace the x, y attributes from any lower priority declaration with
the provided value (must be present on the same node).
When importing a library with a lower target SDK than the project’s, it may be necessary to explicitly grant permissions (and perhaps make other changes) for the library to function properly in the later runtime. This will be performed automatically by the manifest merger.
You are getting
Manifest merger failed : Attribute application#supportsRtl
value=(false) from AndroidManifest.xml:23:9-36
You can add
tools:replace="android:supportsRtl"
Finally
<application android:allowBackup="true"
android:label="#string/app_name"
android:supportsRtl="true"
tools:replace="android:supportsRtl"/>
It is required if you want to support right-to-left (RTL) layouts.
If set to true and targetSdkVersion is set to 17 or higher, various RTL APIs will be activated and used by the system so your app can display RTL layouts. If set to false or if targetSdkVersion is set to 16 or lower, the RTL APIs will be ignored or will have no effect and your app will behave the same regardless of the layout direction associated to the user's Locale choice (your layouts will always be left-to-right).
The default value of this attribute is false.
This attribute was added in API level 17.
(Source: http://developer.android.com/guide/topics/manifest/application-element.html)
Should I use android.maxSdkVersion in manifest.xml file? Because I read in documents that I should not use this in manifest.xml file. And as regards most version of android devices are 2.3 to higher. What is your opinion?
Google stated at Android Developers:
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.
Syntax:
<uses-sdk
android:minSdkVersion="integer"
android:targetSdkVersion="integer"
android:maxSdkVersion="integer" />
However if you use the new Gradle then android:minSdkVersion="integer" and android:targetSdkVersion="integer" will always be overridden in the Gradle scripts.
I suggest you not to use it.
Here is a guide for more detailed information:
Android Developers - uses-sdk-element in manifest
Currently, I have a piece of code, which is designed to run both in Android 2.3 and 4+
The code will perform much better (Where it will not have OutOfMemory exception most of the time), if android:largeHeap is being applied in AndroidManifest.xml.
<application
android:name=".MyApplication"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:screenOrientation="nosensor"
android:largeHeap="true"
Currently, my android:minSdkVersion need to set to 15 instead of 10 (Android 2.3). If not, android:largeHeap is not allowable in AndroidManifest.xml.
<uses-sdk
android:minSdkVersion="15"
android:targetSdkVersion="15" />
Within single APK, how possible I can set
Use android:largeHeap option if I were in Android 4+
Do not use android:largeHeap option if I were in Android 2.3
You can also disable large heap in Honeycomb and enable it in ICS or JB. Just a little hacky or something. Here's what I tried.
Before we proceed, change your Build target to Honeycomb, Jelly Bean or ICS so we can put android:largeHeap attribute. Also, you can set android:minSdkVersion to API 10.
Android API 10 doesn't support large heap.
Create a folder values-v14 in res folder
I created bools.xml in values-v14
Put this value in bools.xml of values-v14
<bool name="largeheap">true</bool>
boolean value for values > bools.xml or values-[API VERSION] > bools.xml to disable large-heap in different API Version or by default.
<bool name="largeheap">false</bool>
Change the value of android:largeHeap to #bool/largeheap instead of hardcoded true or false
<application
android:largeHeap="#bool/largeheap"
android:allowBackup="true"
android:icon="#drawable/ic_launcher">
....
</application>
I tested this code by making a memory leak application or just load a Huge bitmaps, and, its working!
Good Luck!
Keep the android:largeHeap="true" attribute in your AndroidManifest.xml. This should be ignored for versions that don't support it. Then, to support older versions, set the heap size using the VMRuntime class (via reflection, if necessary).
More on this topic: How to increase heap size of an android application?
1.Build project with target Android 3.0 (API 11) or above.
(Project properties - Android - Project Build Target - select above API level 11)
in Manifest file, Change the uses-sdk value as following
< uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="11" />
For prior versions of Android 3.0, you can use VMRuntime class for memory manipulations.
Seems that you have incorrect target sdk in project.properties file, check it out and change target to your AndroidManifest`s targetSdk (15) and rebuild project.
project.properties
# Project target.
target=15
P.S. I tryed add android:largeHeap to my Project (minSdk = 7, targetSdk = 17) compiled and run normally on all Android versions.
Please change project properties:
In project Properties -> Android -> Project Build Target -> Google API, API level 19 (or any other you need) :)
So your can leave your minimum SDK option without change, for example 8 :)
I'm working on an Android application where I'd like to have the largeHeap and hardwareAccelerated flags on. However, it also needs to support Android 2.3.
My AndroidManifest.xml looks like the following:
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="10"/>
<application
android:icon="#drawable/icon"
android:label="#string/app_name"
android:hardwareAccelerated="true"
android:largeHeap="true"
>
However, Eclipse refuses to build the project, saying:
error: No resource identifier found for attribute 'hardwareAccelerated' in package 'android'
error: No resource identifier found for attribute 'largeHeap' in package 'android'
Raising the targetSdkVersion to 11, where such flags were introduced, does not solve the problem.
Is it possible to support Android 2.3 and still set these flags?
Yes you can add the XML attributes but you have to build with the required sdk level for those attributes. Older plattforms will just ignore those attributes. To do so change the Project Build Target to 11 in the project specific Android settings in Eclipse.
But pay attention, if you start building your project with sdk level 11 you could easily slip in code that does not execute on devices with level <11.
See Backward Compatiblity for an similar explanation on how to enable the installLocation attribute (introduced in level 8) and still build for sdk level less than 8.
I got a Problem with implementing Admob into an App.
This is my main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
</LinearLayout>
</LinearLayout>
and this is my Manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.ollidiemaus.testmob"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="7" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:label="#string/app_name"
android:name=".TestAdmobActivity" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.google.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation"/>
</application>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
</manifest>
And finaly this is my Activity:
public class TestAdmobActivity extends Activity {
private AdView adView;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Create the adView
adView = new AdView(this, AdSize.BANNER, "a14ead58dc2a456");
// Lookup your LinearLayout assuming it’s been given
// the attribute android:id="#+id/mainLayout"
LinearLayout layout = (LinearLayout)findViewById(R.id.linearLayout1);
// Add the adView to it
layout.addView(adView);
// Initiate a generic request to load it with an ad
adView.loadAd(new AdRequest());}
#Override
public void onDestroy() {
adView.destroy();
super.onDestroy();
}}
Now when i'll start the app in the AdView is an error called: "you must have AdActivity declared in AndroidManifest.xml with configChanges."
I used Android 4.0 so above 3.2 but it is not working.
I hope anyone could help me.
I had exactly the same problem with getting the "you must have AdActivity declared in AndroidManifest.xml with configChanges." error message after integrating the latest AdMob SDK. Even though I have found this and the other two related discussions (see links at the bottom of this article) at StackOverflow, they didn't help me to solve the issue, as -- for me -- they did not differentiate clear enough between the targetSdkVersion attribute in the manifest and the build target. This answer describes what solved the issue for me and what caused trouble.
Solution
The easiest part at first: you are missing a few flags in the configChanges attribute of the definition of the AdActivity in your AndroidManifest.xml. As shown in the AdMob SDK Docs the definition needs to look like this:
<activity android:name="com.google.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>
The second -- and more complicated part -- is related to the SDK target: The only solution that really seems to work is to use the SDK manager to install the SDK for at least Android 3.2 (API level 13). After you have installed this SDK version you need to configure your IDE to build your project using this SDK. The exact setting depends on the IDE you are using. In my case it is IntelliJ IDEA and there you will find the option in the project settings on the Project page below the headline Project SDK.
You should also adjust the target property in your project's project.properties. This is at least important if you are building your release using ANT. The line should look like this:
target=android-13
The configuration above alone does the trick. There are no changes required to the <uses-sdk> element in the AndroidManifest. Read the pitfalls below to learn why this may cause trouble.
Explanation
The build target and the <uses-sdk> elements have completely different scopes.
The build target is evaluated only at build time by your build tools to determine which version of the SDK tools on your system should be used to build your app. The newer the SDK the more API features does it know. Out of whatever reason Google forces us to specify some configChanges which aren't available before API level 13 and so we need to build our app using at least the SDK tools 13 because a previous version of the SDK tools does not know these new configChanges and will report an error. At runtime the build target does not have any meaning and Android will ignore all elements (e.g. in configChanges) which it does not know.
The targetSdkVersion element specified on the <uses-sdk> element in the android manifest in contrast is only evaluated at run time -- not at compile time. In fact you can specify any value you want here without the compiler changing anything or bringing up an error message. This is why changing this attribute does not help us to solve our AdMob problem. On the other hand at runtime the attribute may be evaluated by android to support some compatibility features for apps which have been build for older android versions. See the pitfalls section below to see a topic which caused trouble for me.
Pitfalls
Do not change set targetSdkVersion to a higher version if you are not able to test your app on this android version: Because I have misunderstood the existing answers regarding this admob topic I have also set the android:targetSdkVersion attribute of the <uses-sdk> element to API level 13 in my app which caused a fatal side effect: As Android 3 thought my app would natively support honeycomb, it did no longer show the menu button in the soft button bar at the bottom border and as my app hides the native title bar to show it's own implementation the user did not have any possibility to access the menu any more on honeycomb. So for me leaving the targetSdkVersion at level 10 helped to bring back the menu button and worked fine.
Handling backward compatibility to older APIs which may be lost in SDK tools 13: OK, so I have set my build process to use the SDK tools 13 and my targetSdkVersion to 10 and everything should be fine, right? Unfortunately not! The reason is, that my app is compatible downwards to Android 1.5 (API level 3) as this still makes up about 5% of my users. Unfortunately after setting the build target to 13 some parts of my code did not compile any more as they referenced deprecated methods which were supported until SDK tools 10 but no longer starting with SDK tools 11 (e.g. Service.setForeground).
The basics how to handle backwards compatibility are described here -- but this article does not describe how to call deprecated methods which are no longer available as they will cause a compiler error. I solved this by creating a new library project used by my app. For this library project I have set the build target back to 10 which will cause it to be compiled using the SDK tools 10 which still know about the android deprecated API I am using. My app then calls helper methods from this compatibility library and so I can compile my app with a newer target SDK.
Related Topics
Here the list of the other related discussions I have found:
AdMob can't display ads because of configChanges
AdMob SDK 4.3.1 - I can't display banner
My solution to a similar case was to use
<uses-sdk
android:minSdkVersion="7"
android:targetSdkVersion="11" />
or just use android:targetSdkVersion= under 13
You also need to set the following permissions in your AndroidManifest.xml.
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Then admob can assess the internet and also not show the ad when it has no internet connectivity.
Have you also set your build target to be higher than Android 3.2, i.e. in default.properties set target higher than android-13? Also make sure that you're using the latest version of the SDK.
PS! Don't expose your device ID to the public.
As you can see here, very few phones have Android versions of 3.x.x or higher installed
http://developer.android.com/resources/dashboard/platform-versions.html
Why would anybody want to compile their app to something few phones can handle? Either I am misunderstanding something or I will need to find some other ad company that doesn't require a newer Android version.
Above error occurs when you use the library GoogleAdMobAdsSdk-4.3.1.jar.
I've been that error and I've found this demo from Google.
I've replaced lib 4.3.1 by 4.0.3 in this demo and it runs OK.
if you use AndroidStudio and Gradle, you must also update the build.gradle file like this:
android {
compileSdkVersion 17
buildToolsVersion "18.0.1"
defaultConfig {
minSdkVersion 3
targetSdkVersion 17
}
...