Skip to content
Publishly
How it worksPlay checksWhat's newPrivacyTerms

Reference

Every check the app report makes

In short

The app report reads an APK or app bundle in your browser and applies the 74 checks below. Each one says why Google Play cares and links to Google's own page; the rules were last compared with those pages on 17 September 2026. Every rule is readable code, so if one is wrong or missing, say so. The command line and the MCP server run the same checks, and publishly check --sarif names them by the ids shown here.

On this page

  1. Google Play policy (17)
  2. Permissions (30)
  3. Security (14)
  4. Compatibility (7)
  5. Libraries (2)
  6. Reach (4)

1. Google Play policy (17)

What Play Console refuses or asks about, from the target SDK to signing and crash-report files.

Targets an Android version below what Play requires

New apps and updates must target the Android version Play currently asks for. Before the deadline this is a warning; after it, Play refuses the upload.

Depends on the build or the dateFix to pastetarget-sdkGoogle's page

Foreground services without a type

An app that targets Android 14 or later must declare a foregroundServiceType on every foreground service. Starting one without a type throws.

Worth fixingFix to pastefgs-typeGoogle's page

Uses the Accessibility APIs

Play only allows accessibility services that help people with disabilities. Automation, overlays and reading other apps are removed, and this is a common cause of rejection.

Worth fixingFix to pasteaccessibility-serviceGoogle's page

Advertising SDKs found

Ad SDKs read the advertising ID and app activity, which the Data safety form has to declare. Apps that target Android 13 or later also need the AD_ID permission.

Good to knowads-data-safetyGoogle's page

Analytics SDKs found

Analytics SDKs collect app activity and device identifiers, which the Data safety form has to cover.

Good to knowanalytics-data-safetyGoogle's page

Sign-in without an account deletion route

Apps where people can create an account must offer a way to delete it, both inside the app and from a web link given in Play Console.

Worth fixingaccount-deletionGoogle's page

A first release from a personal account needs a closed test

Personal developer accounts created recently must run a closed test with a minimum number of testers for a set period before their first production release.

Good to knowclosed-testingGoogle's page

Developer verification

Google is starting to require every developer who distributes apps to certified Android devices to verify their identity, whether or not they publish on Play.

Good to knowdeveloper-verificationGoogle's page

Not signed

Android won't install an unsigned APK, and Google Play won't accept an unsigned upload.

Blocks a releaseFix to pasteunsignedGoogle's page

Signed with the debug key

The debug certificate is the same on every developer machine. Play refuses anything signed with it.

Blocks a releaseFix to pastedebug-certificateGoogle's page

The signing certificate has expired

A certificate past its end date can't sign an update that installs over the version people already have.

Blocks a releasecertificate-expiredGoogle's page

Signing certificate expires too soon

Google Play requires the key an app is signed with to stay valid until after 22 October 2033, so users can keep updating it.

Worth fixingFix to pastecertificate-validityGoogle's page

No native debug symbols in the bundle

Without symbols, native crashes in Play Console's Android vitals show addresses instead of function names.

Worth fixingFix to pastenative-symbols-missingGoogle's page

Upload native debug symbols with this APK

An APK can't carry debug symbols for its native libraries, so they go up alongside it in Play Console.

Good to knownative-symbols-apkGoogle's page

No R8 mapping file in the bundle

The code is shrunk and renamed by R8, but the mapping is missing, so crash and ANR stack traces in Play Console stay obfuscated.

Worth fixingmapping-missingGoogle's page

Upload the R8 mapping file with this APK

An APK doesn't carry the R8 mapping, so stack traces in Play Console stay obfuscated until it's uploaded for this version.

Good to knowmapping-apkGoogle's page

Play Billing Library below the version Play requires

A new app or an update that uses Play's billing system must use a supported major version of the Billing Library. Older versions keep working for what is already published, but no further update can be released.

Blocks a releaseFix to pastebilling-versionGoogle's page

2. Permissions (30)

Permissions Play restricts or asks a declaration for, and the narrower API that usually does the same job.

Asks for permissions only system apps can get

Signature and privileged permissions are refused for a normal app. They do nothing except alarm anyone reading the manifest.

Worth fixingFix to pastepermission-signature-onlyGoogle's page

Permissions that need a Play declaration

Each one is a form to fill in, a reason to be reviewed, and a reason for users to hesitate on the install screen.

Good to knowpermission-loadGoogle's page

Read all photos (READ_MEDIA_IMAGES)

Play only allows broad photo access when it is the app's core purpose; everything else must use the photo picker. Instead: The Android photo picker (PickVisualMedia), which needs no permission at all.

