Я хочу распространить свое приложение как можно большему количеству пользователей через Google Play Store, но у меня странное поведение в отношении совместимых устройств для моего обновленного приложения (я обновляю приложение, сохраняя тот же идентификатор приложения; старая версия - текущая производственная онлайн-версия - последний раз обновлялась в 2021 году).
Я уже прочитал все связанные вопросы о переполнении стека, а также официальную документацию по Android. Я использую последнюю версию Android Studio, создавая формат App Bundle.
Play Console указывает для обеих версий одинаковое количество совместимых устройств (около 19 тысяч+).
На некоторых устройствах новый несовместим, но старый можно установить.
Вот некоторые устройства, определенные Play Store как несовместимые (все без рута):
Я уже пробовал это, но безуспешно:
<supports-screens android:xlargeScreens = "true" android:largeScreens = "true" android:normalScreens = "true" android:smallScreens = "true" android:anyDensity = "true" android:resizeable = "true" />
Вот сообщение в Play Store:
Это приложение несовместимо с вашим устройством, так как оно было создано для более старой версии Android.
Мое приложение нацелено на Api 33 (Android 13), а минимальная цель — 19 (Android 4.4). Итак, настолько очевидно, что версия для Android совместима!
Сгенерированный манифест в .apk (старая версия приложения):
<?xml version = "1.0" encoding = "utf-8"?>
<manifest
xmlns:android = "http://schemas.android.com/apk/res/android"
platformBuildVersionCode = "29"
platformBuildVersionName = "10"
package = "com.app.my"
android:compileSdkVersion = "29"
android:compileSdkVersionCodename = "10"
android:versionCode = "24"
android:versionName = "2.1">
<uses-sdk android:minSdkVersion = "19" android:targetSdkVersion = "29" />
<uses-permission android:name = "android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name = "android.permission.INTERNET" />
<uses-permission android:name = "android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name = "android.permission.WAKE_LOCK" />
<uses-permission android:name = "com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE" />
<application
android:theme = "@ref/0xtheme"
android:label = "@ref/0xlabel"
android:icon = "@ref/0xicon"
android:roundIcon = "@ref/0xroundIcon"
android:supportsRtl = "true"
android:appComponentFactory = "androidx.core.app.CoreComponentFactory">
<activity
android:name = "com.app.my.MainActivity"
android:theme = "@ref/0xtheme"
android:label = "@ref/0xlabel"
android:screenOrientation = "1">
<intent-filter>
<action android:name = "android.intent.action.MAIN" />
<category android:name = "android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name = "com.app.my.NotificationReceiver" />
<receiver
android:name = "com.app.my.BootReceiver">
<intent-filter>
<action android:name = "android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<meta-data
android:name = "com.google.android.gms.ads.APPLICATION_ID"
android:value = "ca-app-pub-12345" />
<provider
android:name = "com.google.firebase.provider.FirebaseInitProvider"
android:authorities = "com.app.my.firebaseinitprovider"
android:directBootAware = "true"
android:exported = "false"
android:initOrder = "100" />
<service
android:name = "com.google.firebase.components.ComponentDiscoveryService"
android:directBootAware = "true"
android:exported = "false">
<meta-data
android:name = "com.google.firebase.components:com.google.firebase.crashlytics.CrashlyticsRegistrar"
android:value = "com.google.firebase.components.ComponentRegistrar" />
<meta-data
android:name = "com.google.firebase.components:com.google.firebase.analytics.connector.internal.AnalyticsConnectorRegistrar"
android:value = "com.google.firebase.components.ComponentRegistrar" />
<meta-data
android:name = "com.google.firebase.components:com.google.firebase.installations.FirebaseInstallationsRegistrar"
android:value = "com.google.firebase.components.ComponentRegistrar" />
<meta-data
android:name = "com.google.firebase.components:com.google.firebase.dynamicloading.DynamicLoadingRegistrar"
android:value = "com.google.firebase.components.ComponentRegistrar" />
</service>
<service
android:name = "com.google.android.datatransport.runtime.backends.TransportBackendDiscovery"
android:exported = "false">
<meta-data
android:name = "backend:com.google.android.datatransport.cct.CctBackendFactory"
android:value = "cct" />
</service>
<receiver
android:name = "com.google.android.gms.measurement.AppMeasurementReceiver"
android:enabled = "true"
android:exported = "false"/>
<service
android:name = "com.google.android.gms.measurement.AppMeasurementService"
android:enabled = "true"
android:exported = "false" />
<service
android:name = "com.google.android.gms.measurement.AppMeasurementJobService"
android:permission = "android.permission.BIND_JOB_SERVICE"
android:enabled = "true"
android:exported = "false" />
<activity
android:theme = "@ref/0xtheme"
android:name = "com.google.android.gms.ads.AdActivity"
android:exported = "false"
android:configChanges = "0xfb0" />
<provider
android:name = "com.google.android.gms.ads.MobileAdsInitProvider"
android:exported = "false"
android:authorities = "com.app.my.mobileadsinitprovider"
android:initOrder = "100" />
<meta-data
android:name = "com.google.android.gms.version"
android:value = "@ref/0x7f0a0009" />
<service
android:name = "com.google.android.datatransport.runtime.scheduling.jobscheduling.JobInfoSchedulerService"
android:permission = "android.permission.BIND_JOB_SERVICE"
android:exported = "false"/>
<receiver
android:name = "com.google.android.datatransport.runtime.scheduling.jobscheduling.AlarmManagerSchedulerBroadcastReceiver"
android:exported = "false" />
<!-- not in the new version -->
<uses-permission android:name = "com.android.vending.CHECK_LICENSE" />
<provider
android:name = "androidx.lifecycle.ProcessLifecycleOwnerInitializer"
android:exported = "false"
android:multiprocess = "true"
android:authorities = "com.app.my.lifecycle-process" />
</application>
</manifest>
Сгенерированный манифест в формате .aab (новая версия приложения):
<?xml version = "1.0" encoding = "utf-8"?>
<manifest
xmlns:android = "http://schemas.android.com/apk/res/android"
platformBuildVersionCode = "33"
platformBuildVersionName = "13"
package = "com.app.my"
android:compileSdkVersion = "33"
android:compileSdkVersionCodename = "13"
android:versionCode = "33"
android:versionName = "3.0.3">
<uses-sdk android:minSdkVersion = "19" android:targetSdkVersion = "33" />
<uses-permission android:name = "android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name = "android.permission.INTERNET" />
<uses-permission android:name = "android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name = "android.permission.WAKE_LOCK" />
<uses-permission android:name = "com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE" />
<application
android:theme = "@style/AppTheme"
android:label = "@string/app_name"
android:icon = "@mipmap/ic_launcher"
android:roundIcon = "@mipmap/ic_launcher_round"
android:supportsRtl = "true"
android:appComponentFactory = "androidx.core.app.CoreComponentFactory">
<activity
android:name = "com.app.my.MainActivity"
android:theme = "@style/AppTheme.NoActionBar"
android:label = "@string/app_name"
android:screenOrientation = "portrait"
android:exported = "true">
<intent-filter>
<action android:name = "android.intent.action.MAIN" />
<category android:name = "android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name = "com.app.my.NotificationReceiver" />
<receiver
android:name = "com.app.my.BootReceiver"
android:exported = "false" >
<intent-filter>
<action android:name = "android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<meta-data
android:name = "com.google.android.gms.ads.APPLICATION_ID"
android:value = "ca-app-pub-12345" />
<provider
android:name = "com.google.firebase.provider.FirebaseInitProvider"
android:authorities = "com.app.my.firebaseinitprovider"
android:directBootAware = "true"
android:exported = "false"
android:initOrder = "100" />
<service
android:name = "com.google.firebase.components.ComponentDiscoveryService"
android:directBootAware = "true"
android:exported = "false" >
<meta-data
android:name = "com.google.firebase.components:com.google.firebase.crashlytics.CrashlyticsRegistrar"
android:value = "com.google.firebase.components.ComponentRegistrar" />
<meta-data
android:name = "com.google.firebase.components:com.google.firebase.analytics.connector.internal.AnalyticsConnectorRegistrar"
android:value = "com.google.firebase.components.ComponentRegistrar" />
<meta-data
android:name = "com.google.firebase.components:com.google.firebase.installations.FirebaseInstallationsRegistrar"
android:value = "com.google.firebase.components.ComponentRegistrar" />
</service>
<service
android:name = "com.google.android.datatransport.runtime.backends.TransportBackendDiscovery"
android:exported = "false" >
<meta-data
android:name = "backend:com.google.android.datatransport.cct.CctBackendFactory"
android:value = "cct" />
</service>
<receiver
android:name = "com.google.android.gms.measurement.AppMeasurementReceiver"
android:enabled = "true"
android:exported = "false" >
</receiver>
<service
android:name = "com.google.android.gms.measurement.AppMeasurementService"
android:enabled = "true"
android:exported = "false" />
<service
android:name = "com.google.android.gms.measurement.AppMeasurementJobService"
android:permission = "android.permission.BIND_JOB_SERVICE"
android:enabled = "true"
android:exported = "false" />
<activity
android:theme = "@android:style/Theme.Translucent"
android:name = "com.google.android.gms.ads.AdActivity"
android:exported = "false"
android:configChanges = "keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" />
<provider
android:name = "com.google.android.gms.ads.MobileAdsInitProvider"
android:exported = "false"
android:authorities = "com.app.my.mobileadsinitprovider"
android:initOrder = "100" />
<meta-data
android:name = "com.google.android.gms.version"
android:value = "@integer/google_play_services_version" />
<service
android:name = "com.google.android.datatransport.runtime.scheduling.jobscheduling.JobInfoSchedulerService"
android:permission = "android.permission.BIND_JOB_SERVICE"
android:exported = "false" >
</service>
<receiver
android:name = "com.google.android.datatransport.runtime.scheduling.jobscheduling.AlarmManagerSchedulerBroadcastReceiver"
android:exported = "false" />
<!-- the below aren't in the old versoin -->
<uses-permission android:name = "android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name = "android.permission.SCHEDULE_EXACT_ALARM" />
<uses-permission android:name = "android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name = "com.app.my.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION" />
<uses-permission android:name = "com.google.android.gms.permission.AD_ID" />
<permission android:name = "com.app.my.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION" android:protectionLevel = "signature" />
<queries>
<intent>
<action android:name = "android.intent.action.VIEW" />
<category android:name = "android.intent.category.BROWSABLE" />
<data android:scheme = "https" />
</intent>
<intent>
<action android:name = "android.support.customtabs.action.CustomTabsService" />
</intent>
</queries>
<activity
android:name = "com.app.my.SettingsActivity"
android:configChanges = "orientation|screenSize"
android:parentActivityName = "com.app.my.MainActivity" />
<provider
android:name = "androidx.core.content.FileProvider"
android:authorities = "com.app.my.provider"
android:exported = "false"
android:grantUriPermissions = "true"
android:readPermission = "com.ANOTHERapp.my.fileprovider.READ" >
<meta-data
android:name = "android.support.FILE_PROVIDER_PATHS"
android:resource = "@xml/provider_paths" />
</provider>
<service
android:name = "com.google.android.gms.ads.AdService"
android:enabled = "true"
android:exported = "false" />
<activity
android:name = "com.google.android.gms.ads.OutOfContextTestingActivity"
android:configChanges = "keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
android:exported = "false" />
<activity
android:name = "com.google.android.gms.common.api.GoogleApiActivity"
android:exported = "false"
android:theme = "@android:style/Theme.Translucent.NoTitleBar" />
<provider
android:name = "androidx.startup.InitializationProvider"
android:authorities = "com.app.my.androidx-startup"
android:exported = "false" >
<meta-data
android:name = "androidx.emoji2.text.EmojiCompatInitializer"
android:value = "androidx.startup" />
<meta-data
android:name = "androidx.work.WorkManagerInitializer"
android:value = "androidx.startup" />
<meta-data
android:name = "androidx.lifecycle.ProcessLifecycleInitializer"
android:value = "androidx.startup" />
</provider>
<uses-library
android:name = "androidx.window.extensions"
android:required = "false" />
<uses-library
android:name = "androidx.window.sidecar"
android:required = "false" />
<service
android:name = "androidx.work.impl.background.systemalarm.SystemAlarmService"
android:directBootAware = "false"
android:enabled = "@bool/enable_system_alarm_service_default"
android:exported = "false" />
<service
android:name = "androidx.work.impl.background.systemjob.SystemJobService"
android:directBootAware = "false"
android:enabled = "@bool/enable_system_job_service_default"
android:exported = "true"
android:permission = "android.permission.BIND_JOB_SERVICE" />
<service
android:name = "androidx.work.impl.foreground.SystemForegroundService"
android:directBootAware = "false"
android:enabled = "@bool/enable_system_foreground_service_default"
android:exported = "false" />
<receiver
android:name = "androidx.work.impl.utils.ForceStopRunnable$BroadcastReceiver"
android:directBootAware = "false"
android:enabled = "true"
android:exported = "false" />
<receiver
android:name = "androidx.work.impl.background.systemalarm.ConstraintProxy$BatteryChargingProxy"
android:directBootAware = "false"
android:enabled = "false"
android:exported = "false" >
<intent-filter>
<action android:name = "android.intent.action.ACTION_POWER_CONNECTED" />
<action android:name = "android.intent.action.ACTION_POWER_DISCONNECTED" />
</intent-filter>
</receiver>
<receiver
android:name = "androidx.work.impl.background.systemalarm.ConstraintProxy$BatteryNotLowProxy"
android:directBootAware = "false"
android:enabled = "false"
android:exported = "false" >
<intent-filter>
<action android:name = "android.intent.action.BATTERY_OKAY" />
<action android:name = "android.intent.action.BATTERY_LOW" />
</intent-filter>
</receiver>
<receiver
android:name = "androidx.work.impl.background.systemalarm.ConstraintProxy$StorageNotLowProxy"
android:directBootAware = "false"
android:enabled = "false"
android:exported = "false" >
<intent-filter>
<action android:name = "android.intent.action.DEVICE_STORAGE_LOW" />
<action android:name = "android.intent.action.DEVICE_STORAGE_OK" />
</intent-filter>
</receiver>
<receiver
android:name = "androidx.work.impl.background.systemalarm.ConstraintProxy$NetworkStateProxy"
android:directBootAware = "false"
android:enabled = "false"
android:exported = "false" >
<intent-filter>
<action android:name = "android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
<receiver
android:name = "androidx.work.impl.background.systemalarm.RescheduleReceiver"
android:directBootAware = "false"
android:enabled = "false"
android:exported = "false" >
<intent-filter>
<action android:name = "android.intent.action.BOOT_COMPLETED" />
<action android:name = "android.intent.action.TIME_SET" />
<action android:name = "android.intent.action.TIMEZONE_CHANGED" />
</intent-filter>
</receiver>
<receiver
android:name = "androidx.work.impl.background.systemalarm.ConstraintProxyUpdateReceiver"
android:directBootAware = "false"
android:enabled = "@bool/enable_system_alarm_service_default"
android:exported = "false" >
<intent-filter>
<action android:name = "androidx.work.impl.background.systemalarm.UpdateProxies" />
</intent-filter>
</receiver>
<receiver
android:name = "androidx.work.impl.diagnostics.DiagnosticsReceiver"
android:directBootAware = "false"
android:enabled = "true"
android:exported = "true"
android:permission = "android.permission.DUMP" >
<intent-filter>
<action android:name = "androidx.work.diagnostics.REQUEST_DIAGNOSTICS" />
</intent-filter>
</receiver>
<service
android:name = "androidx.room.MultiInstanceInvalidationService"
android:directBootAware = "true"
android:exported = "false" />
</application>
</manifest>
build.gradle старой версии приложения:
apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'
android {
compileSdkVersion 29
defaultConfig {
applicationId "com.app.my"
minSdkVersion 19
targetSdkVersion 29
versionCode 24
versionName "2.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
debug {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
debuggable true
}
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
debuggable false
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.navigation:navigation-fragment:2.1.0'
implementation 'androidx.navigation:navigation-ui:2.1.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0'
implementation 'org.jetbrains:annotations-java5:15.0'
implementation 'com.google.android.gms:play-services-ads:19.2.0'
implementation project(path: ':lvl_library') // it was used for the Google licensing verification
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
// Import the Firebase BoM
implementation platform('com.google.firebase:firebase-bom:27.1.0')
// Add the dependency for the Firebase SDK for Google Analytics
// When using the BoM, don't specify versions in Firebase dependencies
implementation 'com.google.firebase:firebase-crashlytics'
implementation 'com.google.firebase:firebase-analytics'
}
build.gradle новой версии приложения:
apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'
android {
compileSdkVersion 33
defaultConfig {
applicationId "com.app.my"
minSdkVersion 19
targetSdkVersion 33
versionCode 34
versionName "3.0.4"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
debug {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
debuggable true
}
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
debuggable false
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
namespace 'com.app.my'
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.google.android.material:material:1.8.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.navigation:navigation-fragment:2.5.3'
implementation 'androidx.navigation:navigation-ui:2.5.3'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'com.google.android.gms:play-services-ads:21.5.0'
implementation 'androidx.preference:preference:1.2.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
implementation 'com.google.android.play:integrity:1.1.0'
// Import the Firebase BoM
implementation platform('com.google.firebase:firebase-bom:31.2.3')
// Add the dependency for the Firebase SDK for Google Analytics
// When using the BoM, don't specify versions in Firebase dependencies
implementation 'com.google.firebase:firebase-crashlytics:18.3.5'
implementation 'com.google.firebase:firebase-analytics:21.2.0'
}
Почему эти устройства не определяются как совместимые? И как я могу сделать свое приложение максимально совместимым?
Спасибо!
@ Роберт, я имею в виду Google Play Store. Я попрошу пользователей повторить попытку проверить версию сервисов Google Play. Предлагаемое вами вспомогательное приложение устарело в 2018 году и поддерживает только Android 9.
Вспомогательное приложение, которое я связал, отлично работает на моем устройстве Android 13 Pixel. Я не знаю, почему вы думаете, что это ограничено Android 9.
@Robert Само приложение говорит в разделе «Что нового», что оно поддерживает Android 9 и последний раз обновлялось в 2018 году (5 лет назад) (возможно, оно работает и для более новых версий). В любом случае, пользователь с OnePlus Nord дважды проверил, что он уже установил последнюю версию приложения Google Play Store (используя вашу ссылку)
Я из темы: Приложение создано для более старой версии андроида
Кажется, что в Play Store есть странная ошибка, когда внутренний тестовый apk имеет более высокий targetSdk, чем производственный, в результате чего при доступе к внутреннему тесту отображается сообщение, что приложение было создано для более старой версии Android.
В нашем случае, следуя последнему сообщению в этой теме: Это приложение недоступно для вашего устройства, потому что оно было создано для более старой версии Android мы сразу запустили новый apk в производство, а не есть ли еще проблемы.
Я надеюсь, что это поможет вам.
спасибо за помощь, попробую в последнюю очередь. Кроме этой возможности, вы видите в моем посте что-нибудь, что должно быть причиной?
Все остальное вроде нормально
Наконец, я могу подтвердить, что это ошибка Play Store -_- единственная вещь, которую я не предполагал быть причиной. Спасибо. Я надеюсь, что Google исправит это как можно скорее
Пожалуйста, попробуйте это: если у вас есть предыдущие сборки в открытом, закрытом или внутреннем тестировании, вам нужно загрузить новую сборку для внутреннего тестирования, а затем перевести ее в рабочую среду.
Почему я должен продвигать его в производство? Мне нужно протестировать обновление, прежде чем выпустить его для всех пользователей.
Под «Google Play» вы подразумеваете приложение Store или PlayServices? Я предполагаю, что последний устарел. Пользователи должны иметь возможность проверить, доступно ли обновление для сервисов Play, перейдя по ссылке play.google.com/store/apps/details?id=com.google.android.gms (должно быть перенаправлено в приложение PlayStore). и показывает, доступно ли обновление). В качестве альтернативы есть вспомогательные приложения, такие как play.google.com/store/apps/…, доступные для отображения версии.