Search code examples
androidgoogle-playgoogle-play-console

Uploaded up on Google Play not supported on many devices


I recently uploaded an app that I have made on Google Play though the Google Play Console. For some reason that I don't really understand on all the devices (mine, friend and family) shows that the app is not supported with my device. It's the first that I'm using Google Play Console and since the app past the review process from Google, I don't really understand why this is happening. I found the device catalog tab, but I haven't put any exclusions there.

After I uploaded the app through Google Play Console, I've send the app to friends and family, like 20 people or so, but none of them was able to download the app. Same thing is happening on my 2 devices.

Here is the manifest

<uses-feature
    android:name="android.hardware.Camera"
    android:required="true" />

<queries>
    <intent>
        <action android:name="android.media.action.IMAGE_CAPTURE" />
    </intent>
</queries>

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.CAMERA" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/Theme.PITAFLPantryManager">
    <activity
        android:name=".ShoppingListActivity"
        android:parentActivityName=".MainActivity" />
    <activity android:name=".TextRecognitionActivity" />
    <activity android:name=".BarcodeScannerActivity" />
    <activity
        android:name=".ProductsActivity"
        android:parentActivityName=".MainActivity">
        <meta-data android:name="android.app.default_searchable"
            android:value=".SearchableActivity" />
    </activity>
    <activity
        android:name=".SettingsActivity"
        android:exported="false"
        android:label="@string/title_activity_settings"
        android:parentActivityName=".MainActivity"/>
    <activity android:name=".AboutActivity"
        android:parentActivityName=".MainActivity" />
    <activity android:name=".SearchableActivity"
        android:launchMode="singleTop"
        android:exported="false">
        <intent-filter>
            <action android:name="android.intent.action.SEARCH" />
        </intent-filter>
        <meta-data android:name="android.app.searchable"
            android:resource="@xml/searchable" />
    </activity>
    <activity android:name=".MainActivity"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <meta-data android:name="android.app.default_searchable"
            android:value=".SearchableActivity" />
    </activity>

    <meta-data
        android:name="com.google.mlkit.vision.DEPENDENCIES"
        android:value="ocr" />

    <!--service
        android:name=".ProductsWatcherWorker"
        android:permission="android.permission.BIND_JOB_SERVICE"></service-->
</application>

And the build.gradle

plugins {
    id 'com.android.application'
}

// Creates a variable called keystorePropertiesFile, and initializes it to the
// keystore.properties file.
def keystorePropertiesFile = rootProject.file('keystore.properties')

// Initializes a new Properties() object called keystoreProperties.
def keystoreProperties = new Properties()

// Loads the keystore.properties file into the keystoreProperties object.
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))

android {
    signingConfigs {
        debug {
            keyAlias keystoreProperties['debugKeyAlias']
            keyPassword keystoreProperties['debugKeyPassword']
            storeFile file(keystoreProperties['debugStoreFile'])
            storePassword keystoreProperties['debugStorePassword']
        }
        release {
            keyAlias keystoreProperties['releaseKeyAlias']
            keyPassword keystoreProperties['releaseKeyPassword']
            storeFile file(file(keystoreProperties['releaseStoreFile']))
            storePassword keystoreProperties['releaseStorePassword']
        }
    }
    compileSdkVersion 32
    buildToolsVersion "30.0.3"

    defaultConfig {
        applicationId "com.timkom.pitafl"
        minSdkVersion 27
        targetSdkVersion 32
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            packagingOptions {
                exclude 'AndroidManifest.xml'
                exclude 'resources.arsc'
            }
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            debuggable false
            jniDebuggable false
            renderscriptDebuggable false
            zipAlignEnabled false
            signingConfig signingConfigs.release
        }
        debug {
            signingConfig signingConfigs.debug
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    buildFeatures {
        viewBinding true
    }

    configurations {
        compile.exclude group: 'com.google.android'
    }
}

dependencies {

    implementation 'androidx.appcompat:appcompat:1.3.1'
    implementation 'androidx.lifecycle:lifecycle-viewmodel:2.3.1'
    implementation 'com.google.android.material:material:1.4.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
    implementation 'androidx.coordinatorlayout:coordinatorlayout:1.1.0'
    implementation 'androidx.fragment:fragment:1.3.6'
    implementation 'com.github.bumptech.glide:glide:4.12.0'
    implementation 'com.github.bigfishcat.android:svg-android:2.0.8'
    implementation 'androidx.work:work-runtime:2.5.0'
    implementation 'androidx.preference:preference:1.1.0'
    implementation 'com.google.mlkit:barcode-scanning:17.0.2'
    implementation "androidx.camera:camera-camera2:1.0.2"
    implementation "androidx.camera:camera-lifecycle:1.0.2"
    implementation "androidx.camera:camera-view:1.0.0-alpha23"
    implementation 'com.google.android.gms:play-services-mlkit-text-recognition:18.0.0'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}

android.applicationVariants.all { variant ->
    variant.outputs.all {
        outputFileName = "${applicationId}-${variant.name}-${variant.versionName}.apk"
    }
}


Solution

  • While you found the problematic part of the manifest, the issue isn't what you think it is - the name of the feature has nothing to do with the package name of the camera API.

    https://developer.android.com/reference/android/hardware/Camera is the old camera API, https://developer.android.com/reference/android/hardware/camera2/ is the new camera API, but both relate to the package manager features like:

    Your problem is that the FEATURE_CAMERA string is "android.hardware.camera", not "android.hardware.Camera". It's case-sensitive.

    And you probably want FEATURE_CAMERA_ANY, "android.hardware.camera.any" unless you only work with back-facing cameras.

    And it is good to have the feature listed as required, if your app is useless without a camera. Otherwise, listing it as android:required="false" is probably best.