Tagalog (Wikang Tagalog) translation by Anna Nelson (you can also view the original English article)
Isa sa mga katangian ng Android na ginagawa itong espesyal ay ang kakayahang mabago ayon sa personal na kagustuhan ang bawat aspekto ng karanasan ng gumagamit. Noong unang inilunsad ang Android Wear sa Google I/O 2014, natuklasan ng maraming mga developer at user na hindi ito totoo para sa mga smart watch, bilang ang opisyal na API sa paggawa ng mga watch face ay kapansin-pansing nawawala. Dahil ang kakayahang gumawa ng sariling mga watch face ay isa sa mga susing kagustuhan ng mga user, hindi kagulat-gulat na nakatuklas ang mga developer ng paraan para lumikha ng sariling mga watch face gamit ng di-dokumentadong hack sa Android Wear.
Sa kabutihang-palad, agad na ipinaalam ng Google sa lahat na ang isang opisyal na API ay parating na, at sa Disyembre ng 2014 ang API ay inilabas na sa komunidad ng mga developer. Sa artikulong ito, iyong matututunan ang tungkol sa opisyal na mga Watch Face API para sa Android Wear, at ang pag-implemeta ng simpleng digital na watch face na maaaring palawakin ayon sa iyong pangangailangan. Ang pagiimplementa ng mga watch face ay maaaring maging masalita ngunit mahahanap ang sample application para sa artikulong ito sa GitHub.
1. Pag-ayos ng IDE
Ang unang kailangang gawin upang gumawa ng sariling watch face ay ang pag-ayos ng iyong project sa Android Studio. Sa paggawa ng iyong project, piliin ang Phone at Tablet na mayroong Minimum SDK na API 18 bilang ang Android 4.3 ay ang pinakamababang bersyon ng operating system na sumusuporta sa kumpol na Android Wear applications. Kailangan ding siguraduhing Wear box na mayroong Minimum SDK na API 21 ang napili. Iyong makikita ang isang halimbawa ng dapat na maging itsura ng iyong Target Android Devices screen.
Kapag nakarating na sa dalawang Add at Activity na mga screen, piliin and Add No Activity sa parehong screen.


Sa pagpindot ng Finish, ang iyong project environment ay dapat mag-build, at mayroong module para sa mobile at isa pa para sa wear.
2. Bagbuo ng Wear Watch Service
Ang Android Wear ay nagiimplementa ng mga
watch face sa pamamagitin ng paggamit ng WatchFace Service.
Sa artikulong ito, ikaw ay lilikha ng
ekstensyon ng CanvasWatchFaceService
class, na implementasyon ng
WatchFaceService
na nagbibigay ng Canvas
sa pagguhit ng iyong watch face. Magsimula sa paglikha ng bagong Java class sa
ilalim ng wear module sa Android Studio na pinapalawig ang
CanvasWatchFaceService.