Blocks a releaseFix to pastepermission:android.permission.READ_MEDIA_IMAGESGoogle's page

Read all videos (READ_MEDIA_VIDEO)

Same policy as photos: broad video access needs a declaration and a core use. Instead: The Android photo picker (PickVisualMedia).

Blocks a releaseFix to pastepermission:android.permission.READ_MEDIA_VIDEOGoogle's page

Read shared storage (READ_EXTERNAL_STORAGE)

Ignored on Android 13 and later, and a broad ask on older ones. Instead: The photo picker for media, or the Storage Access Framework for documents.

Worth fixingFix to pastepermission:android.permission.READ_EXTERNAL_STORAGEGoogle's page

Write to shared storage (WRITE_EXTERNAL_STORAGE)

Has no effect from Android 11 onwards, and Play treats it as sensitive on older devices. Instead: MediaStore for media, or the Storage Access Framework for files the user picks.

Worth fixingFix to pastepermission:android.permission.WRITE_EXTERNAL_STORAGEGoogle's page

Access all files (MANAGE_EXTERNAL_STORAGE)

The widest storage access there is. Play allows it only for file managers, backup and antivirus apps, and asks for a declaration. Instead: The Storage Access Framework, or app-specific storage.

Blocks a releaseFix to pastepermission:android.permission.MANAGE_EXTERNAL_STORAGEGoogle's page

See every installed app (QUERY_ALL_PACKAGES)

Play allows it only when the app genuinely needs to know about all apps; it needs a declaration. Instead: A <queries> element naming the apps or intents you actually need.

Blocks a releaseFix to pastepermission:android.permission.QUERY_ALL_PACKAGESGoogle's page

Read text messages (READ_SMS)

Play restricts SMS access to a default SMS handler; using it for verification codes is not allowed. Instead: The SMS Retriever API, which reads only your own verification code and needs no permission.

Blocks a releaseFix to pastepermission:android.permission.READ_SMSGoogle's page

Receive text messages (RECEIVE_SMS)

Same SMS restriction: only a default SMS handler may keep it. Instead: The SMS User Consent API.

Blocks a releaseFix to pastepermission:android.permission.RECEIVE_SMSGoogle's page

Send text messages (SEND_SMS)

Restricted by Play, and it can cost the user money. Instead: Hand the message to the SMS app with an intent, so the user presses send.

Blocks a releaseFix to pastepermission:android.permission.SEND_SMSGoogle's page

Read the call log (READ_CALL_LOG)

Restricted to default phone and assistant apps. Instead: Usually nothing is needed; ask what the feature really requires.

Blocks a releaseFix to pastepermission:android.permission.READ_CALL_LOGGoogle's page

See outgoing calls (PROCESS_OUTGOING_CALLS)

Removed in Android 10 and restricted by Play. Instead: CallScreeningService, for a call-screening app.

Worth fixingFix to pastepermission:android.permission.PROCESS_OUTGOING_CALLSGoogle's page

Location in the background (ACCESS_BACKGROUND_LOCATION)

Play allows it only when a feature genuinely needs location while the app is closed, and asks for a video showing it. Instead: Ask only for location while the app is in use.

Blocks a releaseFix to pastepermission:android.permission.ACCESS_BACKGROUND_LOCATIONGoogle's page

Exact location (ACCESS_FINE_LOCATION)

Exact location is sensitive; many features work with an approximate one. Instead: ACCESS_COARSE_LOCATION, which is accurate to about a city block.

Good to knowFix to pastepermission:android.permission.ACCESS_FINE_LOCATIONGoogle's page

Install other apps (REQUEST_INSTALL_PACKAGES)

Play allows it only for app stores, file managers and similar; it is a common reason for rejection. Instead: Send the user to Play, or open the file with the system installer.

Blocks a releaseFix to pastepermission:android.permission.REQUEST_INSTALL_PACKAGESGoogle's page

Draw over other apps (SYSTEM_ALERT_WINDOW)

Overlays can hide what the user is agreeing to, so Play looks at them closely. Instead: A notification, a bubble, or picture-in-picture.

Worth fixingFix to pastepermission:android.permission.SYSTEM_ALERT_WINDOWGoogle's page

Exact alarms (SCHEDULE_EXACT_ALARM)

From Android 14 this is only granted to alarm clocks and calendars; other apps get it denied. Instead: setWindow or WorkManager, or USE_EXACT_ALARM if the app really is an alarm clock.

Worth fixingFix to pastepermission:android.permission.SCHEDULE_EXACT_ALARMGoogle's page

