Post on 26-Jan-2016
description
Android6Essentials
TableofContents
Android6Essentials
Credits
AbouttheAuthor
Acknowledgments
AbouttheReviewer
www.PacktPub.com
Supportfiles,eBooks,discountoffers,andmore
Whysubscribe?
FreeaccessforPacktaccountholders
Preface
Whatthisbookcovers
Whatyouneedforthisbook
Whothisbookisfor
Conventions
Readerfeedback
Customersupport
Downloadingtheexamplecode
Downloadingthecolorimagesofthisbook
Errata
Piracy
Questions
1.AndroidMarshmallowPermissions
AnoverviewofAndroidpermissions
Permissions
Permissiongroupdefinitions
Permissionsthatimplyfeaturerequirements
Viewingthepermissionsforeachapp
UnderstandingAndroidMarshmallowpermissions
Anoverview
Permissiongroups
Runtimepermissions
Takingcodingpermissionsintoaccount
Testingpermissions
Codingforruntimepermissions
Bestpracticesandusagenotes
Minimalismisagreatoption
Askingfortoomanypermissionsatonce
Honestycanbeagreatpolicy
Needsupporthandlingruntimepermissions?
Somepermissionsarenormalandsafertouse
Summary
2.AppLinks
TheAndroidIntentsystem
Creatingawebsiteassociation
Whythisfile?
Triggeringapplinkverification
Applinksettingsandmanagement
Testingapplinks
Checkingmanifestandlistingdomains
TheDigitalAssetLinksAPI
Testingourintent
Checkingpoliciesusingadb
Summary
3.Apps’AutoBackup
Anoverview
Databackupconfiguration
Includingorexcludingdata
Thebackupconfigurationsyntax
Optingoutfromappdatabackup
Backupconfigurationtesting
Settingbackuplogs
Testingthebackupphase
Testingtherestorephase
Troubleshooting
Importantbytes
Whattoexcludefromthebackup
BackupAgentandbackupevents
Summary
4.ChangesUnfold
Power-savingmodes
TheDozemode
Whathappenstoappswhenadeviceisdozing?
TestingappswithDozemode
TheAppStandbymode
WhathappenstoappswhenintheAppStandbymode?
TestingappswiththeAppStandbymode
Excludedappsandsettings
Tips
Removablestorageadoption
ApacheHTTPclientremoval
Notifications
Textselection
Supportlibrarynotice
AndroidKeystorechanges
Wi-Fiandnetworkingchanges
Runtime
Hardwareidentifier
APKvalidation
USBconnection
DirectShare
Whatifwehavenothingtoshare?
DirectSharebestpractices
Voiceinteractions
TheAssistAPI
BluetoothAPIChanges
Bluetoothstylussupport
ImprovedBluetoothlowenergyscanning
Summary
5.Audio,Video,andCameraFeatures
Audiofeatures
SupportfortheMIDIprotocol
MidiManager
Digitalaudiocaptureandplayback
Audioandinputdevices
Informationonaudiodevices
ChangesinAudioManager
Videofeatures
android.media.MediaSync
MediaCodecInfo.CodecCapabilities.getMaxSupportedInstances
Whydoweneedtoknowthis?
MediaPlayer.setPlaybackParams
Camerafeatures
TheflashlightAPI
ThereprocessingAPI
android.media.ImageWriter
android.media.ImageReader
Changesinthecameraservice
Summary
6.AndroidforWork
Behavioralchanges
Theworkprofilecontactsdisplayoption
Wi-Ficonfigurationoptions
TheWi-Ficonfigurationlock
WorkPolicyControlleraddition
DevicePolicyManagerchanges
Single-usedeviceimprovements
Silentlyinstalling/uninstallingapps
Improvedcertificateaccess
Automaticsystemupdates
Third-partycertificateinstallation
Datausagestatistics
Managingruntimepermissions
VPNaccessanddisplay
Workprofilestatus
Summary
7.ChromeCustomTabs
WhatisaChromecustomtab?
WhatisWebView?
Customizationoptions
WhentouseChromecustomtabs
Theimplementationguide
CanweuseChromecustomtabs?
CustomUIandtabinteraction
Thecustomactionbutton
Configuringacustommenu
Configuringcustomenterandexitanimations
Chromewarm-up
ConnectingtotheChromeservice
Warmingupthebrowserprocess
Creatinganewtabsession
SettingtheprefetchingURL
Customtabsconnectioncallback
Summary
8.Authentication
TheFingerprintauthenticationAPI
Howdoweusefingerprintauthentication?
Settingupfortesting
Credentials’GracePeriod
Cleartextnetworktraffic
So,whatdowedowiththecleartextnetworktrafficflag?
Summary
Index
Android6Essentials
Android6EssentialsCopyright©2015PacktPublishing
Allrightsreserved.Nopartofthisbookmaybereproduced,storedinaretrievalsystem,ortransmittedinanyformorbyanymeans,withoutthepriorwrittenpermissionofthepublisher,exceptinthecaseofbriefquotationsembeddedincriticalarticlesorreviews.
Everyefforthasbeenmadeinthepreparationofthisbooktoensuretheaccuracyoftheinformationpresented.However,theinformationcontainedinthisbookissoldwithoutwarranty,eitherexpressorimplied.Neithertheauthor,norPacktPublishing,anditsdealersanddistributorswillbeheldliableforanydamagescausedorallegedtobecauseddirectlyorindirectlybythisbook.
PacktPublishinghasendeavoredtoprovidetrademarkinformationaboutallofthecompaniesandproductsmentionedinthisbookbytheappropriateuseofcapitals.However,PacktPublishingcannotguaranteetheaccuracyofthisinformation.
Firstpublished:November2015
Productionreference:1251115
PublishedbyPacktPublishingLtd.
LiveryPlace
35LiveryStreet
BirminghamB32PB,UK.
ISBN978-1-78588-441-2
www.packtpub.com
CreditsAuthor
YossiElkrief
Reviewer
PavelPavlasek
CommissioningEditor
EdwardGordon
AcquisitionEditor
ReshmaRaman
ContentDevelopmentEditor
RiddhiTuljapurkar
TechnicalEditor
GauravSuri
CopyEditor
StutiSrivastava
ProjectCoordinator
SanchitaMandal
Proofreader
SafisEditing
Indexer
HemanginiBari
Graphics
KirkD’Penha
DishaHaria
AbhinashSahu
ProductionCoordinator
AparnaBhagat
CoverWork
AparnaBhagat
AbouttheAuthorYossiElkriefisanAndroidenthusiastwithover7yearsofexperienceintheAndroidplatformandiscurrentlyworkingasanAndroidarchitectandgroupleaderatTikalKnowledge.
Amonghispreviousexperiences,thenoteworthyonesincludeooVoo,Fiverr,Mobli,andGlide,reachingouttoover135millionusersworldwide.
YossiisamentoratGoogleLaunchpad,alectureronIoTandmobiledevelopment,andco-techleadontheMadgeraaccelerator.HecofoundedtheGDGBe’erShevagroupandco-leadsthegrouptoday,holdingtechnologyeventsforthetechnologycommunityinIsrael.Hehasaspouseandadaughter,andhelivesinBe’erSheva,Israel.
HismaininterestsareLiverpoolFootballClubandhisAndroidminicollectiblescollection,withover120differentpieces.YoucanfindhimonLinkedInathttps://il.linkedin.com/in/yossielkrief,onGitHubatMaTriXy,andonGoogle+atYossi.Elkrief.
AcknowledgmentsFirst,Iwanttothankmyfamilyfortheirpatience,love,andendurancewithmetakingyetanotherchallenge,reducingtheamountoftimeIcanspendwiththem.
ToIrit,mywife,fortheconstantloveandsupportandrememberingtofeedmewhenIcouldn’tremembertofeedmyself.
ToMia,mydaughterIloveyou.
Tomymotherandfather,whomIloveandcherish.
Tomyfriends,forbeingtherewiththeircodingarmoronandforgivingmethechancetoshine.
Tomymentor,friend,andfamily,IsraelMali;thankyouforguidingmefor15years,helpingmecarvemycareerpath.Mayyourestinpeace.
IwanttothankPacktPublishingforthisopportunityandforpublishingmyfirstbook.AspecialthankstoRiddhiTuljapurkarforallthehelpandguidance.
Lastbutnotleast,IchallengeyoutotryouttheChubbyBunnychallengeathttp://icebreakerideas.com/chubby-bunny-challenge/.
AbouttheReviewerPavelPavlasekhasbeenanAndroiddeveloperforover5years,apartfrombeingalong-timeJavadeveloper.HedevelopswebinformationsystemsandAndroidapplications,andheispassionateaboutnewtechnologies.
Iwouldliketothanktomyfamilyfortheirsupportandinspiration—mywife,Daniela,andmychildren,Michaela,Jakub,andJuraj.IwouldalsoliketothankmycolleaguesandotherAndroiddevelopersI’vemet.
www.PacktPub.com
Supportfiles,eBooks,discountoffers,andmoreForsupportfilesanddownloadsrelatedtoyourbook,pleasevisitwww.PacktPub.com.
DidyouknowthatPacktofferseBookversionsofeverybookpublished,withPDFandePubfilesavailable?YoucanupgradetotheeBookversionatwww.PacktPub.comandasaprintbookcustomer,youareentitledtoadiscountontheeBookcopy.Getintouchwithusat<service@packtpub.com>formoredetails.
Atwww.PacktPub.com,youcanalsoreadacollectionoffreetechnicalarticles,signupforarangeoffreenewslettersandreceiveexclusivediscountsandoffersonPacktbooksandeBooks.
https://www2.packtpub.com/books/subscription/packtlib
DoyouneedinstantsolutionstoyourITquestions?PacktLibisPackt’sonlinedigitalbooklibrary.Here,youcansearch,access,andreadPackt’sentirelibraryofbooks.
Whysubscribe?FullysearchableacrosseverybookpublishedbyPacktCopyandpaste,print,andbookmarkcontentOndemandandaccessibleviaawebbrowser
FreeaccessforPacktaccountholdersIfyouhaveanaccountwithPacktatwww.PacktPub.com,youcanusethistoaccessPacktLibtodayandview9entirelyfreebooks.Simplyuseyourlogincredentialsforimmediateaccess.
PrefaceAndroid6willprimarilyfocusonimprovingtheoveralluserexperience,anditwillbringinafewfeatures,suchasaredesignedpermissionmodelinwhichapplicationsarenolongerautomaticallygrantedalloftheirspecifiedpermissionsatthetimeofinstallation,theDozepowerschemeforextendedbatterylifewhenadeviceisnotmanipulatedbytheuser,andnativesupportforfingerprintrecognition.
Ifyou’realreadyanAndroiddeveloper,you’reonlyafewstepsawayfrombeingabletouseyourexistingdevelopmentexperiencetoreachyouruserswhereverorwhenevertheywantorneedyourapp.
AsaprofessionalAndroiddeveloper,youhavetocreateproduction-readyappsforyourusers.Thisbookwillgiveyouwhatittakestoshippolishedappsaspartofadevelopmentteamatacompany,anindependentappdeveloper,orjustasaprogrammerusingAndroiddevelopmentbestpractices.
Bytheendofthebook,you’llbeabletoidentifycriticalareasforimprovementinanappandimplementthenecessarychangesandrefinementstoensureitmeetsAndroid’sCoreAppGuidelinespriortoshipping.
WhatthisbookcoversChapter1,AndroidMarshmallowPermissions,discusseshowtheAndroidpermissionsystemandmodelarevastandhavemadeafewchangesthatcanhelpappdevelopersandapplicationsgainmoretraction,installations,andgiveuserstheabilitytodecidewhenyourapplicationswillbeabletouseeachpermission-dependentfeature.Keepinmind,though,thatthisisjustastartingpointandAndroidMarshmallowstillneedstogainmarketshareandgetadoptedbyOEMs,enablinguserswiththefreedomofchoice.Youasanappdevelopermustprepareinadvanceandmakesureyourapplicationdevelopmentisforward-facing,allowingnewuserstoenjoythelatestupdatesassoonaspossiblewhilemaintainingahighlevelofperformanceforyourapplications.
Chapter2,AppLinks,talksabouthowapplinkinghasbecomepowerfulinAndroidMarshmallow.Thisallowsyou,theappdevelopers,helpthesystembetterdecidehowtoact.HandlingwebURLswillgiveyouwiderexposure,abiggerfunnelintoyourapps,andbetterexperience,whichyoucanprovidetoyourusers(sumsuptobetterratingsandmoredownloadsandviceversa).
Applinkingissimpletoimplement,easytounderstand,andisamust-havefeatureinthemobile/webworldtoday.Whileapplinkingenablesbetteractionhandlingforusersusingyourapplications,userscanhavemultipledevices,expectingthesamebehavioroneachdevice,andwouldbemoreengagediftheirdataandactionhandlingisallaround.
Chapter3,Apps’AutoBackup,informsyouthatAndroidMarshmallowbringswithitagreatbackupfeatureforapps,reducingfrictionforusersmigratingtonewdevices.
Inaworldfullofsuchdiverseapps,maximizingthebenefitsfromautomaticbackupsleadstoexcellentuserexperience.Thegoalofthisfeatureistounloadtheburdenandshortenthetimerequiredtosetupanewdevicewiththeuser’sfavoriteapps.Allowingtheuserstoenteryourappwithjustapasswordprompt,ifrequired,afteranewinstallationcanbeagreatexperience.Tryityourself!
Chapter4,ChangesUnfold,goesoverafewofthechangesinAndroidMarshmallow.Allofthesechangesareimportanttofollowandwillhelpyouinyourappdevelopmentcycles.Afewmorechangesarediscussedinfuturechapterswithamoredetailedapproach.
Chapter5,Audio,Video,andCameraFeatures,coversquiteafewchangesandadditionstoAndroidAPIs.AndroidMarshmallowismoreabouthelpingus,thedevelopers,achievebettermediasupportandshowcaseourideaswhenusingaudio,video,orcameraAPIs.
Chapter6,AndroidforWork,covershowAndroidMarshmallowhasbroughtinquiteafewchangestotheworldofAndroidforWork.Asdevelopers,weneedtoalwaysmaintainaviableconnectionwiththeneedsofanorganization.MakingsurethatwegooverandunderstandtheAndroidforWorkworldwiththechangesinMarshmallowhelpsusbuildandtargetenterpriseworkflowswiththeaddedbenefitofasimplerAPI.
Chapter7,ChromeCustomTabs,talksaboutthenewlyaddedfeature,Chromecustom
tabs,thatallowsusdeveloperstoembedwebcontentintoourapplication,modifytheUI,andadjustittoourapp’sthemeandcolorsandthelookandfeel.ThishelpsuskeeptheuserinourapplicationandstillprovideaniceUIandoverallfeel.
Chapter8,Authentication,discusshowAndroidMarshmallowgivesusanewAPItoauthenticateuserswiththefingerprintAPI.WecanusethesensorandauthenticatetheuserevenwithinourapplicationandsaveitforlaterusageifwewanttosavetheneedofuserloginusingtheCredentialsgraceperiodabilitiesAndroidMarshmallowhasintroduced.WealsocoveredawaytomakeourapplicationmoresecureusingHTTPSonly.TheStrictModepolicy,enforcedwiththehelpoftheusesCleartextTrafficflag,allowsustomakesurethatallthenodesweconnecttotheouterworldareexaminedtocheckifthere’saneedforasecureconnectionornot.
WhatyouneedforthisbookForthisbook,youwillrequirepreviousknowledgeoftheAndroidplatform,APIs,andtheapplicationdevelopmentprocess.Youwillalsoneedtosetupyourworkenvironmenttohaveatleastthefollowing:
AndroidStudio,whichcanbedownloadedfromhttps://developer.android.com/sdk/index.htmlThelatestAndroidSDKtoolsandplatforms.MakesurethatyouupgradetothelatestversionsandaddtheAndroid6.0(Marshmallow)platformifit’smissingAnAndroiddeviceishelpful,butyoumayuseanemulatorifyouprefer,oryoumayusethegreatsolutionofGenymotionasanemulator,athttps://www.genymotion.com/
WhothisbookisforThisbookisforAndroiddeveloperswhoarelookingtomovetheirapplicationsintothenextAndroidversionwithease.Inthechaptersofthisbook,theauthorhasreferredtoAndroid6asAndroidMarshmallow.YoushouldhaveagoodunderstandingofJavaandpreviousAndroidAPIs,andyoushouldbeabletowriteapplicationswithAPIspriortoMarshmallow.
ConventionsInthisbook,youwillfindanumberoftextstylesthatdistinguishbetweendifferentkindsofinformation.Herearesomeexamplesofthesestylesandanexplanationoftheirmeaning.
Codewordsintext,databasetablenames,foldernames,filenames,fileextensions,pathnames,dummyURLs,userinput,andTwitterhandlesareshownasfollows:“ThesetTorchMode()methodhasbeenaddedtocontroltheflashtorchmode.”
Ablockofcodeissetasfollows:
<?xmlversion="1.0"encoding="utf-8"?>
<full-backup-content>
<excludedomain="database"path="sensitive_database_name.db"/>
<excludedomain="sharedpref"path="androidapp_shared_prefs_name"/>
<excludedomain="file"path="some_file.file_Extension"/>
<excludedomain="file"path="some_file.file_Extension"/>
</full-backup-content>
Anycommand-lineinputoroutputiswrittenasfollows:
$adbshellsmset-force-adoptabletrue
Newtermsandimportantwordsareshowninbold.Wordsthatyouseeonthescreen,forexample,inmenusordialogboxes,appearinthetextlikethis:“WhenheadingtoSettings|More|VPN,youcannowviewtheVPNapps.”
NoteWarningsorimportantnotesappearinaboxlikethis.
TipTipsandtricksappearlikethis.
ReaderfeedbackFeedbackfromourreadersisalwayswelcome.Letusknowwhatyouthinkaboutthisbook—whatyoulikedordisliked.Readerfeedbackisimportantforusasithelpsusdeveloptitlesthatyouwillreallygetthemostoutof.
Tosendusgeneralfeedback,simplye-mail<feedback@packtpub.com>,andmentionthebook’stitleinthesubjectofyourmessage.
Ifthereisatopicthatyouhaveexpertiseinandyouareinterestedineitherwritingorcontributingtoabook,seeourauthorguideatwww.packtpub.com/authors.
CustomersupportNowthatyouaretheproudownerofaPacktbook,wehaveanumberofthingstohelpyoutogetthemostfromyourpurchase.
DownloadingtheexamplecodeYoucandownloadtheexamplecodefilesfromyouraccountathttp://www.packtpub.comforallthePacktPublishingbooksyouhavepurchased.Ifyoupurchasedthisbookelsewhere,youcanvisithttp://www.packtpub.com/supportandregistertohavethefilese-maileddirectlytoyou.
DownloadingthecolorimagesofthisbookWealsoprovideyouwithaPDFfilethathascolorimagesofthescreenshots/diagramsusedinthisbook.Thecolorimageswillhelpyoubetterunderstandthechangesintheoutput.Youcandownloadthisfilefromhttps://www.packtpub.com/sites/default/files/downloads/4412OS_ColoredImages.pdf.
ErrataAlthoughwehavetakeneverycaretoensuretheaccuracyofourcontent,mistakesdohappen.Ifyoufindamistakeinoneofourbooks—maybeamistakeinthetextorthecode—wewouldbegratefulifyoucouldreportthistous.Bydoingso,youcansaveotherreadersfromfrustrationandhelpusimprovesubsequentversionsofthisbook.Ifyoufindanyerrata,pleasereportthembyvisitinghttp://www.packtpub.com/submit-errata,selectingyourbook,clickingontheErrataSubmissionFormlink,andenteringthedetailsofyourerrata.Onceyourerrataareverified,yoursubmissionwillbeacceptedandtheerratawillbeuploadedtoourwebsiteoraddedtoanylistofexistingerrataundertheErratasectionofthattitle.
Toviewthepreviouslysubmittederrata,gotohttps://www.packtpub.com/books/content/supportandenterthenameofthebookinthesearchfield.TherequiredinformationwillappearundertheErratasection.
PiracyPiracyofcopyrightedmaterialontheInternetisanongoingproblemacrossallmedia.AtPackt,wetaketheprotectionofourcopyrightandlicensesveryseriously.IfyoucomeacrossanyillegalcopiesofourworksinanyformontheInternet,pleaseprovideuswiththelocationaddressorwebsitenameimmediatelysothatwecanpursuearemedy.
Pleasecontactusat<copyright@packtpub.com>withalinktothesuspectedpiratedmaterial.
Weappreciateyourhelpinprotectingourauthorsandourabilitytobringyouvaluablecontent.
QuestionsIfyouhaveaproblemwithanyaspectofthisbook,youcancontactusat<questions@packtpub.com>,andwewilldoourbesttoaddresstheproblem.
Chapter1.AndroidMarshmallowPermissionsAndroidpermissionshavebeenthereforaslongaswecanremember—sinceAndroid1.0,tobeexact.Throughtheyearsandwiththeevolvementofplatforms,theAndroidpermissionsmodelhasbeenmodifiedbyaddingnewpermissionsandtryingtoallowmoregranularcontroloverthepartofthedevicehardware/datatheapplicationhas.
Inthischapter,wewillreviewabitoftheAndroidpermissionsmodelthatwaspriortoAndroidMarshmallow,andwe’llfocusonthechangesitbringstothetable.WewillalsoexplainthechangesthatyouasadevelopermustdoinordertohandlealltheotherchangesandmakesureyourapplicationsworkasintendedonAndroidMarshmallow.
Inthischapter,wewillcoverthefollowing:
AnoverviewofAndroidpermissionsUnderstandingAndroidMarshmallowpermissionsHandlingcodepermissionswithbestpractices
AnoverviewofAndroidpermissionsInAndroid,eachapplicationrunswithdistinctsystemIDsknownasLinuxuserIDandGroupID.ThesystempartsarealsoseparatedintodistinctIDs,formingisolatedzonesforapplications—fromeachotherandfromthesystem.Aspartofthisisolatedlifecyclescheme,accessingservicesorotherapplications’datarequiresthatyoudeclarethisdesireinadvancebyrequestingapermission.
Thisisdonebyaddingtheuses-permissionelementtoyourAndroidManifest.xmlfile.Yourmanifestmayhavezeroormoreuses-permissionelements,andallofthemmustbethedirectchildrenoftheroot<manifest>element.
Tryingtoaccessdataorfeatureswithoutproperpermissionwouldgiveoutasecurityexception(usingaSecurityExceptionclass),informingusaboutthemissingpermissioninmostcases.
ThesendBroadcast(Intent)methodisexceptionalasitcheckspermissionsafterthemethodcallhasreturned,sowewillnotreceiveanexceptioniftherearepermissionfailures.Apermissionfailureshouldbeprintedtothesystemlog.NotethatinAndroidversionspriortoMarshmallow,missingpermissionswereduetomissingdeclarationsinthemanifest.Hence,itisimportantthatyoukeeppermissionsinmindwhenyoucomeupwiththefeaturelistforyourapp.
PermissionsWhenusingAndroidplatformasanapp,youhaverestrictionspreventingaccesstosomehardware,systemAPIs,privateuserdata,andapplicationdata.
PermissionisneededinordertoallowaccesstoaspecificAPI,data,orhardware;itwasaskedupontheinstallationofyourappupuntilAndroidMarshmallow.Mostpermissionsareusedtorestrictaccess.Whenapermissionisgranted,youthenhaveaccesstothatspecificrestrictedarea.Afeaturecanbeprotectedbyonepermissionatmost.
Theuses-permissionelementtakesanameattribute,android:name,whichisthenameofthepermissionyourapplicationrequires:
<uses-permissionandroid:name="string"android:maxSdkVersion="integer"/>
Didyouknowthattheandroid:maxSdkVersionattribute,addedinAPIlevel19,isusedtonotifytheversionoftheAPIfromwhichthispermissionshouldnotbegranted?ThisisusefulifapermissionisnolongerneededonhigherversionsoftheAPI.Forexample,takealookatthefollowing:
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="18"/>
InAPI19,yourappdoesn’tneedtoaskforthispermission—it’sgrantedtoyou.
Yourapplicationcanalsoprotectitsowncomponents,suchasactivities,services,broadcastreceivers,andcontentproviderswithpermissions.
ItcanemployanyofthepermissionsdefinedbyAndroidanddeclaredbyotherapplications,oritcandefineitsown.
Formoreinformationonpermissions,youcanreadhttp://developer.android.com/reference/android/Manifest.permission.html.
PermissiongroupdefinitionsPermissionsaredividedintogroups.AccordingtoGoogle,wecansaythatapermissiongroupputstogetherrelatedpermissionsinasinglename/tag.YoucangrouppermissionstogetherusingthepermissionGroupattributeinsidethe<permission>element.
Permissionsgroupedinthesamepermissiongroupareshownasonegroupwhenapprovingpermissionsorwhencheckinganappforitspermissions.
ThepermissiongroupiswhatyouseewheninstallinganapplicationfromthePlayStore;forexample,takealookatthefollowingscreenshot:
Let’stakealookatthestructureofthepermission-grouptag:
<permission-groupandroid:description="stringresource"
android:icon="drawableresource"
android:label="stringresource"
android:name="string"/>
Theelementsoftheprecedingstructurecanbeexplainedasfollows:
android:description:Thisreferstosimpletextusedtodescribethegroup.android:icon:Thisreferstoaniconfromadrawableresourcethatrepresentsthepermission.android:label:Thisreferstoasimpletextnameforthegroup.android:name:Thisisthenameofthegroup.Itisusedtoassignpermissionstoaspecificgroup.
Thefollowingtableshowsyouthevariouscategoriesofpermissionsthatarethereinapermissionsgroup:
Permissionsgroup
In-apppurchases Deviceandapphistory
Contacts Calendar
Phone Photos,media,andfiles
Wi-Ficonnectioninformation Bluetoothconnectioninformation
Identity Cellulardatasettings
SMS Location
Microphone Camera
DeviceIDandcallinformation Wearablesensors/activitydata
Other
NoteAnypermissionsthatarenotpartofapermissionsgroupwillbeshownasOther.Whenanappisupdated,theremaybechangestothepermissionsgroupforthatapp.
PermissionsthatimplyfeaturerequirementsSomepermissionsareimpliedbyfeaturerequirements;wewillcoverthisnext.
Whendeclaringafeatureinthemanifest,wemustalsorequestthepermissionsthatweneed.
Let’ssay,forexample,thatwewanttohaveafeaturethatsetspicturesforourcontacts.IfwewanttotakeapictureviatheCameraAPI,thenwemustrequestaCamerapermission.
The<users-feature>tagmakessurewedeclarethatweneeddevicesthatsupporttherequiredfeatureforourapplicationtoworkandusethatfeature.Ifthisfeatureisnotarequiredfeatureandourappcanworkwithoutitbutwithfewerfeatures,wecanuseandroid:required="false",keepingitinmindthatthisfeatureisoptional.
The<uses-feature>declarationsalwaystakeprecedenceoverfeaturesimpliedbypermissions.Thecompletelistofpermissioncategoriesthatimplyfeaturerequirementscanbefoundathttp://developer.android.com/guide/topics/manifest/uses-feature-element.html#permissions.
ViewingthepermissionsforeachappYoucanlookatthepermissionsforeachappusingthesettingsapportheadbshellcommand.
Tousethesettingsapp,gotoSettings|Apps.PickanappandscrolldowntoseethepermissionsthattheappusesYoucanseetheLollipopversioninthefollowingscreenshot:
InAndroidMarshmallow,theUIisdifferent.
Thesecondoptionistousetheadbshellcommandswiththeaaptcommand:
1. Listalltheapplicationsalongwiththeirinstallationpaths.Asanexample,let’strytofindoutFacebookgroups’apppermissionsusingthefollowingcommand:
adbshellpmlistpackages–f
Wecanusethe-3flagtojustshowthethird-partyappsinsteadoftheentirelist.
2. Oncewegetthepackagelocation(apk),weneedtopullitfromthedeviceviatheadbpull:
adbpull/data/app/com.facebook.groups-1/base.apk
3. Ourfinalsteptoshowpermissionsistouseaaptfoundinthebuild-toolsfolderofyourspecificbuildtoolsversion:
aaptdpermissionsbase.apk
Thisgivesusthefollowingscreenshotasaresult:
Toviewthepermissionsfortheentiredevice,takealookatthefollowingscreenshot:
Usinganadbcommand,youcanprintallknownpermissionsonthedevice.Thepackagemanager(pm)commandinsidetheadbcommandlookssomethinglikethefollowing:
$adbshellpmlistpermissions[options]<GROUP>
Listpermissionsgetthe[options]and<GROUP>arguments(bothoptional).
Here,optionscanbeasfollows:
-g:Thisreferstoalistofpermissionsorganizedbyagroup-f:Thisprintsalltheinformation-s:Thisprintsashortsummary,andthisiswhattheuserseesonscreenwhencheckingpermissionsorapprovingthem-d:Thislooksupandprintsonlypermissionsthatareconsidereddangerous-u:Thislistspermissionsvisibletotheuseronly
UnderstandingAndroidMarshmallowpermissionsAndroidMarshmallowintroducesanewapplicationpermissionsmodel,allowingasimplerprocessforuserswheninstallingand/orupgradingapplications.ApplicationsrunningonMarshmallowshouldworkaccordingtoanewpermissionsmodel,wheretheusercangrantorrevokepermissionsaftertheinstallation—permissionsarenotgivenuntilthereisuseracceptance.
Supportingthenewpermissionsmodelisbackward-compatible,whichmeansyourappscanstillbeinstalledandrunondevicesrunningolderversionsofAndroidusingtheoldpermissionsmodelonthosedevices.
AnoverviewWiththeAndroidMarshmallowversion,anewapplicationpermissionsmodelhasbeenintroduced.
Let’sreviewitabitmorethoroughly:
Declaringpermissions:Allpermissionsanappneedsaredeclaredinthemanifest,whichisdonetopreservebackwardcompatibilityinamannersimilartoearlierAndroidplatformversions.Permissiongroups:Asdiscussedpreviously,permissionsaredividedintopermissiongroupsbasedontheirfunctionalities:
PROTECTION_NORMALpermissions:Someofthepermissionsaregrantedwhenusersinstalltheapp.Uponinstallation,thesystemchecksyourapp’smanifestandautomaticallygrantspermissionsthatmatchthePROTECTION_NORMALgroup.INTERNETpermission:OneimportantpermissionistheINTERNETpermission,whichwillbegranteduponinstallation,andtheusercan’trevokeit.
Appsignaturepermissionsgranted:Theuserisnotpromptedtograntanypermissionsatthetimeofinstallation.Permissionsgrantedbyusersatruntime:Youasanappdeveloperneedtorequestapermissioninyourapp;asystemdialogisshowntotheuser,andtheuserresponseispassedbacktoyourapp,notifyingwhetherthepermissionisgranted.Permissionscanberevoked:Userscanrevokepermissionsthatweregrantedpreviously.Wemustlearnhowtohandlethesecases,aswe’lllearnlateron.
NoteIfanapptargetsanAndroidMarshmallowversion,itmustusethenewpermissionsmodel.
PermissiongroupsWhenworkingwithpermissions,wedividethemintogroups.Thisdivisionisdoneforfastuserinteractionwhenreviewingandapprovingpermissions.Grantingisdoneonlyonceperpermissiongroup.Ifyouaddanewpermissionorrequestanewpermissionfromthesamepermissiongroupandtheuserhasalreadyapprovedthatgroup,thesystemwillgrantyoutheaddedpermissionwithoutbotheringtheuserabouttheapproval.
Formoreinformationonthis,visithttps://developer.android.com/reference/android/content/pm/PermissionInfo.html#constants
Whentheuserinstallsanapp,theappisgrantedonlythosepermissionsthatarelistedinthemanifestthatbelongstothePROTECTION_NORMALgroup.
RequestingpermissionsfromthePROTECTION_SIGNATUREgroupwillbegrantedonlyiftheapplicationissignedwiththesamecertificateastheappwiththedeclaredpermission.
NoteAppscannotrequestsignaturepermissionsatruntime.
Systemcomponentsautomaticallyreceiveallthepermissionslistedintheirmanifests.
RuntimepermissionsAndroidMarshmallowshowcasedanewpermissionsmodelwhereuserswereabletodirectlymanageapppermissionsatapplicationruntime.Googlehasalteredtheoldpermissionsmodel,mostlytoenableeasierandfrictionlessinstallationsandauto-updatesforusersaswellasforappdevelopers.Thisallowsuserstoinstalltheappwithouttheneedtopreapproveeachpermissiontheapplicationneeds.Theusercaninstalltheappwithoutgoingthroughthephaseofcheckingeachpermissionanddecliningtheinstallationduetoasinglepermission.
Userscangrantorrevokepermissionsforinstalledapps,leavingthetweakingandthefreedomofchoiceintheusers’hands.
MostoftheapplicationswillneedtoaddresstheseissueswhenupdatingthetargetAPIto23.
TakingcodingpermissionsintoaccountWell,afteralltheexplanations,we’vereachedthecodingpart,andthisiswherewewillgetourcodinghandsdirty.Thefollowingarekeymethodsusedforhandlingpermissions:
Context.checkSelfPermission():ThischeckswhetheryourapphasbeengrantedapermissionActivity.requestPermission():Thisrequestsapermissionatruntime
EvenifyourappisnotyettargetingAndroidMarshmallow,youshouldtestyourappandpreparetosupportit.
TestingpermissionsIntheAndroidMarshmallowpermissionsmodel,yourappmustasktheuserforindividualpermissionsatruntime.Thereislimitedcompatibilitysupportforlegacyapps,andyoushouldtestyourappandalsotestaversiontomakesureit’ssupported.
Youcanusethefollowingtestguideandconductapptestingwiththenewbehavior:
Mapyourapp’spermissionsTestflowswithpermissionsgrantedandrevoked
Theadbcommandshellcanbequitehelpfultocheckforpermissions:
Listingapplicationpermissionsandstatusbygroupcanbedoneusingthefollowingadbcommand:
adbshellpmlistpermissions-g
Youcangrantorrevokepermissionsusingthefollowingadbsyntax:
adbshellpm[grant|revoke]<permission.name>
Youcangrantpermissionsandinstallapkusingthefollowingadbcommand:
adbinstall-g<path_to_apk>
CodingforruntimepermissionsWhenwewanttoadjustourapplicationtothenewmodel,weneedtomakesurethatweorganizeourstepsandleavenopermissionstranded:
Checkwhatplatformtheappisrunningon:WhenrunningapieceofcodethatissensitiveattheAPIlevel,westartbycheckingtheversion/APIlevelthatwearerunningon.
Bynow,youshouldbefamiliarwithBuild.VERSION.SDK_INT.
Checkwhethertheapphastherequiredpermission:Here,wegetourselvesabrandnewAPIcall:
Context.checkSelfPermission(Stringpermission_name).
Withthis,wesilentlycheckwhetherpermissionsaregrantedornot.
Thismethodreturnsimmediately,soanypermission-relatedcontrols/flowsshouldbedealtwithbycheckingthisfirst.
Promptingforpermissions:WehaveanewAPIcall,Activity.requestPermissions(String[]permissions,intrequestCode).Thiscalltriggersthesystemtoshowthedialogrequestingapermission.Thismethodfunctionsasynchronously.
Youcanrequestmorethanonepermissionatonce.Thesecondargumentisasimplerequestcodereturnedinthecallbacksothatyoucanrecognizethecalls.Thisisjustlikehowwe’vebeendealingwithstartActivityForResult()andonActivityResult()foryears.
AnothernewAPIisActivity.shouldShowRequestPermissionRationale(Stringpermission).
Thismethodreturnstruewhenyouhaverequestedapermissionandtheuserdeniedtherequest.It’sconsideredagoodpracticeafterverifyingthatyouexplaintotheuserwhyyouneedthatexactpermission.TheusercandecidetoturndownthepermissionrequestandselecttheDon’taskagainoption;then,thismethodwillreturnfalse.
Thefollowingsamplecodecheckswhethertheapphaspermissiontoreadtheuser’scontacts.Itrequeststhepermissionifrequired,andtheresultcallbackreturnstoonRequestPermissionsResult:
if(checkSelfPermission(Manifest.permission.READ_CONTACTS)!=
PackageManager.PERMISSION_GRANTED){
requestPermissions(newString[]{Manifest.permission.READ_CONTACTS},
SAMPLE_MATRIXY_READ_CONTACTS);
}
//Nowthisisourcallback
@Override
publicvoidonRequestPermissionsResult(intrequestCode,String
permissions[],int[]grantResults){
switch(requestCode){
caseSAMPLE_MATRIXY_READ_CONTACTS:
if(grantResults[0]==PackageManager.PERMISSION_GRANTED){
//permissiongranted-wecancontinuethefeatureflow.
}else{
//permissiondenied!-weshoulddisablethefunctionalitythat
dependsonthispermission.
}
}
}
Justtomakesureweallknowtheconstantsused,here’stheexplanation:
publicstaticfinalintPERMISSION_DENIED=-1:
Sinceit’sAPIlevel1,permissionhasnotbeengrantedtothegivenpackage
publicstaticfinalintPERMISSION_GRANTED=0:
Sinceit’sAPIlevel1,permissionhasbeengrantedtothegivenpackage.
Iftheuserdeniesyourpermissionrequest,yourappshouldtaketheappropriateaction,suchasnotifyingtheuserwhythispermissionisrequiredorexplainingthatthefeaturecan’tworkwithoutit.
NoteYourappcannotassumeuserinteractionhastakenplacebecausetheusercanchoosetorejectgrantingapermissionalongwiththedonotshowagainoption;yourpermissionrequestisautomaticallyrejectedandonRequestPermissionsResultgetstheresultback.
BestpracticesandusagenotesThenewpermissionsmodelhasbroughttolifeasmootherexperienceforusersandabitmorecode-handlingfordevelopers.Itmakesiteasiertoinstallandupdateappsandfeelcomfortablewithwhattheappsaredoing.
MinimalismisagreatoptionDon’tbeapermissionhog!Inourapplicationlifecycle,weshouldtrytominimizeourpermissionrequests.Askingforalotofpermissionsandmaintainingthemcanseemhazardousforsome,andweshouldtryandmakethefeaturesmoothandaskforthesmallestnumberofpermissionsasfaraspossibleinordertoallowrelaxed,undisturbedusage.Considerusingintentswheneverpossible—relyonotherapplicationsdoingsomeoftheworkforus(fewerpermissionsmeanslessfriction,turningagoodappintoagreatone).
AskingfortoomanypermissionsatonceUserscangetdistractedbytoomanydialogspoppingup,askingthemformoreandmorepermissions.Instead,youshouldaskforpermissionsasandwhenyouneedthem.
However,wehavesomeexceptionstoeveryrule.Yourappmayrequireafewpermissionstobeginwith,suchasacameraapplicationshowingthecamerapermissionsrightatthebeginning.However,settingthephototoyourcontactcanbedoneandrequestedonlywhentheusertriggersthatspecificaction.Trytomapyourflowandmakeiteasierforuserstounderstandwhatisgoingon.Userswillunderstandthatyou’verequestedpermissionsforcontactsiftheyhaveaskedtosetinformationtoacontactviayourapp.
Onemoresuggestion:appswithatutorialcanintegratetheessentialpermissions’requestinthetutorial,allowingtheuserstobetterunderstandtheflowandwhyeachpermissionisused.
HonestycanbeagreatpolicyWhenaskingforapermission,thesystemshowsadialogstatingwhichpermissionyourappwants,butitdoesn’tsaywhy.Consideruserswhohatebeingleftinthedarkthinkingwhythispermissionisneedednoworuserswhodenythepermissionsduetospeculation.Thingscanbeevenworse:sometimes,auser’scursormaybe2cmawayfromthe1-starratingortheuninstallbutton.
Thisiswhyit’sagoodideatoexplainwhyyourappwantsthepermissionsbeforecallingrequestPermissions().
Keepinmindthatmostdeveloperswillchooseatutorialbutalotofusersmaychoosetoskiptutorialswheneverpossible,soyoumustmakesurethatyoucanprovideinformationaboutpermissions,apartfromtheonesinthetutorial.
Needsupporthandlingruntimepermissions?Managingpermissionsiseasierwiththelatestrevisionofthev4orv13supportlibraries(23,whichisthesameastheAndroidMarshmallowAPIversion,soit’seasytoremember)
Thesupportlibrariesnowprovideseveralnewmethodstomanagepermissionsandworkproperlyonanydevicethatcanusetheselibraries.This,forinstance,savesyouthetimerequiredtocheckforasufficientAPIlevelregardlessofwhetherthedevicerunsAndroidMarshmallowornot.IfanappisinstalledonadevicerunningAndroidMarshmallow,properbehaviorisachieved—asifyou’rerunningthesameframeworkcalls.Evenwhenrunningonlowerversions,yougettheexpectedbehaviorfromthesupportlibrarymethods.
Thev4supportlibraryhasthefollowingmethods:
ActivityCompat.checkSelfPermission(Contextcontext,Stringpermission):
Thischeckswhetheryourapphasapermission.PERMISSION_GRANTEDisreturnediftheapphasthepermission;otherwise,PERMISSION_DENIEDisreturned.
ActivityCompat.requestPermissions(Activityactivity,String[]
permissions,intrequestCode:
Thisrequestspermissions,ifrequired.IfthedeviceisnotrunningAndroid6.0,youwillgetacallback.
ActivityCompat.OnRequestPermissionsResultCallback(intrequestCode,
String[]permissions,int[]grantResults):
ThispassesPERMISSION_GRANTEDiftheappalreadyhasthespecifiedpermissionandPERMISSION_DENIEDifitdoesnot.
ActivityCompat.shouldShowRequestPermissionRationale(Activityactivity,
Stringpermission):
ThisreturnstrueiftheuserhasdeniedapermissionrequestatleastonceandhasnotyetselectedtheDon’taskagainoption.
Accordingtothedesignpatterns,weshouldnowgiveourusersmoreinformationaboutthefeatureandwhythesepermissionsaresoimportanttotheapp.
NoteIfthedeviceisnotrunningAndroidMarshmallow,shouldShowRequestPermissionRationalewillalwaysreturnfalse.
ThePermissionCheckerclassisalsoincludedinv4.
ThisclassprovidesseveralmethodsforappsthatuseIPCtocheckwhetheraparticular
packagehasaspecifiedpermissionwhenIPCcallsaremade.
Androidhasacompatibilitymode,allowinguserstorevokeaccesstopermission-protectedmethodsforlegacyapps.Whenauserrevokesaccessinthecompatibilitymode,theapp’spermissionsremainthesamebutaccesstotheAPIsisrestricted.
ThePermissionCheckermethodverifiesapppermissionsinnormalaswellaslegacymodes.
NoteIfyourappactsasamiddlemanonbehalfofotherappsandneedstocallplatformmethodsthatrequireruntimepermissions,youshouldusetheappropriatePermissionCheckermethodinordertoensurethattheotherappisallowedtoperformtheoperation.
Thev13supportlibraryprovidesthefollowingpermissionmethods:
FragmentCompat.requestPermissions():
Thisrequestspermissions,ifrequired.IfthedeviceisnotrunningAndroid6.0,youwillgetacallback.
FragmentCompat.OnRequestPermissionsResultCallback:
ThispassesPERMISSION_GRANTEDiftheappalreadyhasthespecifiedpermissionandPERMISSION_DENIEDifitdoesnot.
FragmentCompat.shouldShowRequestPermissionRationale():
ThisreturnstrueiftheuserhasdeniedapermissionrequestatleastonceandhasnotyetselectedtheDon’taskagainoption.
Accordingtothedesignpatterns,weshouldnowgiveourusersmoreinformationaboutthefeatureandwhythispermissionissoimportanttotheapp.
NoteIfthedeviceisnotrunningAndroidMarshmallow,itwillalwaysreturnfalse.
Youcancheckoutthesampleprojectforthethreewaystohandlepermissions:
https://github.com/MaTriXy/PermissionMigrationGuide
Formoreinformationonpermissiondesignpatterns,readPatterns–PermissionsbyGoogleathttps://www.google.com/design/spec/patterns/permissions.html.
SomepermissionsarenormalandsafertouseTheAndroidsystemflagspermissionsaccordingtotheirprotectionlevels.Thelevelsaredescribesathttp://developer.android.com/reference/android/content/pm/PermissionInfo.html.
ThelevelthatisrelevanttoourdiscussionisPROTECTION_NORMAL,inwhichpermissionsareconsideredtohavelittleornoriskwhenapplicationshavethem.
Let’ssayyouwanttobuildaflashlightapp;allowingyourapptoturnontheflashisnotconsideredahugerisktoprivacyorsecurity,andthisiswhyflashlightpermissionisflaggedPROTECTION_NORMAL.
Whenyoudeclarenormalpermissionsinthemanifest,thesystemgrantsthesepermissionsautomaticallyatthetimeofinstallation.Thereisnoprompttograntpermissionsforanormalpermissionsgroup,andthesepermissionscan’tberevokedbyusers.
Thismeansthatyoucanbesurethatnormalpermissionsaregrantedatthetimeofinstallation.
Currently,thepermissionsclassifiedasPROTECTION_NORMALareasfollows:
android.permission.ACCESS_LOCATION_EXTRA_COMMANDS
android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_WIFI_STATE
android.permission.ACCESS_WIMAX_STATE
android.permission.BLUETOOTH
android.permission.BLUETOOTH_ADMIN
android.permission.BROADCAST_STICKY
android.permission.CHANGE_NETWORK_STATE
android.permission.CHANGE_WIFI_MULTICAST_STATE
android.permission.CHANGE_WIFI_STATE
android.permission.DISABLE_KEYGUARD
android.permission.EXPAND_STATUS_BAR
android.permission.FLASHLIGHT
android.permission.GET_ACCOUNTS
android.permission.GET_PACKAGE_SIZE
android.permission.INTERNET
android.permission.KILL_BACKGROUND_PROCESSES
android.permission.MODIFY_AUDIO_SETTINGS
android.permission.NFC
android.permission.PERSISTENT_ACTIVITY
android.permission.READ_SYNC_SETTINGS
android.permission.READ_SYNC_STATS
android.permission.READ_USER_DICTIONARY
android.permission.RECEIVE_BOOT_COMPLETED
android.permission.REORDER_TASKS
android.permission.SET_TIME_ZONE
android.permission.SET_WALLPAPER
android.permission.SET_WALLPAPER_HINTS
android.permission.SUBSCRIBED_FEEDS_READ
android.permission.TRANSMIT_IR
android.permission.VIBRATE
android.permission.WAKE_LOCK
android.permission.WRITE_SETTINGS
android.permission.WRITE_SYNC_SETTINGS
android.permission.WRITE_USER_DICTIONARY
com.android.alarm.permission.SET_ALARM
com.android.launcher.permission.INSTALL_SHORTCUT
SummaryAsyousaw,theAndroidpermissionsystemandmodelisvastandhasintroducedafewchangesthatcanhelpappdevelopersandapplicationsgainmoretractionandinstallationsandgivetheuserstheabilitytodecidewhenyourapplicationswillbeabletouseeachpermission-dependentfeature.Keepinmind,though,thatthisisjustastartingpointandAndroidMarshmallowstillneedstogainmarketshareandgetadoptedbyOEMs,enablinguserswithfreedomofchoice.Youasanappdevelopermustprepareinadvanceandmakesureyourapplicationdevelopmentisforward-facing,allowingnewuserstoenjoythelatestupdatesassoonaspossiblewhilemaintainingahighlevelofperformanceforyourapplications.
Inthenextchapter,wewillgooverasmallyetimportantfeatureintheAndroidMarshmallowversion:applinking.
Chapter2.AppLinksOneofthemajorimprovementstothenewAndroidMarshmallowversionispowerfulapplinking.Itallowstheassociationofyourappwithyourownedwebdomain.Withthisassociation,youasadeveloperallowthesystemtodeterminethedefaultappthatshouldhandleaparticularweblinkandskippromptinguserstoselectanapp.Savingclicksmeanslessfriction,whichmeansthatyoureachthecontentfaster;thisleadstousersanddevelopersbeinghappy.Inthischapter,wewillcoverthefollowingtopics:
TheAndroidIntentsystemCreatingawebsiteassociationTriggeringapplinkverificationApplinksettingsandmanagementTestingapplinks
TheAndroidIntentsystemAlmosteverydeveloperknowswhatanAndroidIntentsystemis,butwewillexplainitabitandlayoutthebasicprinciplesrequiredtounderstandtheapplinksfeature.TheAndroidIntentsystemcanbefoundintheAndroidplatform;thisallowsthepassingofdatainasmall,simplepackage.Intentmeansthatwewanttoperformanaction.Youmayalreadyknowaboutthebasicintents:
startActivity()
startActivityForResult()
startService()
sendBroadcast()
ThefollowingfigureshowsanAndroidIntentsystemforthestartActivity()andonCreate()intents:
Source:http://developer.android.com/guide/components/intents-filters.html
TheAndroidIntentsystemisaflexiblemechanismthatisusedtoenableappstohandlecontentandrequests.MultipleappsmaydeclarematchingURI(shortforUniformResourceIdentifier)patternsintheirintentfilters.Whenauserclicksonaweblinkthatdoesnothaveadefaultlaunchhandler,theplatformmaydisplayadialogfortheusertoselectfromalistofappsthathavedeclaredmatchingintentfilters.
Intentsarealsousedtotriggeractionsacrossthesystem,andsomeoftheseactionsaresystem-defined,suchasACTION_SEND(referredtoastheshareaction),whereyouasanappdevelopercanshare/sendspecificinformationtoanotherapplicationinordertocompleteanactionrequiredbyauser.
UntilAndroidMarshmallow,browsershandledeachlinkclickedontheWeb,andthesystemcheckedwhetheracustomURIschemewasavailable.YourapplicationcouldhandlespecificcustomactionsviathecustomURIscheme.Thiswastrickyattimesanddidn’tallowthehandlingoflinksunderanentirewebdomain.Now,it’spossible.AndroidMarshmallow’saddedsupportforapplinksallowsyou,asanappdeveloper,toassociateanappwithawebdomain.Automatically,thiswillallowyoutodeterminethedefaultapp
thatwillhandleaparticularweblinkinsteadofshowingtheselectedapplicationtohandlethedialog.
NoteIfyouwishtoreadmoreaboutintents,youcangotothefollowinglink:
http://developer.android.com/guide/components/intents-filters.html
CreatingawebsiteassociationYouasanappdeveloperaswellasawebsiteownerneedtodeclareawebsiteassociationwithanapp.ThedeclarationisdonebyhostingaJSONfile,whichisspecificallynamedassetlinks.json.Thefilemustresideinaspecificlocationonthedomaininquestion,suchas:https://<domain>:<optionalport>/.well-known/assetlinks.json
NoteThisfileisaccessedandverifiedovertheHTTPSprotocolandnotHTTP.
Whythisfile?TheJSONfileholdsinformationabouttheAndroidapplicationthatwillbethedefaulthandlerfortheURLsunderthisdomain.IntheJSONfile,youmusthavethefollowingstructure:
[{
"relation":["delegate_permission/common.handle_all_urls"],
"target":{
"namespace":"android_app",
"package_name":"com.yourapp.androidapp",
"sha256_cert_fingerprints":[""]
}
}]
Thefollowingaresomeelementsoftheprecedingstructure:
package_name:Thisisthepackagenamefromyourapp’smanifestsha256_cert_fingerprints:ThisistheSHA-256fingerprintofyourapp
Usethefollowingcommandifyoudon’thavethisSHA(shortforSecureHashAlgorithm):
keytool-list-v-keystoreapp_release_signing.keystore
TriggeringapplinkverificationYoucanrequestautomaticverificationforanyapplinksdeclaredintheassetlinks.jsonfile.Requestingaverificationisdonebyaddingtheandroid:autoVerifyattributetoeachintentfilterinthemanifestandsettingittotrue.
Let’ssayweownaWhatsAppapplicationanddomain.Wewanttoautoverifyanintentfilterthathastheandroid.intent.action.VIEWaction.
ThefollowingisasampleactivityfromWhatsAppthathandlesapplinksandtheautoverificationattribute:
<activityandroid:name="com.whatsapp.XXX"…>
<intent-filterandroid:autoVerify="true">
<actionandroid:name="android.intent.action.VIEW"/>
<categoryandroid:name="android.intent.category.DEFAULT"/>
<categoryandroid:name="android.intent.category.BROWSABLE"/>
<dataandroid:scheme="http"android:host="www.whatsapp.com"/>
<dataandroid:scheme="https"android:host="www.whatsapp.com"/>
</intent-filter>
</activity>
Theandroid:autoVerifyattributealertstheplatformtoverifyapplinkswhentheappisinstalled.Iftheapplink’sverificationfails,yourappwillnotbesetasthepreferredapptohandletheselinks.Ifthereisnopreferredapptohandletheselinkswheneverauseropensoneofthem,adialogtochooseanappisdisplayed.
Ifauserhasusedthesystemsettingsandsetanappasthepreferredapp,thenthelinkwillgodirectlytotheappbutnotbecausetheverificationwassuccessful.
ApplinksettingsandmanagementForeasymanagement,youcanenterthesystemsettingsandtweaktheURLhandlingbynavigatingtoSettings|Apps|Appinfo|Openbydefault.
TestingapplinksAswitheverynewfeatureweadd,wemusttesttheapplinksfeaturethatwewilladdtoourapplication.
CheckingmanifestandlistingdomainsOurfirststepistogooverthemanifestandmakesureallthedomainsareregisteredcorrectlyandallintentfiltersarewelldefined.Onlythelinks/domainsunderallthecriteriamentionedinthefollowingbulletsaretheonesweneedtotest:
Theandroid:schemeattributewithavalueofHTTPorHTTPSTheandroid:hostattributewithadomainURIpatternThecategoryelement,whichcanbeoneofthefollowing:
android.intent.action.VIEW
android.intent.category.BROWSABLE
TheDigitalAssetLinksAPIWecanusetheDigitalAssetLinksAPItoconfirmthatourlink’sJSONfileisproperlyhostedanddefinedusingthefollowingsyntax:
https://digitalassetlinks.googleapis.com/v1/statements:list?
source.web.site=https://<DOMAIN>:<port>&
relation=delegate_permission/common.handle_all_urls
TestingourintentNowthatwehaveconfirmedthatthehostedJSONfileisvalid,wewillinstalltheapponourdeviceandwaitforatleast20-30secondsfortheverificationprocesstocomplete.Afterthis,wecancheckwhetherthesystemhasverifiedourappandsetthecorrectlink-handlingpoliciesusingthefollowingsyntax:adbshellamstart-aandroid.intent.action.VIEW\-c
android.intent.category.BROWSABLE\-d"http://<DOMAIN>:<port>"
Forexample,ifwetakeYouTubevideos,wecantriggertheYouTubeapptoopenthevideodirectlyusingthefollowingcommand:
adbshellamstart-aandroid.intent.action.VIEW-c
android.intent.category.BROWSABLE-d"http://youtu.be/U9tw5ypqEN0"
CheckingpoliciesusingadbAndroidDebugBridge(adb)canhelpuscheckexistinglink-handlingpoliciesforallapplicationsinourdeviceusingthefollowingcommand:
adbshelldumpsyspackagedomain-preferred-apps
Thefollowingscreenshotistheresultoftheprecedingcommand:
Anotheroptionisasfollows:
adbshelldumpsyspackaged
Thefollowingscreenshotistheresultoftheprecedingcommand:
NoteWemustwaitatleast20-30secondsaftertheinstallationforthesystemtocompletetheverificationprocess.
Thefollowinglistingindicatesapps’associationwithdomainsperuser:
Package:Thisreferstotheapp’spackagename,asdeclaredinitsmanifestDomains:Thisreferstothelistofhostswhoseweblinksarehandledbythisapp;blankspacesareusedasdelimitersStatus:Thisreferstothecurrentlink-handlingsettingforthisapp
Passingtheverificationandandroid:autoVerify="true"willshowastatusofalways.
Thehexadecimalnumberafterthestatus(asshownintheprecedingscreenshot)istheAndroidsystem’srecordoftheuser’sapplinkagepreferences.Itdoesnotindicatethattheverificationhassucceeded.
NoteTheusercanchangetheapplinksettingsbeforetheendoftheverificationprocess,whichmeansthatwemayseeafalsepositiveforasuccessfulverification.Userpreferencestakeprecedenceoverprogrammaticverification,sowewillseethatthelinkgoesdirectlytoourappwithoutdisplayingadialog,asifverificationhadsucceeded.
SummaryAswesaw,applinkinghasbecomepowerfulinAndroidMarshmallow.Thisallowsyou,theappdevelopers,helpthesystembetterdecidehowtoact.HandlingwebURLswillgiveyouwiderexposure,abiggerfunnelforyourapps,andbetterexperience,whichyoucanprovidetoyourusers(whichinturnleadstobetterratings,moredownloads,andviceversa).
Applinkingissimpletoimplement,easytounderstand,andisamust-havefeatureinthemobile/webworldtoday.Whileapplinkingenablesbetteractionhandlingforthoseusingyourapplications,userscanhavemultipledevices,expectingthesamebehavioroneachdevice,andwouldbemoreengagediftheirdataandactionhandlinghappenssmoothly.Thisbringsustoournextchapter,whichwillteachyouhowtobackupusersettingsandmore.
Chapter3.Apps’AutoBackupHaveyouevertakenthetimetosetupanapponyourphone,useitforawhile,pourinalotofcontent,andswitchphonesduetoamishapjusttodiscoverthatyourdataandsettingshavegonewiththewind?
OneofthekeyfeaturesofAndroidMarshmallowisthatitsupportsfullautomaticdatabackupandrestoreforuserapps.Thisimprovestheuserexperience,makestheoverallengagementmorefun,andshortenstheboardingtimeformultipledevices.Likewediscussedinthepreviouschapters,happyusersleadtohappydevelopers.
Youcanunloadtheburdenofsettingupanewdevice;itdoesn’tmatterwhetherit’sanaddeddeviceorareplacement.Theuserwillendupwiththesameappconfigurationanddata,allowingworktobemoredevice-agnostic.Forthisfeaturetobeenabledonyourapplications,youmusttargettheAndroidMarshmallowSDK’sversion23;noextracodeisneededbydefaulteventhoughyoucanconfigurethefeatureandallowspecificbehaviorwheneverrequired.Dataisautomaticallyrestoredwhenauserchangesorupgradesthedevice.
Inthischapter,wewilllearnhowthisfeatureworksandconfiguretheinformationthatwewanttobackup.We’llcoverthefollowingtopics:
AnoverviewDatabackupconfigurationBackupconfigurationtestingImportantbytes
AnoverviewTheautomaticbackupfeatureiscreatedbytakingthedatacreatedwithinyourappanduploadingittotheuser’sGoogleDriveaccount,keepingitencrypted.Thisdoesn’taffecttheuser’sdrivequotaoryourquota,forthatmatter.Eachappislimitedto25MBbackupperuser,andonceyoureachthatamount,yourappwillstopbackingup.Also,notethatit’scompletelyfree!
Backupisdoneincyclesof24hours,nightsonly,andit’sdoneautomatically,usuallywhenthedeviceisidle,charging,andconnectedtoaWi-Finetwork.Theseconditionsarethereforbatteryefficiency,datacharges,and,ofcourse,tokeeptheuserinterferencetoaminimum.AndroidsystemshaveaBackupManagerservice,whichuploadsalltheavailablebackupdatatothecloud.Switchingtoanewdeviceoruninstallingandreinstallingtheappwilltriggertherestoreoperation,whichinturncopiesthedataintotheapp’sdatadirectory.
NoteThisnewbehaviorallowsyoutokeepusingyourexistingbackupservicecallsaswell.
ToreadmoreabouttheAndroidBackupServicethatwasusedpriortoAndroidMarshmallow,headto:
https://developer.android.com/guide/topics/data/backup.html
DatabackupconfigurationWehavealotofdatathatwewanttobackupforourusers,butwealsodon’twanttobackupallthedata.Let’ssayweallagreenottobackupusers’passwordsorothersensitivedata,butwhatifyouhaveaspecificappconfigurationthatisgeneratedbasedonthedevicetheuserisusing?ThistooshouldbeexcludedinamannersimilartodevicetokenssuchasGoogleCloudMessaging(GCM)andothers.Iwouldrecommendthatyoufigureoutwhichdatayourappkeepspersistentlyandwhetherthisdatashouldandcanbedevice-agnostic.
Youcanconfigurewhatisbeingbackedupbesidestheautomaticallyexcludedfilesmentionedearlier.Thisconfigurationshouldbedeclaredinyourapp’smanifestviatheandroid:fullBackupContentattribute.YouwillneedtocreateanewXMLfilethatshouldresideinyourres/xmlfolder,andthiswillhavespecificrulesforthebackingupofyourapp’sdata.
IncludingorexcludingdataXMLfileconfigurationincludesasimplebatchofinclude/excludetags,whichindicatewhetherornotyouneedtobackupadirectoryoraspecificfile.Keepinmindthatbydefault,theXMLisreductive,whichmeansthatyoubackupeverythingpossibleunlessthereisaninstructiontoexcludeitinyourXML.
Anotherpossibleconfigurationistheconstructiveconfigurationinwhichyouspecifyonlythethingsyouwanttobackup,andtheywillbeaddedtothebackup.ThisconfigurationbehaviorisdonebyaddinganincludetagtoyourXML,andfromthenonward,itwillremainconstructive.
Aswecanseeinourexample,wespecifyabackupschemeconfigurationintheapp’smanifest:
<?xmlversion="1.0"encoding="utf-8"?>
<manifestxmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.yourapp.androidapp">
<uses-sdkandroid:minSdkVersion="16"/>
<uses-sdkandroid:targetSdkVersion="23"/>
<appandroid:fullBackupContent="@xml/androidapp_backup_config">
</app>
</manifest>
Afterdeclaringthefileinourmanifest,wealsoneedtoconstructitinourres/xmlfolder;forexample,takealookatthefollowing:
<?xmlversion="1.0"encoding="utf-8"?>
<full-backup-content>
<excludedomain="database"path="sensitive_database_name.db"/>
<excludedomain="sharedpref"path="androidapp_shared_prefs_name"/>
<excludedomain="file"path="some_file.file_Extension"/>
<excludedomain="file"path="some_file.file_Extension"/>
</full-backup-content>
Thisexamplebackupconfigurationexcludesonlyspecificdatafrombeingbackedup.Allotherfilesarebackedup.
ThebackupconfigurationsyntaxAlthoughyoushould’vesortedoutyourapp’sspecificpersistentdata,wecangoovertheconfigurationsyntaxthatshouldbeintheXML.ThesyntaxfortheconfigurationXMLfileisasfollows:
<full-backup-content>
<includedomain=["root"|"sharedpref"|"database"|"file"|
"external"]path="string"/>
<excludedomain=["root"|"sharedpref"|"database"|"file"|
"external"]path="string"/>
</full-backup-content>
Don’tforgettoreadtheexplanationforeachattributeandelementhere:
<include>:Youshouldusethistagwheneveryouwanttospecificallyaddaresourcefromanyoftheapprovedsortstothebackup.Rememberthatwheneveryouspecifyan<include>tag,thebackupbehaviorchangestoconstructive,andthesystemonlybacksupresourcesspecifiedwiththe<include>tags.<exclude>:Youshouldusethistagwheneveryouwanttoexcludeanyoftheapp’sresourcesfromthebackup.Asmentionedearlier,youshouldexcludesensitivedataandyourapp’sdevice-specificdata.Here,thebehaviorislikethis:thesystembacksupallofyourapp’sdataexcepttheresourcesspecifiedwiththe<exclude>tag.domain:Thisappearsonincludeaswellasexcludetags.Itallowsyoutodeclaretheresourcetypeyouwanttoincludeorexcludefromthebackup.Thedomainhasspecificvalidvaluesthatyoucanchoosefrom:
root:Thisimpliesthattheresourceshouldbeintheapp’srootdirectoryfile:ThisimpliesthattheresourceisafilelocatedintheFilesdirectoryandisaccessibleviathegetFilesDir()methoddatabase:ThisimpliesthatyourresourceisadatabasefilethatcanbelocatedviathegetDatabasePath()methodortheSQLiteOpenHelperclasssharedpref:ThisimpliesthatyourresourceisaSharedPreferencesobjectthatcanbeaccessedviathegetSharedPreferences()methodexternal:ThisimpliesthatyourresourceisafileinanexternalstoragelocatedinadirectoryaccessedbythegetExternalFilesDir()methodpath:ThisaStringpathtotheresourcethatyouwantincludedinorexcludedfrombackup
OptingoutfromappdatabackupOnsomeoccasions,youmightdecidethatyouwishnottousetheappdatabackupfeatureinyourapp.Insuchasituation,youwillbeabletonotifythesystemthatyourapphasoptedout.
Settingtheandroid:allowBackupattributetofalseinyourmanifestisdoneusingthefollowingcommand:
android:allowBackup="false"
BackupconfigurationtestingBynow,youhavecreatedabackupconfigurationandyoumight(should)testitandmakesurethatyourappsavesthedata,restoresit,andworkswithoutanyissues.
SettingbackuplogsBeforeyoutestyourapp’sconfiguration,youmightwanttoenablelogging;thisisdoneviaadb,whereyousettheparserlogpropertytoVERBOSE:
$adbshellsetproplog.tag.BackupXmlParserLoggingVERBOSE
Testingthebackupfeaturecanbesplitintotwoparts:
TestingthebackupphaseTestingtherestorephase
TestingthebackupphaseThebackupcanberunmanually,butfirst,youmustruntheBackupManagerviatheadbcommand:
$adbshellbmgrrun
AftertheBackupManagerisupandrunning,wecantriggerthebackupphaseviaadbandrunourapp’spackagenameasthe<PACKAGE.NAME>parameter:
$adbshellbmgrfullbackup<PACKAGE.NAME>
TestingtherestorephaseWeexecutedthebackupphaseandallwentwell.Now,wewanttotesttherestorephaseandverifythatallthebacked-updataisrestoredproperlyandwedidn’tmissoutonanyresource.Wemanuallyrunarestore(mustbedoneafteryourappdataisbackedup).Thisisdoneviatheadbshell,specifyingthepackagenameforyourappasthe<PACKAGE.NAME>parameter:
$adbshellbmgrrestore<PACKAGE.NAME>
NoteTherestoreactionstopsyourappandwipesitsdatabeforeactuallyperformingtherestoreoperation.
TroubleshootingIssuescanoccurinanyplace,includingourcase.Ifyourunintoissues,youshouldtryandclearthedatabyturningbackuponandoffbynavigatingtoSettings|Backup&reset,factoryresettingthedevice:
Youcanclearthedatausingthiscommand:
$adbshellbmgrwipe<TRANSPORT><PACKAGE.NAME>
The<TRANSPORT>tagisprefixedbycom.google.android.gms/.Toviewthelistoftransports,youcanrunfollowingadbcommand:
$adbshellbmgrlisttransports
Thefollowingscreenshotistheresultoftheprecedingcommand:
ImportantbytesBeforewejumpintothenextchapter,let’sgothroughacoupleofimportantsubtopicswithintheAndroidapps’backupfeature.
Systembackupdoesnotincludethefollowing:
FileslocatedinCacheDirviathegetCacheDir()method(API1andabove)FileslocatedinCodeCacheDirviathegetCodeCacheDir()method(API21andabove)FileslocatedintheexternalstorageandnotinExternalFilesDirviathegetExternalFilesDir(Stringtype)method,wherethetypecanbeasfollows:
nullfortherootofthefiledirectoryAnyofthesetypesforaspecificsubfolder/directory:
android.os.Environment.DIRECTORY_MUSIC
android.os.Environment.DIRECTORY_PODCASTS
android.os.Environment.DIRECTORY_RINGTONES
android.os.Environment.DIRECTORY_ALARMS
android.os.Environment.DIRECTORY_NOTIFICATIONS
android.os.Environment.DIRECTORY_PICTURES
android.os.Environment.DIRECTORY_MOVIES
FileslocatedinNoBackupFilesDirviathegetNoBackupFilesDir()method(API21andabove)
WhattoexcludefromthebackupThoughwehavediscussedthisearlier,youmayneedtorevisewhichappdataiseligibleforbackup.
Amongtheexcludeddata,youmustexcludeanydevice-specificidentifiersthatareeitherissuedbyaserverorgeneratedonthedevice,includingtheGCMregistrationtoken.
Youmustalsoaddtheexcludinglogicforanyaccountcredentialsorothersensitiveinformation.
BackupAgentandbackupeventsYoucanimplementyourownBackupAgentattribute,whichallowsyoutolistentoevents.BackupAgenthasseveralcallbacksthatyoucanoverride,oneofwhichistheonRestoreFinished()method,whichiscalledafterasuccessfulrestoretakesplace.Youshouldaddtheandroid:fullBackupOnly="true"attributetoyourmanifestinadditiontoandroid:backupAgent;thiswillindicatethatwhileyourapplicationhasaBackupAgentattribute,AndroidMarshmallowandotherdeviceswillonlyperformfull-databackupoperations.
ThistechniquecancomeinhandywhenyouwanttoexcludeafewkeysfromyourSharedPreferencesbackup(device-specifictokens,GCMtokens,andsoon).InsteadofpartitioningSharedPreferencesintomultiplefiles,youcansimplyremovethekeysatrestoretimewhenonRestoreFinished()iscalled.
Keepinmindthatothersensitivedataisnotsupposedtobebackedupanyway.YoucanreadmoreaboutBackupAgentat:
http://developer.android.com/reference/android/app/backup/BackupAgent.html.
SummaryAndroidMarshmallowhasbroughtinagreatbackupfeatureforapps,reducingfrictionforusersmigratingtonewdevices.
Inaworldfullofdiverseapps,maximizingthebenefitsfromautomaticbackupsleadstobetteruserexperience.Thegoalofthisfeatureistounloadtheburdenandshortenthetimerequiredtosetupanewdevicewiththeuser’sfavoriteapps.
Allowingtheuserstoenteryourappwithmerelyapasswordpromptafterthenewinstallationcanbeagreatexperience;tryityourself!Youcancheckoutthesamplecodethat’sincludedorgototheGitHubrepositoryat:
https://github.com/MaTriXy/apps_autobackup_example
Inournextchapter,wewilldiveintomorechangesexecutedinAndroidMarshmallowasweunfolditsawesomeness.
Chapter4.ChangesUnfoldAndroidMarshmallowholdssomechangesthatmightgetoverlooked.Alotofthesechangesareshortbutwillrequireyourfullattentiontofullyunderstandthemandmakesureyoudon’tmissoutwhentryingtousearemoved/deprecatedAPI,anewflow,oranewandimprovedAPI.
I’vebundledupagroupofchangesthatyoumightuseorneedtoknowandunderstandwhenbuildingyourapplicationsforAndroid6.0(Marshmallow):
Power-savingmodesRemovablestorageadoptionApacheHTTPclientremovalNotificationsTextselectionSupportlibrarynoticeAndroidKeystorechangesWi-FiandnetworkingchangesRuntimeHardwareidentifierAPKvalidationUSBconnectionDirectShareVoiceinteractionsTheAssistAPIBluetoothAPIchanges
Theprecedinggroupdoesn’tincludeaseparatechapterformajorchanges,forexample,thepermissionsmodelcoveredinChapter1,AndroidMarshmallowPermissions,oranimprovedAPI,suchasthevideo/audio/cameraAPIthatwewillcoverinthenextchapter.
Power-savingmodesAndroid6.0hasaddednewpower-savingmodes,DozeandAppStandby,prolongedbatterylifebyupto2timesaccordingtoGoogle’smeasurements.TheDozemodehasbeencreatedtoimprovethesleepefficiencyofidledevices,whiletheAppStandbymodehasbeendesignedtopreventappsfromeatinguppowerwhileintheidlestate.Onbothoccasions,plugginginthedevicetochargersallowsnormaloperationstoresume.
TheDozemodeDozingiswhenadeviceisunplugged,thescreenisoff,andit’sstationary(thiscanbedeterminedviasensors,suchastheaccelerometer)foradeterminedperiodoftime.Whatwegetisastatewherethesystemiskeptinthesleepstateaslongaspossible.WhenanAndroid6.0deviceisintheDozemode,notmuchwillhappeninthebackground,asshowninthefollowingfigure:
Inshort,everythingyouthinkwillhappeninthebackgroundwillnotactuallyhappen.
Whathappenstoappswhenadeviceisdozing?Whenadeviceentersthedozingstate,youwillencountersomebattery-efficientsystembehavior,whichwillincludethefollowing:
Networkaccessisrestrictedunlessyourappreceivesahigh-priorityGCMWakelocksareignoredbutaregrantedtoappsSyncsandjobsaredeferredusingthefollowing:
SyncadaptersJobScheduler(notallowedtorun;thisisenforcedbythesystem)
Alarmsaredeferred
NoteIfyouhaveimportantalarmsandneedtotriggertheUI:
UsethesetAndAllowWhileIdle()methodCan’tbeabused;thisisallowedonceevery15minutesWi-FiscansareoffGPSisoff
TheDozemodewillendshortlybeforeanysetAlarmClock()alarms;itcanalsoendwhenthestatesofbeingstationaryandunpluggedareexchanged.ExitingtheDozemode
willtriggerthedevicetoexecuteanyjobsandsyncsthatarepending.
TestingappswithDozemodeTestappsusingyourdevice(withAndroid6.0)andadbcommands:
1. Simulateanunpluggeddeviceusingthefollowingcommand:
$adbshelldumpsysbatteryunplug
Thiswillcauseyourbatteryicontoshowasifthedeviceisnotpluggedin.
2. Takethesteptothenextstateusingthefollowingcommand:
$adbshelldumpsysdeviceidlestep
Thiscanbeseeninthefollowingscreenshot:
3. Resetthebatterystatebacktoitsnormalconditionusingthefollowingcommand:
$adbshelldumpsysbatteryreset
Youcanalsolisttheavailablecommandsusingthefollowingcommand:
$adbshelldumpsysdeviceidle-h
Thisprintsmoreinformationaboutthedeviceidleusage,asshowninthefollowingscreenshot:
TheAppStandbymodeAppStandbyisaspecialmodethatappswillbeinwhenasystemdeterminesthatanappisidle.Anappisconsideredidleafteraperiodoftimeunlesstheappexhibitsthefollowingfeatures:
Ithasaforegroundprocessatthattime(anactivityorservice)ItdisplaysnotificationsonthelockscreenorinthenotificationtrayItwasexplicitlylaunchedbytheuserItwasmarkedasexcludedfromoptimizationsviathesettingsapp
WhathappenstoappswhenintheAppStandbymode?Ifthedeviceisunplugged,syncsandjobsaredeferredandnetworkaccessisrestricted.
Ifthedeviceispluggedin,thesystemreleasestheapplockinthestandbystate,allowingthedevicetoresumeaccesstothenetworkand/orexecuteanypendingjobsandsyncs.
NoteWhenintheidlestateforalongperiodoftime,thesystemallowsidleappstoaccessthenetworkjustonceaday.
TestingappswiththeAppStandbymodeTestappsusingyourdevice(withAndroid6.0)andadbcommands:
1. Simulatetheappthat’sgoingintothestandbymode:
$adbshellambroadcast-aandroid.os.action.DISCHARGING
$adbshellamset-inactive<AppPackageName>true
2. Simulatebywakingyourapp:
$adbshellamset-inactive<AppPackageName>false
3. Seewhathappenswhenyourappawakens.Testrecoveringgracefullyfromstandbymode.Checkwhetheryourapp’snotificationsandbackgroundjobsfunctionasyouwouldanticipate.
Youcansetyourappasinactiveviathefollowingcommand:
$adbshellamset-inactive<AppPackageName>true
Youcanalsocheckthestatusofyourappviathefollowingcommand:
$adbshellamget-inactive<AppPackageName>
NoteThesampletestwasdoneonGooglePhotosbehavior;allrightsarereserved.
Theconsoleoutput,forexample,isasfollows:
~adbshellamset-inactivecom.google.android.apps.photosfalse
~adbshellamget-inactivecom.google.android.apps.photos
Idle=false
~adbshellamset-inactivecom.google.android.apps.photostrue
~adbshellamget-inactivecom.google.android.apps.photos
Idle=true
ExcludedappsandsettingsYoucanexcludeappsfromtheAppStandbymodeviathesettingsapps,asmentionedearlier.Theproceduretodothisisasfollows:
1. GotoSettings|Apps.
2. Clickonthecog/gearicontoopentheConfigureappsscreen.
3. ChooseBatteryoptimization.
4. ThefollowingscreenshotshowsalistoftheappsexcludedfromtheAppStandbymode—thatis,theonesthatarenotoptimized.Youcanopentheselectionforallappsandchoosetheexactbehavioryourequireforeachapplication.
TipsHereareafewpointsandtipsforyoutonoteandremember:
UseisIgnoringBatteryOptimizations()withaPowerManagerinstanceandcheckwhetheryourappisonthewhitelistNavigatetheuserdirectlytotheconfigurationscreenusingthefollowing:
startActivity(new
Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS));
Performthefollowingstepstodisplayasystemdialogaskingaboutaddingaspecificapptothewhitelist:
1. AddtheREQUEST_IGNORE_BATTERY_OPTIMIZATIONSpermissiontotheapplication’smanifest.
2. CreateaURIpackagepointingtoyourapplication.3. WraptheURIinanintentandcallstartActivity()withitasshowninthe
followingcode:
Intentintent=new
Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,
Uri.parse("package:"+getPackageName()));
startActivity(intent);
Notethatifourappisalreadywhitelisted,thedialogwon’tbedisplayedagain
RemovablestorageadoptionAndroidMarshmallowallowsuserstoadoptexternalstoragedevices,suchasSDcards.Suchadoptionswillformatandencryptthestoragedeviceandmountitasinternalstorage.Oncedone,userscanmoveappsandapps’privatedatabetweenstoragedevices.Theandroid:installLocationpreferenceinthemanifestwillthenbeusedbythesystemtodeterminetheavailablelocationsforeachapp.WhatyouneedtokeepinmindisthatusingContextmethodsfordirectoriesorfilesandApplicationInfofieldswillreturnvaluesthatcanchangebetweenruns.YoushouldalwayscalltheseAPIsdynamically.Don’tusehardcodedfilepathsorpersistfullyqualifiedfilepaths.
TheContextmethodsareasfollows:
getFilesDir()
getCacheDir()
getCodeCacheDir()
getDatabasePath()
getDir()
getNoBackupFilesDir()
getFileStreamPath()
getPackageCodePath()
getPackageResourcePath()
TheApplicationInfofieldsareasfollows:
dataDir
sourceDir
nativeLibraryDir
publicSourceDir
splitSourceDirs
splitPublicSourceDirs
YoucandebugthisfeatureandenabletheadoptionofaUSBdriveconnectedviaanOTG(shortforOnTheGo)cableusingthefollowingcommand:
$adbshellsmset-force-adoptabletrue
FormoreonUSB,headtohttps://developer.android.com/guide/topics/connectivity/usb/index.html.
ApacheHTTPclientremovalTheApacheHTTPclienthasbeendeprecatedforquitesometime—since2011orso.UsingthisclientonAndroid2.3andhigherwasnotrecommended;nowwithAndroid6.0Marshmallow,thisAPIhasbeenremoved.So,we’llusetheHttpURLConnectionclassinstead.
ThisAPIismoreefficient,reducesnetworkuse,andminimizespowerconsumption.
IfyouwishtocontinueusingtheApacheHTTPAPIs,youmustfirstdeclarethefollowingcompile-timedependenciesinyourbuild.gradlefile:
android{
useLibrary'org.apache.http.legacy'
}
NoteIfyouhavecompileerrorsintheAndroidstudio,youcanheadtothesequestionsandsolutionsonstackoverflow:
http://stackoverflow.com/q/30856785/529518http://stackoverflow.com/q/31653002/529518
NotificationsThereareafewchangestothenotificationsfeature,asfollows:
TheNotification.setLatestEventInfo()methodisnowremoved.Whenconstructingnotifications,wemustusetheNotification.Builderclass.UpdatinganotificationisalsodoneviatheNotification.Builderinstanceusingthesameinstanceofthebuilder,andcallingthebuild()methodwillgetusanupdatedNotificationinstance.Iflegacysupportisrequired,youcanuseNotificationCompat.Builderinstead,whichisavailableintheAndroidSupportLibrary.Theadbshelldumpsysnotificationcommandnolongerprintsoutnotificationtext.Theproperusagenowisadbshelldumpsysnotification--noredact.ThenewlyaddedINTERRUPTION_FILTER_ALARMSfilterlevelcorrespondstoanewmode:Alarmsonlydonotdisturb.ThenewlyaddedCATEGORY_REMINDERcategoryisusedforuser-scheduledreminders.ThenewlyaddedIconclassallowsiconstobeattachedtonotificationsviathesetSmallIcon()andsetLargeIcon()methods.TheupdatedaddAction()methodnowacceptsanIconobjectinsteadofadrawableresourceID.ThenewlyaddedgetActiveNotifications()methodallowsyoutofindoutwhichnotificationsarecurrentlyalive.Wecanobtainsomeknowledgeaboutwhattheuserisandisnotexpectingtoseeundernotificationswhenusingthefollowingmethods:
ThenewlyaddedgetCurrentInterruptionFilter()methodreturnsthecurrentnotificationinterruptionfilterinwhichnotificationsareallowedtointerrupttheuserThenewlyaddedgetNotificationPolicy()methodreturnsthecurrentnotificationpolicy
TextselectionPartofthematerialdesignguidespecificationsdiscusstextselectioninyourapplications.Usersselecttextwithinyourapp,andyounowhaveanAPItoincorporateafloatingtoolbardesignpatternthat’ssimilartoacontextualactionbar.Formoreinformationaboutthedesignspecifications,headtohttp://www.google.com/design/spec/patterns/selection.html#selection-item-selection.
Theimplementationstepsareasfollows:
1. ChangeyourActionModecallstostartActionMode(Callback,ActionMode.TYPE_FLOATING).
2. ExtendActionMode.Callback2.3. OverridetheonGetContentRect()methodandprovidecoordinatesforthecontent
Rectobjectintheview.4. CalltheinvalidateContentRect()methodwhenyouneedtoinvalidatetheRect
objectandit’spositionisnolongervalid.
SupportlibrarynoticeFloatingtoolbarsarenotbackward-compatible.AppcompattakescontroloverActionModeobjectsbydefault.Thiswillpreventfloatingtoolbarsfrombeingdisplayed.
Theimplementationstepsareasfollows:
1. CallgetDelegate()andsetHandleNativeActionModesEnabled()onthereturnedAppCompatDelegateobject.
2. Settheinputparametertofalse.
ThiscallwillreturncontrolofActionModeobjectstotheframework,allowing6.0devicestosupportActionBarorfloatingtoolbarmodesandallowingearlierversionstosupporttheActionBarmodes.
AndroidKeystorechangesFromAndroid6.0onward,theAndroidKeystoreprovidernolongersupportsDigitalSignatureAlgorithm(DSA).
Formoreinformationaboutkeystoreanditsusage,visithttps://developer.android.com/training/articles/keystore.html.
Wi-FiandnetworkingchangesAndroidMarshmallowhasintroducedafewchangestotheWi-FiandnetworkingAPIs.
ChangingthestateofWifiConfigurationobjectsisonlypossibleforself-createdobjects.YouarerestrictedfrommodifyingordeletingWifiConfigurationobjectscreatedbytheuserorotherapps.
Inearlierversions,forcingthedevicetoconnecttoaspecificWi-FinetworkusingenableNetwork()andsettingupdisableAllOthers=truecausedthedevicetodisconnectfromothernetworks.ThisdoesnothappeninAndroid6.0.WithtargetSdkVersion<=20,yourappispinnedtousetheselectedWi-Finetwork.WhentargetSdkVersion>=21,youneedtousetheMultiNetworkAPIsandensurethatnetworktrafficisassignedtothepropernetwork.FormoreinformationontheMultiNetworkAPI,refertohttps://developer.android.com/about/versions/android-5.0.html#Wireless.
RuntimeTheAndroidART(shortforAndroidruntime)runtimewasalsoupdatedinAndroidMarshmallow,andthefollowingaretheupdates:
ThenewInstance()method:TheDalvik(anotherruntime)issueforthecheckingofaccessrulesincorrectlywasfixed.Ifyouwishtooverrideaccesschecks,callthesetAccessible()methodwiththeinputparametersettotrue.Usingthev7Appcompatlibraryorthev7Recyclerviewlibrary?Youmustupdatetothelatestversion.MakesurethatanycustomclassesreferencedfromXMLareupdatedsothattheirclassconstructorsareaccessible.Behaviorofthedynamiclinkerisupdated.TheARTruntimeunderstandsthedifferencebetweenalibrary’ssonameanditspath;searchbysonameisnowimplemented.Therewasanopenbugwiththisissuethatwasfixed;ifyouwishtoextendyourreading,visithere:
https://code.google.com/p/android/issues/detail?id=6670
HardwareidentifierAndroid6.0hasintroducedamajorchangeforgreaterdataprotection;theWifiInfo.getMacAddress()andBluetoothAdapter.getAddress()methodsnowreturnaconstantvalueof02:00:00:00:00:00,whichmeansyoucan’trelyonthesemethodstogetinformation.
Now,whenyou’retryingtousesomeofthemethodsintheAPI,youneedtoaddpermissions:
WifiManager.getScanResults()andBluetoothLeScanner.startScan()needoneofthesetwopermissionsgranted:
TheACCESS_FINE_LOCATIONpermissionTheACCESS_COARSE_LOCATIONpermission
BluetoothDevice.ACTION_FOUND:ThismusthavetheACCESS_COARSE_LOCATIONpermission
NoteWhenadevicerunningAndroid6.0(Marshmallow)initiatesabackgroundWi-FiorBluetoothscan,externaldevicesseetheoriginasarandomizedMACaddress.
APKvalidationTheplatformnowperformsstrictvalidationofAndroidPackageKits(APKs).
IfafiledeclaredinthemanifestisnotpresentintheAPKitself,thentheAPKisconsideredcorrupted.RemovingcontentsfromtheAPKrequiresre-signingoftheAPK.
USBconnectionBydefault,theUSBconnectionischarge-only.UsersmustnowgrantpermissionstointeractviatheUSBport.Yourapplicationsshouldtakethisintoaccountandbeawarethatpermissionsmightnotbegranted.
DirectShareOneofthebestthingsabouttechnology,inmyhumbleopinion,isthatitgivesusersgreatoptionstointeractandbenefitfromthem.DirectSharecanbetreatedasagreatadditiontothelistofmerits,withgreat,fluiduserexperienceallaroundtheappworld.So,whatisDirectShare?Well,almosteveryapptodayusessomesortofinformation/dataexchangewithotherapplicationsontheuser’sdeviceorwiththeoutsideworldviathesharingmechanism.Thesharingmechanismexposesapieceofinformationfromoneapplicationtoanother.Usually,auserwillinteractwithafewclosecompanions(family,closefriends,orcolleagues),andthisiswhereDirectSharecomestoyouraid.
DirectShareisaboutasetofAPIsrequiredtomakesharingintuitiveandquickforusers.YoudefineDirectSharetargetsthatlaunchaspecificactivityinyourapp.ThesetargetsareshownintheSharemenu,allowingfastersharingandfluiddataflow.
WithDirectShare,userscansharecontenttotargets—say,contactsinotherapps.
Theimplementationstepsareasfollows:
1. DefineaclassthatextendstheChooserTargetServiceclass.2. Declareyourserviceinthemanifest.3. SpecifytheBIND_CHOOSER_TARGET_SERVICEpermissionandanintentfilter
SERVICE_INTERFACEaction.
Anexampleservicedeclarationisasfollows:
<serviceandroid:name=".MyChooserTargetService"
android:label="@string/McTs_name"android:permission=
"android.permission.BIND_CHOOSER_TARGET_SERVICE">
<intent-filter>
<actionandroid:name="android.service.chooser.ChooserTargetService"/>
</intent-filter>
</service>
Now,wehaveaservicedeclaredand,foreachtargetwewanttoexpose,weadda<meta-data>elementwiththeandroid.service.chooser.chooser_target_servicenameinyourappmanifest:
<activityandroid:name=".SampleDirectShareTarget"
android:label="@string/SampleDirectShareTarget_name">
<intent-filter>
<actionandroid:name="android.intent.action.SEND"/>
</intent-filter>
<meta-dataandroid:name="android.service.chooser.chooser_target_service"
android:value=".ChooserTargetService"/>
</activity>
Let’stakealookatthecodeinourservice:
publicclassMyChooserTargetServiceextendsChooserTargetService{
privateStringmDirectShareTargetName;
privatefinalintMAX_SHARE_TARGETS=5;
@Override
publicvoidonCreate(){
super.onCreate();
mDirectShareTargetName="SharingPersondemo#%d";
}
@Override
publicList<ChooserTarget>onGetChooserTargets(ComponentName
sendTarget,IntentFiltermatchedFilter){
ArrayList<ChooserTarget>result=new
ArrayList<ChooserTarget>();
for(inti=1;i<=MAX_SHARE_TARGETS;i++){
result.add(buildTarget(i));
}
return(result);
}
privateChooserTargetbuildTarget(inttargetId){
Stringtitle=String.format(mDirectShareTargetName,targetId);
Iconicon=Icon.createWithResource(this,
R.drawable.share_target_picture);
floattarget_value=((float)(25-targetId)/25);
ComponentNamecomponentName=new
ComponentName(MyChooserTargetService.this,TargetActivity.class);
Bundlebundle=newBundle();
bundle.putInt("simple_key",targetId);
return(newChooserTarget(title,icon,target_value,componentName,
bundle));
}
}
Youcanheadtothegistifyouwishtobetterviewthecode;youcanvisithttps://gist.github.com/MaTriXy/adeacdf5496bcdae5f42.
YouhavetoimplementtheonGetChooserTargets()methodasitwillbecalledwhendirect-shareistriggered.YoureturnalistofChooserTargetobjectsthatrepresentsharingentrypointstoyourapplication.TheonGetChooserTargets()resultsareincludedalongwiththeregularACTION_SENDactivityitself.So,weonlywantChooserTargetobjectsthatimprovetheflowandnotduplicates.
WhencreatingseveralChooserTargetobjects,eachofthemwillprobablypointtothesameactivity.Youmustensurethattheextrasbundlewillcontaindistinguishinginformationsothateachrequestwillbeunique.DonotputcustomParcelableobjectsinthisbundleasitwillcausecrashes.YoucanfindoutmoreaboutChooserTargetathttps://developer.android.com/reference/android/service/chooser/ChooserTarget.html#ChooserTarget
Whatifwehavenothingtoshare?Sometimes,youwon’thaveanydirect-sharetargetsforaparticularrequest;then,returninganemptylistwouldbegreat.Youcanalsodisabletheserviceviaandroid:enabled="false"ifyouknowthatnoresultswillbeavailableuntilfutureusageoftheapp.AnotheroptionistoenabletheservicejustforAndroid6.0.ThiscaneasilybedoneusingBooleanresources:
Let’saddaBooleanresourcenamedis_share_targets_on:
Thedefaultvalueisres/values/bools.xml;setittofalseAndroid6.0isAPI23,soinres/values-v23/bools.xml,setittotrue
Addandroid:enabled="@bool/is_share_targets_on"toyourservicedeclaration
DirectSharebestpracticesThefollowingarefewofthebestpracticesfollowedinDirectShare:
Android6.0limitsthenumberofsharetargets,onlyshowingeightofthem.Providingmorethaneightsharetargetswillshowthebesteightaccordingtothescore.TheFAILEDBINDERTRANSACTIONexceptioncanpopinforavisitifyourlistoftargetsexceeds1MB.Trytolimit/caphowmanysharetargetsyoutrytoreturnfromyourChooserTargetServiceclass.Makesureyourapp’siconisshownproperlyasitwillbeappliedasabadgeovertheiconsthatyouuseforDirectSharetargets.
VoiceinteractionsVoiceinteractionsusuallyoriginatefromuservoiceaction.However,thevoiceinteractionactivitystartswithoutanyuserinput.AndroidMarshmallowhasanewvoiceinteractionAPIthat,togetherwithvoiceactions,allowsustobuildconversationalvoiceexperiencesintoourapps.UsetheisVoiceInteraction()methodtodeterminewhetheranactivityistriggeredbyavoiceaction.Then,youcanusetheVoiceInteractorclassandinteractwiththeuser.
Don’tgetconfusedwiththeisVoiceInteractionRoot()method,whichreturnstrueonlyiftheactivityisalsotherootofavoiceinteraction.Here,youwillgettrueifyouractivitywasstarteddirectlybythevoiceinteractionserviceandnotbyanotheractivity(anotherapp)whileundergoingvoiceinteraction.
Abestpracticewouldbetoprompttheusersandconfirmthatthisistheirintendedaction.YoualreadyknowthatvoiceinputisinvokedfromGoogleNow,whereyoucanopenURLswithasimplevoiceinput,suchasopenandroid.com.Now,youcaninventnewvoiceactionsandregisterthemwithGoogle,drivingtrafficdirectlyandspecificallytoyourapp.
Tolearnmoreaboutimplementingvoiceactions,headtohttps://developers.google.com/voice-actions/interaction/.
TheAssistAPIBackinGoogleI/O2015,wesawtheNowonTapfeature,whereGoogleNowcouldpeekintoarunningappandprovidecontextualassistance.TheAssistAPIoffersanewwayforuserstoengagethroughanassistant.Theassistantmustbeenabledpriortousingit,allowingittobeawareofthecurrentcontext.Triggeringtheassistantisdonebylong-pressingtheHomebutton,nomatterwhichappisactive.
YoucanoptoutofthisbysettingtheWindowManager.LayoutParams.FLAG_SECUREflag.
OptinginrequiresyoutousethenewAssistContentclass.
Inorderforustobeabletofeedadditionalcontextfromourapptotheassistant,weneedtofollowthesesteps:
1. ImplementtheApplication.OnProvideAssistDataListenerinterface,whichiscalledwhentheuserrequestsassistance.
2. RegisteritusingApplication.registerOnProvideAssistDataListener().3. OverridetheonProvideAssistData()callback,whichiscalledwhentheuser
requestsassistance.ItisusedtobuildanACTION_ASSISTintentwithallofthecontextofthecurrentapp.
4. OverridetheonProvideAssistContent()callback;thisisoptional.Itiscalledwhentheuserrequestsassistance,allowingustoprovidereferencestocontentrelatedtothecurrentactivity.
5. Whendone,unregisteryourselfusingApplication.unregisterOnProvideAssistDataListener().
BluetoothAPIChangesBesidesthechangesmentionedpreviously,AndroidMarshmallow6.0hasintroducedafewmorechangestotheBluetoothAPI.
BluetoothstylussupportStylushasbeenhereaforawhile;Bluetoothstylusdidn’thavefullsupportforspecificationsinversionsbeforeAndroidMarshmallow.YoucanpairandconnectacompatibleBluetoothstyluswitheitheraphoneoratablet.Becauseyouarenotboundjusttotouchesonscreen,youcanfusetheposition,pressure,andbuttonstatedata,allowingmorepreciseuserinputandexperience.Yourappcanaddalistenertothestylusbuttonsandactaccordingly.JustusetheView.OnContextClickListenerandGestureDetector.OnContextClickListenerobjectsinyouractivity.
Inordertodetectstylusbuttoninteractionsandmovement,youneedthefollowing:
TheMotionEventmethodsThegetTooltype()method,whichreturnsTOOL_TYPE_STYLUSifastyluswithabuttonistouchedonthescreenThegetButtonState()method,whichreturns(onAndroid6.0-targetedapps)thefollowing:
BUTTON_STYLUS_PRIMARY:PresstheprimarystylusbuttonBUTTON_STYLUS_SECONDARY:PressthesecondarybuttonBUTTON_STYLUS_PRIMARY|BUTTON_STYLUS_SECONDARY:Pressboththebuttons
TargetedappswithalowerAPIlevelthanAndroid6.0willresultinthefollowing:
BUTTON_SECONDARY:PresstheprimarystylusbuttonBUTTON_TERTIARY:PressthesecondarybuttonBUTTON_SECONDARY|BUTTON_TERTIARY:Pressboththebuttons
ImprovedBluetoothlowenergyscanningUsedtoBluetoothlowenergyinyourapp?Well,nowthescanningprocessiseasierandimproved.UsethenewsetCallbackType()methodandspecifythatyouwantacallbackwhenthesystemfinds/seesanadvertisementpacketmatchingtheScanFilterclass.Yougetmorepower-efficiencythaninpreviousAndroidversions.
SummaryWewentoverafewofthechangesinAndroidMarshmallow.Allofthesechangesareimportanttofollowandwillhelpyouinyourappdevelopmentcycles.Thereareafewmorechangestobediscussedinfuturechaptersinamoredetailedmanner.Ournextchaptertalksaboutaudio,video,andcamerafeaturesandthechangesmadeinAndroid6.0.6.
Chapter5.Audio,Video,andCameraFeaturesAndroidMarshmallowgivesusgoodaudio,video,andcameracapabilities,andyoucanseethatimprovementshavebeenmadetoenableandbettersupportnewormintconditionprotocolsorevenchangethebehaviorofsomeAPIs,suchasthecameraservice.
Inthischapter,wewilltryandexplainthesechangeswithaproperdiscussionontheirusageandbenefits.Ourjourneyintheupcomingpageswillcoverthefollowingtopics:
AudiofeaturesVideofeaturesCamerafeatures
AudiofeaturesAndroidMarshmallow6.0addssomeenrichmentstotheaudiofeaturesthatwewillcoverintheupcomingsections.
SupportfortheMIDIprotocolTheandroid.media.midipackagewasaddedinAndroid6.0(API23).
WiththenewmidiAPIs,youcannowsendandreceiveMIDI(shortforMusicalInstrumentDigitalInterface)eventsinamuchsimplerwaythanearlier.
Thepackagewasbuilttoprovideuswithcapabilitiestodothefollowing:
ConnectanduseaMIDIkeyboardConnecttootherMIDIcontrollersUseexternalMIDIsynthesizers,externalperipherals,lights,showcontrol,andsoonAllowdynamicmusicgenerationfromgamesormusic-creationappsAllowthecreationandpassingofMIDImessagesbetweenappsAllowAndroiddevicestoactasmulti-touchcontrollerswhenconnectedtoalaptop
WhendealingwithMIDI,youmustdeclareitinthemanifest,asfollows:
<uses-featureandroid:name="android.software.midi"
android:required="true"/>
Payattentiontotherequiredpart;inamannersimilartootherfeatures,settingittotruewillmakeyourappvisibleintheplaystoreonlyifthedevicesupportstheMIDIAPI.
YoucanalsocheckinruntimeforMIDIsupportandthenchangetherequiredparttofalse:
PackageManagerpkgMgr=context.getPackageManager();
if(pkgMgr.hasSystemFeature(PackageManager.FEATURE_MIDI)){
//wecanuseMIDIAPIhereasweknowthedevicesupportstheMIDIAPI.
}
MidiManagerAwaytoproperlyusetheMIDIAPIisviatheMidiManagerclass;obtainitviacontextanduseitwhenrequired:
MidiManagermidiMgr=
(MidiManager)context.getSystemService(Context.MIDI_SERVICE);
Formoreinformation,youcanreferto:
https://developer.android.com/reference/android/media/midi/package-summary.html
DigitalaudiocaptureandplaybackTwonewclasseshavebeenaddedfordigitalaudiocaptureandplayback:
android.media.AudioRecord.Builder-digitalaudiocaptureandroid.media.AudioTrack.Builder-digitalaudioplayback
Thesewillhelpconfiguretheaudiosourceandsinkproperties.
AudioandinputdevicesThenewhasMicrophone()methodhasbeenaddedtotheInputDeviceclass.Thiswillreportwhetherthedevicehasabuilt-inmicrophonethatdeveloperscanuse.Let’ssayyouwanttoenablevoicesearchfromacontrollerconnectedtoAndroidTVandyougetanonSearchRequested()callbackfortheuser’ssearch.Youcanthenverifythatthere’samicrophonewiththeinputDeviceobjectyougetinthecallback.
InformationonaudiodevicesThenewAudioManager.getDevices(intflags)methodallowseasyretrievalofalltheaudiodevicescurrentlyconnectedtothesystem.Ifyouwanttobenotifiedwhenthereareaudiodeviceconnections/disconnections,youcanregisteryourapptoanAudioDeviceCallbackcallbackviatheAudioManager.registerAudioDeviceCallback(AudioDeviceCallbackcallback,
Handlerhandler)method.
ChangesinAudioManagerSomechangeshavebeenintroducedintheAudioManagerclass,andtheyareasfollows:
UsingAudioManagertosetthevolumedirectlyisnotsupported.UsingAudioManagertomutespecificstreamsisnotsupported.TheAudioManager.setStreamSolo(intstreamType,booleanstate)methodisdeprecated.Ifyouneedexclusiveaudioplayback,useAudioManager.requestAudioFocus(AudioManager.OnAudioFocusChangeListener
l,intstreamType,intdurationHint).TheAudioManager.setStreamMute(intstreamType,booleanstate)methodisdeprecated.IfyouneedtouseAudioManager.adjustStreamVolume(intstreamType,intdirection,intflags)fordirection,youcanuseoneofthenewlyaddedconstants.ADJUST_MUTEwillmutethevolume.Notethatithasnoeffectifthestreamisalreadymuted.ADJUST_UNMUTEwillunmutethevolume.Notethatithasnoeffectifthestreamisnotmuted.
VideofeaturesInAndroidMarshmallow,thevideoprocessingAPIhasbeenupgradedwithnewcapabilities.Somenewmethodsandevenanewclasshasbeenaddedjustfordevelopers.
android.media.MediaSyncTheallnewMediaSyncclasshasbeendesignedtohelpuswithsynchronousaudioandvideostreams’rendering.Youcanalsouseittoplayaudio-orvideo-onlystreams.Youcanusethedynamicplaybackrateandfeedthebuffersinanonblockingactionwithacallbackreturn.Formoreinformationontheproperusage,read:
https://developer.android.com/reference/android/media/MediaSync.html
MediaCodecInfo.CodecCapabilities.getMaxSupportedInstancesNow,wehaveaMediaCodecInfo.CodecCapabilities.getMaxSupportedInstanceshelpermethodtogetthemaximumnumberofsupportedconcurrentcodecinstances.However,wemustconsiderthisonlyanupperbound.Theactualnumberofconcurrentinstancescanbelowerdependingonthedeviceandtheamountofavailableresourcesatthetimeofusage.
Whydoweneedtoknowthis?Let’sthinkofacasewherewehaveamedia-playingapplicationandwewanttoaddeffectsbetweenthemoviesplayed.Wewillneedtousemorethanonevideocodec,decodetwovideos,andencodeonevideostreambacktobedisplayedonscreen.CheckingwiththisAPIwillallowyoutoaddmorefeaturesthatrelyuponmultipleinstancesofcodecs.
MediaPlayer.setPlaybackParamsWecannowsetthemediaplaybackrateforfastorslowmotionplayback.Thiswillgiveusthechancetocreateafunnyvideoappwhereweslowdownpartsorplaythemfast,creatinganewvideowhileplaying.Audioplayingissyncedaccordingly,soyoumighthearapersontalkingslowlyorevenfast,forthatmatter.
CamerafeaturesInAndroidLollipop,therewasthenewCamera2API,andnow,inAndroidMarshmallow,thereareafewmoreupdatestothecamera,flashlight,andimagereprocessingfeatures.
TheflashlightAPIAlmosteverydevicetodayhasacamera,andalmosteverycameradevicehasaflashunit.ThesetTorchMode()methodhasbeenaddedtocontroltheflashtorchmode.
ThesetTorchMode()methodisusedinthefollowingmanner:
CameraManager.setTorchMode(StringcameraId,booleanenabled)
ThecameraIdelementistheuniqueIDfortheflashunitcamerawithwhichyouwanttochangethetorchmode.YoucanusegetCameraIdList()togetthelistofcamerasandthenusegetCameraCharacteristics(StringcameraId)tocheckwhetherflashissupportedinthatcamera.ThesetTorchMode()methodallowsyoutoturnitonoroffwithoutopeningthecameradeviceandwithoutrequestingpermissionfromthecamera.Thetorchmodewillbeswitchedoffassoonasthecameradevicebecomesunavailableorwhenothercameraresourcesthathavethetorchonbecomeunavailable.Otherappscanusetheflashunitaswell,soyouneedtocheckthemodewhenrequiredorregisteracallbackviatheregisterTorchCallback()method.
Refertothesampleapp,Torchi,toseetheentirecodeat:
https://github.com/MaTriXy/Torchi
NoteTurningonthetorchmodemayfailifthecameraorothercameraresourcesareinuse.
ThereprocessingAPIAsmentionedearlier,theCamera2APIwasgivenafewbooststoallowaddedsupportforYUVandprivateopaqueformatimagereprocessing.BeforeusingthisAPI,weneedtocheckwhetherthesecapabilitiesareavailable.ThisiswhyweusethegetCameraCharacteristics(StringcameraId)methodandcheckfortheREPROCESS_MAX_CAPTURE_STALLkey.
android.media.ImageWriterThisisanewclassthat’sbeenaddedtoAndroid6.0.
ItallowsustocreateanimageandfeeditintoasurfaceandthenbacktoCameraDevice.Usually,ImageWriterisusedalongwithImageReader.
android.media.ImageReaderThisisanewclassthat’sbeenaddedtoAndroid6.0.
Itallowsusdirectaccesstotheimagedatarenderedinasurface.ImageReader,alongwithImageWriter,allowsourapptocreateanimagefeedfromthecameratothesurfaceandbacktothecameraforreprocessing.
ChangesinthecameraserviceAndroidMarshmallowhasmadeachangetothefirstcome,firstserveaccessmodel;now,theserviceaccessmodelhasfavoritesprocesses—onesthataremarkedashigh-priority.Thischangeresultsinsomemorelogic-relatedworkforusdevelopers.Weneedtomakesurethatwetakeintoaccountasituationwherewegetbumpedup(higherpriority)ordebunked(lowerpriorityduetoachangeinourapplication).
Let’stryandexplainthisinafewsimplebullets:
Whenyouwanttoaccesscameraresourcesoropenandconfigureacameradevice,youraccessisverifiedaccordingtothepriorityofyourapplicationprocess.Anapplicationprocesswithforegroundactivities(visibleuser)isnormallygivenahigherpriority,whichinturnallowsabetterchancetogetthedesiredaccesswhenneeded.Ontheothersideofthepriorityscale,youcanfindlow-priorityappsthatcanandwillbetossedaside(revokedfromaccess)whenahigh-priorityapplicationattemptstousethecamera.Forexample,whenusingtheCameraAPI,youwillgettheonError()callwhenevicted,andwhenusingtheCamera2API,youwillgettheonDisconnected()callwhenevicted.Somedevicesoutinthewildcanallowseparateapplicationstoopenanduseseparatecameradevicessimultaneously.Thecameraservicenowdetectsanddisallowsperformanceissuesthatarecausedduetomultiprocessusage.Whentheservicedetectssuchanissue,itwillevictlow-priorityappsevenifonlyoneappisusingthatcameradevice.Inamultiuserenvironment,whenswitchingusers,allactiveappsusingthecameraintheprevioususerprofilewillbeevictedinordertoallowproperusageandaccesstoappsforthecurrentuser.Thismeansthatswitchinguserswillstopthecamera-usingappsfromusingthecameraforsure.
SummaryInthischapter,wecoveredquiteafewchangesinandadditionstotheAndroidAPIs.AndroidMarshmallowismoreabouthelpingus,thedevelopers,achievebettermediasupportandshowcaseourideaswhenusingtheaudio,video,orcameraAPIs.
Inthenextchapter,wewillgooversomeoftheAndroidfeaturestounderstandthefeatures,additions,andchangesmade.
Chapter6.AndroidforWorkMostofyouknowthatAndroiddeviceshaveahugemarketsharepercentageworldwide,andmoreandmorebusinessesarefollowingtheBYOD(shortforBringYourOwnDevice)policy.ThisisdonewiththehelpofAndroidforWork,aspecialprogramforcompanieswhereseveraladdedfeaturesintheAndroidplatformallowbettermobiledevicemanagement,administration,andintegrationwithinthecompany.
Whendealingwithenterprisesorevensmall-sizedandmedium-sizedbusinesses,youneedtofollowspecificguidelinesandharnesstheAndroidAPItoyourbenefit.YoucanreadmoreaboutAndroidforWorkat:
http://developer.android.com/training/enterprise/index.html
AndroidMarshmallowhasmadeafewchangestotheAndroidforWorkprogram,wherealotofthechangesweremadeforbetterandeasierusagefordevelopersaswellasworkusers.
Inthischapter,wewillcovertheAndroidMarshmallowchangesthatreflectorarerelateddirectlytoAndroidforWork:
BehavioralchangesSingle-usedeviceimprovementsSilentlyinstalling/uninstallingappsImprovedcertificateaccessAutomaticsystemupdatesThird-partycertificateinstallationDatausagestatisticsManagingruntimepermissionsVPNaccessanddisplayWorkprofilestatus
BehavioralchangesAndroidMarshmallowhasintroducedafewbehavioralchangesrelatedtoAndroidforWork.
TheworkprofilecontactsdisplayoptionUsingthefollowingsetting,youcannowdisplayyourworkprofilecontactsinthedialercalllog:
DevicePolicyManager.setCrossProfileCallerIdDisabled(ComponentNameadmin,
booleandisabled)
YoucanalsodisplaytheworkcontactsoverBluetoothwiththenewoption.Settingthistofalsewillallowthedisplay;thedefaultvalueistrue(disablingthecontact-sharingoption):
DevicePolicyManager.setBluetoothContactSharingDisabled(ComponentName
admin,booleandisabled)
Wi-FiconfigurationoptionsWhenaddingaWi-Finetworkviaaworkprofile,usually,addedconfigurationsstaypersistentevenaftertheprofileisdeleted.Now,allconfigurationsaddedbyaprofileownerareremovediftheworkprofileisdeleted.
TheWi-FiconfigurationlockAnewSettings.Globalsettinghasbeenadded:
WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN
Thissettingisanintegervaluesetting,whichmeansthatazerovalueorabsencewillleadtoallWi-Ficonfigurationsbeingmodifiedordeletedbytheuser.Settingtheintegervaluetoanonzerovaluewillinitiatethelock,whichmeansthattheusercan’tmodifyordeleteWi-Ficonfigurationscreatedbyadeviceowner—user-createdconfigurationswillstillbemodifiable.NotethatanactivedeviceownerhascompleteprivilegesinanyWi-Ficonfigurations,eventhosenotcreatedbythem.
WorkPolicyControlleradditionYoucancontinuetoaddGoogleaccountstothedevice,butnow,whenaddinganaccountthatismanagedbyWorkPolicyController,theflowischangedtoincludetheWorkPolicyControlleraddition.AnaddedaccountpromptstheusertoinstalltheappropriateWorkPolicyController.Thisisalsotruewhenaddinganaccountthroughsettingsorviathestartupdevice’ssetupwizard.FormoreinformationonhowtobuildaWorkPolicyController,read:
http://developer.android.com/training/enterprise/work-policy-ctrl.html
DevicePolicyManagerchangesInDevicePolicyManager,youmayencounterquiteafewchangesinbehavior;thesearelistedinthefollowingbulletswithashortexplanation:
setCameraDisabled()affectsthecamerajustforthecallinguser;iftheprofileisamanagedprofile,thenthecalldoesn’taffectthecameraappsrunningontheprimaryuser.setKeyguardDisabledFeatures()wasmadeavailableforprofileownersanddeviceowners.Profileownerscansetkeyguardrestrictionsviathefollowing:
KEYGUARD_DISABLE_TRUST_AGENTS:Thiswillignorethetrustagentstateonthekeyguardonsecurescreens(thePINcode,pattern,orthepasswordscreen)KEYGUARD_DISABLE_FINGERPRINT:Thiswilldisablethefingerprintsensoronthekeyguardonsecurescreens(PINcode,pattern,orthepasswordscreen)KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS:Thiswillallowonlyredactednotificationsonsecurekeyguardscreensandonlynotificationsgeneratedbyapplicationsinthemanagedprofile
createAndInitializeUser()isdeprecatednow.createUser()isdeprecatednow.UsingthesetScreenCaptureDisabled()method,theAssistfeatureisblocked,butthishappensonlywhenanappofthegivenuserisintheforeground.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUMisSHA-256now.LegacysupportforSHA-1stillexists,butitwillberemovedinfutureversionsaccordingtothedocumentation.EXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUMisSHA-256onlynow.EXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERSwasremovedsothatNFCbumpprovisioningwouldnotunlockafactory-reset-protecteddevice.PassingdatatothedeviceownerduringNFCprovisioningcanbedonewithEXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE.NewDevicePolicyManagerAPIforpermissionsunderAndroidMarshmallow’snewpermissionmodel.YoucanreadmoreaboutDevicePolicyManagerathttps://developer.android.com/reference/android/app/admin/DevicePolicyManager.htmlRESULT_CANCELEDisnowreturnedifuserscancelthesetupflowinitiatedthroughanACTION_PROVISION_MANAGED_PROFILEorACTION_PROVISION_MANAGED_DEVICEintent.ChangestoSettings.Global.DisabledthefollowingsetofsettingsviasetGlobalSettings():
BLUETOOTH_ON
DEVELOPMENT_SETTINGS_ENABLED
MODE_RINGER
NETWORK_PREFERENCE
WIFI_ON
EnabledtheWIFI_DEVICE_OWNER_CONFIGS_LOCKDOWNsettingvia
setGlobalSettings().
Single-usedeviceimprovementsYouasthedeviceownercannowcontroladdedsettings,thusimprovingdevicemanagementusingthefollowing:
setKeyguardDisabled()canbeusedtodisableorre-enablethekeyguardsetStatusBarDisabled()canbeusedtodisableorre-enablethestatusbarUserManager.DISALLOW_SAFE_BOOTisanewconstantthatstateswhethertheusercanbootadevicetosafebootSettings.Global.STAY_ON_WHILE_PLUGGED_INwillpreventthescreenfromturningoffwhilepluggedintopower
Silentlyinstalling/uninstallingappsNow,youcansilentlyinstallanduninstallapplicationsusingPackageInstallerAPIs.Thismeansinstallingappswithoutuserinteractionorevenremovingappsaspartofthecompanypolicy.ThisfeatureenablesyoutousedeviceswithoutactuallyactivatingaGoogleaccount.GooglePlayforWorkisnotrequired,allowingyoutousedevicesaskiosks,showcasingspecificappsnotreleasedyet,andsoon.
ImprovedcertificateaccessAllowinguserstograntmanagedapps’accesstocertificateswithoutuserinteractionwasnotpossiblepriortoAndroidMarshmallow,sonow,anewcallbackhasbeenadded:
DeviceAdminReceiver.onChoosePrivateKeyAlias(Contextcontext,Intent
intent,intuid,Uriuri,Stringalias)
Thiscallbackwillallowthedeviceownertoprovidethealiassilentlytotherequestingapplication.
AutomaticsystemupdatesThefollowingoptionhasbeenaddedinAndroid6.0anditsmainpurposeistoallowdeviceownerstoauto-acceptasystemupdate:
DevicePolicyManager.setSystemUpdatePolicy(ComponentNameadmin,
SystemUpdatePolicypolicy)
SystemUpdatePolicyhasbeenaddedaswell,andyoucanchoosefromthreeoptions:
TYPE_INSTALL_AUTOMATIC:updateassoonasyougetanupdateTYPE_INSTALL_WINDOWED:updateshouldbedonewithinatimedsystemmaintenanceandonlythen,justfor30daysandthenreturntonormalbehaviorTYPE_POSTPONE:postponeupdatesforupto30daysandthenreturntonormalbehaviorafterwards
Thiscancomeinhandyifyouhavedevicessuchasshowcasetabletsorkioskmodedevices,wheretheupdateshouldnotmesswiththedevices’work.
Third-partycertificateinstallationThird-partyappsnowhavetheabilitytocallDevicePolicyManagerAPIs:
getInstalledCaCerts()
hasCaCertInstalled()
installCaCert()
uninstallCaCert()
uninstallAllUserCaCerts()
installKeyPair()
TheseAPIcallscanonlybedoneifthepermissionhasbeengrantedbythedeviceownerorprofileowner.
DatausagestatisticsAnewclasshasbeenaddedinAndroid6.0:NetworkStatsManager.ThishelpsyouqueryfordatausagestatisticsthatcanbeseeninSettings|Datausage.
Accessforprofileownersisautomaticallygrantedinorderforthemtoquerydataontheirprofile.Deviceownersgetaccesstothedatausageofthemanagedprimaryuser.
NoteTheandroid.app.usage.NetworkUsageStatsclasshasbeenrenamedtoNetworkStats.
ManagingruntimepermissionsAndroidMarshmallowintroducedtheruntimepermissionsmodel,andAndroidforWorkhadtodealwithmanagingpoliciesfordevices.YouasdeviceownercannowsetapolicyforallruntimerequestsofallapplicationsusingsetPermissionPolicy().
Youcanchoosetopromptuserstograntpermissionsorautomaticallygrantordenythepermissionssilently.Theautomaticpolicymeansthattheusercannotmodifytheapp’spermissionsscreeninSettings.
VPNaccessanddisplayWhenheadingtoSettings|More|VPN,youcannowviewtheVPNapps.WhenusingVPN,thenotificationsshownarenowspecifictohowthatVPNisconfigured:
Theprofileowner:NotificationsareshownaccordingtotheVPNconfigurationandbasedontheprofile(personal,work,orboth)Thedeviceowner:NotificationsareshownwhentheVPNisconfiguredfortheentiredevice
WorkprofilestatusTwonewadditionswereintroducedfortheuserstoknowthattheyareunderadifferentprofile:
Whenusinganappfromaworkprofile,thestatusbarwilldisplayabriefcaseiconWhenunlockingadevicestraightfromaworkprofileapp,apopupisdisplayed,alertingtheuserthatthisapprunsontheworkprofile
SummaryAswesawinthischapter,AndroidMarshmallowhasbroughtinquiteafewchangestotheAndroidforWorkworld.Asdevelopers,weneedtoalwaysmaintainaviableconnectiontotheneedsofanorganization.WeneedtomakesurewegooverandunderstandtheAndroidforWorkworld;thechangesinMarshmallowhelpusbuildandtargetenterpriseworkflowswiththebenefitofasimplerAPI.
Inthenextchapter,wewilllearnabouttheChromecustomtabsAPI’susageandflow.
Chapter7.ChromeCustomTabsHaveyoueverwantedtoaddaWebViewtoyourapplication?Maybeyou’vewantedtoaddbrowsingforafewwebpagesandshowsomerelevantcontentfromwithinyourapplication?IknowIhadto.Onalmosteveryoccasion,IwasreluctanttousetheWebViewfeatureasthiswasoneoftheugliestpartsoftheapp.
YoucanclearlyseethattheWebViewfeatureisawebportionandtheUIwasaddedquiteafewAndroidversionsback,whichcausedmyOCDUI/UXsensegokaboom.OneofthenewestadditionsreleasedbyGooglewasChromecustomtabs.
Inthischapter,wewillexploreChromecustomtabsandtrytoexplainanddemonstratethebenefitsofusingitinsteadoftheplainoldWebView:
WhatisaChromecustomtab?WhentouseChromecustomtabsTheimplementationguide
WhatisaChromecustomtab?Well,mostofusknowtabsfromeverydayInternetbrowsing.Itdoesn’treallymatterwhichbrowseryouuse;allbrowserssupporttabsandmultipletabs’browsing.Thisallowsustohavemorethanonewebsiteopenatthesametimeandnavigatebetweentheopenedinstances.InAndroid,thingsaremuchthesame,butwhenusingWebView,youdon’thavetabs.
WhatisWebView?WebViewisthepartintheAndroidOSthat’sresponsibleforrenderingwebpagesinmostAndroidapps.IfyouseewebcontentinanAndroidapp,chancesareyou’relookingatWebView.ThemajorexceptionstothisrulearesomeoftheAndroidbrowsers,suchasChrome,Firefox,andsoon.
InAndroid4.3andlower,WebViewusescodebasedonApple’sWebkit.InAndroid4.4andhigher,WebViewisbasedontheChromiumproject,whichistheopensourcebaseofGoogleChrome.InAndroid5.0,WebViewwasdecoupledintoaseparateappthatallowedtimelyupdatesthroughGooglePlaywithoutrequiringfirmwareupdatestobeissued,andthesametechniquewasusedwithGooglePlayservices.
Now,let’stalkagainaboutasimplescenario:wewanttodisplaywebcontent(URL-related)inourapplication.Wehavetwooptions:eitherlaunchabrowserorbuildourownin-appbrowserusingWebView.Bothoptionshavetrade-offsordisadvantagesifwewritethemdown.Abrowserisanexternalapplicationandyoucan’treallychangeitsUI;whileusingit,youpushtheuserstootherappsandyoumaylosetheminthewild.Ontheotherhand,usingWebViewwillkeeptheuserstightlyinside.However,actuallydealingwithallpossibleactionsinWebViewisquiteanoverhead.
GoogleheardourrantandcametotherescuewithChromecustomtabs.Nowwehavebettercontroloverthewebcontentinourapplication,andwecanstitchwebcontentintoourappinacleaner,prettiermanner.
CustomizationoptionsChromecustomtabsallowseveralmodificationsandtweaks:
ThetoolbarcolorEnterandexitanimationsCustomactionsforthetoolbarandoverflowmenuPrestartedandprefetchedcontentforfasterloading
WhentouseChromecustomtabsEversinceWebViewcameout,applicationshavebeenusingitinmultipleways,embeddingcontent—localstaticcontentinsidetheAPKanddynamiccontentasloadingwebpagesthatwerenotdesignedformobiledevicesatthebeginning.Lateronwesawtheriseofthemobileweberacompletewithhybridapplications).
Chromecustomtabsareabitmorethanjustloadinglocalcontentormobile-compatiblewebcontent.Theyshouldbeusedwhenyouloadwebdataandwanttoallowsimpleimplementationandeasiercodemaintenanceand,furthermore,makethewebcontentpartofyourapplication—asifit’salwaystherewithinyourapp.
Amongthereasonswhyyoushouldusecustomtabsarethefollowing:
Easyimplementation:youusethesupportlibrarywhenrequiredorjustaddextrastoyourViewintent.It’sthatsimple.InappUImodifications,youcandothefollowing:
SetthetoolbarcolorAdd/changetheactionbuttonAddcustommenuitemstotheoverflowmenuSetandcreatecustomin/outanimationswhenenteringthetaborexitingtothepreviouslocation
Easiernavigationandnavigationlogic:youcangetacallbacknotifyingyouaboutanexternalnavigation,ifrequired.Youknowwhentheusernavigatestowebcontentandwheretheyshouldreturnwhendone.Chromecustomtabsallowaddedperformanceoptimizationsthatyoucanuse:
Youcankeeptheenginerunning,sotospeak,andactuallygivethecustomtabaheadstarttostartitselfanddosomewarmuppriortousingit.Thisisdonewithoutinterferingortakingawaypreciousapplicationresources.YoucanprovideaURLtoloadinadvanceinthebackgroundwhilewaitingforotheruserinteractions.Thisspeedsuptheuser-visiblepageloadingtimeandgivestheuserasenseofblazingfastapplicationwhereallthecontentisjustaclickaway.
Whileusingthecustomtab,theapplicationwon’tbeevictedastheapplicationlevelwillstillbeintheforegroundeventhoughthetabisontopofit.So,weremainatthetoplevelfortheentireusagetime(unlessaphonecallorsomeotheruserinteractionleadstoachange).UsingthesameChromecontainermeansthatusersarealreadysignedintositestheyconnectedtointhepast;specificpermissionsthatweregrantedpreviouslyapplyhereaswell;evenfilldata,autocomplete,andsyncworkhere.Chromecustomtabsallowusgivetheusersthelatestbrowserimplementationonpre-LollipopdeviceswhereWebViewisnotthelatestversion.
TheimplementationguideAsdiscussedearlier,wehaveacoupleoffeaturesintegratedintoChromecustomtabs.ThefirstcustomizestheUIandinteractionwiththecustomtabs.Thesecondallowspagestobeloadedfasterandkeepstheapplicationalive.
CanweuseChromecustomtabs?Beforewestartusingcustomtabs,wewanttomakesurethey’resupported.Chromecustomtabsexposeaservice,sothebestcheckforsupportistotryandbindtotheservice.Successmeansthatcustomtabsaresupportedandcanbeused.Youcancheckoutthisgist,whichshowsahelperhowtotocheckit,orchecktheprojectsourcecodelateronat:
https://gist.github.com/MaTriXy/5775cb0ff98216b2a99d
Aftercheckingandlearningthatsupportexists,wewillstartwiththeUIandinteractionpart.
CustomUIandtabinteractionHere,wewillusethewell-knownACTION_VIEWintentaction,andbyappendingextrastotheintentsenttoChrome,wewilltriggerchangesintheUI.RememberthattheACTION_VIEWintentiscompatiblewithallbrowsers,includingChrome.TherearesomephoneswithoutChromeoutthere,orthereareinstanceswherethedevice’sdefaultbrowserisn’tChrome.Inthesecases,theuserwillnavigatetothespecificbrowserapplication.
IntentisaconvenientwaytopassthatextradatawewantChrometoget.
Don’tuseanyoftheseflagswhencallingtotheChromecustomtabs:
FLAG_ACTIVITY_NEW_TASK
FLAG_ACTIVITY_NEW_DOCUMENT
BeforeusingtheAPI,weneedtoaddittoourgradlefile:
compile'com.android.support:customtabs:23.1.0'
Thiswillallowustousethecustomtabsupportlibraryinourapplication:
CustomTabsIntent.EXTRA_SESSION
Theprecedingcodeisanextrafromthecustomtabssupportlibrary;it’susedtomatchthesession.Itmustbeincludedintheintentwhenopeningacustomtab.Itcanbenullifthereisnoneedtomatchanyservice-sidesessionswiththeintent.
NoteWehaveasampleprojecttoshowtheoptionsfortheUIcalledChubbyTabbyathttps://github.com/MaTriXy/ChubbyTabby.
Wewillgoovertheimportantpartshereaswell.OurmaininteractioncomesfromaspecialbuilderfromthesupportlibrarycalledCustomTabsIntent.Builder;thisclasswillhelpusbuildtheintentweneedforthecustomtab:
CustomTabsIntent.BuilderintentBuilder=newCustomTabsIntent.Builder();
//initourBuilder
//SettingToolbarColor
intcolor=getResources().getColor(R.color.primary);
//weuseprimarycolorforourtoolbaraswell-youcandefineanycolor
youwantanduseit.
intentBuilder.setToolbarColor(color);
//EnablingTitleshowing
intentBuilder.setShowTitle(true);
//thiswillshowthetitleinthecustomtabalongtheurlshowingatthe
bottompartofthetabtoolbar.
//Thispartisaddingcustomactionstotheoverflowmenu
StringmenuItemTitle=getString(R.string.menu_title_share);
PendingIntentmenuItemPendingIntent=createPendingShareIntent();
intentBuilder.addMenuItem(menuItemTitle,menuItemPendingIntent);
StringmenuItemEmailTitle=getString(R.string.menu_title_email);
PendingIntentmenuItemPendingIntentTwo=createPendingEmailIntent();
intentBuilder.addMenuItem(menuItemEmailTitle,menuItemPendingIntentTwo);
//SettingcustomCloseIcon.
intentBuilder.setCloseButtonIcon(mCloseButtonBitmap);
//Addingcustomiconwithcustomactionfortheshareaction.
intentBuilder.setActionButton(mActionButtonBitmap,
getString(R.string.menu_title_share),createPendingShareIntent());
//Settingstartandexitanimationforthecustomtab.
intentBuilder.setStartAnimations(this,R.anim.slide_in_right,
R.anim.slide_out_left);
intentBuilder.setExitAnimations(this,android.R.anim.slide_in_left,
android.R.anim.slide_out_right);
CustomTabActivityHelper.openCustomTab(this,intentBuilder.build(),
Uri.parse(URL),newWebviewFallback(),useCustom);
Afewthingstonoticehereareasfollows:
Everymenuitemusesapendingintent;ifyoudon’tknowwhatapendingintentis,headto:
http://developer.android.com/reference/android/app/PendingIntent.html
Whenwesetcustomicons,suchasclosebuttonsoranactionbutton,forthatmatter,weusebitmapsandwemustdecodethebitmappriortopassingittothebuilderSettinganimationsiseasyandyoucanuseanimations’XMLfilesthatyoucreatedpreviously;justmakesurethatyoutesttheresultbeforereleasingtheapp
ThefollowingscreenshotisanexampleofaChromecustomtab:
ThecustomactionbuttonAsdevelopers,wehavefullcontrolovertheactionbuttonspresentedinourcustomtab.Formostusecases,wecanthinkofashareactionormaybeamorecommonoptionthatyouruserswillperform.TheactionbuttonisbasicallyabundlewithaniconoftheactionbuttonandapendingintentthatwillbecalledbyChromewhenyouruserhitstheactionbutton.Theiconshouldbe24dpinheightand24-48dpinwidthaccordingtospecifications.
//Addingcustomiconwithcustomactionfortheshareaction
intentBuilder.setActionButton(mActionButtonBitmap,
getString(R.string.menu_title_share),createPendingShareIntent());
ConfiguringacustommenuBydefault,Chromecustomtabsusuallyhaveathree-iconrowwithForward,PageInfo,andRefreshontopatalltimesandFindinpageandOpeninBrowser(OpeninChromecanappearaswell)atthefooterofthemenu.
We,developers,havetheabilitytoaddandcustomizeuptothreemenuitemsthatwill
appearbetweentheiconrowandfootitemsasshowninthefollowingscreenshot:
Themenuweseeisactuallyrepresentedbyanarrayofbundles,eachwithmenutextandapendingintentthatChromewillcallonourbehalfwhentheusertapstheitem:
//Thispartisaddingcustombuttonstotheoverflowmenu
StringmenuItemTitle=getString(R.string.menu_title_share);
PendingIntentmenuItemPendingIntent=createPendingShareIntent();
intentBuilder.addMenuItem(menuItemTitle,menuItemPendingIntent);
StringmenuItemEmailTitle=getString(R.string.menu_title_email);
PendingIntentmenuItemPendingIntentTwo=createPendingEmailIntent();
intentBuilder.addMenuItem(menuItemEmailTitle,menuItemPendingIntentTwo);
ConfiguringcustomenterandexitanimationsNothingiscompletewithoutafewanimationstotagalong.Thisisnodifferent,aswehavetwotransitionstomake:oneforthecustomtabtoenterandanotherforitsexit;wehavetheoptiontosetaspecificanimationforeachstartandexitanimation:
//Settingstartandexitanimationforthecustomtab.
intentBuilder.setStartAnimations(this,R.anim.slide_in_right,
R.anim.slide_out_left);
intentBuilder.setExitAnimations(this,android.R.anim.slide_in_left,
android.R.anim.slide_out_right);
Chromewarm-upNormally,afterwefinishsettinguptheintentwiththeintentbuilder,weshouldcallCustomTabsIntent.launchUrl(Activitycontext,Uriurl),whichisanonstaticmethodthatwilltriggeranewcustomtabactivitytoloadtheURLandshowitinthecustomtab.Thiscantakeupquitesometimeandimpacttheimpressionofsmoothnesstheappprovides.
Weallknowthatusersdemandanear-instantaneousexperience,soChromehasaservicethatwecanconnecttoandaskittowarmupthebrowseranditsnativecomponents.CallingthiswillaskChrometoperformthefollowing:
TheDNSpreresolutionoftheURL’smaindomainTheDNSpreresolutionofthemostlikelysubresourcesPreconnectiontothedestination,includingHTTPS/TLSnegotiation
TheprocesstowarmupChromeisasfollows:
1. Connecttotheservice.2. Attachanavigationcallbacktogetnotifieduponfinishingthepageload.3. Ontheservice,callwarmuptostartChromebehindthescenes.4. CreatenewSession;thissessionisusedforallrequeststotheAPI.5. TellChromewhichpagestheuserislikelytoloadwithmayLaunchUrl.6. LaunchtheintentwiththesessionIDgeneratedinstep4.
ConnectingtotheChromeserviceConnectingtotheChromeserviceinvolvesdealingwithAndroidInterfaceDefinitionLanguage(AIDL).
Ifyoudon’tknowaboutAIDL,read:
http://developer.android.com/guide/components/aidl.html
TheinterfaceiscreatedwithAIDL,anditautomaticallycreatesaproxyserviceclassforus:
CustomTabsClient.bindCustomTabsService()
So,wecheckfortheChromepackagename;inoursampleproject,wehaveaspecialmethodtocheckwhetherChromeispresentinallvariations.Afterwesetthepackage,webindtotheserviceandgetaCustomTabsClientobjectthatwecanuseuntilwe’redisconnectedfromtheservice:
pkgName-Thisisoneofseveraloptionscheckingtoseeifwehavea
versionofChromeinstalledcanbeoneofthefollowing
staticfinalStringSTABLE_PACKAGE="com.android.chrome";
staticfinalStringBETA_PACKAGE="com.chrome.beta";
staticfinalStringDEV_PACKAGE="com.chrome.dev";
staticfinalStringLOCAL_PACKAGE="com.google.android.apps.chrome";
privateCustomTabsClientmClient;
//Bindstotheservice.
CustomTabsClient.bindCustomTabsService(myContext,pkgName,new
CustomTabsServiceConnection(){
@Override
publicvoidonCustomTabsServiceConnected(ComponentNamename,
CustomTabsClientclient){
//CustomTabsClientshouldnowbevalidtouse
mClient=client;
}
@Override
publicvoidonServiceDisconnected(ComponentNamename){
//CustomTabsClientisnolongervalidwhichalsoinvalidatessessions.
mClient=null;
}
});
Afterwebindtotheservice,wecancallthepropermethodsweneed.
WarmingupthebrowserprocessThemethodforthisisasfollows:
booleanCustomTabsClient.warmup(longflags)
//Withourvalidclientearlierwecallthewarmupmethod.
mClient.warmup(0);
NoteFlagsarecurrentlynotbeingused,sowepass0fornow.
Thewarm-upprocedureloadsnativelibrariesandthebrowserprocessrequiredtosupportcustomtabbrowsinglateron.Thisisasynchronous,andthereturnvalueindicateswhethertherequesthasbeenacceptedornot.Itreturnstruetoindicatesuccess.
CreatinganewtabsessionThemethodforthisisasfollows:
booleanCustomTabsClient.newSession(ICustomTabsCallbackcallback)
ThenewtabsessionisusedasthegroupingobjecttyingthemayLaunchUrlcall,theVIEWintentthatwebuild,andthetabgeneratedaltogether.WecangetacallbackassociatedwiththecreatedsessionthatwouldbepassedforanyconsecutivemayLaunchUrlcalls.ThismethodreturnsCustomTabsSessionwhenasessioniscreatedsuccessfully;otherwise,itreturnsNull.
SettingtheprefetchingURLThemethodforthisisasfollows:
booleanCustomTabsSession.mayLaunchUrl(Uriurl,Bundleextras,
List<Bundle>otherLikelyBundles)
ThismethodwillnotifythebrowserthatanavigationtothisURLwillhappensoon.Makesuretowarmup()priortocallingthismethod–thisisamust.ThemostlikelyURLhastobespecifiedfirst,andwecansendanoptionallistofotherlikelyURLs(otherLikelyBundles).Thelisthavetobesortedinadescendingorderandtheoptionallistmaybeignored.AnewcalltothismethodwilllowerthepriorityofpreviouscallsandcanresultinURLsnotbeingprefetched.Booleanvaluesinformuswhethertheoperationhasbeencompletedsuccessfully.
CustomtabsconnectioncallbackThemethodforthisisasfollows:
voidCustomTabsCallback.onNavigationEvent(intnavigationEvent,Bundle
extras)
Wehaveacallbacktriggereduponeachnavigationeventinthecustomtab.TheintnavigationEventelementisoneofthesixthatdefinesthestatethepageisin.Refertothefollowingcodeformoreinformation:
//Sentwhenthetabhasstartedloadingapage.
publicstaticfinalintNAVIGATION_STARTED=1;
//Sentwhenthetabhasfinishedloadingapage.
publicstaticfinalintNAVIGATION_FINISHED=2;
//Sentwhenthetabcouldn'tfinishloadingduetoafailure.
publicstaticfinalintNAVIGATION_FAILED=3;
//Sentwhenloadingwasabortedbyauseraction.
publicstaticfinalintNAVIGATION_ABORTED=4;
//Sentwhenthetabbecomesvisible.
publicstaticfinalintTAB_SHOWN=5;
//Sentwhenthetabbecomeshidden.
publicstaticfinalintTAB_HIDDEN=6;
privatestaticclassNavigationCallbackextendsCustomTabsCallback{
@Override
publicvoidonNavigationEvent(intnavigationEvent,Bundleextras){
Log.i(TAG,"onNavigationEvent:Code="+navigationEvent);
}
}
SummaryWelearnedaboutanewlyaddedfeature,Chromecustomtabs,whichallowsustoembedwebcontentintoourapplicationandmodifytheUI.Chromecustomtabsallowustoprovideafuller,fasterin-appwebexperienceforourusers.WeusetheChromeengineunderthehood,whichallowsfasterloadingthanregularWebViewsorloadingtheentireChrome(oranotherbrowser)application.
Wesawthatwecanpreloadpagesinthebackground,makingitappearasifourdataisblazingfast.WecancustomizethelookandfeelofourChrometabsothatitmatchesourapp.Amongthechangeswesawwerethetoolbarcolor,transitionanimations,andeventheadditionofcustomactionstothetoolbar.
CustomtabsalsobenefitfromChromefeaturessuchassavedpasswords,autofill,taptosearch,andsync;theseareallavailablewithinacustomtab.Fordevelopers,integrationisquiteeasyandrequiresonlyafewextralinesofcodeinthebasiclevel.Thesupportlibraryhelpswithmorecomplexintegration,ifrequired.
ThisisaChromefeature,whichmeansyougetitonanyAndroiddevicewherethelatestversionsofChromeareinstalled.RememberthattheChromecustomtabsupportlibrarychangeswithnewfeaturesandfixes,whichisthesameasothersupportlibraries,sopleaseupdateyourversionandmakesurethatyouusethelatestAPItoavoidanyissues.
Inournextchapter,wewilltakeadeepbreathandlookatsomeofthenewauthentication/securityfeaturesAndroidMarshmallowhastooffer.
Chapter8.AuthenticationAndroidMarshmallowhasintroducedanewlyintegratedAPItobettersupportuserauthenticationanduserverification.WecannowusethenewFingerprintAPIfordeviceswithafingerprintscannerinordertoauthenticatetheuser.Wecanalsosetaspecifictimeforuserlockscreenverificationtobeconsideredvalidintheapplogin.Inthischapter,wewilltryandgoovertheseadditionsandexplainhowtousethem:
TheFingerprintauthenticationAPICredentials’GracePeriodCleartextnetworktraffic
TheFingerprintauthenticationAPIAndroidMarshmallownowallowsus,thedevelopers,toauthenticateuserswiththeirfingerprintscanswhenusingsuchauthenticationscannersonsupporteddevices.
TheFingerprintAPIwasaddedtoAndroidMarshmallowviaawholenewpackage:android.hardware.fingerprint
Thepackagecontainsfourclasses:
FingerprintManager
FingerprintManager.AuthenticationCallback
FingerprintManager.AuthenticationResult
FingerprintManager.CryptoObject
Eachclasshasaspecificroleinourfingerprintauthenticationprocess.
Howdoweusefingerprintauthentication?Theprecedingfourclassesoftheandroid.hardware.fingerprintpackagecanbeexplainedinthefollowingmanner:
FingerprintManager:ManageaccesstofingerprinthardwareFingerprintManager.AuthenticationCallback:CallbackusedintheauthprocessFingerprintManager.AuthenticationResult:ResultcontainerforauthprocessFingerprintManager.CryptoObject:SpecificCryptoobjecttousewithFingerprintManager
Say,wewanttoauthenticateusersviatheirfingerprints.Adevicewithafingerprintsensormustbeinuse;otherwise,wecan’tusethisAPI.WeneedtogetaninstanceofFingerprintManager,andthenwecalltheauthenticate()method.Wemustimplementaspecificuserinterfaceforthefingerprintauthenticationflow,andthestandardAndroidfingerprinticon(c_fp_40px.png)isincludedinthesource.Weneedtoaddtheappropriatepermissiontoourapp’smanifest:
<uses-permissionandroid:name="android.permission.USE_FINGERPRINT"/>
Rightnow,wedon’thaveadevicewithafingerprintsensor,sowewillneedtotestourcodefromanemulator.(Nexus5XandNexus6Parestillwithlimitedsupply)
SettingupfortestingAndroidSDKToolsRevision24.3(atleast)mustbeinstalled.Now,wenavigatetoSettings|Security|Fingerprintandaddonefingerprint.
Followtheinstructionsmanually;weareaskedtoselectthePINandleadingustofindthefollowingscreenshot:
Finally,wemustuseaspecialadbcommand,trickingthesensorintocapturingamockfingerprint:
adb-eemufingertouch<finger_id>
Theresultantscreenshouldlooklikethefollowingscreenshot:
Weusedfinger_id=1forasinglefinger.Thesamecommandalsoemulatesfingerprinttoucheventsonthelockscreenorinourapp.
Ifyouneedhelptosetupanemulator,read:
https://developer.android.com/tools/devices/index.html
Now,wecanlaunchourapplicationandseethatwecanusethefingerprintasourauthenticationmethodwhentheuserpurchasesanitem.
Credentials’GracePeriodEvergottheitchwhenyouwantedtouseanappafterdeviceunlockonlytofindthatyouneedtologinagainorentertheapppasswordagain?Well,nowwecanquerythedeviceandcheckwhetheritwasunlockedrecentlyandhowrecentwasit.Thiswillgiveourusersachancetoavoidallthefussthatcomeswithusingourapp.Notethatthismustbeusedinconjunctionwithapublicorsecretkeyimplementationforuserauthentication.IfyouwanttoreadmoreabouttheAndroidKeystoreSystem,headtohttps://developer.android.com/training/articles/keystore.html.
WeuseKeyguardManagerandcheckwhetherourlockscreenissecuredviatheisKeyguardSecure()method.Onceweknowthatit’ssecured,wecantryandusethefeature;otherwise,it’dimplythattheuserdidn’tsetasecurelockscreenandthisfeatureisano-op.
WegenerateasymmetrickeywithKeyGeneratorinAndroidKeyStore,whichcanonlybeusedaftertheuserhasauthenticatedwithdevicecredentialswithinthelastxseconds.Settingthisvalue(x)isdoneviathesetUserAuthenticationValidityDurationSeconds()method,whenwesetupKeyGeneratororKeyPairGenerator.
Youcancheckoutthesamplecodeformoreinformation.TheactivityiscalledCredGraceActivity.
NoteTryanddisplaythereauthenticationdialogaslessaspossible.Whenusingacryptographicobject,youshouldtryandverifyitsexpiry,andonlyifitpasses,usecreateConfirmDeviceCredentialIntent()toreauthenticatetheuser.
CleartextnetworktrafficAndroidMarshmallowalsoaddedanewflagtothemanifest.ThisflagindicateswhethertheapplicationisusingacleartextnetworktrafficsuchasHTTP.Theflagisandroid:usesCleartextTraffic,andthedefaultvalueistrue.SettingthistofalsemeansthatsomesystemAPIcomponents—suchasHTTPandFTPstacks,DownloadManagerandMediaPlayer—willrefusetoissueHTTPtrafficandwillonlyallowHTTPS.Itwouldbeagoodpracticetobuildathird-partylibrarythathonorthissettingaswell.Whyisthisgood?Well,cleartexttrafficlacksconfidentiality,authenticity,andprotectionsagainsttampering,anddatacanbetemperedwithoutitbeingdetected.Thisisamajorriskforapplications,andwecannowuseittotryandenforceastrongerandmoresecuredatatransportto/fromourapplications.
Weneedtorememberthatthisflagishonoredonthebasisofthebesteffort,andit’snotpossibletopreventallcleartexttrafficfromAndroidapplicationsgiventhattheyhavepermissionstousetheSocketAPI,forinstance,wheretheSocketAPIcannotdeterminecleartextusage.WecancheckoutthisflagbyreadingitfromeitherApplicationInfo.flagsorNetworkSecurityPolicy.isCleartextTrafficPermitted().
NoteWebViewdoesnothonorthisflag,whichmeansthatitwillloadHTTPeveniftheflagisfalse.
So,whatdowedowiththecleartextnetworktrafficflag?Duringappdevelopment,wecanuseStrictModeandidentifyanycleartexttrafficfromourappusingStrictMode.VmPolicy.Builder.detectCleartextNetwork().
ThedownsideofusesCleartextTrafficisthatitcausesappcrashesorprocessterminationwhenit’snotusingSSL(shortforSecureSocketLayer).Thisisgreatintheorybutnotinproduction,whereyourSSLcertificate,forsomereason,hasissuesandyoureroutethetraffictoHTTP.So,payextraattentiontowhereHTTPSisusedinyourappandwhereit’sokaytouseHTTP.
Luckily,wehaveStrictMode,whichnowhasawaytowarnyouifyourapplicationexecutesanyunencryptednetworkoperationsviaadetectCleartextNetwork()methodonStrictMode.VmPolicy.Builder.Inoursampleproject,wehaveaClearTextNetworkUsageActivityactivity;whenrunningtheTestStrictHttpproductFlavorvariant,youwillseethisinLogCat.
SummaryAndroidMarshmallowgaveusanewAPItoauthenticateuserswiththeFingerprintAPI.Wecanusethesensor,authenticatetheuserevenwithinourapplication,andsaveitforlateruseifwewanttosavetheneedforuserloginusingtheCredentials’GracePeriodcapabilitiesAndroidMarshmallowintroduced.
WealsocoveredawaytomakeourapplicationmoresecureusingHTTPSonly,andtheStrictModepolicy,enforcedwiththehelpoftheusesCleartextTrafficflag,whichallowsustomakesurethatallthenodesweconnecttotheouterworldandexaminetheneedforareasecureconnectionornot.
Iwouldliketothankyouforreading.
IwouldliketothanktheAndroidteam.Thisproducthaschangedmylife.
TheAndroidecosystemhasgreatdeveloperscontributingbypublishinglibraries,writingblogpostsandansweringsupportquestions;I’mproudtobepartofit.
Lookingforwardforfutureeditions.
IndexA
android.hardware.fingerprintpackageclasses/TheFingerprintauthenticationAPIFingerprintManager/Howdoweusefingerprintauthentication?FingerprintManager.AuthenticationCallback/Howdoweusefingerprintauthentication?FingerprintManager.AuthenticationResult/Howdoweusefingerprintauthentication?FingerprintManager.CryptoObject/Howdoweusefingerprintauthentication?
AndroidARTabout/Runtime
AndroidBackupServiceabout/Anoverview
AndroidDebugBridge(adb)/CheckingpoliciesusingadbAndroidIntentsystem
about/TheAndroidIntentsystemwebsiteassociation,creating/Creatingawebsiteassociationapplinkverification,triggering/Triggeringapplinkverificationapplinksettingsandmanagement/Applinksettingsandmanagement
AndroidInterfaceDefinitionLanguage(AIDL)URL/ConnectingtotheChromeservice
AndroidKeystorechangesabout/AndroidKeystorechanges
AndroidKeystoreSystemURL/Credentials’GracePeriod
AndroidMarshmallowaudiofeatures/Audiofeaturesvideofeatures/Videofeaturescamerafeatures/Camerafeaturesbehavioralchanges/Behavioralchanges
AndroidMarshmallowchangesbehavioralchanges/Behavioralchangessingle-usedeviceimprovements/Single-usedeviceimprovementsapps,silentlyinstalling/Silentlyinstalling/uninstallingappsapps,silentlyuninstalling/Silentlyinstalling/uninstallingappsimprovedcertificateaccess,granting/Improvedcertificateaccessautomaticsystemupdates/Automaticsystemupdatesthird-partycertificateinstallation/Third-partycertificateinstallationdatausagestatistics,querying/Datausagestatisticsruntimepermissions,managing/ManagingruntimepermissionsVPN,accessing/VPNaccessanddisplay
VPN,configuring/VPNaccessanddisplayworkprofilestatus/Workprofilestatus
AndroidMarshmallowpermissionsabout/UnderstandingAndroidMarshmallowpermissionsdeclaringpermissions/Anoverviewpermissiongroups/Anoverview,PermissiongroupsPROTECTION_NORMALpermissions/AnoverviewINTERNETpermission/Anoverviewappsignaturepermissionsgranted/Anoverviewpermissionsgrantedbyusersatruntime/Anoverviewpermissions,revoking/Anoverviewruntimepermissions/Runtimepermissionsbestpractices/Bestpracticesandusagenotes,Honestycanbeagreatpolicymanaging/Needsupporthandlingruntimepermissions?
Androidpermissionsabout/AnoverviewofAndroidpermissions,Permissionspermissiongroupdefinitions/Permissiongroupdefinitionspermissions,impliedbyfeaturerequirements/Permissionsthatimplyfeaturerequirementsviewing,foreachapp/Viewingthepermissionsforeachapp
AndroidSDKToolsRevision24.3/SettingupfortestingAndroidSupportLibrary
about/NotificationsAndroidsystemflagspermissions
about/SomepermissionsarenormalandsafertouseApacheHTTPclientremoval
about/ApacheHTTPclientremovalAPKvalidation
about/APKvalidationApple’sWebkit/WhatisWebView?ApplicationInfofields
about/Removablestorageadoptionapplinks
testing/Testingapplinksmanifest,checking/Checkingmanifestandlistingdomainsdomains,listing/CheckingmanifestandlistingdomainsDigitalAssetLinksAPI/TheDigitalAssetLinksAPIintent,testing/Testingourintentpolicies,checkingwithadb/Checkingpoliciesusingadb
appsinstalling,silently/Silentlyinstalling/uninstallingappsuninstalling,silently/Silentlyinstalling/uninstallingapps
AppStandbymodeabout/TheAppStandbymode
device,inAppStandbymode/WhathappenstoappswhenintheAppStandbymode?apps,testingwith/TestingappswiththeAppStandbymodeexcludedappsandsettings/Excludedappsandsettingspointsandtips/Tips
assistant/TheAssistAPIAssistAPI/TheAssistAPIaudiofeatures,AndroidMarshmallow
about/AudiofeaturessupportforMIDIprotocol/SupportfortheMIDIprotocolMidiManager/MidiManagerdigitalaudiocaptureandplayback/Digitalaudiocaptureandplaybackaudioandinputdevices/Audioandinputdevicesinformationonaudiodevices/Informationonaudiodeviceschanges,inAudioManager/ChangesinAudioManager
authenticate()method/Howdoweusefingerprintauthentication?automaticbackup
about/Anoverviewsubtopics/Importantbytesexcludeddata/WhattoexcludefromthebackupBackupAgent/BackupAgentandbackupeventsbackupevents/BackupAgentandbackupevents
automaticsystemupdates/Automaticsystemupdates
Bbackupconfigurationsyntax
<include>tag/Thebackupconfigurationsyntax<exclude>tag/Thebackupconfigurationsyntaxdomain/Thebackupconfigurationsyntax
backupconfigurationtestingabout/Backupconfigurationtestingbackuplogs,setting/Settingbackuplogsbackupphase,testing/Testingthebackupphaserestorephase,testing/Testingtherestorephasetroubleshooting/Troubleshooting
BackupManagerserviceabout/Anoverview
behavioralchanges,AndroidMarshmallowworkcontacts,displayoption/TheworkprofilecontactsdisplayoptionWi-Ficonfigurationoptions/Wi-FiconfigurationoptionsWi-Ficonfigurationlock/TheWi-FiconfigurationlockWorkPolicyController,adding/WorkPolicyControlleradditionDevicePolicyManagerchanges/DevicePolicyManagerchanges
BluetoothAPIabout/BluetoothAPIChangesstylussupport/Bluetoothstylussupport
Ccamerafeatures
about/CamerafeaturesflashlightAPI/TheflashlightAPIreprocessingAPI/ThereprocessingAPIchanges,incameraservice/Changesinthecameraservice
Chromecustomtababout/WhatisaChromecustomtab?WebView/WhatisWebView?customizationoptions/Customizationoptionsusing/WhentouseChromecustomtabs,CanweuseChromecustomtabs?implementationguide/TheimplementationguidecustomUI/CustomUIandtabinteractiontabinteraction/CustomUIandtabinteractioncustomactionbutton/Thecustomactionbuttoncustommenu,configuring/Configuringacustommenucustomenteranimations,configuring/Configuringcustomenterandexitanimationscustomexitanimations,configuring/Configuringcustomenterandexitanimationswarmingup/Chromewarm-upChromeservice,connecting/ConnectingtotheChromeservicebrowserprocess,warmingup/Warmingupthebrowserprocessnewtabsession,creating/CreatinganewtabsessionprefetchingURL,setting/SettingtheprefetchingURLconnectioncallback/Customtabsconnectioncallback
Chromiumproject/WhatisWebView?ChubbyTabb
URL/CustomUIandtabinteractioncleartextnetworktraffic
about/Cleartextnetworktrafficdownside/So,whatdowedowiththecleartextnetworktrafficflag?using/So,whatdowedowiththecleartextnetworktrafficflag?
codingpermissionsabout/Takingcodingpermissionsintoaccounttesting/Testingpermissionscoding,forruntimepermissions/Codingforruntimepermissions
Contextmethodsabout/Removablestorageadoption
Credentials’GracePeriodusing/Credentials’GracePeriod
CredGraceActivity/Credentials’GracePeriodcustomizationoptions,Chromecustomtab/Customizationoptions
CustomTabsHelperURL/CanweuseChromecustomtabs?
customURIscheme/TheAndroidIntentsystem
DDalvik
about/Runtimedatabackupconfiguration
about/Databackupconfigurationdata,includingorexcluding/Includingorexcludingdatabackupconfigurationsyntax/Thebackupconfigurationsyntaxpptingout,fromappdatabackup/Optingoutfromappdatabackup
datausagestatisticsquerying/Datausagestatistics
DevicePolicyManagerURL/DevicePolicyManagerchanges
DevicePolicyManager,changessetCameraDisabled()/DevicePolicyManagerchangessetKeyguardDisabledFeatures()/DevicePolicyManagerchangeskeyguardrestrictions,setting/DevicePolicyManagerchangescreateAndInitializeUser()/DevicePolicyManagerchangescreateUser()/DevicePolicyManagerchangessetScreenCaptureDisabled()method/DevicePolicyManagerchangesEXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_CHECKSUM/DevicePolicyManagerchangesEXTRA_PROVISIONING_DEVICE_ADMIN_SIGNATURE_CHECKSUM/DevicePolicyManagerchangesEXTRA_PROVISIONING_RESET_PROTECTION_PARAMETERS/DevicePolicyManagerchangesEXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE,using/DevicePolicyManagerchangesRESULT_CANCELED/DevicePolicyManagerchangessetofsettings,disabling/DevicePolicyManagerchangesWIFI_DEVICE_OWNER_CONFIGS_LOCKDOWNsetting,enabling/DevicePolicyManagerchanges
DigitalAssetLinksAPI/TheDigitalAssetLinksAPIdigitalaudiocaptureandplayback/DigitalaudiocaptureandplaybackDigitalSignatureAlgorithm(DSA)
about/AndroidKeystorechangesDirectShare
about/DirectSharebestpractices/DirectSharebestpractices
Dozemodeabout/TheDozemodedevice,indozingstate/Whathappenstoappswhenadeviceisdozing?apps,testingwith/TestingappswithDozemode
Eemulator
settingup,URL/Settingupfortesting
FFingerprintauthenticationAPI
about/TheFingerprintauthenticationAPIadding/TheFingerprintauthenticationAPIusing/Howdoweusefingerprintauthentication?settingup,fortesting/Settingupfortesting
GGoogleCloudMessaging(GCM)
about/DatabackupconfigurationGoogleI/O2015/TheAssistAPIGoogleNow/VoiceinteractionsGooglePlayforWork/Silentlyinstalling/uninstallingappsGroupID
about/AnoverviewofAndroidpermissions
Hhardwareidentifier
about/Hardwareidentifier
IimprovedBluetoothlowenergyscanning
about/ImprovedBluetoothlowenergyscanningimprovedcertificateaccess
granting/Improvedcertificateaccessintentfilters/TheAndroidIntentsystemisKeyguardSecure()method/Credentials’GracePeriod
JJSONfile
about/Whythisfile?
Kkiosks/Silentlyinstalling/uninstallingapps
Llaunchhandler/TheAndroidIntentsystemLinuxuserID
about/AnoverviewofAndroidpermissions
MMidiManager/MidiManagerMIDIprotocol/SupportfortheMIDIprotocol
Nnotificationsfeature
about/Notifications
Ppendingintent
URL/CustomUIandtabinteractionpermissionfailure
about/AnoverviewofAndroidpermissionspower-savingmodes
about/Power-savingmodesDozemode/TheDozemodeAppStandbymode/TheAppStandbymode
Rremovablestorageadoption
about/RemovablestorageadoptionreprocessingAPI/ThereprocessingAPI
android.media.ImageWriter/android.media.ImageWriterandroid.media.ImageReader/android.media.ImageReader
runtimeabout/Runtime
runtimepermissionsmanaging/Managingruntimepermissions
SSecureSocketLayer(SSL)/So,whatdowedowiththecleartextnetworktrafficflag?sendBroadcast(Intent)method
about/AnoverviewofAndroidpermissionssetUserAuthenticationValidityDurationSeconds()method/Credentials’GracePeriodSharedPreferences/BackupAgentandbackupeventssingle-usedeviceimprovements
setKeyguardDisabled(),using/Single-usedeviceimprovementssetStatusBarDisabled(),using/Single-usedeviceimprovementsUserManager.DISALLOW_SAFE_BOOT,using/Single-usedeviceimprovementsSTAY_ON_WHILE_PLUGGED_IN,using/Single-usedeviceimprovements
stylusabout/Bluetoothstylussupport
SystemUpdatePolicyTYPE_INSTALL_AUTOMATICoption/AutomaticsystemupdatesTYPE_INSTALL_WINDOWEDoption/AutomaticsystemupdatesTYPE_POSTPONEoption/Automaticsystemupdates
Ttextselection
about/Textselectionsupportlibrarynotice/Supportlibrarynotice
Third-partycertificateinstallationDevicePolicyManagerAPIs,calling/Third-partycertificateinstallation
Torchi/TheflashlightAPI
UURI(UniformResourceIdentifier)/TheAndroidIntentsystemUSBconnection
about/USBconnection
Vvideofeatures
about/Videofeaturesandroid.media.MediaSync/android.media.MediaSyncMediaCodecInfo.CodecCapabilities.getMaxSupportedInstances/MediaCodecInfo.CodecCapabilities.getMaxSupportedInstancesMediaPlayer.setPlaybackParams/MediaPlayer.setPlaybackParams
voiceactions/Voiceinteractionsvoiceinteractions/VoiceinteractionsVPN
profileowner/VPNaccessanddisplaydeviceowner/VPNaccessanddisplay
WWebView
about/WhatisWebView?Wi-FiandnetworkingAPIs
about/Wi-FiandnetworkingchangesWorkPolicyController
about/WorkPolicyControlleradditionURL/WorkPolicyControlleraddition
workprofilestatuschecking/Workprofilestatus
YYUV/ThereprocessingAPI