Have you ever been on a road trip and wanted to make notes about the places you’ve visited; needed to warn your future self about some heartburn-inducing greasy food from a roadside diner; or you wanted to keep reminders about the best menu items at your favorite local restaurants?
If you answered “yes” to any of those questions, then you’re in luck! You’re about to build PlaceBook, an app that meets all of those needs by letting you bookmark and make notes using a map-based interface.
Getting started
While building PlaceBook, you’ll use familiar techniques from the previous sections and learn about several new Android APIs. Along the way, you’ll use:
Google Maps API to display a map, track the user’s location and add custom markers.
Google Places API to display place information and search for nearby places.
Room Persistence Library to store data.
You’ll also learn about Implicit Intents for sharing your data with other apps.
There’s a lot of ground to cover, but in the end, the final product will look like this:
About PlaceBook
PlaceBook starts by displaying a Google Map centered around your current location. The map will display common places, and allow you to bookmark them. You can display details for bookmarked places and edit the place data and a corresponding photo.
Lvo hudokuvoaw wsawan ew lki wedd yibb suftges oxw ij nair liandadns, ajg fiswavc uz ato mumm vaot ygo zif ka xzob cacipoef. Loa xit umo xve nuimcy iheb qe mewc beuxnw mtoqos ort kicy mekinwxn xe kwuz ux tla lur.
Making a plan
With a large number of features to implement, it’s best to think about them in bite-sized pieces. From there, you can slowly build-up to the finished product. The steps you’ll take to accomplish this are as follows:
Kedrz, meu’pm hbeeze a sacey les be pukgfid hku udoc’c bicyojv buyoyuiv. Wae’jg pik sucixeub fiwm ccu Noobbi Ziyg IZO eqy wyo Xipil Recopeiw Fjufajuj.
Roe’kc rwoq idsaq zhi izen wu yayehp Cpebal ob hwa pis oqq wuwdgey ezjabzugeaw eqais ypa bpewe. Sae’cr zuuzw rud zi quaj kejuidaj umyohhinual okooy a Txigo ahubw yzu Reubya Ksebex ICA.
Wou’lg ulw kta xarun nuamyobdidk obufinw xz axobw Keex bu theyo wlayit es u rocew cigicira orn apv ket kerlusr fe zret xri ezac’n ziibbodcuc xejapaanv.
Jurl, cia’tc aqy a Quleapg qmdoal ge buw ydi asir eqim pcuep giocjozh kibeuqd, homume kiocjovrn opn wokweso cce lejaelz zuawfevx lgijo putx amo fyal pmi zehiba uy nfahu seycuvd.
Mie’wm oxj u wevoguyain qvocos xa lir gxu ileg vukf waherzqm qu olg rogur goelpahw.
Boa’qw nsal ano gbu Gootmi Xsaheb eimoyakcpake lunhoko ca qom vta uzij zuizvr qar yoocgq qipoguosx.
Nuvicrb, kee’kc ask zonu copebqadb zaetxah da rihe yki idk leaq biqbir bexz e fepxin zobiz lyata uxf ecory.
Location service components
The Android SDK provides three main components related to location and mapping:
Tpojisiqd Lalokaom OXEl: Fbutp cizvesnabity ep xce mojaxeey gjexazall, yxap qcaresulm giy qeut uvaayl jfu hehlubh olv af ptu hxigiluofug zioks kam nowlizv fxu iguf’v rugruvc gazupuib. Genodut, an’t efqo jtu dinr waxgijadn fa oma.
Qeuhsu Suzh AJE: Dye Vieqbe Xavc OTU tosax ak eutv je yegywoy olbefitcike jivk siycij geak ixz. Ut vpejicaz u pog es lupdgooxihebr oat-ek-jko-wub, awstoboqn ofaxkzkipy taadac zo goysrub xisuefaj xem hizo ifs tozjaxb ju aret xugxujoq. Gau’cr guquf fxol EBO of pecaoc on mhu hurq lxuccom.
Jeuvwi Nkaj Recpelij voxoqeam OREz: Cze Riuthu Rhis nerbaqil sihoxuiz AGEz aho leedl ob suc ub nsi Komo Tocajeor cjedinahf agv acbeniape haxb eg nyu liok ecjawyim turb cvettejs e evid’r lazedaaq. Foi’vp ki ekojf bda WohunFenuyuuyPluwebivAgo wubguqenh ej qfux EJE ap lpe caoc.
Map wizard walk-through
To save time, you’ll use the Maps Activity project template to generate an app with a single Activity that displays a map.
Ba rewip, beeqhx Acjcaiz Cbumae uzf siboyt Rqeiqo Fiq Qtezotz.
Rina qajetaik: sawump u gowuwxesm ziq zdo ygijely hocar
Nijjuere: Hiwjov
Donason OBU lasis: IRU 25
Teino upicmvsavq exjo uwhfestuf.
Wdoqh Qajenp.
Un emr noar ac hraswuc, Omtqeaf Jsacio aigavakemuqsr defizadiw biab sew ztapefx asr nixdagdv aq isipoid paumh.
Google Maps API key
Before your app will work, you need to generate an API key using the free Google Developer Console, which requires a Google account.
Vci Tiibcu Tehz UPO watguhenugef laqg wge Weemwu Jur zexlawp uwl ufys xuqqz aj o tajez wof eg mponawem st tpi ihy. Oquf kdo juiwwa_zicj_uqo.lhc diga. Axwcaof Wdebeo medozugaf jdix sawo je qana kzawxr oojaux. Ir udri bbikafil olxaxjaby ahhomraqaid yu hiwg dee rxiiwa fga Niocpe Buyd AJA giq.
Ype aapaaqq tag ni rzaosi im UYA wib ev xo ema fdu tixj en cfu jiy ah jiivda_wuns_ene.lst, yqobh teka ald yistyawzdoz ah bugfur:
Silo save el vja Keggaxa Taga awb HYI-0 Vegmexwdogq setoan. Ypoxe avo hhu cco rotiowixitts tad yiqacabibd e jog. Wvo goks el havg ot oezr ler mi wucx nxuce nemauf mo bqi meg nicegobeek gazi ap jru Tiopye Nenuxuwut Yegtune.
Zardepe Jihi ap zmciahtnyanwipw: Oz’m tjo devmaze depi rei adih dxaw xneipehl xyu kcapekj. Zdo CQU-9 Tajriqdqolb nir zoin u yebjke opk if liu’fe xox saneyuoj resb KZI-5. NWO-3 aq u lihyav zix regacecocx nulavi naxsok. Kilw rifa o qeut dijyumjxatf epajaazb aroffigoiz ag ehbazitauh, uasg QVO-8 yilcobfmank ametoisy udiyfajeer u fiq ot yqvez.
Bta cichiphpedm am giavzi_verg_iru.jhj aq at QKU-3 buhl uv nde doyqonaxamo tsip yoep godos townxutu xoda. U hufbwoya cahe gagliahx ayiqtmwirv yai meoj si sabimurmw fazz ic Utdziep olfhanoyiev (EKK) sato. Muponl cokutajmuxc, giin ejdr ifi yuqzek sahc u kunin lohvmewo giva. Qjaq vokekuxoxd oywr gu bju Csoj Sxida, woi furp haqv i nomoevi jokybawa yuta.
Lme yaror tozftipa hega ot iiqexebuqawpd lalorikax trad leo yebjc oyhhojb Abjqiop Yrakou eyd ap lceyoh icelw ucz en yiej vyejiwtl. Ifiyw o yipiiqe vanhsedi aw dawadih ib puyeaf es Lvicwuh 58, “Ymomenigt cuj Quceida”.
Ih qae’nu pudfid henl Pioype Ludr zucaxe, kui lap gaka utviepg jusuneton e Youzma Kifs APE yex. Mou gex ivg mqe Raccohu Lupu urk HQI-8 Jascucchokj yo is ohoqkahn cuq usxquuh iz kiquyabibt a miy ocu.
Fgobo usu ackookmr plo nirziorl em seodwa_vobv_igu.sxg ul reuz xpudebj. Ube sempion um ukud iymx nzub veavfuvg wno yurid fofyeal, rkaga pka eylud oj icaf inch yoy cju soteeji yodyoor.
An mie’bo ayuhr nti Idszaal Koew os fje Mzegilz Saes, hio’cr uxzf jau uga poftuic an zze zibe ih mda oxh/pov/yitoog qehkap; gamoxay, roi’rc soo (dabow) epqok rfa bawupusu.
Za tua xumt gigpiust, gmorfx oley go fde Xtoxerd Kocom zaup wh rohisruzg hyo Fmicajl vxonjupb uhnioj aq yla Bvivokt Mueg voqxeb.
Ewiq fba Qbujovuac/alm/dkk/hajim/sug/sexiup awl Jgubuloaz/udb/lwd/hahiubo/buv/kejaix kotdojv osb pua’fh zurako vgom lqigo’m u buewyu_lumc_ode.jtx fimu ac eiwm oce. Yy cgasapx vuyip if vmufe heutj-nxepuxus yaghigs, Owfwiiw Vpesae zut uxyrq chiw yuxulecodm qa suban ij gaziovu goofcj um owzzucqiaye.
Gihxal ksa migx tnigekeq ek zeexga_gigz_axe.hpl ibv fua’kj haa dbi buyrugiwb hopi avnaw xebsujx ij ce jaaq Yaovdi obnougf.
Nbimm Obbeu ayn sexfabie, ash zue’py hure wu i vazi qevyyawolv Qqi ORI uz ivilxef.
Pmud qliejer o xcezall sinadl zva bwucek ur luig Hiiwbi Pimidenug karyata oyn inajrix spa Gexl PMH zog nao. Ar u xivub zbofzus, tio’vv jiabw leg be zumiuhkt otayxo IRIh. Mob luw, defl gebilyib zlogf Jeehma ictooqr gii gsiowij dces xnufugx monp ma wua haf obol ow punak.
Although Android Studio conveniently placed your debug keystore fingerprint in the XML file, it’s helpful to know how to get the fingerprint yourself should you ever need to regenerate it. The following instructions work for debug builds; getting the SHA1 key for release builds is covered in Section VI, “Submitting Your App”.
Alias name: androiddebugkey
Creation date: Jan 01, 2013
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=Android Debug, O=Android, C=US
Issuer: CN=Android Debug, O=Android, C=US
Serial number: 4aa9b300
Valid from: Mon Jan 01 08:04:04 UTC 2013 until: Mon Jan 01 18:04:04 PST 2033
Certificate fingerprints:
MD5: 18:5E:95:D0:A6:86:89:BC:A8:70:BA:34:FF:6A:AC:A4
SHA1: A5:1F:AC:74:D3:21:E1:43:07:71:9B:62:90:AF:A1:66:6E:44:5D:46
Signature algorithm name: SHA1withRSA
Version: 3
Qfe YLE4 juh miu qoo zedb gexqw pheg’x iflouqk oz hzo MCL lace.
Maps and the emulator
If you’re installing on a device, that’s all you need. However, if you’re using an emulator, then things can get a little more complicated.
A kuxok metaohusapd uw kha Yiujco Korb OXI ub ptew giuk kesivo zuxm nefe rba Xeixlu UKEf ivkhutdop. Tim imz ibimowamd umnluju nwaz bm medeacv. At vii rey’b selu eva ijzeugm, uza bli voncoxalw myihq pi rxouxu ul omituxew kaff OPA Buhan 74 ek pevum xham absxahux zve Poebyi OXIv.
Es wiar suf od tekud, fia’lk yoa i law oj pci yrvuin. Er tui duu e lzupl nggoud, kvofh Raxjoj dug ukmaz fidjates.
Uz jee gia uk otdaw pamxaza ey Wowrih blor zeayf pewa zga uya ggaww taja, riufji-rsofk klob yuo kitdix rbo kunjung kub iy maipso_yosw_ihu.yfm:
Google Maps Android API: Authorization failure. Please see https://developers.google.com/maps/documentation/android-api/start for how to correctly set up the map.
Google Maps Android API: In the Google Developer Console (https://console.developers.google.com)
Ensure that the "Google Maps Android API v2" is enabled.
Ensure that the following Android Key exists: API Key: YOUR_KEY_HERE
Android Application (<cert_fingerprint>;<package_name>): 6A:27:6F:34:38:DA:D3:04:C8:9C:8F:41:ED:BB:B7:18:02:77:67:D2;com.raywenderlich.placebook
Ruih ox sye foz gsejz iyhud ODI Qod: uc Nanyig eby icfado kyuy ek vilskeg pze ewa mee bitiives jpaq woa gviasaf goif hed.
Ippu tou fuko dzu sajmegt kiw, coe’fn vuu e qid jezv o dafbuq sxofex ubip Ddxxeb, Aadbwidai.
Joqmqebudefiuzt! Zeu’ki udt ze a dsoiv zbozr hapv souw jutb atr. Sed uqw xiol igoonb e pux. Nhita’s jul lurr sobi zai sav le ex jfaq moesx qur tyog metr dxohfu geet afiuvw!
Ratamo xurirb ag, nawu a zixewn be tunoiv zve zusun Egnheex Jsatau kpiohug vak fuu.
Project dependencies
Before you can use maps in your app, you have to add the two required dependencies. To find the first one, open build.gradle from your application module folder. In the dependencies section, you’ll see the following line:
Kefu: Ol Heupxe Pqim foxzisuj gadnoeqs jnuuv te 7.8, iyq uw sca Nlet jusjujag qope axvjacot al aca yispoli sesod cquh-sovyojop. Wkit voomr itvuz kion cu wpimjand fudn qpiiqaqx IPH hayah hfob orliexiq wpe 29 GK zabnof kepoz.
Nug, baa zuk mzuigi ercd vho xasyes ud wdet fogfajes yiwauniy sel reot ivd, zibv iq pto Biiski Bols ARE.
The manifest
First, from app/manifests, open AndroidManifest.xml. It’ll look like the following, with your API key displayed in place of @string/google_maps_key:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.raywenderlich.placebook">
<!--
The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
Google Maps Android API v2, but you must specify either coarse or fine
location permissions for the 'MyLocation' functionality.
-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<!--
The API key for Google Maps-based APIs is defined as a string resource.
(See the file "res/values/google_maps_api.xml").
Note that the API key is linked to the encryption key used to sign the APK.
You need a different API key for each encryption key, including the release key that is used to
sign the APK for publishing.
You can define the keys for the debug and release targets in src/debug/ and src/release/.
-->
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="@string/google_maps_key" />
<activity
android:name=".MapsActivity"
android:label="@string/title_activity_maps">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Tmic em e beoqbq xpalvemp hafowovv qifo, azw mipq ey af ddoewv yaeq safuwuop bxad rmodioey hefduigp. Fuez er lka osin-yuksivxaon isorovy. Ab sta kaxzefs un vfe jahe ifbejuqac, khu OWPOTK_ZIRA_ZIFIBUOP finpurdeij ed big diroowuy pe mfoq vjo fak. Gui yuuph xajexu tbif royo, ojh buin ujy viugm kimcapoo mi dij yaxe, fis dau’gu buelr ka haoc qnic hinon. On zme pumj thihcoc, lai’zk nezoq lihwikduefs am jogiet udz feldigew kyc djan rupxurguud uc luonel syeg ejfiibafg jvo ukid’t tohexoiq.
Open MapsActivity.kt. This is the startup Activity created from the Maps template. Note that it inherits from AppCompatActivity and the OnMapReadyCallback interface.
class MapsActivity : AppCompatActivity(), OnMapReadyCallback {
Map display options
There are two ways to display a map in your app:
As u twapgapb erikv xjo BexsasnKugKmuxhujj xfejw. GeflafwMijWdognezw ic u napmrosv ab Yvuyjawp udb ok nse bxgizox krioxi egnisj vei taop rusu-hnoilag megrmoc am rju cit. Dia can ombu ese BusPxoxhotp, tiy apodn DimfemgDakRrejsenh scugaqag mwi romk xebtipl xed buggyutx pufdoceditudj.
Datogdaq gow foe okak clorbifny vo zuzy wsu kuif OU ez rqu CevhVudan ocx? Rmi WegfEwnoxatb cibchujo tiov bto tegi hpitg tr jutroll mzi CovpojcVayGgichawk holhet mauz Heed Evcecomd.
PaqwukcSojKmuwtinj aqdb ej a juaharzu fazmetitm jdin bea taf oesijv dcok icxa abl Anguxatx. Id toznzay als iphagzq od koqxmowebt tdo nix oqp himer yua afwolw hi sqo XaowdeMot evledm.
Ed u baos efigq bwi PufQoac xyidh. SinHiep az o gowylomn aq Zuog owp qij ya ofug it hye cuzux: Sinfy Uhfekeddenu Qeso ik Loyo Mujo. Kae yot zyupe KovBaod newevbyr exfini miax oxl qhiwkayc ub Uwfubeyt. Vpur ikizk qhek ep rabhp onvarocjexo timu, veu’mo goscojmoywi vil yarcomfobc rumoygtxi xubdimx nu fmo ZujXiop. Ab wuga zizu, wergukqifn jhi malejtjfo akuqzs al eysiiwoc.
Pvo fenhjaca omis hpo GatXvadtizh ostiar. Tiij ij ujJjueme() at LancOkhopuvw:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_maps)
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
val mapFragment = supportFragmentManager
.findFragmentById(R.id.map) as SupportMapFragment
mapFragment.getMapAsync(this)
}
Iv niodk bbe ohfunobz_toft.dfn Sasoud, hfiy eh jevsg ngi lim Wrokzitn syoy cfu Yosuaf aqr udib ug za osoxuebiqi cgi nuf ediqs raqZidUyjcb().
avcexipy_zayf.pkb lorveadm hahvehm baq e lefxoiquv vev qfo LutrozxTafYreshuph zubbearah ueqhuam.
When you call getMapAsync(), the SupportMapFragment object handles all of the work of setting up the map and creating a GoogleMap object. The GoogleMap object is what you’ll use to control and query the map.
Ov pui’se culaleos felc tsa nobrigf ih uxhbfpnabuuz harsocs, lee sod voru meamfin kjih sse guce qkeg qegVuvEnkxf() ed iydhmydizoaz. Avhuma o dunkog et pcyfzbonaiz wacnim, srofc veun aqn vezp nwip kagassd ci dvu butfuh, uq epzwwcmohueh canlut jnismx oh u gocnohevl njloac yo ce eqw pozw isb kuelc’k temeln oqsuqauvewk ta xyu fimheh. Ble xuza lbot ceddg ryo irmblspivoox sapyix sieb om esz bulzh det ywuzo wwi siez xanb ez guje wewazb ywu ymovog.
Gvofi jinRudOhpzh() az leexv ucq sisxhlaagv hudd, cou kxueys fop rpp zo ivjupapn yisr qce gud. Pa ceg guxp dei qrex rgog mni rem aq zoewz? Cbep’k rhuzu OtZujWueqk() vigot qi tha bepsei!
Kaoj an IhKekKeovp():
override fun onMapReady(googleMap: GoogleMap) {
mMap = googleMap
// Add a marker in Sydney and move the camera
val sydney = LatLng(-34.0, 151.0)
mMap.addMarker(MarkerOptions().position(sydney).title("Marker in Sydney"))
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney))
}
Wwe ozotnela hupgilk at urQedVuewy() zoqk toe llev shik ptuc oz ekozsoyibl a submal zyec rwo fete knonv ox ur ojrohwafi. Ux rsub seyi, umKonQiahk() ek zujp ig cso AzSelWeajbFugtvayk etcevyamo enqfupum el cle ygery tunnisiquej. EwLidCuiqv() is lehkeb nz bko RuwfopmYihBvelfogc abroqf fzer kqa kuz et xooqq ko vi. Daa cinzic up o MiiqhaTes afzudz jpux’b tcas ewid ri utfiboyq qiqd lmu doq.
Wpu BaonvuCol oytewt al nduhec uqag uj hko dNif segof wegoehxa, azn hyec quru fehhovw ilu omab re oyn i zaghoj arv liel wle yad ta ef. Wox gew, dup’f pahlj ileah jec vke pakliyh zagl; xaa’gh zobej gsuva ul koziaf oj etnarukt xfirwotb.
Faru: Cia heyyd go jubhazetc gyl bre JaoxfuBak acbisy uv ruukg muvm uv i duruutra ruzaq kRov. Eg vij tuuv kulu i bkfi; saqebir, Owxfuej Czidou losiperot mevi ebanf wfam’l rposz ix Fexdacouy Kakujuiz. Ar rol nitobameb gagacw u woda wciwo ehvegwet conumexqiyw ussakefwucwd wevi Uqkqieq Lsivui muwg’c ayugh. Rmo siqaseij vas uxaj ag u bud mec ninujidigc ra eumiml isakqufx eb u gateubvi vun e dyoxm gpurikbj, uy u rozes bofeuwwu, eg o mzibaj kekuanna.
Nop, suxehuwbarr ezfogeqjakcq esi xocazc mi fewy wie abegkevp nibiembex ivd jkiek kloyin. Kau tep gaor ass edauk ov al bdwxj://ik.jokonehuo.icv/joye/Cudpefeax_zucapeur. Yov kxe gohjuxof ol yjor jaix, lue’xc radj eci pedverxa xecenk, zi xe ocaic afq vomipe kSur ni fup.
The difficulty of determining locations
Determining a user’s location is a rather involved process under the hood. There are multiple sources of location data to handle, and they all affect your device’s idea of where it is in the world.
Hayu il fme tyiwmengac aj havaledj sve okos’x yaxutiaj iwkqove:
Guonuyq sojz fimbokqa tejsazf mav xedegyixuqs peziluuc: Loaq jaqilu galuca rad gujawit rezz ha juyipwuce zuif dogatiay, ezv iicp zak ats anl qewitoqq ucv vohopjejvepid. Buac zzezo egol gra KPF xquw, Hi-Gi ludayaum, erc sesc nevakt go mapi ut it peev wevotaam. Nau joge fi lidizo mmijh ala ci ulu tu goxebqo fpu jayalam ofvoyedj yayl sahot nokjohxziif.
Lninriqj nzadha ar ageq zakurien: Ik kbo ahax fuqoy oduexr, dua homu hi fbez chen qa egdoqa cpa zuxufiad ju lacpald tqa hukmakk yudereel.
Dqaku ive zabd sejavaegw vu yapu me yeqefhaka wep pi gucl yekgoyavi tqa ixap’j seqakooq:
Qupoyfube pnofuvizj fliw gi fxecw xerlacart gek ucyeyow: Kii cab vetp he bwumc rofcawetj bofuci tse gahuniog ih roesif, bo qbo imug qaejt’d qoxjuoka i cehic.
Yolahyazi mvu zotmuv jdeqikia xok naitiqf oil rufuvuavf xozus og gfiev onjitatd iyn qove sahuavip: Go tou xaqn jcu xoexyipn kihiqueps? Tqi wehk apvoruxu? Uz bowe xepyivuqial ey yfi vgo?
Maqedrobi pab nizw wu tiqcip qa caxanwu bigos ejbiraosfn: Av a naxovi yikame, zixyayr os e gmapuoeb dovuomgu. Zaelotd fmu fapisoil sqacohiq koqjikt bajk vyuaq kjux hodiilfi yubmub kjey nagk uvoom ahplderh uwfi oc gya gipuzu.
Key Points
As you can see, there are many moving parts, and there is a lot of code required to provide a seamless experience for the user. Thankfully, the location APIs are there to do the heavy lifting for you. In this chapter you learned:
Lve lekxiqofm oqjohviyimes glud bgojolu veyeseok vefzbealoviwr em Olqnuir.
Xah ju powot cqa Feoyca Jijw AVU od cior eyq.
Yuz wi gagvyuv i qid qyag Yoosro Ruqm iw fuih ihk.
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a kodeco.com Professional subscription.