Full-screen notifications (USE_FULL_SCREEN_INTENT)

From Android 14 only calling and alarm apps are granted this by default. Instead: A normal high-priority notification.

Worth fixingFix to pastepermission:android.permission.USE_FULL_SCREEN_INTENTGoogle's page

Read contacts (READ_CONTACTS)

Personal data that most apps only need one entry from. Instead: The contact picker intent, which returns just the contact the user chose.

Worth fixingFix to pastepermission:android.permission.READ_CONTACTSGoogle's page

See the device accounts (GET_ACCOUNTS)

Mostly replaced, and it exposes every account on the phone. Instead: Credential Manager or Sign in with Google.

Worth fixingFix to pastepermission:android.permission.GET_ACCOUNTSGoogle's page

Read phone state (READ_PHONE_STATE)

Often taken for a device id, which Play treats as personal data. Instead: The Phone Number Hint API for a number, or an app-generated id for analytics.

Worth fixingFix to pastepermission:android.permission.READ_PHONE_STATEGoogle's page

Camera (CAMERA)

Fine when the app has its own camera view, wasteful when it only wants one photo. Instead: ACTION_IMAGE_CAPTURE, which lets the camera app take the picture.

Good to knowFix to pastepermission:android.permission.CAMERAGoogle's page

Microphone (RECORD_AUDIO)

Play asks that it only be used while a feature the user started is running.

Good to knowFix to pastepermission:android.permission.RECORD_AUDIO

App usage history (PACKAGE_USAGE_STATS)

Shows what the user does in every other app. Instead: Only digital-wellbeing style apps should ask; most features don't need it.

Worth fixingFix to pastepermission:android.permission.PACKAGE_USAGE_STATS

Accessibility service (BIND_ACCESSIBILITY_SERVICE)

Play only allows the Accessibility APIs when they help users with disabilities; anything else must use another API and will be removed. Instead: isAccessibilityTool must be set and the service must genuinely assist users.

Blocks a releaseFix to pastepermission:android.permission.BIND_ACCESSIBILITY_SERVICEGoogle's page

Advertising ID (com.google.android.gms.permission.AD_ID)

Apps that target Android 13 or later must declare this to read the advertising ID, and disclose it in Data safety.

Good to knowFix to pastepermission:com.google.android.gms.permission.AD_IDGoogle's page

Notifications (POST_NOTIFICATIONS)

Normal for most apps; ask for it when the user does something that expects a notification.

Good to knowFix to pastepermission:android.permission.POST_NOTIFICATIONS

Scan for Bluetooth devices (BLUETOOTH_SCAN)

Without the neverForLocation flag this drags location permission in with it. Instead: Add android:usesPermissionFlags="neverForLocation", or use Companion Device Manager.

Good to knowFix to pastepermission:android.permission.BLUETOOTH_SCANGoogle's page

Foreground service (FOREGROUND_SERVICE)

From Android 14 each foreground service also needs a type, and Play asks what it is for.

Good to knowFix to pastepermission:android.permission.FOREGROUND_SERVICEGoogle's page

3. Security (14)

What anyone who opens the APK can see or reach.

Built as debuggable

android:debuggable lets anyone attach a debugger and read the app's data on any device. Play rejects debuggable uploads.

Blocks a releaseFix to pastedebuggableGoogle's page

Allows unencrypted HTTP traffic

With usesCleartextTraffic on, the app may send data over plain HTTP, where anyone on the same network can read or change it.

Worth fixingFix to pastecleartextGoogle's page

Plain http:// addresses in the code

Traffic to these is unencrypted and can be read or changed on any shared network. Some may belong to a library rather than the app's own code.

Worth fixinghttp-urlsGoogle's page

Backups are on by default

App data is copied into the user's backup, which can include tokens and local databases, unless rules exclude them.

Good to knowFix to pasteallow-backupGoogle's page

No backup rules for Android 12 and later

With backups on and a target of Android 12 or later, dataExtractionRules decides what goes into backups and phone-to-phone transfers. Without them, everything does.

Good to knowFix to pastebackup-rulesGoogle's page

Components open to other apps

Exported activities, services and receivers can be started by any app on the phone, so each one has to expect that.

Worth fixingFix to pasteexported-componentsGoogle's page

Code can be loaded at runtime

Play's Device and Network Abuse policy forbids downloading executable code from outside the store. A class loader is fine for a plugin the app ships with, and worth a look otherwise.

Good to knowdex-class-loaderGoogle's page

A WebView can call back into the app

