Android 6.0 Marshmallow is the release where apps stopped getting every permission at install. From API 23, an app asks for a dangerous permission while it runs, and the user can say no. It also added Doze, which parks background work on an idle phone, and a security patch level that devices report as a date.

At a glance
| Version | Android 6.0 |
| API level | 23 |
| Name | Marshmallow, public |
Build.VERSION_CODES | M |
| Final SDK | 17 August 2015 |
| Release | Nexus rollout began 5 October 2015 |
| Launch devices | Nexus 5X (LG) and Nexus 6P (Huawei), announced 29 September 2015 |
| Google Play target-API deadline | None. Play’s target-API rule started in 2018, at API 26 |
Google released the first developer preview, then called Android M, at Google I/O on 28 May 2015. On 17 August it published the final SDK, named the release Marshmallow and opened Play to apps targeting API 23. On 29 September it announced the rollout to the Nexus 5, 6, 7 (2013), 9, Nexus Player and Android One “starting next week”. The Official Android Blog announced on 5 October that the rollout was starting that day, and Phone Scoop reported the same date. The three developer previews before the release are the parts that follow this note: Preview 1, Preview 2 and Preview 3.
The same 29 September event showed the Pixel C tablet, which runs Marshmallow; its first builds in AOSP are Android 6.0.1. Android 6.0.1 arrived on 7 December 2015 with the December security patch, the Unicode 8 emoji and the return of “until next alarm” in Do Not Disturb.
What it brought
- Runtime permissions. Covered in its own section below.
- Doze. An unplugged phone that sits still with the screen off enters Doze. Network access stops, wake locks are ignored, and alarms, jobs and syncs wait for short maintenance windows.
- App Standby. An app the user has not touched for a while, with no foreground process or visible notification, loses network access and its jobs and syncs while the phone is unplugged.
- App Links. With
android:autoVerify="true"on an intent filter, Android 6.0 checkshttps://<host>/.well-known/assetlinks.jsonat install. If it matches, links to that site open in the app without the chooser dialog. - Fingerprint API.
FingerprintManager.authenticate()behind theUSE_FINGERPRINTpermission, tied to keys in the Android Keystore. - Auto Backup for Apps. Apps targeting API 23 get their data backed up to a private folder in the user’s Google Drive, with no code. The limit is 25 MB per app, and it does not count against the user’s Drive quota.
- Adoptable storage. A user can format an SD card as internal storage.
Apps should ask for paths with
getFilesDir()andgetCacheDir()instead of hard-coding them. Samsung and LG left it out of the Galaxy S7 and LG G5, so do not count on it being there. - Assist API. Apps can hand context to the assistant through
Activity#onProvideAssistContent(). Ars Technica describes Google Now on Tap as the feature built on it: a long press on home sends the screen to Google. - Smaller additions. Direct Share (
ChooserTargetService), voice interactions (VoiceInteractor), the camera torch (CameraManager#setTorchMode()),android.media.midi, Bluetooth stylus buttons and 4K display modes.
Security and privacy
- Monthly security updates. On 5 August 2015 Google said Nexus devices would get an OTA “each month focused on security”. The first public bulletin, published 13 August 2015, covered the Stagefright media flaws. Nexus devices were promised security patches for three years from launch or 18 months from last sale on the Google Store, whichever is longer.
- Security patch level. API 23 added
Build.VERSION.SECURITY_PATCH, the date of the last security patch the device applied. Settings shows it as “Android security patch level” under About phone. - Encryption. The 6.0 CDD requires full-disk encryption on any device with a secure lock screen that is not a low-RAM device. If its AES speed is above 50 MiB/s, encryption must be on by default after setup.
- Verified Boot. Under the same CDD, devices with AES above 50 MiB/s must support Verified Boot, from a hardware root of trust up to the system partition.
- Hardware-isolated keys. A new HAL protects keys used by the fingerprint API, the lock screen, device encryption and client certificates against a kernel compromise.
- Fingerprint rules. The CDD caps the false acceptance rate at 0.002%, locks out for at least 30 seconds after five failed tries, and requires matching inside the Trusted Execution Environment.
- Hardware identifiers.
WifiInfo.getMacAddress()andBluetoothAdapter.getAddress()return02:00:00:00:00:00for every app. Background Wi-Fi and Bluetooth scans use a randomized MAC address. - Smaller changes. SELinux policy got tighter (IOCTL filtering, very
limited
/proc). USB defaults to charge-only, and file access needs the user’s approval. A newStrictModecheck flags cleartext traffic. Android moved from OpenSSL to BoringSSL. Adopted SD cards are encrypted and work in one device only.
Permissions
Permissions now come in two kinds. Normal permissions are still granted at install. Dangerous ones (location, contacts, camera, microphone, SMS and the like) have to be requested at runtime by apps that target API 23.
The system owns the dialog (dashed above), so the app cannot change its text.
Call shouldShowRequestPermissionRationale() to know when to explain the
request first. On Android 6.0, a second request after a denial added a
“Never ask again” checkbox.

- Groups. Users grant and revoke by permission group. Until Android 8.0, a grant also gave the app every other permission from that group declared in its manifest.
- Older apps. Apps targeting API 22 or lower still get their permissions at install. Users can switch them off anyway, for old and new apps alike.
- Added.
USE_FINGERPRINT. - Removed.
READ_HISTORY_BOOKMARKSandWRITE_HISTORY_BOOKMARKS, along withBrowser.getAllBookmarks()andBrowser.saveBookmark(). - Location for scans. Reading nearby hardware IDs from
WifiManager.getScanResults(),BluetoothDevice.ACTION_FOUNDorBluetoothLeScanner.startScan()needsACCESS_FINE_LOCATIONorACCESS_COARSE_LOCATION. - Device owners.
DevicePolicyManager#setPermissionPolicy()lets an enterprise admin set how runtime permissions are granted.
What changed for your app
All apps on Android 6.0
| Change | What to do |
|---|---|
| Doze and App Standby | Test with adb shell dumpsys deviceidle force-idle and adb shell am set-inactive <package> true. Use setAndAllowWhileIdle() or setExactAndAllowWhileIdle() for alarms that must fire. Send urgent pushes as high-priority FCM messages: they get brief network access during Doze |
| Apps that want out of Doze | ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS sends the user to Settings. ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS asks directly, but Play policy allows it only when Doze breaks the app’s core function |
| Users can switch off permissions for any app | Test with permissions off, even if you do not target API 23 |
MAC address returns 02:00:00:00:00:00 | Stop using it as a device ID |
| Bookmark APIs removed | Keep bookmarks in your own storage |
setStreamSolo() and setStreamMute() deprecated | Use requestAudioFocus() and adjustStreamVolume() |
| Keystore drops DSA | Use ECDSA |
| Camera access goes by process priority | Handle onError() (Camera) or onDisconnected() (Camera2) |
| An APK missing a file named in its manifest is corrupt | Re-sign after removing any content |
The Apache HTTP client left the SDK, so compileSdkVersion 23 no longer sees
it. Switch to HttpURLConnection, or add useLibrary 'org.apache.http.legacy'
to build.gradle. Devices kept the classes on the bootclasspath until Android 9.
Apps targeting API 23
| Change | What to do |
|---|---|
| Dangerous permissions are requested at runtime | checkSelfPermission() before each access, requestPermissions() when denied |
| Auto Backup is on by default | Choose what is backed up with android:fullBackupContent, or set android:allowBackup="false" |
| Native libraries with text relocations are rejected | Rebuild them without text relocations |
Stylus buttons report BUTTON_STYLUS_PRIMARY and BUTTON_STYLUS_SECONDARY | Read them through MotionEvent#getButtonState() |
What lasted
- Runtime permissions are still the model. Android 8.0 fixed the
group-wide grant, Android 10 split out
ACCESS_BACKGROUND_LOCATION, and Android 11 added one-time grants. - Doze grew in Android 7.0: part of it now applies while the phone is moving in a pocket with the screen off.
- Verified Boot became strictly enforced in Android 7.0: a compromised device does not boot.
- Apache HTTP left the bootclasspath in Android 9. Apps targeting 9 that
still need it declare
<uses-library android:name="org.apache.http.legacy" android:required="false"/>. - Fingerprint: Android 9 tells apps to move from
FingerprintManagertoBiometricPrompt. - Adoptable storage could not be combined with file-based encryption on Android 7.0 to 8.1. From Android 9, both work together.
- Monthly bulletins still ship. Play’s target-API requirement, which did not exist in 2015, started in 2018 and now moves up every year.
- End of support. The August 2018 bulletin was the last to list Android
6.0 and 6.0.1 among its updated AOSP versions. The last Marshmallow build in
Google’s list,
android-6.0.1_r81(MOI10E), carries the October 2017 patch level. Google Play services now lists Android 7.0 (API 24) as its minimum; OSnews reported the drop of 6.0 on 24 July 2026.
Worth knowing
- The
Mconstant in AOSP carries a one-line comment:M comes after L. - The Easter egg is Marshmallow Land, a Flappy Bird-style game. Its code
allows up to six players (
MAX_PLAYERS = 6) and runs in a process named:sweetsweetdesserts. 02:00:00:00:00:00is what every app on Marshmallow reads as the Wi-Fi and Bluetooth MAC address.- Android Police reported in May 2015 that the internal code name was
Macadamia Nut Cookie, which is where the
mnc-devbranch in AOSP got its name.
M Developer Preview 1: Android M at I/O
28 May 2015. The first build of Android M, shown at Google I/O, brought runtime permissions, App Links, Doze and the fingerprint APIs to four Nexus devices.
Read on its own: M Developer Preview 1: Android M at I/OGoogle announced Android M at Google I/O on 28 May 2015 and released the first
developer preview the same day, right after the keynote. The release had no
number and no name yet: the SDK called it “Android MNC Preview”, and projects
built against it with compileSdkVersion 'android-MNC'.
| Release date | 28 May 2015 |
| Build | MPZ44Q |
| Devices | Nexus 5, Nexus 6, Nexus 9 and Nexus Player, by flashing system images |
| Emulator | x86 and ARM, 32- and 64-bit |
| Google Play services | 7.5 |
| API status | Preview APIs, not final; no API level yet |
What Preview 1 introduced
Google’s announcement framed M as “improving the fundamentals”. The headline changes for developers were already in this build:
- Runtime permissions. Apps request permissions in context while running, and users can grant or refuse each one and change it later in settings. Google told developers to “account for permissions that don’t get granted”.
- App Links. An
autoVerifyattribute in the manifest lets a verified app open its own URLs with no disambiguation prompt. - Doze. When significant motion detection shows the device has been left unattended, Android backs off background activity. Google pointed chat apps to high-priority messages to wake them.
- Fingerprint. New APIs let apps authorise with the fingerprint sensor, the same mechanism behind Android Pay and Play purchases.
- Now on tap. Assist APIs feed the current screen to Google Now; Google asked developers to implement App Indexing to appear in it.
Google released Android Studio 1.3 Preview, with C and C++ editing and debugging for the NDK, and the Android Design Support Library alongside it.
The planned timeline
This time Google promised “a clear timeline”. The preview site set it out: Preview 2 in “late June/early July”, Preview 3 “near final, late July”, and the final SDK later in the third quarter. Devices already on a preview build would get each update over the air.
M Developer Preview 2: near-final APIs
9 July 2015. The second preview reshaped the permission model, made external storage a runtime permission and set USB connections to charge-only by default.
Read on its own: M Developer Preview 2: near-final APIsPreview 2 arrived on 9 July 2015, within the “late June/early July” window Google had set. Google described it as “near-final APIs” with fixes from developer feedback. Most of its changes were to the permission model.
| Release date | 9 July 2015 |
| Build | MPZ79M (Nexus 5, 6, 9); MPZ79N (Nexus Player) |
| Devices | Same four Nexus devices; over the air from MPZ44Q, or by flashing |
| Emulator | x86 and ARM, 32- and 64-bit, through the SDK Manager |
| Google Play services | 7.6 |
| API status | Near-final |
How Preview 2 reshaped permissions
- Storage.
WRITE_EXTERNAL_STORAGEbecame “dangerous”, so apps must ask for it at runtime. It andREAD_EXTERNAL_STORAGEform theSTORAGEgroup. - Fingerprint.
USE_FINGERPRINTbecame “normal” and no longer needs the user’s approval. It does not give access to fingerprint enrolment. - Wi-Fi and Bluetooth.
BLUETOOTH,BLUETOOTH_ADMIN,CHANGE_WIFI_STATE,CHANGE_WIMAX_STATEandCHANGE_WIFI_MULTICAST_STATEbecame “normal”. Reading the MAC address of a remote Bluetooth or Wi-Fi device now needsACCESS_COARSE_LOCATIONorACCESS_FINE_LOCATION. - Accounts. Some account and identity permissions moved into the
CONTACTSgroup;USE_CREDENTIALS,MANAGE_ACCOUNTSandAUTHENTICATE_ACCOUNTSwere left ungrouped “pending further changes”. Bookmark and subscribed-feed permissions were removed. - System apps. Apps in the system image stopped getting dangerous permissions automatically.
- Rationale.
Activity.shouldShowRequestPermissionRationale(String)tells an app whether the user has already refused a permission, so it can explain why it needs it.
Other Preview 2 changes
- USB connections default to charge-only; the user must allow data access.
android.app.AssistContentandAssistStructuremoved to the newandroid.app.assistpackage.- The stylus listeners were renamed:
View.OnContextClickListenerandGestureDetector.OnContextClickListenerreplace theOnStylusButtonPressversions. InputDevice.hasMicrophone()reports whether an input device has a microphone.
The “Dark” system theme from Preview 1 was gone. 9to5Google later quoted a Googler on the preview issue tracker: “This will not be included in the M release.”
M Developer Preview 3: final SDK, a name
17 August 2015. The last preview shipped the official Android 6.0 SDK at API 23, named the release Marshmallow and opened Google Play to apps targeting it.
Read on its own: M Developer Preview 3: final SDK, a namePreview 3 came out on 17 August 2015, with the official Android 6.0 SDK. The same post named the release Marshmallow and fixed it at API level 23. Google Play began accepting apps that target API 23 on every channel: Alpha, Beta and Production.
| Release date | 17 August 2015 |
| Build | MPA44I |
| Devices | Nexus 5, Nexus 6, Nexus 9 and Nexus Player, over the air or by flashing |
| Emulator | x86 and ARM, 32- and 64-bit; Android 6.0 SDK through the SDK Manager |
| Google Play services | 7.8 |
| API status | Final, API level 23; system images near final and not meant for consumer use |
It was late. The plan had been “near final, late July”; on 31 July Android
Police reported that Google would miss that date. The first Preview 3 images
were build MPA44G, and Google replaced them the same day with MPA44I,
which the preview site lists as the Preview 3 build.
What Preview 3 finalised
Google called the API changes since Preview 2 “fairly incremental”:
- Permissions UI. The permission dialogs and settings took their final form, with some behaviour changes.
GET_ACCOUNTS. It joined theCONTACTSgroup as “dangerous”, so apps targeting API 23 must request it at runtime.READ_PROFILEandWRITE_PROFILEleft theCONTACTSgroup.- Wi-Fi and Bluetooth LE scans. Apps targeting API 23 need a location permission to get scan results. Apps targeting API 22 or lower still get them, but only in the foreground.
- Fingerprint API. Better error reporting, a better enrolment flow and enumeration support.
Support Library 23 shipped the same day, with new customtabs, percent,
recommendation and preference libraries, and backward-compatible helpers for
the permission and fingerprint APIs.
Preview builds could not take consumer updates. To get the public release, which reached Nexus devices on 5 October, testers had to flash a factory image by hand.