Filter
-
Content Type
-
Category
Mobile/Wearable
Visual Display
Digital Appliance
Platform
Recommendations
Filter
Learn Code Lab
codelabdevelop a secure blockchain app objective learn how to create your own decentralized applications dapp using samsung blockchain keystore sdk overview integrating with new technology like blockchain is a burden to most developers for this reason, we offer a way to interwork with samsung blockchain keystore sdk with less effort developers can easily become a dapp developer with our samsung blockchain keystore sdk decentralized applications dapps run and store data on the blockchain network instead of a central server dapps offer increased security and reliability compared to centralized applications moreover, it provides a simple method for in-app payments using cryptocurrency samsung blockchain keystore sdk is used to obtain account information and sign a transaction to transfer cryptocurrency or execute smart contract execution in this code lab, you can learn how to integrate samsung blockchain keystore sdk into your app and how to implement blockchain basic concepts such as account information and signing transactions set up your environment you will need the following java se development kit 8 or later android studio latest version recommended mobile phone which supports samsung blockchain sample code here is a sample code for you to start coding in this code lab download it and start your learning experience! keystore sdk sample code 897 12 kb enable developer mode the developer mode helps developers test the samsung blockchain keystore in developer mode, app id verification is bypassed, so samsung blockchain keystore apis will be enabled to activate developer mode on your mobile device, follow the steps below navigate through settings > biometrics and security > samsung blockchain keystore and click about blockchain keystore tap the samsung blockchain keystore app name quickly, ten times or more if succeeded, developer mode will show noteonly a limited number of devices can be activated for one test app open project file after downloading the sample code, open the given android application project this project is a simple comments dapp based on ethereum ropsten test network it retrieves comments data from smart contract, displays them on the screen, and makes a transaction to execute smart contract function to post user’s comment in the next steps, you can get an account address and execute dapp service with blockchain keystore and you can see the result of successful dapp execution set the app id here, you don’t need to set the application id to use samsung blockchain keystore sdk instead, you must enable developer mode as described previously for the release version of your android app, in your android manifest file, add a metadata with a name as scw_app_id and a value as the app id issued by samsung blockchain keystore team samsung blockchain keystore aar file will read this value when your android app is initialized and help your android app connect to samsung blockchain keystore <manifest xmlns android="http //schemas android com/apk/res/android" package="com samsung android sdk coldwallet test" android versioncode="1" android versionname="1 0"> <application> <meta-data android name="scw_app_id" android value= <!-- put your app id here --> /> </application> </manifest> import samsung blockchain keystore sdk library into the project the sdk library is located at aar/keystoresdk_v1 5 1 aar of the project file to import the library go to gradle scripts > build gradle and enter the following dependencies dependencies { repositories { flatdir{ dirs 'aar' } } implementation 'com samsung android sdk coldwallet keystoresdk_v1 5 1@aar' } check the status of samsung blockchain keystore the first thing to do is to check the status of samsung blockchain keystore in the sample application, it is implemented at initializekeystore in presenter intropresenter java you can find the following steps to check the status of keystore in your android app, call scwservice getinstance if the returned value is an instance and not null, then it means samsung blockchain keystore is supported on the device however, if null is returned, the user must use a different keystore in the sample code, toast a message to notify that the device doesn’t support the keystore // check samsung blockchain keystore is supported or not if scwservice getinstance == null { mcontract toastmessage "samsung blockchain keystore is not supported on your device " ; } call getkeystoreapilevel api to see if the current samsung blockchain keystore being used, properly supports the features that your android app is currently aiming for if the required api level is higher than the current samsung blockchain keystore level, users are directed to samsung blockchain keystore app page in galaxy store through the provided deeplink to update // check installed api level else if scwservice getinstance getkeystoreapilevel < 1 { // if api level is lower, jump to galaxy apps to update keystore app mcontract showdialog "" , "ok" , "the api level is too low jump to galaxy store" , -> mcontract launchdeeplink scwdeeplink galaxy_store ; } check if a user has set up the samsung blockchain keystore and is ready to use it by calling getseedhash api if the seed hash value in string is zero-length, this means the user has not set up samsung blockchain keystore yet hence, your app will need to guide the user to jump to samsung blockchain keystore via deeplink to either create or import a wallet // check seed hash exist else if scwservice getinstance getseedhash length == 0 { // if seed hash is empty, // jump to blockchain keystore to create or import wallet mcontract showdialog "" , "ok" , "the seed hash is empty " + "jump to blockchain keystore to create/import wallet " , -> mcontract launchdeeplink scwdeeplink main ; } if the getseedhash api returned value is not zero-length, it means that the user has successfully set up samsung blockchain keystore if there is a previously saved or cached seed hash value, compare the two seed hash values if those two values are not equal, nor if there is no such saved cached seed hash value, then the address has to be checked again if the seed hash value has been changed, it means the master seed has been changed as well, meaning the address that your android app was linked to may no longer be the same address // check seed hash cached else if !textutils equals cachedseedhash, scwservice getinstance getseedhash { // if the seed hash is different from cached, update seed hash and address // go to next activity final string ethereumhdpath = "m/44'/60'/0'/0/0"; getethereumaddress ethereumhdpath , success, errorcode, address, seedhash -> { if success { updateaddress address ; updateseedhash seedhash ; mcontract showtimelineactivity true ; } else { mcontract toastmessage "cannot get address error code " + errorcode ; } mcontract setloading false ; } ; return false; } if those two values are equal, it means checking the keystore status was successful, and you can move on to the next step // success else { // set address from cached value // go to next activity string address = prefshelper getinstance getcachedaddress ; updateseedhash cachedseedhash ; updateaddress address ; mcontract showtimelineactivity false ; } get the ethereum address in the blockchain network, the address can be used like a user’s account as the balance and the transaction history can be checked using the address in this sample project, get the address from keystore and display the address and account balance in the bottom sheet of the screen keystore is a hierarchical deterministic hd wallet, a standard tree structure represented by derivation paths for the ethereum address, use “m/44'/60'/0'/0/0” follow bip44 it is implemented at getethereumaddress string hdpath, getethereumaddresscallback callback in presenter/intropresenter java arraylist<string> path = new arraylist<> ; path add hdpath ; scwservice getinstance getaddresslist new scwservice scwgetaddresslistcallback { @override public void onsuccess list<string> list { string seedhash = scwservice getinstance getseedhash ; string address = list get 0 ; callback onaddressreceived true, 0, address, seedhash ; } @override public void onfailure int errorcode, string errormessage { callback onaddressreceived false, errorcode, "", "" ; } }, path ; sign a transaction ether value transfer or smart contract execution is executed by transactions that users create and sign signing a transaction is the process of generating a signature on it using the private key of the transaction sender samsung blockchain keystore can be utilized to sign a cryptocurrency transaction, such as ethereum by implementing the following steps creates an unsigned transaction, and requests samsung blockchain keystore to sign the transaction via apis like signethtransaction then the user will see a transaction confirmation page on a secure screen called, trusted user interface tui executed in trusted execution environment tee by samsung blockchain keystore once the user confirms the transaction with pin or biometrics authentication, like fingerprint, samsung blockchain keystore will sign a transaction with the private key derived from the given hd path when samsung blockchain keystore returns the signed transaction, your app can submit or send the signed transaction to the blockchain network in this sample project, create an unsigned transaction to execute posting a comment smart contract in addition, sign the transaction with keystore and send the transaction it is implemented at signtransaction in presenter/writefeedpresenter java // sign the transaction with samsung blockchain keystore // use hdpath m/44'/60'/0'/0/0 final string hdpath = "m/44'/60'/0'/0/0"; scwservice getinstance signethtransaction new scwservice scwsignethtransactioncallback { @override public void onsuccess byte[] signedtransaction { boolean result = sendsignedtransaction signedtransaction ; listener transactiondidfinish result, "" ; } @override public void onfailure int errorcode, string errormessage { listener transactiondidfinish false, "error code " + errorcode ; } }, unsignedtx, hdpath, null ; run the app and try it out the app screen should look like below you're done! congratulations! you have successfully achieved the goal of this code lab now, you can create a decentralized app by yourself! if you're having trouble, you may download this file keystore sdk complete code 897 07 kb
web
foldables and large screens new opportunities in the mobile experience design guidelines design guidelines boost your apps’ value withfoldable & large screen optimization your galaxy becomes simpler, more convenient and better optimized with one ui. one ui provides meaningful innovations and improves your everyday life, ensuring that you adapt in the ever-changing world. also, one ui continues to evolve to bring your joyful experiences to life. code labs all tags all tags galaxy z develop a widget for flex window 25 mins start gamedev galaxy z implement flex mode into a unity game 30 mins start watch face studio galaxy z customize flex window using good lock plugin on watch face studio 20 mins start galaxy z implement multi-window picture-in-picture on a video player 20 mins start gamedev galaxy z implement flex mode on an unreal engine game 120 mins start samsung internet galaxy z develop a camera web app on foldables 30 mins start galaxy z implement app continuity and optimize large screen ui of a gallery app 40 mins start galaxy z configure an app to enable drag and drop in multi-window 30 mins start galaxy z implement flex mode on a video player 30 mins start rich ui optimized for large screens! foldable devices can provide richer experiences than phones. learn how to optimize your app's ui for large screen devices in our newly updated one ui guide. read more if you don’t have any galaxy z devices try remote test lab! remote control test lab provides a foldable device for testing app even when you don’t onw one. check out the video tutorial on the remote test lab to max out your knowledge! video thumbanil blogs go to blog search this wide range of blog articles for tips and valuable know-how in developing apps related to foldable & large screen optimization. galaxy z tech docs get detailed info on the galaxy z (foldable) in the following tech documents. overview the new form factor is not the only thing notable in foldable phones. it opens new opportunities in the mobile experience. app continuity app continuity refers to the capability of an app to seamlessly restore the user state when it receives a configuration change. multi-window the ability to have multiple windows open simultaneously benefits from larger screen real estate. flex mode when your phon is partially folded, it will go into flex mode. apps will reorient to fit the screen, letting you sending messages. ux and ui considerations by considering new layouts and navigation patterns, app developers can explore opportunities to build greater experence. testing the how your app reacts to optimized ui layout, app continuity, multi-active window and flex mode. community forums & tech support ask question and find answers at forums. if you need development support, submit a support request. developer forum tech support our partners meet samsung’s partners already making use of ui optimized for large screens.
Learn Code Lab
codelabtransfer erc20 token with blockchain app objective develop a decentralized application dapp to transfer erc20 tokens between ethereum accounts using samsung blockchain platform sdk overview blockchain technology has been creating a significant impact in multiple sectors, such as banking, cybersecurity, and supply chain management it is widely used as a means of secure payment between different parties samsung blockchain platform sdk brings developers and consumers to the blockchain world by providing a complete set of functions that the decentralized app dapp or blockchain app needs ethereum is a decentralized blockchain network where you can perform transactions using its native currency, ether, and token you can interact with the network through simple api calls provided by the sdk for detailed information, see samsung blockchain platform sdk set up your environment you will need the following java se development kit 8 or later android studio latest version recommended samsung galaxy device that supports samsung blockchain sample code here is a sample code for you to start coding in this code lab download it and start your learning experience! token transaction sample code 2 73 mb enable developer mode to activate developer mode on your mobile device, follow the steps below navigate through settings > biometrics and security > samsung blockchain keystore and click about blockchain keystore tap the samsung blockchain keystore app name quickly, ten times or more if succeeded, developer mode will show start your project after downloading the sample code containing the project files, in android studio, click open to open the existing project locate the downloaded android project codelab-send-token-transaction-blank-code from the directory and click ok noteuser interface ui resources are already included in the provided project simply apply the code in the next steps in this code lab moreover, going through the sdk document is recommended initialize the instance since sblockchain is the initial base class of the samsung blockchain platform sdk, the first thing you need to do is create an sblockchain instance along with that, create the following in sendtokenfragment java hardwarewalletmanager for wallet operations accountmanager for account operations ethereumservice for transactions msblockchain = new sblockchain ; try { msblockchain initialize mcontext ; } catch ssdkunsupportedexception e { e printstacktrace ; } maccountmanager = msblockchain getaccountmanager ; mhardwarewalletmanager = msblockchain gethardwarewalletmanager ; mcoinnetworkinfo = new coinnetworkinfo cointype eth, ethereumnetworktype goerli, rpcurl ; mcoinservice = coinservicefactory getcoinservice getcontext , mcoinnetworkinfo ; ethereumservice = ethereumservice mcoinservice; connecttohardwarewallet ; connect to samsung blockchain keystore connect the app to the hardware wallet, which, in this case, is the samsung blockchain keystore you can get a hardware wallet instance from hardwarewalletmanager if you want to reset the wallet, set the second parameter of connect api to true otherwise, set it to false mhardwarewalletmanager connect hardwarewallettype samsung, false setcallback new listenablefuturetask callback<hardwarewallet> { @override public void onsuccess hardwarewallet hardwarewallet { handler post new runnable { @override public void run { log i tag, "hardwarewallet is connected " ; mprogressbar setvisibility view invisible ; getaccount ; } } ; } @override public void onfailure @nonnull executionexception e { mprogressbar setvisibility view invisible ; log e tag, "hardwarewallet connection failed " + e ; } @override public void oncancelled @nonnull interruptedexception e { mprogressbar setvisibility view invisible ; log e tag, "hardwarewallet connection cancelled " + e ; } } ; generate new account samsung blockchain platform sdk manages the address on blockchain as an account it contains the information required for signing and the blockchain address accountmanager provides apis dedicated for fetching, creating, and restoring accounts use generatenewaccount api for the creation of a new ethereum account upon clicking the create account button in the app hardwarewallet connectedhardwarewallet = mhardwarewalletmanager getconnectedhardwarewallet ; maccountmanager generatenewaccount connectedhardwarewallet, mcoinnetworkinfo setcallback new listenablefuturetask callback<account> { @override public void onsuccess account account { mprogressbar setvisibility view invisible ; log i tag, "generate new account successful " + account ; handler post new runnable { @override public void run { getaccount ; } } ; } @override public void onfailure @nonnull executionexception e { mprogressbar setvisibility view invisible ; log e tag, "generate new account failed " + e ; } @override public void oncancelled @nonnull interruptedexception e { mprogressbar setvisibility view invisible ; log e tag, "generate new account cancelled " + e ; } } ; after creating a new account, call the getaccounts api to get the account list if you already have an account, the textview will show the account's address and the create account button will be disabled in the app accounts = maccountmanager getaccounts null, cointype eth, ethereumnetworktype goerli ; if !accounts isempty { methereumaccount = ethereumaccount accounts get accounts size - 1 ; showaccounttextview settext methereumaccount getaddress ; generateaccountbutton setenabled false ; } create a token account to perform a token transaction, add the token address with the corresponding ethereum account and create a token account by calling the addtokenaddress api use the generated token account to perform token-related actions an ethereum account can add one or more tokens ethereumservice addtokenaddress methereumaccount, tokenaddress setcallback new listenablefuturetask callback<ethereumaccount> { @override public void onsuccess ethereumaccount ethereumaccount { mprogressbar setvisibility view invisible ; log i tag, "add token successful " + ethereumaccount ; handler post new runnable { @override public void run { toast maketext getcontext , "add token successful", toast length_short show ; } } ; } @override public void onfailure @nonnull executionexception e { mprogressbar setvisibility view invisible ; log e tag, "add token failed " + e ; } @override public void oncancelled @nonnull interruptedexception e { mprogressbar setvisibility view invisible ; log e tag, "add token cancelled " + e ; } } ; get token balance fetch the balance of the added token using gettokenbalance api ethereumservice gettokenbalance mtokenaccount, ethereumblockparameter latest setcallback new listenablefuturetask callback<biginteger> { @override public void onsuccess biginteger biginteger { mprogressbar setvisibility view invisible ; bigdecimal tokendecimal = bigdecimal ten pow 18 ; bigdecimal balance = new bigdecimal biginteger divide tokendecimal ; log d tag, "gettokenbalance success " + balance ; handler post new runnable { @override public void run { tokenbalance settext balance tostring ; } } ; } @override public void onfailure @nonnull executionexception e { mprogressbar setvisibility view invisible ; log e tag, "gettokenbalance failed " + e ; } @override public void oncancelled @nonnull interruptedexception e { mprogressbar setvisibility view invisible ; log e tag, "gettokenbalance cancelled " + e ; } } ; transfer token to transfer tokens between accounts, set the receiver address and the amount of tokens to send the trusted ui of the samsung blockchain keystore hardware wallet appears upon pressing the send button in the app, showing all the information regarding the transaction for confirmation generate a transaction hash upon confirmation of the transaction ethereumservice sendtokentransaction mhardwarewalletmanager getconnectedhardwarewallet , mtokenaccount, mtoaddress, tokenaddress, maxpriorityfee, methereumfeeinfo getestimatedbasefee add maxpriorityfee , mgaslimit, msendtokenamount, null setcallback new listenablefuturetask callback<transactionresult> { @override public void onsuccess transactionresult transactionresult { mprogressbar setvisibility view invisible ; log i tag, "send token successful " + transactionresult gethash ; handler post new runnable { @override public void run { toast maketext getcontext , "transaction hash " + transactionresult gethash , toast length_short show ; } } ; } @override public void onfailure @nonnull executionexception e { mprogressbar setvisibility view invisible ; log e tag, "send token failed " + e ; } @override public void oncancelled @nonnull interruptedexception e { mprogressbar setvisibility view invisible ; log i tag, "send token cancelled " + e ; } } ; run the app after building the apk, follow the steps below to test the application on a samsung blockchain-compatible device in send token tab, click create account copy the generated account address go to eth faucet tab to open the free faucet site already added to the application paste the account address and press the send me eth button click the hash string under your transactions to open etherscan and wait until the transaction succeeded go to token faucet tab and press get token to add some tokens in the account confirm the transaction go back to send token tab, click add token and press token balance to see added tokens press gas limit and max priority fee lastly, press send to transfer tokens confirm the transaction check the transaction status and details by finding the account address or the generated transaction hash txn hash in goerli testnet explorer you're done! congratulations! you have successfully achieved the goal of this code lab now, you can develop a decentralized application that can transfer erc20 tokens using samsung blockchain platform sdk if you face any trouble, you may download this file token transaction complete code 2 73 mb to learn more about developing apps with samsung blockchain, visit developer samsung com/blockchain
tutorials game, mobile
blogwith the increasing popularity of foldable phones such as the galaxy z fold3 and galaxy z flip3, apps on these devices are adopting its foldable features. in this blog, you can get started on how to utilize these foldable features on android game apps. we focus on creating a java file containing an implementation of the android jetpack windowmanager library that can be imported into game engines like unity or unreal engine. this creates an interface allowing developers to retrieve information about the folding feature on the device. at the end of this blog, you can go deeper in learning by going to code lab. android jetpack windowmanager android jetpack, in their own words, is "a suite of libraries to help developers follow best practices, reduce boilerplate code, and write code that works consistently across android versions and devices so that developers can focus on the code they care about." windowmanager is one of these libraries, and is intended to help application developers support new device form factors and multi-window environments. the library had its 1.0.0 release in january 2022 for targeted foldable devices. according to its documentation, future versions will be extended to more display types and window features. creating the android jetpack windowmanager setup as previously mentioned, we are creating a java file that can be imported into either unity or unreal engine 4, to create an interface for retrieving information on the folding feature and pass it over to the native or engine side of your applications. set up the foldablehelper class and data storage class create a file called foldablehelper.java in visual studio or any source code editor. let's start off by giving it a package name of package com.samsung.android.gamedev.foldable; next, let's import all the necessary libraries and classes in this file: //android imports import android.app.activity; import android.graphics.rect; import android.os.handler; import android.os.looper; import android.util.log; //android jetpack windowmanager imports import androidx.annotation.nonnull; import androidx.core.util.consumer; import androidx.window.java.layout.windowinfotrackercallbackadapter; import androidx.window.layout.displayfeature; import androidx.window.layout.foldingfeature; import androidx.window.layout.windowinfotracker; import androidx.window.layout.windowlayoutinfo; import androidx.window.layout.windowmetrics; import androidx.window.layout.windowmetricscalculator; //java imports import java.util.list; import java.util.concurrent.executor; start by creating a class, foldablehelper, that is going to contain all of our helper functions. let's then create variables to store a callback object as well as windowinfotrackercallbackadapter and windowmetricscalculator. let's also create a temporary declaration of the native function to pass the data from java to the native side of application once we start working in the game engines. public class foldablehelper { private static layoutstatechangecallback layoutstatechangecallback; private static windowinfotrackercallbackadapter wit; private static windowmetricscalculator wmc; public static native void onlayoutchanged(foldablelayoutinfo resultinfo); } let's create a storage class to hold the data received from the windowmanager library. an instance of this class will also be passed to the native code to transfer the data. public static class foldablelayoutinfo { public static int undefined = -1; // hinge orientation public static int hinge_orientation_horizontal = 0; public static int hinge_orientation_vertical = 1; // state public static int state_flat = 0; public static int state_half_opened = 1; // occlusion type public static int occlusion_type_none = 0; public static int occlusion_type_full = 1; rect currentmetrics = new rect(); rect maxmetrics = new rect(); int hingeorientation = undefined; int state = undefined; int occlusiontype = undefined; boolean isseparating = false; rect bounds = new rect(); } initialize the windowinfotracker since we are working in java and the windowmanager library is written in kotlin, we have to use the windowinfotrackercallbackadapter. this is an interface provided by android to enable the use of the windowinfotracker from java. the window info tracker is how we receive information about any foldable features inside the window's bounds. next is to create windowmetricscalculator, which lets us retrieve the window metrics of an activity. window metrics consists of the windows' current and maximum bounds. we also create a new layoutstatechangecallback object. this object is passed into the window info tracker as a listener object and is called every time the layout of the device changes (for our purposes this is when the foldable state changes). public static void init(activity activity) { //create window info tracker wit = new windowinfotrackercallbackadapter(windowinfotracker.companion.getorcreate(activity)); //create window metrics calculator wmc = windowmetricscalculator.companion.getorcreate(); //create callback object layoutstatechangecallback = new layoutstatechangecallback(activity); } set up and attach the callback listener in this step, let's attach the layoutstatechangecallback to the windowinfotrackercallbackadapter as a listener. the addwindowlayoutinfolistener function takes three parameters: the activity to attach the listener to, an executor, and a consumer of windowlayoutinfo. we will set up the executor and consumer in a moment. the adding of the listener is kept separate from the initialization, since the first windowlayoutinfo is not emitted until activity.onstart has been called. as such, we'll likely not be needing to attach the listener until during or after onstart, but we can still set up the windowinfotracker and windowmetricscalculator ahead of time. public static void start(activity activity) { wit.addwindowlayoutinfolistener(activity, runonuithreadexecutor(), layoutstatechangecallback); } now, let's create the executor for the listener. this executor is straightforward and simply runs the command on the mainlooper of our activity. it is possible to set this up to run on a custom thread, however this is not going to be covered in this blog. for more information, we recommend checking the official documentation for the jetpack windowmanager. static executor runonuithreadexecutor() { return new myexecutor(); } static class myexecutor implements executor { handler handler = new handler(looper.getmainlooper()); @override public void execute(runnable command) { handler.post(command); } } we're going to create the basic layout of our layoutstatechangecallback. this consumes windowlayoutinfo and implements consumer<windowlayoutinfo>. for now, let's simply lay out the class and give it some functionality a little bit later. static class layoutstatechangecallback implements consumer<windowlayoutinfo> { private final activity activity; public layoutstatechangecallback(activity activity) { this.activity = activity; } } if the use of the listener is no longer needed, we want a way to remove it and the windowinfotrackercallbackadapter contains a function to do just that. public static void stop() { wit.removewindowlayoutinfolistener(layoutstatechangecallback); } this just tidies things up for us and ensures that the listener is cleaned up when we no longer need it. next, we're going to add some functionality to the layoutstatechangecallback class. we are going to process windowlayoutinfo into foldablelayoutinfo we created previously. using java native interface (jni), we are going to send that information over to the native side using the function onlayoutchanged. note: this doesn't actually do anything yet, but we cover how to set this up in unreal engine and in unity through code lab tutorials. static class layoutstatechangecallback implements consumer<windowlayoutinfo> { @override public void accept(windowlayoutinfo windowlayoutinfo) { foldablelayoutinfo resultinfo = updatelayout(windowlayoutinfo, activity); onlayoutchanged(resultinfo); } } let's implement the updatelayout function to process windowlayoutinfo and return a foldablelayoutinfo. firstly, create a foldablelayoutinfo that contains the processed information. follow this up by getting the window metrics, both maximum metrics and current metrics. private static foldablelayoutinfo updatelayout(windowlayoutinfo windowlayoutinfo, activity activity) { foldablelayoutinfo retlayoutinfo = new foldablelayoutinfo(); windowmetrics wm = wmc.computecurrentwindowmetrics(activity); retlayoutinfo.currentmetrics = wm.getbounds(); wm = wmc.computemaximumwindowmetrics(activity); retlayoutinfo.maxmetrics = wm.getbounds(); } get the displayfeatures present in the current window bounds using windowlayoutinfo.getdisplayfeatures. currently, the api only has one type of displayfeature: foldingfeatures, however in the future there will likely be more as screen types evolve. at this point, let's use a for loop to iterate through the resulting list until it finds a foldingfeature. once it detects a folding feature, it starts processing its data: orientation, state, seperation type, and its bounds. then, store these data in foldablelayoutinfo we've created at the start of the function call. you can learn more about these data by going to the jetpack windowmanager documentation. private static foldablelayoutinfo updatelayout(windowlayoutinfo windowlayoutinfo, activity activity) { foldablelayoutinfo retlayoutinfo = new foldablelayoutinfo(); windowmetrics wm = wmc.computecurrentwindowmetrics(activity); retlayoutinfo.currentmetrics = wm.getbounds(); wm = wmc.computemaximumwindowmetrics(activity); retlayoutinfo.maxmetrics = wm.getbounds(); list<displayfeature> displayfeatures = windowlayoutinfo.getdisplayfeatures(); if (!displayfeatures.isempty()) { for (displayfeature displayfeature : displayfeatures) { foldingfeature foldingfeature = (foldingfeature) displayfeature; if (foldingfeature != null) { if (foldingfeature.getorientation() == foldingfeature.orientation.horizontal) { retlayoutinfo.hingeorientation = foldablelayoutinfo.hinge_orientation_horizontal; } else { retlayoutinfo.hingeorientation = foldablelayoutinfo.hinge_orientation_vertical; } if (foldingfeature.getstate() == foldingfeature.state.flat) { retlayoutinfo.state = foldablelayoutinfo.state_flat; } else { retlayoutinfo.state = foldablelayoutinfo.state_half_opened; } if (foldingfeature.getocclusiontype() == foldingfeature.occlusiontype.none) { retlayoutinfo.occlusiontype = foldablelayoutinfo.occlusion_type_none; } else { retlayoutinfo.occlusiontype = foldablelayoutinfo.occlusion_type_full; } retlayoutinfo.isseparating = foldingfeature.isseparating(); retlayoutinfo.bounds = foldingfeature.getbounds(); return retlayoutinfo; } } } return retlayoutinfo; } if there's no folding feature detected, it simply returns the foldablelayoutinfo without setting its data leaving it with undefined (-1) values. conclusion the java file you have now created should be usable in new or existing unity and unreal engine projects, to provide access to the information on the folding feature. continue learning about it by going to the code lab tutorials showing how to use the file created here, to implement flex mode detection and usage in game applications. additional resources on the samsung developers site the samsung developers site has many resources for developers looking to build for and integrate with samsung devices and services. stay in touch with the latest news by creating a free account and subscribing to our monthly newsletter. visit the marketing resources page for information on promoting and distributing your apps. finally, our developer forum is an excellent way to stay up-to-date on all things related to the galaxy ecosystem.
Lochlann Henry Ramsay-Edwards
Learn Code Lab
codelabimplement flex mode into a unity game objective learn how to implement flex mode into a unity game using android jetpack windowmanager and unity's java native interface jni wrapper overview the flexible hinge and glass display on galaxy foldable devices, such as the galaxy z fold4 and galaxy z flip4, let the phone remains propped open while you use apps when the phone is partially folded, it will go into flex mode apps will reorient to fit the screen, letting you watch videos or play games without holding the phone for example, you can set the device on a flat surface, like on a table, and use the bottom half of the screen to navigate unfold the phone to use the apps in full screen mode, and partially fold it again to return to flex mode to provide users with a convenient and versatile foldable experience, developers need to optimize their apps to meet the flex mode standard set up your environment you will need the following unity hub with unity 2022 3 5f1 or later must have android build support visual studio or any source code editor galaxy z fold2 or newer remote test lab if physical device is not available requirements samsung account java runtime environment jre 7 or later with java web start internet environment where port 2600 is available sample code here is a sample project for you to start coding in this code lab download it and start your learning experience! flex mode on unity sample code 1 17 gb start your project after downloading the sample project files, follow the steps below to open your project launch the unity hub click projects > open locate the unzipped project folder and click open to add the project to the hub and open in the editor notethe sample project was created in unity 2022 3 5f1 if you prefer using a different unity version, click choose another editor version when prompted and select a higher version of unity configure android player settings to ensure that the project runs smoothly on the android platform, configure the player settings as follows go to file > build settings under platform, choose android and click switch platform wait until this action finishes importing necessary assets and compiling scripts then, click player settings to open the project settings window go to player > other settings and scroll down to see target api level set it to api level 33 as any less than this will result in a dependency error regarding an lstar variable you can set the minimum api level on lower levels without any problem next, in the resolution and presentation settings, enable resizable window it is also recommended that render outside safe area is enabled to prevent black bars on the edges of the screen lastly, enable the custom main manifest, custom main gradle template, and custom gradle properties template in the publishing settings after closing the project settings window, check for the new folder structure created within your assets in the project window the newly created android folder contains androidmanifest xml, gradletemplate properties, and maintemplate gradle files import the foldablehelper and add dependencies foldablehelper is a java file that you can use in different projects it provides an interface to the android jetpack windowmanager library, enabling application developers to support new device form factors and multi-window environments before proceeding, read how to use jetpack windowmanager in android game dev and learn the details of how foldablehelper uses windowmanager library to retrieve information about the folded state of the device flat for normal mode and half-opened for flex mode , window size, and orientation of the fold on the screen download the foldablehelper java file here foldablehelper java 6 22 kb to import the foldablehelper java file and add dependencies to the project, follow the steps below in assets > plugins > android, right-click and select import new asset locate and choose the foldablehelper java file, then click import next, open the gradletemplate properties file to any source code editor like visual studio and add the following lines below the **additional_properties** marker android useandroidx = true android enablejetifier = true useandroidx sets the project to use the appropriate androidx libraries instead of support libraries enablejetifier automatically migrates existing third-party libraries to use androidx by rewriting their binaries lastly, open the maintemplate gradle file and add the dependencies for the artifacts needed for the project **apply_plugins** dependencies { implementation filetree dir 'libs', include ['* jar'] implementation "androidx appcompat appcompat 1 6 1" implementation "androidx core core 1 10 1" implementation "androidx core core-ktx 1 10 1" implementation "androidx window window 1 0 0" implementation "androidx window window-java 1 0 0" implementation "org jetbrains kotlin kotlin-stdlib-jdk8 1 9 0" **deps**} create a new playeractivity to implement flex mode on your applications, you must make necessary changes to the activity since it is impossible to access and change the original unityplayeractivity, you need to create a new playeractivity that inherits from the original to do this create a new file named foldableplayeractivity java and import it into the android folder, same as when you imported the foldablehelper java file to extend the built-in playeractivity from unity, write below code in the foldableplayeractivity java file package com unity3d player; import android os bundle; import com unity3d player unityplayeractivity; import com samsung android gamedev foldable foldablehelper; import com samsung android gamedev foldable foldablehelper windowinfolayoutlistener; import android util log; public class foldableplayeractivity extends unityplayeractivity { @override protected void oncreate bundle savedinstancestate { super oncreate savedinstancestate ; foldablehelper init this ; } @override protected void onstart { super onstart ; foldablehelper start this ; } @override protected void onstop { super onstop ; foldablehelper stop ; } @override protected void onrestart { super onrestart ; foldablehelper init this ; } public void attachunitylistener windowinfolayoutlistener listener { foldablehelper attachnativelistener listener, this ; } } oncreate calls the foldablehelper init to ensure that the windowinfotracker and metrics calculator gets created as soon as possible onstart calls the foldablehelper start since the first windowlayoutinfo doesn't get created until onstart onstop calls the foldablehelper stop to ensure that when the application closes, the listener gets cleaned up onrestart calls foldablehelper init when returning to the app after switching away windowinfotracker must be re-initialized; otherwise, flex mode will no longer update after creating the foldableplayeractivity, ensure that the game uses it open the androidmanifest xml file and change the activity name to the one you've just created <activity android name="com unity3d player foldableplayeractivity" android theme="@style/unitythemeselector"> … </activity> store foldablelayoutinfo data to flexproxy implement a native listener that receives calls from java when the device state changes by following these steps use the androidjavaproxy provided by unity in its jni implementation androidjavaproxy is a class that implements a java interface, so the next thing you need to do is create an interface in the foldablehelper java file public interface windowinfolayoutlistener { void onchanged foldablelayoutinfo layoutinfo ; } this interface replaces the temporary native function therefore, remove the code below from the foldablehelper java file public static native void onlayoutchanged foldablelayoutinfo resultinfo ; then, go to the assets > flex_scripts folder and right-click to create a new c# script called flexproxy cs inside this script, replace the automatically generated class with the flexproxy class inheriting from androidjavaproxy public class flexproxy androidjavaproxy { } in flexproxy class, define the variables needed to store the data from foldablelayoutinfo and use enumerators for the folded state, hinge orientation, and occlusion type for the various bounds, use unity's rectint type also, use a boolean to store whether the data has been updated or not public enum state { undefined, flat, half_opened }; public enum orientation { undefined, horizontal, vertical }; public enum occlusiontype { undefined, none, full }; public state state = state undefined; public orientation orientation = orientation undefined; public occlusiontype occlusiontype = occlusiontype undefined; public rectint foldbounds; public rectint currentmetrics; public rectint maxmetrics; public bool needsupdate = false; next, define what java class the flexproxy is going to implement by using the interface's fully qualified name as below public flexproxy base "com samsung android gamedev foldable foldablehelper$windowinfolayoutlistener" { } com samsung android gamedev foldable is the package name of the foldablehelper java file foldablehelper$windowinfolayoutlistener is the class and interface name separated by a $ after linking the proxy to the java interface, create a helper method to simplify java to native conversions private rectint converttorectint androidjavaobject rect { if rect != null { var left = rect get<int> "left" ; var top = rect get<int> "top" ; var width = rect call<int> "width" ; var height = rect call<int> "height" ; return new rectint xmin left, ymin top, width width, height height ; } else { return new rectint -1, -1, -1, -1 ; } } this method takes a java rect object and converts it into a unity c# rectint now, use this converttorectint function for the onchanged function to retrieve the information from the java object and store it in the flex proxy class public void onchanged androidjavaobject layoutinfo { foldbounds = converttorectint layoutinfo get<androidjavaobject> "bounds" ; currentmetrics = converttorectint layoutinfo get<androidjavaobject> "currentmetrics" ; maxmetrics = converttorectint layoutinfo get<androidjavaobject> "maxmetrics" ; orientation = orientation layoutinfo get<int> "hingeorientation" + 1 ; state = state layoutinfo get<int> "state" + 1 ; occlusiontype = occlusiontype layoutinfo get<int> "occlusiontype" + 1 ; needsupdate = true; } implement native flex mode this section focuses on creating the flex mode split-screen effect on the game’s ui create a new c# script in the flex_scripts folder called flexmodemanager cs after creating the script, define the variables you need for this implementation public class flexmodemanager monobehaviour { private flexproxy windowmanagerlistener; [serializefield] private camera maincamera; [serializefield] private camera skyboxcamera; [serializefield] private canvas controlscanvas; [serializefield] private canvas healthcanvas; [serializefield] private gameobject flexbg; [serializefield] private gameobject uiblur; windowmanagerlistener is the callback object which receives the foldablelayoutinfo from the foldablehelper java implementation maincamera and skyboxcamera are two cameras to modify in this project for creating a seamless flex mode implementation controlscanvas and healthcanvas are the two ui elements to manipulate for implementing the flex mode flexbg is a background image to disable in normal mode and enable in flex mode to fill the bottom screen uiblur is a background blur element used as part of the tutorial text it doesn't function properly with flex mode, so disabling it when in flex mode makes the ui looks better next, in the start method, create a new instance of the flexproxy class and attach it to the unity application's activity via the attachunitylistener function void start { windowmanagerlistener = new flexproxy ; using androidjavaclass javaclass = new androidjavaclass "com unity3d player unityplayer" { using androidjavaobject activity = javaclass getstatic<androidjavaobject> "currentactivity" { activity call "attachunitylistener", windowmanagerlistener ; } } } in the update method, check if the windowmanagerlistener has received any new data on the folded state of the device if the system needs an update, then call updateflexmode void update { if windowmanagerlistener needsupdate { updateflexmode ; } } create the updateflexmode method to enable or disable flex mode notethis project is set up for landscape mode only the implementation discussed in this code lab only covers setting up flex mode with a horizontal fold in landscape however, if you were able to follow, it should be simple to set up something similar for different fold orientations on devices such as the galaxy z flip series of devices private void updateflexmode { } check the folded state of the device via the windowmanagerlistener if the device is half_opened, implement flex mode private void updateflexmode { if windowmanagerlistener state == flexproxy state half_opened { } } to split the ui screen horizontally, set the anchor points of the controlscanvas and the healthcanvas so they are locked at the bottom screen or below the fold also, set the viewports of the maincamera and skyboxcamera to be above the fold - which is the top screen next, set the anchors for the flexbg object and enable it to fill the space behind the ui on the bottom screen deactivate the uiblur element if it exists the ui blur element is only present at level 1 of the demo game a check is necessary to ensure the flex mode manager works on the second level private void updateflexmode { if windowmanagerlistener state == flexproxy state half_opened { float lowerscreenanchormax = float windowmanagerlistener foldbounds ymin / windowmanagerlistener currentmetrics height; recttransform controlscanvastransform = controlscanvas getcomponent<recttransform> ; recttransform healthcanvastransform = healthcanvas getcomponent<recttransform> ; recttransform flexbgtransform = flexbg getcomponent<recttransform> ; controlscanvastransform anchormin = new vector2 0, 0 ; controlscanvastransform anchormax = new vector2 1, lowerscreenanchormax ; healthcanvastransform anchormin = new vector2 0, lowerscreenanchormax ; healthcanvastransform anchormax = new vector2 0, lowerscreenanchormax ; flexbgtransform anchormin = new vector2 0, 0 ; flexbgtransform anchormax = new vector2 1, lowerscreenanchormax ; float upperscreenrectheight = float windowmanagerlistener foldbounds ymax / windowmanagerlistener currentmetrics height; maincamera rect = new rect 0, upperscreenrectheight, 1, upperscreenrectheight ; skyboxcamera rect = new rect 0, upperscreenrectheight, 1, upperscreenrectheight ; flexbg setactive true ; if uiblur != null uiblur setactive false ; } } return the ui to full screen when the device is no longer in flex mode by disabling flexbg; enabling uiblur when it exists; and setting all the anchor points and viewports back to their original values and finally, inform the windowmanagerlistener that it doesn't need an update else { recttransform controlscanvastransform = controlscanvas getcomponent<recttransform> ; recttransform healthcanvastransform = healthcanvas getcomponent<recttransform> ; controlscanvastransform anchormin = new vector2 0, 0 ; controlscanvastransform anchormax = new vector2 1, 1 ; healthcanvastransform anchormin = new vector2 0, 1 ; healthcanvastransform anchormax = new vector2 0, 1 ; maincamera rect = new rect 0, 0, 1, 1 ; skyboxcamera rect = new rect 0, 0, 1, 1 ; flexbg setactive false ; if uiblur != null uiblur setactive true ; } windowmanagerlistener needsupdate = false; set up the scenes for flex mode go back to the unity editor in assets > 3dgamekit > scenes > gameplay, double-click on the level 1 scene to open it right-click in the hierarchy window and select create empty name the new gameobject as flexmanager or a similar name to reflect its purpose select the flexmanager object and click the add component button in the inspector window type in flexmodemanager, and select the script when it shows up select the relevant objects for each camera, canvas and game object as below do the same for level 2 but leave the ui blur empty build and run the app go to file > build settings click build at the bottom of the window to build the apk after building the apk, run the game app on a foldable galaxy device and see how the ui switches from normal to flex mode if you don’t have any physical device, you can also test it on a remote test lab device tipwatch this tutorial video and know how to easily test your app via remote test lab you're done! congratulations! you have successfully achieved the goal of this code lab now, you can implement flex mode in your unity game app by yourself! to learn more, visit www developer samsung com/galaxy-z www developer samsung com/galaxy-gamedev
Learn Code Lab
codelabmeasure blood oxygen level on galaxy watch objective create a health app for galaxy watch, operating on wear os powered by samsung, utilizing samsung health sensor sdk to trigger and obtain blood oxygen level spo2 measurement results overview samsung health sensor sdk provides means of accessing and tracking health information contained in the health data storage its tracking service gives raw and processed sensor data such as accelerometer and body composition data sent by the samsung bioactive sensor the latest bioactive sensor of galaxy watch runs powerful health sensors such as photoplethysmogram ppg , electrocardiogram ecg , bioelectrical impedance analysis bia , sweat loss, and spo2 see samsung health sensor sdk descriptions for detailed information set up your environment you will need the following galaxy watch4 or newer android studio latest version recommended java se development kit jdk 11 or later sample code here is a sample code for you to start coding in this code lab download it and start your learning experience! measuring blood oxygen level sample code 146 3 kb connect your galaxy watch to wi-fi go to settings > connection > wi-fi and make sure that wi-fi is enabled from the list of available wi-fi networks, choose and connect to the same one as your pc turn on developer mode and adjust its settings on your watch, go to settings > about watch > software and tap on software version 5 times upon successful activation of developer mode, a toast message will display as on the image below afterwards, developer options will be visible under settings tap developer options and enable the following options adb debugging in developer options find wireless debugging turn on wireless debugging check always allow on this network and tap allow go back to developer options and click turn off automatic wi-fi notethere may be differences in settings depending on your one ui version connect your galaxy watch to android studio go to settings > developer options > wireless debugging and choose pair new device take note of the wi-fi pairing code, ip address & port in android studio, go to terminal and type adb pair <ip address> <port> <wi-fi pairing code> when prompted, tap always allow from this computer to allow debugging after successfully pairing, type adb connect <ip address of your watch> <port> upon successful connection, you will see the following message in android studio’s terminal connected to <ip address of your watch> now, you can run the app directly on your watch turn on developer mode for health platform on your watch go to settings > apps > health platform quickly tap health platform title for 10 times this enables developer mode and displays [dev mode] below the title to stop using developer mode, quickly tap health platform title for 10 times to disable it start your project in android studio, click open to open existing project locate the downloaded android project from the directory and click ok check capabilities for the device to track data with the samsung health sensor sdk, it must support a given tracker type – blood oxygen level to check this, get the list of available tracker types and verify that the tracker is on the list in the connectionmanager java file, navigate to the isspo2available function, use a provided healthtrackingservice object to create a healthtrackercapability instance, send it to the checkavailabletrackers function, and assign its result to the availabletrackers list gettrackingcapability returns a healthtrackercapability instance in the healthtrackingservice object healthtrackingservicehealthtrackingservice initiates a connection to samsung's health tracking service and provides a healthtracker instance to track a healthtrackertype public healthtrackercapability gettrackingcapability provide a healthtrackercapability instance to get a supporting health tracker type list /****************************************************************************************** * [practice 1] check capabilities to confirm spo2 availability * * ---------------------------------------------------------------------------------------- * * hint replace todo 1 with java code * get healthtrackercapability object from healthtrackingservice * send the object to checkavailabletrackers ******************************************************************************************/ public boolean isspo2available healthtrackingservice healthtrackingservice { if healthtrackingservice == null return false; list<healthtrackertype> availabletrackers = null; //"todo 1" if availabletrackers == null return false; else return availabletrackers contains healthtrackertype spo2_on_demand ; } check connection error resolution using samsung health sensor sdk api, resolve any error when connecting to health tracking service in the connectionmanager java file, navigate to the processtrackerexception function, and check if the provided healthtrackerexception object has a resolution assign the result to hasresolution variable hasresolution function in the healthtrackerexception object checks if the api can fix the error healthtrackerexceptionhealthtrackerexception contains error codes and checks the error's resolution if there is a resolution, solving the error is available by calling resolve activity boolean hasresolution checks whether the given error has a resolution /******************************************************************************************* * [practice 2] resolve healthtrackerexception error * * ----------------------------------------------------------------------------------------- * * hint replace todo 2 with java code * call hasresolution on healthtrackerexception object ******************************************************************************************/ public void processtrackerexception healthtrackerexception e { boolean hasresolution = false; //"todo 2" if hasresolution e resolve callingactivity ; if e geterrorcode == healthtrackerexception old_platform_version || e geterrorcode == healthtrackerexception package_not_installed observerupdater getobserverupdater notifyconnectionobservers r string novalidhealthplatform ; else observerupdater getobserverupdater notifyconnectionobservers r string connectionerror ; log e tag, "could not connect to health tracking service " + e getmessage ; } initialize spo2 tracker before the measurement starts, initialize the spo2 tracker by obtaining the proper health tracker object in the spo2listener java file, navigate to the init function using the provided healthtrackingservice object, create an instance of the spo2 tracker and assign it to the spo2tracker object gethealthtracker with healthtrackertype spo2_on_demand as an argument will create a healthtracker instance healthtrackingservicehealthtrackingservice initiates a connection to samsung's health tracking service and provides a healthtracker instance to track a healthtrackertype healthtracker gethealthtracker healthtrackertype healthtrackertype provides a healthtracker instance for the given healthtrackertype /******************************************************************************************* * [practice 3] initialize spo2 tracker * * ---------------------------------------------------------------------------------------- * * hint replace todo 3 with java code * initialize spo2tracker with proper samsung health sensor sdk functionality * call gethealthtracker on healthtrackingservice object * use healthtrackertype spo2_on_demand as an argument ******************************************************************************************/ void init healthtrackingservice healthtrackingservice { //"todo 3" } perform measurement for the client app to start obtaining the data through the sdk, it has to set a listener method on the healthtracker the application setups the listener when the user taps on the measure button each time there is new data, the listener callback receives it after the measurement is completed, the listener has to be disconnected due to battery drain, on-demand measurement should not last more than 30 seconds the measurement is cancelled if the final value is not delivered in time note that the sensor needs a few seconds to warm up and provide correct values, which adds to the overall measurement time the blood oxygen level values come in the ondatareceived callback of trackereventlistener in spo2listener java file, you can see the code for reading the value private final healthtracker trackereventlistener spo2listener = new healthtracker trackereventlistener { @override public void ondatareceived @nonnull list<datapoint> list { for datapoint data list { updatespo2 data ; } } }; private void updatespo2 datapoint data { int status = data getvalue valuekey spo2set status ; int spo2value = 0; if status == measurement_completed spo2value = data getvalue valuekey spo2set spo2 ; observerupdater getobserverupdater notifytrackerobservers status, spo2value ; } run unit tests for your convenience, you can find an additional unit tests package this lets you verify your code changes even without using a physical watch see instructions below on how to run unit tests right click on com samsung health spo2tracking test and execute run 'tests in 'com samsung health spo2tracking'' command if you completed all the tasks correctly, you can see that all the unit tests passed successfully run the app after building the apk, you can run the application on a connected device to measure blood oxygen level right after the app is started, it requests for user permission allow the app to receive data from the body sensors afterwards, it shows the application's main screen to get the blood oxygen level, tap on the measure button to stop the measurement, tap on the stop button you're done! congratulations! you have successfully achieved the goal of this code lab now, you can create a health app that measures blood oxygen level by yourself! if you're having trouble, you may download this file measuring blood oxygen level complete code 146 2 kb to learn more about samsung health, visit developer samsung com/health
Learn Code Lab
codelabcreate a smartthings edge driver for an iot bulb objective learn how to create and customize an edge driver for an iot bulb to seamlessly interoperate on the smartthings platform overview smartthings is a platform for iot devices to communicate within its ecosystem, enabling smarter living solutions that simplify everybody else's way of life there are multiple methods to connect an iot device to the smartthings platform, one of which is through a smartthings hub hub connected devices connect to a smartthings-compatible hub using matter, zigbee, z-wave, or lan protocols the smartthings-compatible hub allows devices that utilize these protocols to integrate within the smartthings platform, permitting users to view and control devices from the smartthings app to automate actions and more the connection from a smartthings device to a smartthings hub is made possible with edge drivers smartthings edge drivers serve as translators between the protocols used by the device and the smartthings platform these drivers enable the devices to run locally on the hub, offering many benefits including speed, reliability, and enhanced functionality learn more about edge drivers in the smartthings edge architecture section set up your environment you will need the following host pc running on windows 10 or higher or ubuntu 20 04 x64 visual studio code latest version recommended devices connected on the same network android mobile device with smartthings app installed with android 10 or higher smartthings station or smartthings hub onboarded with samsung account philips hue bulb smartthings connected device sample code here is a sample code for this code lab download it and start your learning experience! edge driver sample code 6 1 kb install smartthings cli you need to install smartthings cli as this is the main tool for developing apps and drivers for smartthings edge drivers to install smartthings cli, open a web browser and download the smartthings msi installer from the latest release open the smartthings cli setup in the downloaded file, then click next accept the license agreement terms, then click next select the destination path for installation and click next to begin the installation process, click install notethe windows installer may display a warning titled windows protected your pc to continue the installation, click more info > run anyway complete the setup by clicking finish to verify if smartthings cli is installed correctly, open the command prompt and run this command smartthings --version view and run available commands for smartthings cli with this command smartthings --help for a full list of commands, visit the smartthings cli commands notethe smartthings cli supports an automatic login flow that launches a browser window, prompting the user to log in with a samsung account and grant the cli permissions to access the user's account start your project after downloading and extracting the sample code containing the project files, click file > open folder in visual studio code to open it locate the sample code directory and click select folder once finished, the project files are seen on the explorer menu set the bulb's color configuration in init lua, under the device_init function, write the code below to set the bulb's colors and its transition time local colorcontrol = clusters colorcontrol local philips_hue_colors = { {0xed, 0xc4}, -- red {0xae, 0xe3}, -- blue {0x2c, 0xc3}, -- yellow {0x53, 0xd3}, -- green {0xca, 0x08}, -- white } local index = 1 local transition_time = 0 --1/10ths of a second -- when sent with a command, these options mask and override bitmaps cause the command -- to take effect when the switch/light is off local options_mask = 0x01 local options_override = 0x01 device send colorcontrol server commands movetohueandsaturation device, philips_hue_colors[5][1], philips_hue_colors[5][2], transition_time, options_mask, options_override local timer = device thread call_on_schedule 1, function local hue = philips_hue_colors[index][1] local sat = philips_hue_colors[index][2] device send colorcontrol server commands movetohueandsaturation device, hue, sat, transition_time, options_mask, options_override index = index + 1 % 6 if index == 0 then index = 1 end end, "color_schedule_timer" save the file and open either the command prompt or terminal notemake sure that the path directory in your cli contains the project file build and upload your edge driver in the terminal, type the following command to build and upload your edge driver package to the smartthings cloud smartthings edge drivers package create a private channel create a new channel for your edge driver and enter the following channel details smartthings edge channels create channel name smartthings edge driver channel channel description channel for sdc2024 channel terms of service url www smartthings com enroll the smartthings hub in your channel enroll your hub in your newly created channel and select the corresponding channel and hub smartthings edge channels enroll assign the edge driver to your channel assign your driver to the created channel smartthings edge channels assign install the edge driver to your hub install the created edge driver from your channel to your own hub smartthings edge drivers install control the bulb via smartthings app on your mobile phone, launch the smartthings app and tap the + icon once you're on the add device page, tap scan nearby make sure that the philips light bulb is turned on wait for the light bulb to be visible once visible, tap done now, observe the blinking and changing colors of your bulb you're done! congratulations! you have successfully achieved the goal of this code lab now, you can create an edge driver for smartthings devices that can be integrated into the smartthings ecosystem! if you're having trouble, you may download this file edge driver complete code 8 6 kb to learn more about smartthings hub connected devices and edge drivers, visit smartthings hub connected devices smartthings edge driver documentation
Learn Code Lab
codelabcontrol a smart bulb objective control a smart light bulb and change its color using bixby home studio overview bixby home studio bhs provides a simple and optimized way for accessing and controlling devices connected to your smartthings account you can quickly create complex diagrams and condition-based flows with bhs's user-friendly graphical user interface gui any device compatible with smartthings can be adjusted, controlled, and updated through bixby home studio for more information, visit getting started with bixby home studio set up your environment you will need the following samsung and smartthings account same email address smart rgb light bulb added to smartthings account virtual switch from smartthings labs if a smart rgb light bulb is not available a go to smartthings app b in the menu, select labs c choose virtual switch and click + to add a virtual switch d enter the name of virtual switch, location, and room notewhen you use a virtual switch, you can only create metadata and test the turning on and off functionality however, a physical smart rgb light bulb is necessary for testing other functions of this code lab activity, such as changing the light bulb color to red smartthings labs feature is available only on android app in us, canada, uk, india, and south korea start your project go to bhs bixbydevelopers com and sign in using your samsung account create a new project select your smartthings location and smart rgb light bulb or virtual switch for the device click create metadata from scratch then, click next choose powerswitch under bixby voice category select the powerswitch-turnoff and powerswitch-turnon voice intents click next input a project name and click done use a sample graph to switch on the bulb sample graphs are various example action flows that you can explore to learn more about the different voice intents, nodes, and smartthings capabilities you can use these sample graphs as starter points for your own devices each sample graph generically handles specific capabilities covered under various user utterances through the different voice intents for example, the turn on device sample graph works for any device it covers a variety of user utterances such as "turn on air conditioner ", "turn on fan ", "turn on speaker ”, and so on follow the steps below to use the turn on device sample graph to switch on the device go to voice intents > powerswitch-turnon > graph click the sample graphs icon on the left sidebar menu to show all the available sample graphs scroll down to see the turn on device sample graph or find it using the search bar drag and drop the sample graph into your powerswitch-turnon graph editor click try it to turn on your light bulb noteif you're using a virtual switch, it will turn on, but you won't be able to see the switch itself however, you can see the state of the virtual switch change from off to on in the smartthings app turn off the light bulb and add an alternative response the turn on device sample graph functions to switch on the device when the start node triggers the command node this graph can be modified to reverse its function, to do that copy the nodes from the powerswitch-turnon graph to the powerswitch-turnoff graph editor click the command node to open the node configuration pane and change the command from on to off right-click on the command node and change its comment to turn off device click try it to turn off the device after the command is performed, the response is either success or execution failed to make the light bulb more responsive, design the graph to provide different responses depending on whether the light bulb is already off or currently on a click the raw button and delete the existing code in the raw graph b copy and paste the following json into it and click add [{"nodeid" "5b648da1-a2c3-4912-baff-a559b968070e","nodever" "1 0","nodetype" "capabilityattribute","isstateful" true,"group" null,"inputports" {"device" {"nodes" [],"portinfo" null}},"triggerports" {"success" {"nodes" ["ccf1cbb8-c99b-439f-8246-bc9e7b7abfbf"],"portinfo" null},"failure" {"nodes" [],"portinfo" null}},"valueports" {},"triggerinports" {},"configurations" {"attribute" {"datatype" "datatype schema afcapabilityattribute","datavalue" {"component" "main","capability" "switch","attribute" "switch","property" {"name" "value","datatype" "datatype primitive afstring"}}},"required" {"datatype" "datatype primitive afboolean","datavalue" true}},"styles" {"x" 415,"y" 360}},{"nodeid" "ccf1cbb8-c99b-439f-8246-bc9e7b7abfbf","nodever" "1 0","nodetype" "equalcomparison","isstateful" true,"group" null,"inputports" {"leftvalue" {"nodes" ["5b648da1-a2c3-4912-baff-a559b968070e"],"portinfo" null},"rightvalue" {"nodes" ["8d9bf8ec-7cb1-4ffe-b4c0-b0424d394027"],"portinfo" null}},"triggerports" {"true" {"nodes" ["593250c4-9c19-4155-8f90-1318f9484aab"],"portinfo" null},"false" {"nodes" ["a9c4d152-eb0d-45d2-a2bd-20217de6fee6"],"portinfo" null}},"valueports" {},"triggerinports" {},"configurations" {"operator" {"datatype" "datatype operator equalcomparisonoperator","datavalue" "equalto"}},"styles" {"x" 585,"y" 332}},{"nodeid" "8d9bf8ec-7cb1-4ffe-b4c0-b0424d394027","nodever" "1 0","nodetype" "constant","isstateful" true,"group" null,"inputports" {},"triggerports" {},"valueports" {},"triggerinports" {},"configurations" {"value" {"datatype" "datatype primitive afstring","datavalue" "on"}},"styles" {"x" 415,"y" 500}},{"nodeid" "a9c4d152-eb0d-45d2-a2bd-20217de6fee6","nodever" "1 0","nodetype" "responsefeaturealreadyset","isstateful" true,"group" null,"inputports" {},"triggerports" {},"valueports" {},"triggerinports" {},"configurations" {},"styles" {"x" 635,"y" 480}}] c four nodes were added to the graph an attribute node that receives and passes an on or off value; a constant node with on as its value; an equal comparison node that compares if the attribute value is equal to the constant value; and a response already set node d rewire the graph to make it work properly by clicking the line coming from the start node and pressing the delete key e create a new line from the start node and connect it to the attribute node's trigger port f connect the equal comparison node's true port to the command node's trigger port g click the align button a couple of times to automatically organize the graph h then, click try it while the device is already off or already on, to observe the different responses change the light bulb's color based on time the command node has two capabilities that can adjust the color of light bulb, such as colorcontrol and colortemperature in this step, use these command node capabilities together with the get current datetime node and get datetime attributes node to set the light bulb's color to red or warm, if the current date time is 8 00 pm or later otherwise, the light bulb's color remains blue add the following json into the powerswitch-turnon graph [{"nodeid" "a31659e2-68fc-42b6-8076-01c2cb9fec23","nodever" "1 0","nodetype" "getcurrentdatetime","isstateful" true,"group" null,"inputports" {"__zoneid" {"nodes" [],"portinfo" null}},"triggerports" {"main" {"nodes" ["ea58c225-7d40-45b9-85d6-d8d941de9b2e"],"portinfo" null}},"valueports" {},"triggerinports" {},"configurations" {},"styles" {"x" 715,"y" 280}},{"nodeid" "ea58c225-7d40-45b9-85d6-d8d941de9b2e","nodever" "1 0","nodetype" "getdatetimeattributes","isstateful" true,"group" null,"inputports" {"input" {"nodes" ["a31659e2-68fc-42b6-8076-01c2cb9fec23"],"portinfo" null}},"triggerports" {"main" {"nodes" ["880416f6-d288-4b97-b763-2abd46bf2737"],"portinfo" null}},"valueports" {"seconds" {"name" "seconds"},"month" {"name" "month"},"hour" {"name" "hour"},"year" {"name" "year"},"minutes" {"name" "minutes"},"timestampinseconds" {"name" "timestampinseconds"},"day" {"name" "day"}},"triggerinports" {},"configurations" {},"styles" {"x" 815,"y" 280}},{"nodeid" "880416f6-d288-4b97-b763-2abd46bf2737","nodever" "1 0","nodetype" "comparablecomparison","isstateful" true,"group" null,"inputports" {"leftvalue" {"nodes" ["gr //node/ea58c225-7d40-45b9-85d6-d8d941de9b2e/value/hour"],"portinfo" null},"rightvalue" {"nodes" ["606796bc-d8ea-4421-942d-91544271615d"],"portinfo" null}},"triggerports" {"true" {"nodes" ["b2ba65ab-5e3e-4615-8d3a-79015a03d7bc"],"portinfo" null},"false" {"nodes" [],"portinfo" null}},"valueports" {},"triggerinports" {},"configurations" {"operator" {"datatype" "datatype operator comparablecomparisonoperator","datavalue" "greaterthanorequalto"}},"styles" {"x" 975,"y" 320}},{"nodeid" "606796bc-d8ea-4421-942d-91544271615d","nodever" "1 0","nodetype" "constant","isstateful" true,"group" null,"inputports" {},"triggerports" {},"valueports" {},"triggerinports" {},"configurations" {"value" {"datatype" "datatype primitive afinteger","datavalue" 20}},"styles" {"x" 815,"y" 420}},{"nodeid" "2b22b1a1-b9cb-4881-a861-3bf74ccd7847","nodever" "1 0","nodetype" "capabilitycommand","isstateful" true,"group" null,"inputports" {"device" {"nodes" [],"portinfo" null},"1 color" {"nodes" ["2389baa9-db45-4eb3-a40c-1166bf1e620f"],"portinfo" {"datatypes" ["undefined"],"minitems" 1,"maxitems" 1,"iscustomport" true}}},"triggerports" {"success" {"nodes" ["a31659e2-68fc-42b6-8076-01c2cb9fec23"],"portinfo" null},"failure" {"nodes" [],"portinfo" null}},"valueports" {},"triggerinports" {},"configurations" {"commands" {"datatype" "datatype util aflist","datavalue" [{"datatype" "datatype schema afcapabilitycommand","datavalue" {"component" "main","capability" "colorcontrol","command" "setcolor","arguments" [{"datatype" "datatype schema afcommandargument","datavalue" {"name" "color","optional" false,"datatype" "datatype primitive afjsonobject"}}]}}]}},"styles" {"x" 590,"y" 274}},{"nodeid" "2389baa9-db45-4eb3-a40c-1166bf1e620f","nodever" "1 0","nodetype" "constant","isstateful" true,"group" null,"inputports" {},"triggerports" {},"valueports" {},"triggerinports" {},"configurations" {"value" {"datatype" "datatype primitive afjsonobject","datavalue" {"hue" 55,"saturation" 55}}},"styles" {"x" 675,"y" 440}},{"nodeid" "b2ba65ab-5e3e-4615-8d3a-79015a03d7bc","nodever" "1 0","nodetype" "capabilitycommand","isstateful" true,"group" null,"inputports" {"device" {"nodes" [],"portinfo" null},"1 temperature" {"nodes" ["4d02fcda-df99-4c75-8b0a-73bb67933acd"],"portinfo" {"datatypes" ["undefined"],"minitems" 1,"maxitems" 1,"iscustomport" true}}},"triggerports" {"success" {"nodes" [],"portinfo" null},"failure" {"nodes" [],"portinfo" null}},"valueports" {},"triggerinports" {},"configurations" {"commands" {"datatype" "datatype util aflist","datavalue" [{"datatype" "datatype schema afcapabilitycommand","datavalue" {"component" "main","capability" "colortemperature","command" "setcolortemperature","arguments" [{"datatype" "datatype schema afcommandargument","datavalue" {"name" "temperature","optional" false,"datatype" "datatype primitive afinteger"}}]}}]}},"styles" {"x" 1115,"y" 380}},{"nodeid" "4d02fcda-df99-4c75-8b0a-73bb67933acd","nodever" "1 0","nodetype" "constant","isstateful" true,"group" null,"inputports" {},"triggerports" {},"valueports" {},"triggerinports" {},"configurations" {"value" {"datatype" "datatype primitive afinteger","datavalue" 500}},"styles" {"x" 975,"y" 478}}] rewire the graph as follows a delete the wire that connects command switch node's success port and response success node's trigger port b connect the command switch node's success port to the command colorcontrol node's trigger port c connect the command colortemperature node's success port to the response success node's trigger port d connect the numerical comparison node's false port to the response success node's trigger port noteadd a constant node with time zone, for example america/new_york, as string value if you want to test this section based on your local time click align then, click try it to see how the light bulb color change based on time you're done! congratulations! you have successfully achieved the goal of this code lab now, you can control a smart light bulb using bixby home studio if you face any trouble, you may download this file control bulb complete code 25 72 kb notewatch this short clip to quickly know how to navigate your way in this code lab and to see how easy it is to use bixby home studio to learn more about bixby, visit developer samsung com/bixby
Learn Code Lab
codelabcreate a daily step counter on galaxy watch objective create a native app for galaxy watch, operating on wear os powered by samsung, using health platform to read your daily steps overview health platform provides a unified and straightforward way for accessing a wide range of health and wellness related data with health platform api, you may easily read and write data stored in health platform on android and wear os powered by samsung applications can have access to these secured data only with explicit user consent additionally, users may disable access to the data at any point in time see health platform descriptions for detailed information set up your environment you will need the following galaxy watch4 or newer android studio latest version recommended java se development kit jdk 11 or later sample code here is a sample code for you to start coding in this code lab download it and start your learning experience! health step count sample code 119 87 kb turn on developer mode and adjust its settings on your watch, go to settings > about watch > software and tap on software version 5 times upon successful activation of developer mode, a toast message will display as on the image below afterwards, developer options will be visible under settings tap developer options and enable the following options adb debugging debug over wi-fi turn off automatic wi-fi connect your galaxy watch to wi-fi go to settings > connection > wi-fi and make sure that wi-fi is enabled from the list of available wi-fi networks, choose and connect to the same one as your pc when successfully connected, tap a wi-fi network name, swipe down, and note the ip address you will need this to connect your watch over adb from your pc connect your galaxy watch to android studio in android studio, go to terminal and type adb connect <ip address as mentioned in previous step> when prompted, tap always allow from this computer to allow debugging upon successful connection, you will see the following message in android studio’s terminal connected to <ip address of your watch> now, you can run the app directly on your watch start your project after downloading the sample code containing the project files, in android studio click open to open existing project locate the downloaded android project stepcount from the directory and click ok check dependency and app manifest in the dependencies section of stepcount/app/build gradle file, see the appropriate dependency for health platform dependencies { implementation com google android libraries healthdata health-data-api 1 0 0-alpha01' // } notelibrary might update from time to time if necessary, choose the version suggested by android studio request for data permissions before accessing any data through health platform, the client app must obtain necessary permissions from the user in permissions java, create a permission instance to trigger relevant permission screen and obtain required consent from end user data type name intervaldatatypes steps read access accesstype read /******************************************************************************************* * [practice 1] build permission object grand permissions for read today's steps * - set interval data type of steps * - set read access type ------------------------------------------------------------------------------------------- * - hint uncomment lines below and fill todos with * 1 for interval data type intervaldatatypes steps * 2 for read access accesstype read ******************************************************************************************/ permission stepsreadpermission = permission builder // setdatatype "todo 1 1 " // setaccesstype "todo 1 2 " build ; make a query to aggregate today’s steps create read request with all necessary information to read data through health platform api the answer from the platform will be asynchronous with the result from which you can get all the data you are interested in follow the steps below to get today's steps count in stepsreader java, create a readaggregateddatarequest with cumulativeaggregationspec instance data type name intervaldatatypes steps /******************************************************************************************* * [practice 2] build read aggregated data request object for read today's steps * - set interval data type of steps ------------------------------------------------------------------------------------------- * - hint uncomment line below and fill todo 2 with * 1 for interval data type intervaldatatypes steps ******************************************************************************************/ readaggregateddatarequest readaggregateddatarequest = readaggregateddatarequest builder settimespec timespec builder setstartlocaldatetime localdatetime now with localtime midnight build // addcumulativeaggregationspec cumulativeaggregationspec builder "todo 2 1 " build build ; read cumulative steps count from cumulativedata set variable steps value to 0l it is the count of daily steps get aggregatedvalue object using cumulativedata api cumulativedataaggregateddata representing total of intervaldata over a period of time e g total steps in a day public aggregatedvalue gettotal check the result if it is not null, get aggregated value using aggregatedvalue api aggregatedvaluevalue fields aggregated over a period of time only numeric fields longfield, doublefield can be included in aggregation public long getlongvalue returns all longfields and their values that are already set add value to the daily steps result counter /******************************************************************************************* * [practice 3] read aggregated value from cumulative data and add them to the result * - get aggregatedvalue from cumulativedata object * - get steps count from aggregatedvalue object ------------------------------------------------------------------------------------------- * - hint uncomment lines below and replace todo 3 with parts of code * 1 get aggregatedvalue object 'obj' using cumulativedata gettotal * 2 get value using obj getlongvalue and add to the result ******************************************************************************************/ long steps = 0l; if result != null { list<cumulativedata> cumulativedatalist = result getcumulativedatalist ; if !cumulativedatalist isempty { for cumulativedata cumulativedata cumulativedatalist { //"todo 3 1 " //"todo 3 2 " } } } return steps; run unit tests for your convenience, you will find an additional unit tests package this will let you verify your code changes even without using a physical watch see instruction below on how to run unit tests right click on com samsung sdc21 stepcount test and execute run 'tests in 'com samsung sdc21 stepcount'' command if you completed all the tasks correctly, you will see all the unit tests passed successfully run the app after building the apk, you can run the application on a connected device to see real-life aggregated steps count measured by a smartwatch right after the app is started, it will request for the user permission allow the app to receive data of the activity afterwards, the application main screen will be shown it will automatically display today’s step count tap on refresh button to read current steps count from health platform you're done! congratulations! you have successfully achieved the goal of this code lab now, you can create a daily step counter app by yourself! if you're having trouble, you may download this file health step count complete code 119 79 kb learn more by going to health platform
Learn Code Lab
codelabtrack deadlift exercise on galaxy watch objective create a native app for galaxy watch, operating on wear os powered by samsung, using health services to track deadlift exercise this app measures repetition count, calories burned, and time spent during the exercise overview health services provides a simple and unified way for accessing a wide range of health and wellness related data with health services api, you will no longer need to develop your own algorithms processing sensors data in order to compute metrics like heart rate, steps counts, distance, calories burned, and other more these are now accessible through health services embedded on wearables operating on wear os powered by samsung see health platform descriptions for detailed information set up your environment you will need the following galaxy watch4 or newer android studio latest version recommended java se development kit jdk 11 or later sample code here is a sample code for you to start coding in this code lab download it and start your learning experience! health track deadlift sample code 132 83 kb turn on developer mode and adjust its settings on your watch, go to settings > about watch > software and tap on software version 5 times upon successful activation of developer mode, a toast message will display as on the image below afterwards, developer options will be visible under settings tap developer options and enable the following options adb debugging debug over wi-fi turn off automatic wi-fi connect your galaxy watch to wi-fi go to settings > connection > wi-fi and make sure that wi-fi is enabled from the list of available wi-fi networks, choose and connect to the same one as your pc when successfully connected, tap a wi-fi network name, swipe down, and note the ip address you will need this to connect your watch over adb from your pc connect your galaxy watch to android studio in android studio, go to terminal and type adb connect <ip address as mentioned in previous step> when prompted, tap always allow from this computer to allow debugging upon successful connection, you will see the following message in android studio’s terminal connected to <ip address of your watch> now, you can run the app directly on your watch start your project after downloading the sample code containing the project files, open your android studio and click open to open an existing project locate the downloaded android project deadlift from the directory and click ok check dependency and app manifest in the dependencies section of gradle scripts > build gradle module app file, see the appropriate dependency for health services dependencies { implementation 'androidx health health-services-client 1 0 0-beta03' // } notesince the library might update from time to time, it is recommended to choose the version suggested by android studio in androidmanifest xml file, note the following <queries> element <queries> <package android name="com google android wearable healthservices" /> </queries> section with requests for necessary permissions <uses-permission android name="android permission body_sensors" /> <uses-permission android name="android permission activity_recognition" /> check capabilities to check what can be measured during an exercise, you need to check its capabilities go to app > java > com samsung sdc21 deadlift open the deadliftutil java file and navigate to the checkcapabilities method an inner class c definition implements the methods of the futurecallback interface within this definition, define the onsuccess method to retrieve the exercise type capabilities public void onsuccess exercisecapabilities result { objects requirenonnull result ; log i tag, "got exercise capabilities" ; /*********************************************************************************** * [practice 1] define the onsuccess method * * - hint uncomment lines below and replace todo 1 * call getexercisetypecapabilities method of result object, * passing already initialized t as an argument **********************************************************************************/ final exercisetype t = exercisetype deadlift; // final exercisetypecapabilities capabilities = "todo 1" // final exerciseconfig builder builder = exerciseconfig builder t ; // builder setdatatypes capabilities getsupporteddatatypes ; // exerciseconfigbuilder = builder; } next, implement the findcapabilitesfuture method to get a callback with exercisecapabilities getcapabilitiesasync returns the exercisecapabilities of the exerciseclient for the device static listenablefuture<exercisecapabilities> findcapabilitiesfuture exerciseclient client { /******************************************************************************************* * [practice 1] create a listenablefuture object that will get a callback with * with exercise capabilities choose the correct method from exerciseclient * * - hint uncomment line and replace null with todo 2 * for checking capabilities use getcapabilitiesasync method ******************************************************************************************/ return null; //"todo 2"; } start the exercise inside the startexercise method, there is a call to the futures addcallback method this method adds a callback function that executes when the asynchronous operation of starting the exercise completes set an update callback for the exercise client within the onsuccess method of the callback function public void onsuccess void result { log i tag, "successfully started" ; /*************************************************************************** * [practice 2] set an update callback * * - hint uncomment lines below and fill todos * 1 make appropriate call of setupdatecallback method * and pass exerciseupdatelistener object as an argument * 2 change ismeasurementrunning flag value to true **************************************************************************/ // exerciseclient setupdatecallback "todo 3 1 " ; log i tag, "successfully set update listener" ; // "todo 3 2 " } in the deadlift java file, call the startexercise method in onbuttonclickhelper public void onbuttonclickhelper { /******************************************************************************************* * [practice 2] start the exercise using a method from deadliftutil java * * - hint uncomment line below and fill todo 4 * call startexercise method on util object * ****************************************************************************************/ // "todo 4" } get the results go to the deadliftutil java file, and in the getnewrepsvalue method, call the getlatestmetrics method from the exerciseupdate class to get the data collected during the exercise store the data in the resultlist, where the last element holds the most up-to-date value of all your repetitions public long getnewrepsvalue exerciseupdate update, deltadatatype<long, intervaldatapoint<long>> datatype { /******************************************************************************************* * [practice 3] get the data collected during exercise * * - hint uncomment lines below and fill todo 5 * call getlatestmetrics method of exerciseupdate object * then, get the data of appropriate type * for this, you can use dedicated method getdata , passing datatype as an argument * ****************************************************************************************/ // final list<intervaldatapoint<long>> resultlist = "todo 5" // if !resultlist isempty { // final int lastindex = resultlist size - 1; // return resultlist get lastindex getvalue ; // } return no_new_value; } run unit tests for your convenience, you will find an additional unit tests package this will let you verify your code changes even without using a physical watch see instruction below on how to run unit tests right click on com samsung sdc21 deadlift test > deadliftunittest and execute run 'deadliftunittest' command if you completed all the tasks correctly, you will see all the unit tests passed successfully run the app after building the apk, you can run the application on a connected device to measure actual deadlift parameters right after the app is started, it will request for the user permission allow the app to receive data of the activity afterwards, the application main screen will be shown before doing deadlifts, press the start button to track your exercise when done, tap on the stop button you're done! congratulations! you have successfully achieved the goal of this code lab now, you can create a deadlift exercise tracker app by yourself! if you're having trouble, you may download this file health track deadlift complete code 132 42 kb learn more by going to health platform
We use cookies to improve your experience on our website and to show you relevant advertising. Manage you settings for our cookies below.
These cookies are essential as they enable you to move around the website. This category cannot be disabled.
These cookies collect information about how you use our website. for example which pages you visit most often. All information these cookies collect is used to improve how the website works.
These cookies allow our website to remember choices you make (such as your user name, language or the region your are in) and tailor the website to provide enhanced features and content for you.
These cookies gather information about your browser habits. They remember that you've visited our website and share this information with other organizations such as advertisers.
You have successfully updated your cookie preferences.