addJavascriptInterface gives web content a route into app code. It is safe only when the page loaded is one the app controls.

Good to knowwebview-bridgeGoogle's page

Google API key in the code

Google API keys inside an app are normal (Maps and Firebase need them), but anyone can read them out of the APK, so each one must be restricted to this app's package and signing certificate.

Worth fixingsecret:google-api-keyGoogle's page

Google OAuth client secret in the code

Anyone who opens the APK can read it, so it is public from now on: revoke it, move the work to a server, and give the app a token it can't misuse.

Blocks a releasesecret:google-oauth-secretGoogle's page

AWS access key in the code

Anyone who opens the APK can read it, so it is public from now on: revoke it, move the work to a server, and give the app a token it can't misuse.

Blocks a releasesecret:aws-keyGoogle's page

Stripe secret key in the code

Anyone who opens the APK can read it, so it is public from now on: revoke it, move the work to a server, and give the app a token it can't misuse.

Blocks a releasesecret:stripe-keyGoogle's page

Slack token in the code

Anyone who opens the APK can read it, so it is public from now on: revoke it, move the work to a server, and give the app a token it can't misuse.

Blocks a releasesecret:slack-tokenGoogle's page

Private key in the code

Anyone who opens the APK can read it, so it is public from now on: revoke it, move the work to a server, and give the app a token it can't misuse.

Blocks a releasesecret:private-keyGoogle's page

4. Compatibility (7)

What stops the app installing or running on some devices.

Lists installed apps without declaring which it needs

QUERY_ALL_PACKAGES needs a Play declaration and is rarely granted. A <queries> element naming the apps it actually needs to see is usually enough.

Good to knowFix to pastepackage-visibilityGoogle's page

Native libraries built for 4 KB pages

Play requires apps with native code to support 16 KB page sizes. Libraries linked for 4 KB pages crash on 16 KB devices, and after the deadline Play refuses the upload.

Depends on the build or the dateFix to pastepage-size-elfGoogle's page

Native libraries not 16 KB aligned in the APK

The libraries themselves are fine, but they don't start on a 16 KB boundary inside the package, so a 16 KB device still can't map them directly.

Worth fixingFix to pastepage-size-zipGoogle's page

Ready for 16 KB page sizes

Every 64-bit native library is aligned for 16 KB pages, so the requirement is already met.

Good to knowpage-size-okGoogle's page

No 64-bit version of the native code

Play has required a 64-bit version alongside 32-bit libraries since 2019, and 64-bit-only devices can't run a 32-bit-only app at all.

Blocks a releaseFix to pasteno-64-bitGoogle's page

Only the old v1 signature

An app that targets Android 11 or later must also be signed with APK Signature Scheme v2 or later, or devices on Android 11 and up refuse to install it.

Worth fixingFix to pastev1-only-signatureGoogle's page

Several dex files, but no multidex library

Below Android 5.0 only the first dex file loads unless the multidex support library is included, so the app crashes on start there.

Worth fixingFix to pastemultidex-missingGoogle's page

5. Libraries (2)

Only with the opt-in library-version lookup, which sends library names to Google's Maven repository.

Libraries several major versions behind

Old SDK versions are where known security and Play policy problems live, and Play's SDK Index warns about some of them in Play Console. They also tend to block a target SDK upgrade.

Worth fixingFix to pastelibraries-oldGoogle's page

Libraries well behind

Worth picking up at the next update; none are urgent on their own.

Good to knowFix to pastelibraries-behindGoogle's page

6. Reach (4)

What keeps the app out of search results or off some phones without breaking anything.

Permissions that imply required hardware

Some permissions make Play assume the hardware is required, which hides the app from devices without it, unless a uses-feature element marks it optional.

Good to knowFix to pasteimplied-featuresGoogle's page

Orientation and resizing locks are ignored on large screens

From Android 16, on screens 600dp and wider, an app that targets API 36 can't lock its orientation or aspect ratio or refuse to resize. Games are exempt, and there is a one-version opt-out.

Depends on the build or the dateFix to pastelarge-screen-limitsGoogle's page

Hidden from new users on recent phones

Play only shows an app to new users whose phone runs an Android version no more than a few versions newer than the one the app targets.

Worth fixingtarget-sdk-reachGoogle's page

Only in one language, or few

Most installs come from people browsing Play in their own language, and an untranslated app is skipped over.

Good to knowfew-languagesGoogle's page

HomeStudioPrivacy policyTerms of service

Google Play is a trademark of Google LLC. App Store is a trademark of Apple Inc. Publishly isn’t affiliated with either.