public class WatchFaceService extends CanvasWatchFaceService
Kapag nakuha na ang iyong class, kailangang
bumuo ng inner class, WatchFaceEngline
sa mga source file ng article na ito, na
pinapalawig ang Engine.
Ito ang ang watch face engine na humahawak sa
mga system event, tulad ng pagpatay ng screen o pagpunta sa ambient mode.
private class WatchFaceEngine extends Engine
Kapag ang iyong stub code para sa
WatchFaceEngine
ay pumasok na, bumalik sa outer class at sapawan ang
onCreateEngine
na method upang bumalik sa bagong inner class. Iuugnay nito ang iyong watch face service sa
code na magpapalakad sa display.
@Override public Engine onCreateEngine() { return new WatchFaceEngine(); }
Kapag naipagsama-sama na ang bare bones service, maaari nang tumungo sa general housekeeping na mga gawain na pag-update ng iyong AndroidManifest files upang ang iyong service ay natutuklas ng Android Wear. Tandaan na ang kasalukuyang code ay wala pang magagawa. Babalikan ang class na ito at sasagarin ang engine matapos ang ilang project housekeeping.
3. Pag-update ng AndroidManifest Files
Buksan ang AdroidManifest.xml na file sa wear module. Malapit sa taas ay dapat makakakita ng linya na sinasabing:
<uses-feature android:name="android.hardware.type.watch" />
Sa ilalim ng linya, dapat magdagdag ng dalawang required permission para sa watch face. Ang mga pangangailangan na ito ay:
<uses-permission android:name="com.google.android.permission.PROVIDE_BACKGROUND" /> <uses-permission android:name="android.permission.WAKE_LOCK" />
Kapag ang mga permission ay nakahanda na,
kakailanganing magdagdag ng node para sa service sa application
node na may
permission na BIND_WALLPAPER
, ilang mga set ng meta-data
na mayroong
sangguniang imahe ng iyong watch face para sa selection screen (sa halimbawa na
ito ginagamit namin ang launcher icon), at isang intent-filter
upang ipaalam sa
system na ang iyong service ay para sa pagpapakita ng watch face.
<service android:name=".service.CustomWatchFaceService" android:label="Tuts+ Wear Watch Face" android:permission="android.permission.BIND_WALLPAPER"> <meta-data android:name="android.service.wallpaper" android:resource="@xml/watch_face" /> <meta-data android:name="com.google.android.wearable.watchface.preview" android:resource="@mipmap/ic_launcher" /> <meta-data android:name="com.google.android.wearable.watchface.preview_circular" android:resource="@mipmap/ic_launcher" /> <intent-filter> <action android:name="android.service.wallpaper.WallpaperService" /> <category android:name="com.google.android.wearable.watchface.category.WATCH_FACE" /> </intent-filter> </service>
Kapag ang iyong wear manifest ay kumpleto na,
kakailanganin mong buksan ang AndroidManifest.xml na file sa mobile module, at
idagdag ang dalawang permission na ginamit sa wear module para sa
PROVIDE_BACKGROUND
at WAKE_LOCK
, dahil and Android Wear ay nangangailangan na
ang parehong wear at mobile module ay hilingin ang parehong permission para sa
pag-install ng wear APK sa relo ng user. Kapag ang parehong manifest file ay napuno na,
maaari nang bumalik sa CustomWatchService.java upang simulan ang pag-implementa
ng engine.
4. Simulan ang Engine
Ang Engine
object na iniugnay sa iyong service
ay ang nagpapatakbo sa iyong watch face. Hinawakan nito ang mga timer, pagpapakita ng
iyong user interface, pagpasok at paglabas sa ambient mode, at pagkuha ng
impormasyon tungkol sa pisikal na display ng relo. Sa maikling salita, dito nagsisimula ang
hiwaga.
Hakbang 1: Pagtukoy sa mga Kinakailangang Value at Variable
Ang unang gagawin ay ang pag-implementa ng isang set ng member variable sa iyong engine upang bantayan ang estado ng device, timer interval, at mga bagay para sa iyong display.
//Member variables private Typeface WATCH_TEXT_TYPEFACE = Typeface.create( Typeface.SERIF, Typeface.NORMAL ); private static final int MSG_UPDATE_TIME_ID = 42; private long mUpdateRateMs = 1000; private Time mDisplayTime; private Paint mBackgroundColorPaint; private Paint mTextColorPaint; private boolean mHasTimeZoneReceiverBeenRegistered = false; private boolean mIsInMuteMode; private boolean mIsLowBitAmbient; private float mXOffset; private float mYOffset; private int mBackgroundColor = Color.parseColor( "black" ); private int mTextColor = Color.parseColor( "red" );
Tulad ng iyong nakikita, tutukuyin natin ang
TypeFace
na ating gagamitin para sa ating digital watch text, pati na rin ang
kulay ng watch face background at kulay ng sulat. Ang Time
object ay ginagamit para sa, nahulaan
mo, pagbantay sa kasalukuyang oras ng device. Ang mUpdateRateMs
ay ginagamit upang kontrolin
ang timer na kakailanganing iimplementa upang magkaroon ng update ang ating
watch face bawat segundo (kaya mayroong 1000 na milisecond na halaga para sa
mUpdateRateMs
), dahil ang karaniwang WatchFaceService
ay binabantayan lamang
ang oras sa isang minutong mga pagitan. mXOffset
at mYOffset
ay maitutukoy kapag alam na ng engine ang
pisikal na hugis ng relo upang ang ating watch face ay maaaring iguhit nang
hindi nagiging masyadong malapit sa taas at kaliwa ng screen, o upang hindi
maputol ng bilugan na kanto. Ang tatlong boolean value ay ginagamit upang
bantayan ang iba’t ibang estado ng device at application.
Ang sunod na object na kakailanganing tukuyin ay ang broadcast receiver na humahawak sa mga sitwasyon kung saan ang gumagamit ay lumalakbay at nag-iiba ng time zone. Ang receiver ay binubura ang mga naka-tabing mga time zone at binabalik sa umpisa ang pinapakitang oras.
final BroadcastReceiver mTimeZoneBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { mDisplayTime.clear( intent.getStringExtra( "time-zone" ) ); mDisplayTime.setToNow(); } };
Matapos matukoy ang receiver, ang huling
object na kakailanganin mong buoin sa tuktok ng iyong engine ay ang Handler
na
bahala sa pag-update ng iyong watch face bawat segundo. Kailangan ito dahil sa mga limitasyon ng
WatchFaceService
na nabanggit na. Kung ang iyong watch face ay kailangan lang ng
update bawat minuto, maaaring huwag pansinin ang bahagi na ito.
private final Handler mTimeHandler = new Handler() { @Override public void handleMessage(Message msg) { switch( msg.what ) { case MSG_UPDATE_TIME_ID: { invalidate(); if( isVisible() && !isInAmbientMode() ) { long currentTimeMillis = System.currentTimeMillis(); long delay = mUpdateRateMs - ( currentTimeMillis % mUpdateRateMs ); mTimeHandler.sendEmptyMessageDelayed( MSG_UPDATE_TIME_ID, delay ); } break; } } } };
Ang pag-implementa ng Handler
ay walang
paligoy-ligoy. Una nitong tinitignan ang message ID. Kung tumutugma sa MSG_UPDATE_TIME_ID
, patuloy nitong maipapawalang-bisa ang kasalukuyang view para sa muling pagguhit. Matapos maisawalang-bisa ang view, ang Handler
ay titignan kung ang screen ay nakikita at hindi naka-ambient mode. Kung ito ay nakikita, magpapadala ito ng isa
pang rekwes matapos ng isang segundo. Ang rason kung bakit inuulit ang aksyon sa
Handler
tuwing ang watch face ay nakikita at hindi tuwing nasa ambient mode ay
dahil maaaring maging magastos sa buhay ng baterya kung bawat segundo ang
update. Kung ang user ay hindi nakatingin sa screen,
bumabalik lamang tayo sa WatchFaceService
implementation na nagkaakroon ng update bawat minuto.
Hakbang 2: Pagsisimula ng Engine
Ngayon na ang iyong mga variable at object ay
nadeklara na, panahon na upang simulan ang watch face. Ang Engine
ay mayroong onCreate
method na
dapat ay ginagamit para sa paglikha ng mga object at iba pang mga gawain na
maaring gumastos ng malaking halaga ng oras at baterya. Ikaw ay magtatakda ng ilang mga flag para sa
WatchFaceStyle
upang kontrolin kung paano nakikipag-ugnayan ang system sa user
tuwing ang watch face ay aktibo.
@Override public void onCreate(SurfaceHolder holder) { super.onCreate(holder); setWatchFaceStyle( new WatchFaceStyle.Builder( CustomWatchFaceService.this ) .setBackgroundVisibility( WatchFaceStyle.BACKGROUND_VISIBILITY_INTERRUPTIVE ) .setCardPeekMode( WatchFaceStyle.PEEK_MODE_VARIABLE ) .setShowSystemUiTime( false ) .build() ); mDisplayTime = new Time(); initBackground(); initDisplayText(); }
Para sa sample app, gagamitin ang
setWatchFaceStyle
upang itakda ang background ng iyong mga notification card
upang maipakita nang sandali kung ang card type ay itinakda bilang
interruptive. Ilalagay din ang peek mode upang ang mga
notification card ay ginagamit lang ang kinakailangang espasyo.
Huli, sasabihan mo ang system na hindi ipakita
ang default time dahil ikaw na mismo ang magpapakita nito. Habang ang mga ito ay iilan lamang sa mga
maaaring pagpilian, maaari kang makakita ng mas marami pang impormasyon sa
opisyal na dokumentasyon ng WatchFaceStyle.Builder
na object.
Matapos ilagay ang iyong WatchFaceStyle
,
maaaring itakda ang mDisplayTime
bilang bagong Time
object.
Ang initBackground
at initDisplayText
ay
naglalaan ng dalawang Paint
object na binibigyang kahulugan sa taas ng engine. Pagkatapos, ang background at text ay mayroong
nakatakdang sariling kulay at ang text ay nakatakda na ang typeface ang laki ng
font, habang ginagamit din ang anti-alisaing.
private void initBackground() { mBackgroundColorPaint = new Paint(); mBackgroundColorPaint.setColor( mBackgroundColor ); } private void initDisplayText() { mTextColorPaint = new Paint(); mTextColorPaint.setColor( mTextColor ); mTextColorPaint.setTypeface( WATCH_TEXT_TYPEFACE ); mTextColorPaint.setAntiAlias( true ); mTextColorPaint.setTextSize( getResources().getDimension( R.dimen.text_size ) ); }
Hakbang 3: Paghawak sa Device State
Sunod, kailangang mag-implementa ng iba’t
ibang mga metodo mula sa Engine
class na nag-uudyok ng mga pagbabago sa device
state. Magsisimula tayo sa pagtingin sa
onVisibilityChnage
method, na tinatawag kapag ang user ay tinatago o pinapakita
ang watch face.
@Override public void onVisibilityChanged( boolean visible ) { super.onVisibilityChanged(visible); if( visible ) { if( !mHasTimeZoneReceiverBeenRegistered ) { IntentFilter filter = new IntentFilter( Intent.ACTION_TIMEZONE_CHANGED ); CustomWatchFaceService.this.registerReceiver( mTimeZoneBroadcastReceiver, filter ); mHasTimeZoneReceiverBeenRegistered = true; } mDisplayTime.clear( TimeZone.getDefault().getID() ); mDisplayTime.setToNow(); } else { if( mHasTimeZoneReceiverBeenRegistered ) { CustomWatchFaceService.this.unregisterReceiver( mTimeZoneBroadcastReceiver ); mHasTimeZoneReceiverBeenRegistered = false; } } updateTimer(); }
Kapag ang metodo na iyon ay tinawag, titignan
nito kung ang watch face ay nakikita o hindi. Kung ang watch face ay nakikita, titignan nito kung ang BroadcastReceiver
na binibigyang kahulugan sa taas ng Engine
ay pumasok. Kung hindi, ang metodo ay gagawa ng IntentFilter
para sa ACTION_TIMEZONE_CHANGED
action at ipapasok ang BroadcastReceiver
na makinig para rito.
Kung ang watch face ay hindi nakikita, ang
method na ito at titignan kung ang BroadcastReceiver
ay pwedge maging unregistered. Kapag ang BroadcastReceiver
ay naihanda na, ang updateTimer
ay tatawagin
upang udyokin ang kawalan ng pagka-balido ng watch face at muling iguhit ang
watch face. Ang updateTimer
ay pinipigilan ang kahit anong
aksyon ng Hanlder
na hindi tiyak at titignan kung dapat bang magpadala ng isa
pa.
private void updateTimer() { mTimeHandler.removeMessages( MSG_UPDATE_TIME_ID ); if( isVisible() && !isInAmbientMode() ) { mTimeHandler.sendEmptyMessage( MSG_UPDATE_TIME_ID ); } }
Hakbang 4: Pakikipag-ugnayan sa Wearable Hardware
Kung ang iyong service ay kaugnay ang Android
Wear, onApplyWindowInsets
ang tinatawag. Ginagamit ito upang malaman kung ang device na
pinapatakbo ng iyong watch face ay pabilog o kuwadrado. Papayagan ka nito na palitan ang iyong watch
face upang tumugma sa hardware.
Kung ang metodo na ito ay tinawag sa sample application, titignan ng metodo ang hugis ng device at papalitan ang x offset na ginagamit sa pagguhit ng watch face upang siguraduhin na ang iyong watch face ay makikita sa device.
@Override public void onApplyWindowInsets(WindowInsets insets) { super.onApplyWindowInsets(insets); mYOffset = getResources().getDimension( R.dimen.y_offset ); if( insets.isRound() ) { mXOffset = getResources().getDimension( R.dimen.x_offset_round ); } else { mXOffset = getResources().getDimension( R.dimen.x_offset_square ); } }
Ang sunod na metodo na kakailanganin mong
sapawan ay ang onPropertiesChanged.
Ang metodo na ito ay tinatawag tuwing ang
naitukoy na ang mga katangian ng hardware, halimbawa, kung ang device ay
sumusuporta ng burn-in protection o low bit ambient mode.
Sa metodo na ito, titignan kung ang mga bagay-bagayay
maipapagana sa device na pinapatakbo ang iyong watch face at ilalagay sa member
variable na tinukoy sa taas ng iyong Engine.
@Override public void onPropertiesChanged( Bundle properties ) { super.onPropertiesChanged( properties ); if( properties.getBoolean( PROPERTY_BURN_IN_PROTECTION, false ) ) { mIsLowBitAmbient = properties.getBoolean( PROPERTY_LOW_BIT_AMBIENT, false ); } }
Hakbang 5: Pagtipid ng Baterya sa Ambient at Muted Mode
Matapos ang unang mga device state, iyong
gugustuhing iimplementa ang onAmbientModeChanged
at onInterruptionFilterChanged
. Tulad ng ipinapahiwatig ng pangalan nito, ang
onAmbientModeChanged
ay tinatawag tuwing ang device ay pumapasok o lumalabas ng
ambient mode.
Kung ang device ay nasa ambient mode, iyong papalitan ang kulay ng iyong watch face sa itim at puti upang maging malay sa baterya ng user. Kapag ang device ay bumabalik mula sa ambient mode, maaaring ibalik sa naunang mga kulay ang mga kulay ng iyong watch face. Iyo ring bigyang-pansin ang anti-aliasing para sa mga device na humihingi ng low bit ambient support. Matapos na maitakda lahat ng flag variables, maaari mong mapawalang-bisa at muling guhitin ang watch face, tapos ay tignan kung dapat bang magsimula ang isang segundong timer.
@Override public void onAmbientModeChanged(boolean inAmbientMode) { super.onAmbientModeChanged(inAmbientMode); if( inAmbientMode ) { mTextColorPaint.setColor( Color.parseColor( "white" ) ); } else { mTextColorPaint.setColor( Color.parseColor( "red" ) ); } if( mIsLowBitAmbient ) { mTextColorPaint.setAntiAlias( !inAmbientMode ); } invalidate(); updateTimer(); }
onInterruptionFilterChanged
ay tinatawag
tuwing ang user ay mano-manong papalitan ang mga interruption setting sa
kanilang wearable. Kapag nangyari
ito, kakailanganin mo tignan kung nakapatay ang tunog ng device at
palitan ang user inferface. Sa ganitong sitwasyon, iyong papalitan ang
transparency ng iyong watch face, itakda ang iyong Handle
r na mag-update bawat
minuto kung ang device ay nakapatay ang tunog, at matapos ay muling guhitin ang
iyong watch face.
@Override public void onInterruptionFilterChanged(int interruptionFilter) { super.onInterruptionFilterChanged(interruptionFilter); boolean isDeviceMuted = ( interruptionFilter == android.support.wearable.watchface.WatchFaceService.INTERRUPTION_FILTER_NONE ); if( isDeviceMuted ) { mUpdateRateMs = TimeUnit.MINUTES.toMillis( 1 ); } else { mUpdateRateMs = DEFAULT_UPDATE_RATE_MS; } if( mIsInMuteMode != isDeviceMuted ) { mIsInMuteMode = isDeviceMuted; int alpha = ( isDeviceMuted ) ? 100 : 255; mTextColorPaint.setAlpha( alpha ); invalidate(); updateTimer(); } }
Tuwing ang iyong device ay nasa ambient mode,
ang Hanlder
timer ay hindi na gagana. Ang iyong watch face ay maaari pa ring
mag-update sa kasalukuyang oras bawat minuto gamit ang nakalagay nang
onTimeTick
method upang mapawalang-bisa ang Canvas
.
@Override public void onTimeTick() { super.onTimeTick(); invalidate(); }
Hakbang 6: Pagguhit ng Face Watch
Kapag lahat ng maaaring mangyari ay naisaayos
na, panahon na sa wakas na guhitin ang iyong watch face. Ang CanvasWatchFaceService
ay gumagamit ng
karaniwang Canvas
object, kaya kailangan mong idagdag ang onDraw
sa iyong
Engine
at mano-manong guhitin ang iyong watch face.
Sa tutoryal na ito, tayo’y simpleng guguhit ng
pasulat na representasyon ng oras, bagaman maaari mo rin baguhin ang iyong
onDraw
upang madaling masuportahan ang analog na watch face. Sa metodo na ito, iyong beberipikahin na iyong
ipinapakita ang tamang oras sa pamamagitan ng pag-update ng iyong Time
object.
Matapos ay maaari nang simulan ang paggamit ng iyong watch face.
@Override public void onDraw(Canvas canvas, Rect bounds) { super.onDraw(canvas, bounds); mDisplayTime.setToNow(); drawBackground( canvas, bounds ); drawTimeText( canvas ); }
Ang drawBackground
ay naglalagay ng buong mga
kulay sa background ng Wear device.
private void drawBackground( Canvas canvas, Rect bounds ) { canvas.drawRect( 0, 0, bounds.width(), bounds.height(), mBackgroundColorPaint ); }
Ang drawTimeText
, gayumpaman, ay gumagawa ng
sulat para sa oras na ipapakita gamit ng tulong ng ilang mga helper method, at
matapos ay ilalagay ito sa canvas ng mga x at y na offset point na iyong
itinakda sa onApplyWindowInsets.
private void drawTimeText( Canvas canvas ) { String timeText = getHourString() + ":" + String.format( "%02d", mDisplayTime.minute ); if( isInAmbientMode() || mIsInMuteMode ) { timeText += ( mDisplayTime.hour < 12 ) ? "AM" : "PM"; } else { timeText += String.format( ":%02d", mDisplayTime.second); } canvas.drawText( timeText, mXOffset, mYOffset, mTextColorPaint ); } private String getHourString() { if( mDisplayTime.hour % 12 == 0 ) return "12"; else if( mDisplayTime.hour <= 12 ) return String.valueOf( mDisplayTime.hour ); else return String.valueOf( mDisplayTime.hour - 12 ); }

Konklusyon
Kapagiyong naimplementa ang mga metodo para sa pagguhit ng iyong watch face, ikaw ay mayroong nang mga panimulang kaalaman na kailangan upang gumawa ng sariling mong mga watch face. Ang maganda sa mga Android Wear watch face ay na umpisa pa lamang ito sa kung ano ang maaaring magawa.
Maaari mong idagdag ang companion
configuration activites sa relo o sa iyong phone, palitan ang watch face na
nakabase sa Canvas
gamit ang OpenGl implementation, o bumuo ng sarili mong
class mula sa WatchFaceService
upang matugunan ang iyong mga pangangailangan.
Idagdag pa rito na maaari mong gamitin ang iba pang mga API o impormasyon mula sa phone ng user, at ang mga posibilad ay tila walang katapusan. Maging malikhain sa iyong mga watch face at magpakasaya.
Envato Tuts+ tutorials are translated into other languages by our community members—you can be involved too!
Translate this post