My question is related to camera. When an application needs to use the system camera, we create an intent with ACTION_IMAGE_CAPTURE action and add a permission like this in the manifest file.
<uses-permission android:name="android.permission.CAMERA"/>
But besides that, there is one such
<uses-feature android:name="android.hardware.camera"/>
What is it for? I read that if this line is written, then if the phone does not have a camera the application will not install. Is it true? And besides this, why do we need this?
And for what the line <uses-feature/> is generally responsible in manifest file?
<uses-feature android:name="android.hardware.camera"/>
above line will use to check the device have camera hardware.
When you upload an app on play store they will filter your app based on the feature for the specific device,
if any device will search your app on play store and that device doesn't have camera hardware then they will not be allowed to install an app on that device.
but if your requirement is to force download the app if the device doesn't have camara hardware the you can use :
<uses-feature android:name="android.hardware.camera" android:required="false"/>
the android:required = "false" will allow you to install
hope you understand
Google documentation for <uses-feature> itself clearly states:
Google Play uses the <uses-feature> elements declared in your app
manifest to filter your app from devices that do not meet its hardware
and software feature requirements.
By specifying the features that your application requires, you enable
Google Play to present your application only to users whose devices
meet the application's feature requirements, rather than presenting it
to all users.
Some permissions in Android are connected to some hardware/software features of a device, like CAMERA. Since every Android device in the market differs in its hardware and software configuration, there's a greater possibility that some feature that you're trying to add in your app doesn't support all Android Devices. If you try to use the camera in a camera-less device (a superficial assumption), then your app will not behave as you expect.
In short, if you want your app to only be available for the set of devices having that particular capability, then you can add <uses-feature> tag inside the manifest with the desired capability.
This is just for filtering apps in Play Store based on device configuration and support.
You can define zero or more <uses-feature> capabilities based on your need.
Note: If you don't want your app to get filtered out just for the sake of a feature that doesn't impact the overall user experience of the app, you can smartly disable the particular feature if it's not available in your app.
For that, you have to write
<uses-feature android:name="YOUR_NON_COMPULSORY_FEATURE" android:required="false" />
For example, if your app uses CAMERA feature, but your app is not dependent on that feature, you can disable just the CAMERA feature to provide a non-buggy user experience.
<uses-feature/> is there to guide Google play store to filter out this application from devices which do not have Camera hardware.
As a developer - lets ask this Question to ourself with respect to your app.
What will user do with my app whose phone does not have Camera?
If the answer to Above is "Not much" - then what is the point allowing user to install your app on phone if user can't do much with it? It is waste of time & Internet bandwidth for the user.
Also if user is really frustrated by eventually learning that this app is not much of use, they may RATE your app poorly on Play Store.
Hence its there is <uses-feature/> option to protect both developers & users from above scenario.
This is very important part. Let suppose your application uses a particular hard ware and that is essential for your app that hardware must be available on a device to use your application. If that is defined, your app will be filtered out for those devices that have that specific hard ware.
NOTE: As it is well documented over Google Developer site
**Google Play uses the elements declared in your app manifest to filter your app from devices that do not meet its hardware and software feature requirements.
By specifying the features that your application requires, you enable Google Play to present your application only to users whose devices meet the application's feature requirements, rather than presenting it to all users.**
Refer this link for further reference guide
I'm using ACTION_IMAGE_CAPTURE to request camera app to take a photo.
According to official doc if my app uses camera feature but doesn't require it for correct functioning, following should be left in manifest
<manifest ... >
<uses-feature android:name="android.hardware.camera"
android:required="false" />
...
</manifest>
I don't really get what is the idea of having those lines in manifest, isn't it just the same without having this not required feature.
I would like to know what is the point to write this ? Can I safely skip this from manifest ?
Doesn't matter if I have the feature listed in manifest, I'll still be able to check it during run-time, correct hasSystemFeature(PackageManager.FEATURE_CAMERA) ?
No, it's not the same. As the docs say:
The element offers a required attribute that lets you specify whether your application requires and cannot function without the declared feature, or whether it prefers to have the feature but can function without it.
This means that it would be nice to have that feature, but the app will still work without it. For example, an app that can take pictures but that does not need it as part of its normal operation would use the required=false for the camera.
You might ask that through code, yes. But the problem is that some permissions imply that you require some particular hardware:
If an application requests hardware-related permissions, Google Play assumes that the application uses the underlying hardware features and therefore requires those features, even though there might be no corresponding to declarations. For such permissions, Google Play adds the underlying hardware features to the metadata that it stores for the application and sets up filters for them.
For example, if an application requests the CAMERA permission but does not declare a element for android.hardware.camera, Google Play considers that the application requires a camera and should not be shown to users whose devices do not offer a camera.
So if you want to use some features but not others, and you are including the permission, you might want to declare that your app does not really requires the presence of a certain device feature.
From Android docs:
The purpose of a declaration is to inform any external
entity of the set of hardware and software features on which your
application depends.
In general, you should always make sure to declare
elements for all of the features that your application requires
<uses-feature android:name="android.hardware.camera"
android:required="false" />
If required = "false" is given in manifest then app uses a camera but it’s not mandatory for the application to work, and all device can install app from play store whether device has camera feature or not.
if required = "true" is given in manifest then device which has camera feature can only use app other devices which do not have camera feature not able to install from google play store.
This allows Google Play Store to filter out apps for devices that don’t have their required features.
I hope it helps!
I face a strange problem,
My application works perfectly on devices with or without a camera; only a few functionalities are not available if you don't have a camera.
After uploading my app to the play store, the play store excluded some devices without a camera in which the app actually works fine!
By using this permission:
<uses-permission android:name="android.permission.CAMERA"/>
play store auto excludes.
Has anybody faced similar problems?
Sorry if this is a duplicate (I hope it is not).
From the docs:
In some cases, the permissions that you request through can affect how your application is filtered by Google Play.
If you request a hardware-related permission — CAMERA, for example — Google Play assumes that your application requires the underlying hardware feature and filters the application from devices that do not offer it.
To control filtering, always explicitly declare hardware features in elements, rather than relying on Google Play to "discover" the requirements in elements. Then, if you want to disable filtering for a particular feature, you can add a android:required="false" attribute to the declaration.
So, just add this to your manifest:
<uses-feature android:name="android.hardware.camera" android:required="false"/>
I know at least for features there is an option to set if it isrequired or not . You could try that.
Just add required=false in the permission declaration.
I am hesitant to ask this question, because it appears as though many people have a similar problem and yet I have found no solution that solves my particular instance.
I have developed an Android app (link to the actual app) and have uploaded it to the Play store. The Play store says
"This app is incompatible with your XT Mobile Network HTC HTC Wildfire S A510b."
Of course that is the phone on which I developed the app, so it ought to be compatible. Some people with other devices say that it reports compatible, others say it reports incompatible, but I can find no trend. (Apparently I don't know very many people with Android devices.)
I have tried the following:
moving a large-ish file out of the res/raw directory as suggested by this answer. The only file in there was a ~700 kB text file, but I moved it to assets/ with no apparent change.
adding the following two feature assertions:
<uses-feature android:name="android.hardware.faketouch" />
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
thinking that maybe my phone doesn't claim to support the usual android.hardware.touchscreen feature, but again, with no apparent change.
When uploading the APK to the Play store, the only filter that it reports as active is the android.hardware.faketouch feature.
The following is the output of aapt dump badging bin/NZSLDict-release.apk:
package: name='com.hewgill.android.nzsldict' versionCode='3' versionName='1.0.2'
sdkVersion:'4'
targetSdkVersion:'4'
uses-feature:'android.hardware.faketouch'
uses-feature-not-required:'android.hardware.touchscreen'
application-label:'NZSL Dictionary'
application-icon-160:'res/drawable/icon.png'
application: label='NZSL Dictionary' icon='res/drawable/icon.png'
launchable-activity: name='com.hewgill.android.nzsldict.NZSLDictionary' label='NZSL Dictionary' icon=''
main
other-activities
supports-screens: 'small' 'normal' 'large'
supports-any-density: 'true'
locales: '--_--'
densities: '160'
and for completeness, my manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.hewgill.android.nzsldict"
android:versionCode="3"
android:versionName="1.0.2">
<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="4" />
<uses-feature android:name="android.hardware.faketouch" />
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
<application android:label="#string/app_name"
android:icon="#drawable/icon">
<activity android:name="NZSLDictionary"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".WordActivity" />
<activity android:name=".VideoActivity" />
<activity android:name=".AboutActivity" />
</application>
</manifest>
In the "Device Availability" section of the Play store, I can see that all the HTC devices, including the Wildfire S, are supported except for "G1 (trout)" and "Touch Viva (opal)", whatever those are. Actually I see that both "Wildfire S (marvel)" and "Wildfire S A515c (marvelc)" are listed as supported, but my "Wildfire S A510b" is not specifically mentioned. Can this sort of sub-model identifier matter that much? I have been able to download several other apps from Google Play to my phone with no problems.
The only thing I haven't done at this point is wait 4-6 hours after uploading the latest version (as in this comment) to see whether it still says it's incompatible with my phone. However, the Play store page currently shows 1.0.2 which is the latest I have uploaded.
The answer appears to be solely related to application size. I created a simple "hello world" app with nothing special in the manifest file, uploaded it to the Play store, and it was reported as compatible with my device.
I changed nothing in this app except for adding more content into the res/drawable directory. When the .apk size reached about 32 MB, the Play store started reporting that my app was incompatible with my phone.
I will attempt to contact Google developer support and ask for clarification on the reason for this limit.
UPDATE: Here is Google developer support response to this:
Thank you for your note. Currently the maximum file size limit for an app upload to Google Play is approximately 50 MB.
However, some devices may have smaller than 50 MB cache partition making the app unavailable for users to download. For example, some of HTC Wildfire devices are known for having 35-40 MB cache partitions. If Google Play is able to identify such device that doesn't have cache large enough to store the app, it may filter it from appearing for the user.
I ended up solving my problem by converting all the PNG files to JPG, with a small loss of quality. The .apk file is now 28 MB, which is below whatever threshold Google Play is enforcing for my phone.
I also removed all the <uses-feature> stuff, and now have just this:
<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="15" />
I ran into this as well - I did all of my development on a Lenovo IdeaTab A2107A-F and could run development builds on it, and even release signed APKs (installed with adb install) with no issues. Once it was published in Alpha test mode and available on Google Play I received the "incompatible with your device" error message.
It turns out I had placed in my AndroidManifest.xml the following from a tutorial:
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.CAMERA" />
Well, the Lenovo IdeaTab A2107A-F doesn't have an autofocusing camera on it (which I learned from http://www.phonearena.com/phones/Lenovo-IdeaTab-A2107_id7611, under Cons: lacks autofocus camera). Regardless of whether I was using that feature, Google Play said no. Once that was removed I rebuilt my APK, uploaded it to Google Play, and sure enough my IdeaTab was now in the compatible devices list.
So, double-check every <uses-feature> and if you've been doing some copy-paste from the web check again. Odds are you requested some feature you aren't even using.
I have experienced this problem too while developing an application for a customer that wanted to have videos offline available from their application. I have written a blogpost about why the app I worked on for months wouldn't show up in the play store for my device (post can be found here). I found the same as #Greg Hewgill found: Cache partition limitations on some devices.
The journey didn't stop for me there. The customer wanted to have these videos in the application and didn't want the quality of the video to be decreased. After some research I figured out that using expansion files was the perfect solution to our problem.
To share my knowledge with the Android community I held a talk at droidconNL 2012 about expansion files. I created a presentation and sample code to illustrate how easy it can be to start using expansion files. For any of you out there wanting to use expansion files to solve this problem feel free to check out the post containing the presentation and the sample code
You might want to try and set the supports-screens attribute:
<supports-screens
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:xlargeScreens="true" >
</supports-screens>
The Wildfire has a small screen, and according to the documentation this attribute should default to "true" in all cases, but there are known issues with the supports-screens settings on different phones, so I would try this anyway.
Also - as David suggests - always compile and target against the most current version of the Android API, unless you have strong reasons not to. Pretty much every SDK prior to 2.2 has some serious issue or weird behavior; the latter SDK's help to resolve or cover up a lot (although not all) of them. You can (and should) use the Lint tool to check that your app remains compatible with API 4 when preparing a release.
Finlay, I have faced same issue in my application. I have developed Phone Gap app for
android:minSdkVersion="7" & android:targetSdkVersion="18" which is recent version of android platform.
I have found the issue using Google Docs
May be issue is that i have write some JS function which works on KEY-CODE to validate only Alphabets & Number but key board has different key code specially for computer keyboard & Mobile keyboard. So that was my issue.
I am not sure whether my answer is correct or not and it might be possible that it could be smiler to above answer but i will try to list out some points which should be care while we are building the app.I hope you follow this to solve this kind of issue.
Use the android:minSdkVersion="?" as per your requirement & android:targetSdkVersion="?" should be latest in which your app will targeting. see more
Try to add only those permission which will be use in your application and remove all which are unnecessary .
Check out the supported screen by application
<supports-screens
android:anyDensity="true"
android:largeScreens="true"
android:normalScreens="true"
android:resizeable="true"
android:smallScreens="true"
android:xlargeScreens="true"/>
May be you have implement some costume code or costume widget which couldn't able to run in some device or tab late so before writing the long code first try to write some beta code and test it whether your code will run in all device or not.
And I hope Google will publish a tool which can validate your code before the upload the app and also says that due to some specific reason we are not allow to run your app in some device so we can easily solve it.
Permissions that Imply Feature Requirements
example, the android.hardware.bluetooth feature was added in Android 2.2 (API level 8), but the bluetooth API that it refers to was added in Android 2.0 (API level 5). Because of this, some apps were able to use the API before they had the ability to declare that they require the API via the system.
To prevent those apps from being made available unintentionally, Google Play assumes that certain hardware-related permissions indicate that the underlying hardware features are required by default. For instance, applications that use Bluetooth must request the BLUETOOTH permission in a element — for legacy apps, Google Play assumes that the permission declaration means that the underlying android.hardware.bluetooth feature is required by the application and sets up filtering based on that feature.
The table below lists permissions that imply feature requirements equivalent to those declared in elements. Note that declarations, including any declared android:required attribute, always take precedence over features implied by the permissions below.
For any of the permissions below, you can disable filtering based on the implied feature by explicitly declaring the implied feature explicitly, in a element, with an android:required="false" attribute. For example, to disable any filtering based on the CAMERA permission, you would add this declaration to the manifest file:
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.bluetooth" android:required="false" />
<uses-feature android:name="android.hardware.location" android:required="false" />
<uses-feature android:name="android.hardware.location.gps" android:required="false" />
<uses-feature android:name="android.hardware.telephony" android:required="false" />
<uses-feature android:name="android.hardware.wifi" android:required="false" />
http://developer.android.com/guide/topics/manifest/uses-feature-element.html#permissions
I have a couple of suggestions:
First of all, you seem to be using API 4 as your target. AFAIK, it's good practice to always compile against the latest SDK and setup your android:minSdkVersion accordingly.
With that in mind, remember that android:required attribute was added in API 5:
The feature declaration can include an android:required=["true" | "false"] attribute (if you are compiling against API level 5 or higher), which lets you specify whether the application (...)
Thus, I'd suggest that you compile against SDK 15, set targetSdkVersion to 15 as well, and provide that functionality.
It also shows here, on the Play site, as incompatible with any device that I have that is (coincidence?) Gingerbread (Galaxy Ace and Galaxy Y here). But it shows as compatible with my Galaxy Tab 10.1 (Honeycomb), Nexus S and Galaxy Nexus (both on ICS).
That also left me wondering, and this is a very wild guess, but since android.hardware.faketouch is API11+, why don't you try removing it just to see if it works? Or perhaps that's all related anyway, since you're trying to use features (faketouch) and the required attribute that are not available in API 4. And in this case you should compile against the latest API.
I would try that first, and remove the faketouch requirement only as last resort (of course) --- since it works when developing, I'd say it's just a matter of the compiled app not recognizing the feature (due to the SDK requirements), thus leaving unexpected filtering issues on Play.
Sorry if this guess doesn't answer your question, but it's very difficult to diagnose those kind of problems and pinpoint the solution without actually testing. Or at least for me without all the proper knowledge of how Play really filters apps.
Good luck.
To give an extra solution to the above 'This app is incompatible with your...' problem, let me share my solution for a different problem cause. I tried installing an app on a low-end Samsung Galaxy Y (GT-S6350) device and got this error from the Play store. To test various AndroidManifest configurations, I created an account and followed the routine as described in https://stackoverflow.com/a/5449397/372838 until my device showed up in the supported device list.
It turned out that a lot of devices become incompatible when you use the Camera permission:
<uses-permission android:name="android.permission.CAMERA" />
When I removed that specific permission, the application was available for 1180 devices instead of 870. Hope it will help someone
Typical, found it right after posting this question in despair; the tool I was looking for was:
$ aapt dump badging <my_apk.apk>
Though there are already quite a few answers, I thought my answer might help some who have exactly the same problem as mine.
In my case, the problem is caused by the following permissions added per the suggestion of an ad network:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
The consequence of the above permissions is that the following features are added automatically:
android.hardware.LOCATION
android.hardware.location.GPS
android.hardware.location.NETWORK
The reason is that "Google Play attempts to discover an application's implied feature requirements by examining other elements declared in the manifest file, specifically, elements."
Two of my testing devices do not have the above features, so the app became incompatible with them. Removing those permissions solved the problem immediately.
I found an additional way in which this problem occurs:
My LG phone's original OS was Froyo (Android 2.2) and was updated to ICS (Android 4.0.4).
But the Google Play Developers' Console shows that it detects my phone as a Froyo device.
(Google Play did not allow the app to be downloaded because of the false 'incompatibility', but it somehow still detects the installation.)
The phone's settings, in 'software', shows ICS V4.0.4. It seems that the Google Play server info for the phone is not updated to reflect the ICS update on the device. The app manifest minSDK is set to Honeycomb (3.0), so of course Google Play filters out the app.
Of addition interest:
The app uses In-app Billing V3. The first time through IabHelper allows the app to make purchases through the Google Play service. But after the purchase is made, the purchase is NOT put in the inventory and IabHelper reports no items are owned. Debug messages show a 'purchase failed' result from the purchase even though the Google Play window announces "purchase successful."
I had the same problem. It was caused by having different version codes and numbers in my manifest and gradle build script. I resolved it by removing the version code and version number from my manifest and letting gradle take care of it.
I also had the same problem. I published an App in Test mode created with React Native 59. it wasn't compatible for certain tester.
The message wasn't clear about why the app is not compatible , after i figured out that i restricted the app to be available only for certain country . that was the problem, but as i said the message wasn't clear.
in Play Store WebApp the message is: "this app is not compatible with your device".
in the mobile app the message "This app is not available in your country"
If you're here in 2020 and you think the device receiving the error message should be compatible:
Several other major apps have run into this including Instagram (1B+ installs) and Clash of Clans (100M+ installs). It appears to be an issue with Google's Android operating system.
To fix the “your device is not compatible with this version” error message, try clearing the Google Play Store cache, and then data. Next, restart the Google Play Store and try installing the app again.
[https://support.getupside.com/hc/en-us/articles/226667067--Device-not-compatible-error-message-in-Google-Play-Store]
Here is a link to Google's official support page that you can link to your users on how to clear the cache: https://support.google.com/googleplay/answer/7513003
In Android some permissions <uses-permission> will imply <uses-feature> requirements to the app.
For example <uses-permission android:name="android.permission.BLUETOOTH" />
Will imply <uses-feature android:name="android.hardware.bluetooth"/>
You can check the whole list here https://developer.android.com/guide/topics/manifest/uses-feature-element#permissions
I've published my app on the Market, but it somehow auto-detected several features that it thinks are required. One of those features is "android.hardware.telephony", and because this is now a required feature, my app can't be installed on wifi-only tablets.
I don't have any "uses-feature" declarations in the manifest file, but my app does have the capability to make calls. I guess that Google is requiring "android.hardware.telephony" because of this functionality. However, this functionality is just a value-added feature. It is by no means required for the core functionality of the app.
I don't want to completely remove the telephony functionality because there are way more users with phone devices vs. wifi-only devices. I also don't want to create and maintain another version of the app for wifi-only devices. Is there any way for me to mark telephony as an optional feature, so that both types of devices can use my app?
See http://developer.android.com/guide/appendix/market-filters.html and http://developer.android.com/guide/topics/manifest/uses-feature-element.html .
In your case add
<uses-feature android:name="android.hardware.telephony"
android:required="false" />
to your manifest.