Filter
-
Content Type
-
Category
Mobile/Wearable
Visual Display
Digital Appliance
Platform
Recommendations
Filter
Learn Code Lab
codelabmeasure blood oxygen level and heart rate 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 results of simultaneous blood oxygen level spo2 and heart rate measurements 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 and heart rate sample code 159 2 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 establish service connection and check capabilities for the device to track data with the samsung health sensor sdk, it must connect to the service by healthtrackingservice api after establishing a connection, verify if the required tracker type is available to check this, get the list of available tracker types and verify that the tracker is on the list in this code lab, you will utilize blood oxygen level and heart rate trackers the healthtrackingservice api usage is in the table below healthtrackingservicehealthtrackingservice initiates a connection to samsung's health tracking service and provides a healthtracker instance to track a healthtrackertype public void connectservice establish a connection with samsung's health tracking service public void disconnectservice release a connection for samsung's health tracking service public healthtrackercapability gettrackingcapability provide a healthtrackercapability instance to get a supporting health tracker type list initialize multiple trackers before the measurement starts, initialize the spo2 tracker by obtaining the proper health tracker object in the connectionmanager java file, navigate to initspo2 , create an oxygen saturation healthtracker instance, and pass it to the spo2listener instance get the healthtracker object using the healthtrackingservice api use the healthtrackertype spo2_on_demand type as parameter healthtrackingservicehealthtrackingservice initiates a connection to samsung's health tracking service and provides a healthtracker instance to track a healthtrackertype public healthtracker gethealthtracker healthtrackertype healthtrackertype provide a healthtracker instance for the given healthtrackertype pass the healthtracker object to the spo2listener instance object spo2listener public void sethealthtracker healthtracker tracker set healthtracker instance for the given tracker /******************************************************************************************* * [practice 1] create blood oxygen level health tracker object * - get health tracker object * - pass it to spo2listener ------------------------------------------------------------------------------------------- * - hint replace todo 1 with parts of code * 1 get healthtracker object using healthtrackingservice gethealthtracker * use healthtrackertype spo2_on_demand type as parameter * 2 pass it to spo2listener using sethealthtracker function ******************************************************************************************/ public void initspo2 spo2listener spo2listener { //"todo 1 1 " //"todo 1 2 " sethandlerforbaselistener spo2listener ; } next, in the connectionmanager java file, in the initheartrate function, create a heart rate healthtracker instance, and pass it to the heartratelistener instance get the healthtracker object using the healthtrackingservice api use the healthtrackertype heart_rate_continuous type as parameter pass the healthtracker object to the heartratelistener instance object heartratelistener public void sethealthtracker healthtracker tracker set healthtracker instance for the given tracker /******************************************************************************************* * [practice 2] create heart rate health tracker object * - get health tracker object * - pass it to heartratelistener ------------------------------------------------------------------------------------------- * - hint replace todo 2 with parts of code * 1 get healthtracker object using healthtrackingservice gethealthtracker * use healthtrackertype heart_rate_continuous type as parameter * 2 pass it to heartratelistener using sethealthtracker function ******************************************************************************************/ public void initheartrate heartratelistener heartratelistener { //"todo 2 1 " //"todo 2 2 " sethandlerforbaselistener heartratelistener ; } start and stop trackers for the client app to start obtaining the data through the sdk, set a listener method on healthtracker this method will be called every time there is new data after the measurement completes, the listener has to be disconnected to start measurement in the baselistener java file, navigate to starttracker function, and set trackereventlistener as listener healthtracker object set an event listener on healthtracker object using healthtracking api use the healthtracker trackereventlistener object instance as parameter healthtrackerhealthtracker enables an application to set an event listener and get tracking data for a specific healthtrackertype public void seteventlistener healthtracker trackereventlistener listener set an event listener to this healthtracker instance /******************************************************************************************* * [practice 3] start health tracker by setting event listener * - set event listener on health tracker ------------------------------------------------------------------------------------------- * - hint replace todo 3 with parts of code * set event listener on healthtracker object using healthtracker seteventlistener * use trackereventlistener object as parameter ******************************************************************************************/ public void starttracker { log i app_tag, "starttracker called " ; log d app_tag, "healthtracker " + healthtracker tostring ; log d app_tag, "trackereventlistener " + trackereventlistener tostring ; if !ishandlerrunning { handler post -> { //"todo 3" sethandlerrunning true ; } ; } } to stop measurement, unset the trackereventlistener from the healthtracker object in the stoptracker function unset the event listener on healthtracker object using healthtracking api healthtrackerhealthtracker enables an application to set an event listener and get tracking data for a specific healthtrackertype public void unseteventlistener stop the registered event listener to this healthtracker instance /******************************************************************************************* * [practice 4] stop health tracker by removing event listener * - unset event listener on health tracker ------------------------------------------------------------------------------------------- * - hint replace todo 4 with parts of code * unset event listener on healthtracker object using healthtracker unseteventlistener ******************************************************************************************/ public void stoptracker { log i app_tag, "stoptracker called " ; log d app_tag, "healthtracker " + healthtracker tostring ; log d app_tag, "trackereventlistener " + trackereventlistener tostring ; if ishandlerrunning { //"todo 4" sethandlerrunning false ; handler removecallbacksandmessages null ; } } process obtained and batching data the response from the platform will be asynchronous with the results you want to obtain follow the steps below to get blood oxygen level and heart rate data in the spo2listener java file, navigate to updatespo2 function, and read spo2 data from datapoint get the oxygen saturation status using the datapoint api key valuekey spo2set status get the oxygen saturation value using the datapoint api key valuekey spo2set spo2 datapointdatapoint provides a map of valuekeyand value with a timestamp public <t>t getvalue valuekey<t> type get data value for the given key /******************************************************************************************* * [practice 5] read values from datapoint object * - get blood oxygen level status * - get blood oxygen level value ------------------------------------------------------------------------------------------- * - hint replace todo 5 with parts of code * 1 remove spo2status calculating and * set status from 'datapoint' object using datapoint getvalue valuekey spo2set status * 2 set spo2value from 'datapoint' object using datapoint getvalue valuekey spo2set spo2 * if status is 'spo2status measurement_completed' ******************************************************************************************/ public void updatespo2 datapoint datapoint { int status = spo2status calculating; //"todo 5 1 " int spo2value = 0; //"todo 5 2 " trackerdatanotifier getinstance notifyspo2trackerobservers status, spo2value ; log d app_tag, datapoint tostring ; } in the heartratelistener java file, navigate to readvaluesfromdatapoint function, and read the heart rate data from datapoint get heart rate status using datapoint api key valuekey heartrateset heart_rate_status get heart rate value using datapoint api key valuekey heartrateset heart_rate get heart rate ibi value using datapoint api key valuekey heartrateset ibi_list get ibi quality using datapoint api key valuekey heartrateset ibi_status_list /******************************************************************************************* * [practice 6] read values from datapoint object * - get heart rate status * - get heart rate value * - get heart rate ibi value * - check retrieved heart rate’s ibi and ibi quality values ------------------------------------------------------------------------------------------- * - hint replace todo 6 with parts of code * 1 set hrdata status from 'datapoint' object using datapoint getvalue valuekey heartrateset heart_rate_status * 2 set hrdata hr from 'datapoint' object using datapoint getvalue valuekey heartrateset heart_rate * 3 set local variable 'list<integer> hribilist' using datapoint getvalue valuekey heartrateset ibi_list * 4 set local variable 'final list<integer> hribistatus' using datapoint getvalue valuekey heartrateset ibi_status_list * 5 set hrdata ibi with the last of 'hribilist' values * 6 set hrdata qibi with the last of 'hribistatus' values ******************************************************************************************/ public void readvaluesfromdatapoint datapoint datapoint { heartratedata hrdata = new heartratedata ; //"todo 6 1 " //"todo 6 2 " //"todo 6 3 " //"todo 6 4 " //"todo 6 5 " //"todo 6 6 " trackerdatanotifier getinstance notifyheartratetrackerobservers hrdata ; log d app_tag, datapoint tostring ; } 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 multisensortracking test and execute run 'tests in 'com samsung health multisensortracking'' 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 see blood oxygen level and heart rate values 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 and automatically display the heart rate to get the blood oxygen level spo2 value, tap on the measure button to stop the measurement, tap on the stop button tap on the details label to see more heart rate data 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 and heart rate by yourself! if you're having trouble, you may download this file measuring blood oxygen level and heart rate complete code 158 8 kb to learn more about samsung health, visit developer samsung com/health
Learn Code Lab
codelabapply gyro effects to a watch face using watch face studio objective learn how to change the appearance of your watch face as the watch tilts in different directions by applying gyro effects using watch face studio overview watch face studio is a graphical authoring tool that enables you to design watch faces for the wear os smartwatch ecosystem, including galaxy watch4 and newer versions it provides easy and simple features, such as gyro effects, for creating attractive and dynamic watch faces without coding gyro effects are a feature in watch face studio, which uses the watch's gyro sensor to animate or alter the look of watch faces the effects are triggered when the watch is tilted within the -90° to 90° tilt angle range along the x and y axes see illustration below a tilt angle of 0° on both axes indicates that the watch rests on a flat surface the following shows the expected tilt angle values when the watch tilts 90° in different directions direction of tilt tilt angle clockwise along the y-axis or tilt forward y = -90° counterclockwise along the y-axis or tilt backward y = 90° clockwise along the x-axis or tilt to the right x = 90° counterclockwise along the x-axis or tilt to the left x = -90° set up your environment you will need the following watch face studio latest version galaxy watch4 or newer smart watch running on wear os api 30 or higher sample project here is a sample project for you to start coding in this code lab download it and start your learning experience! gyro effects sample project 322 00 kb start your project to load the sample project in watch face studio click open project locate the downloaded file and click open the sample project is a premade watch face design it contains a background image, a digital clock, and a date notein watch face studio, you can add a digital clock component in different formats such as hh, mm, ss, or hh mm ss setting the digital time properties, such as color and dimension, per digit is also possible when you choose a component from variable options the project also contains three ellipses two ellipses with tag expressions in rotate > angle properties to represent the analog time hour and second and one ellipse as the background of the digital hour in the style tab, you can see the watch face's different theme color palettes resize a component when tilted forward or backward as the watch tilts, a component can enlarge or shrink relative to its pivot when applying gyro effects the pivot is the point at the center of the component the component remains at the same position as it gets bigger or smaller select the time background component in properties, you can see that the component's dimension width x height is 100px by 100px select apply gyro to show the properties of gyro effects initially, a component does not resize, move, rotate, or change opacity when you tilt the watch in any direction the gyro effect occurs when you set the changing to properties higher or lower than the default values to resize the component when the watch tilts forward or backward, go to y-axis properties and set the scale width and height to the following 70% for -90° to 0° range 130% for 0° to 90° range in the run pane, you can simulate the rotation of the watch the component enlarges from 100% to 130% as the watch tilts backward and shrinks to 70% as the watch tilts forward notewhen you drag the gyro joystick upward, it simulates the backward rotation of the watch similarly, when you move the joystick downward, it simulates the forward rotation rotate a component when tilted to the left or right in gyro mode, a component can rotate around its pivot when a component rotates, its position remains the same select the digital date component the format of the digital date is a curved text, and its pivot is at the center of the canvas inner pivot x = 225px, inner pivot y = 225px enable gyro effects then, change the rotation angle to -90° for the following tilt angle ranges along the x-axis -90° to 0° 0° to 90° as the watch tilts to the left or right, the date component rotates up to 90° gradually counter-clockwise change the appearance of the background image based on the adjusted tilt angle range range values define how tilted the watch should be for a component to resize, rotate, appear, or move to the maximum value you set for example, when you set the range from 0° to 45° along the x-axis and the scale to 200%, the component will enlarge twice from its original size once the watch reaches the 45° tilt angle to the right select the background image change the opacity of the components to 0° for the following ranges -45° to 0° along the x-axis 0° to 45° along the x-axis -45° to 0° along the y-axis as the watch tilts in any direction other than backward, the background image slowly disappears as it approaches the 45° tilt angle then, for the 0° to 45° range along the y-axis, change the rotation angle to 360° to rotate the background image clockwise as the watch tilts backward test the watch face in the run pane, click the preview watch face icon move the gyro simulator joystick to see how the appearance of time background, digital date, and background image changes to test your watch face on a smartwatch, you need to connect a watch device to the same network as your computer in watch face studio, select run on device select the connected watch device you want to test with if your device is not detected automatically, click scan devices to detect your device or enter its ip address manually by clicking the + button notethe always-on display is already set in the project to run the watch face successfully, you may need to configure its always-on display to avoid any error when you click run on device you’re done! congratulations! you have successfully achieved the goal of this code lab now, you can apply gyro effects using watch face studio to change the appearance of your watch face all by yourself! if you’re having trouble, you may download this file gyro effects complete project 322 02 kb to learn more about watch face studio, visit developer samsung com/watch-face-studio
Learn Code Lab
codelabcreate an android automotive operating system aaos app with payments via samsung checkout objective create a shopping app for android automotive os aaos , which uses templates from aaos and ignite store, and processes payments via the ignite payment sdk powered by samsung checkout partnership request to use the ignite payment sdk and have access to development tools and resources, such as ignite aaos emulators, you must become an official partner once done, you can fully utilize this code lab you can learn more about the partnership process by visiting the ignite store developer portal overview android automotive os android automotive os aaos is a base android platform that runs directly on the car and is deeply integrated with the underlying vehicle hardware unlike the android auto platform, users can download compatible apps with aaos directly into their cars, without needing a phone, and utilize an interface specifically designed for the car screen aaos can run both system and third-party android applications as aaos is not a fork and shares the same codebase as android for mobile devices, developers can easily adapt existing smartphone apps to function on aaos the diagram below illustrates the architecture of aaos at the hardware abstraction layer hal level, aaos incorporates additional components such as the vehicle hal vhal , exterior view system evs , and broadcast radio br to handle vehicle properties and connectivity at the framework level, car service and webview modules are included at the application level, the main system applications include car system ui, car launcher, and car input method editor ime additionally, car media and automotive host are incorporated as system apps third-party apps are classified into three categories audio media, car templated, and parked car templates the car templated apps use templates specified by the car app library, which are rendered by the automotive host, customized by original equipment manufacturers oem the library consists of approximately 10 templates list, grid, message, pane, navigation and is utilized in both android auto aa and android automotive os aaos apps to target aaos, you must incorporate an additional app-automotive library that injects the carappactivity into the app the carappactivity needs to be included in the manifest and can be set as distractionoptimized upon launching the application, the carappactivity provides a surface that is employed by the automotive host to render the template models additionally, on the harman ignite store, you can optionally integrate the ignite-car-app-lib, which adds supplementary templates such as explore, listdetails, routeoverview, and poistreaming harman ignite store the harman ignite store is a white-labeled and modular aaos-based automotive app store by connecting app developers with car manufacturers, harman creates unique in-vehicle experiences the ignite store has a rich app ecosystem with unique content, growth opportunities, and long-term partnerships it facilitates future-proof monetization with a payments api powered by samsung checkout after registering at the ignite store developer portal, developers can submit their apps for certification and testing by harman upon approval from the oem, the developer can proceed with publishing their app comprehensive developer documentation and tools are available to support app developers throughout the development process payments api the ignite store comes enabled with payment features empowering developers to monetize their apps developers are now able to offer their apps as paid apps the payment sdk exposes apis for goods and services, in-app purchases, and subscriptions developers can also integrate their own payment service providers psps , to sell goods or services, and receive the money directly in their bank account for a frictionless in-car payment experience, ignite provides a dedicated digital wallet app for end-users to securely store their credit card information the payment processor is powered by the industry proven samsung checkout the developer portal provides additional documentation to allow developers to access ignite aaos emulators, vim3, tablet or cuttlefish ignite images, and additional guidelines set up your environment you will need the following ignite aaos system image running on android emulator or on reference devices 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! aaos ignite shopping app sample code 11 7 mb prepare your ignite aaos emulator add the ignite aaos emulator to your android studio by following the guide provided in the ignite store developer console open the device manager and start the emulator configure the emulator to use fake data for payments, as instructed in the ignite store developer console under the offline mode tab in the payment sdk section the sample app requires navigation from point a starting location to point b destination location the destination addresses are predefined and near san jose mcenery convention center to shorten the distance between two locations, follow the steps below to set the starting location a open the extended controls in the emulator panel b go to location, search for a location near the destination location, and click set location next, in the emulator, go to the ignite navigation app's settings and enable the following enable navigation simulation enable mock location provider go to settings > system > developer options > location and set ignite navigation as mock location app 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 igniteautomotivepaymentssdc202488 from the directory and click ok check the ignite payment sdk dependency verify that the ignite payment sdk library is included in the dependencies section of the module's build gradle file dependencies { implementation files 'libs/ignite-payment-sdk-3 13 0 24030417-0-snapshot aar' } add payment permission next, go to the manifests folder and, in the androidmanifest xml file, include the payment_request permission to perform in-app purchases <uses-permission android name="com harman ignite permission payment_request" /> this ensures that the app has the necessary permissions to perform transactions and handle sensitive financial data show the payment screen when an item is added to the cart, the shopping cart screen displays the select store button, selected pickup store address, total amount to pay, and details of each item added the screen also includes the pay button go to kotlin + java > com harman ignite pickupstore > screens > shoppingcartscreen kt in the docheckout function, use the car app's screenmanager to navigate to the payment screen from the shopping cart screen after clicking the pay button getscreenmanager push paymentscreen carcontext, session notethe screenmanager class provides a screen stack you can use to push screens that can be popped automatically when the user selects a back button in the car screen or uses the hardware back button available in some cars instantiate the ignite payment client the ignite payment api provides a singleton class called ignitepaymentclientsingleton, which enables performing and tracking transactions navigate to the paymentscreen kt file and instantiate the ignite payment client private val mipc = ignitepaymentclientsingleton getinstance carcontext define the ignite payment transaction callback the ignite payment transaction provides three callback methods onsuccess, oncanceled, and onfailure after each callback, make sure to set the ispaymentfailed variable to track whether a payment is successful or not update the session which owns the shopping cart screen to reflect the status of the payment transaction call the updatetemplate function to invalidate the current template and create a new one with updated information private val mipctcb = object iignitepaymentclienttransactioncallback { override fun onsuccess requestuuid string?, sessionid string?, successmessage string?, paymentadditionalproperties hashmap<string, string>? { log d tag, log_prefix + "onsuccess rid $requestuuid, sid $sessionid, sm $successmessage" cartoast maketext carcontext, "payment successful", cartoast length_short show ispaymentfailed = false session paymentdone requestuuid, sessionid, successmessage updatetemplate } override fun oncanceled requestuuid string?, sessionid string? { log d tag, log_prefix + "oncanceled rid $requestuuid, sid $sessionid" cartoast maketext carcontext, "payment canceled", cartoast length_long show ispaymentfailed = true session paymenterror requestuuid, sessionid, null updatetemplate } override fun onfailure requestuuid string?, sessionid string?, wallererrorcode int, errormessage string { log d tag, log_prefix + "onfailure rid $requestuuid, sid $sessionid, wec $wallererrorcode, em $errormessage" cartoast maketext carcontext, "payment failed", cartoast length_long show ispaymentfailed = true session paymenterror requestuuid, sessionid, errormessage updatetemplate } } define the ignite payment client connection callback the ignite payment client needs to be connected in order to perform a payment request once the client connects successfully, retrieve the names of the shopping cart items and use them to create an order summary afterwards, construct an ignite payment request containing the total amount, currency code, merchant id, and details of the order summary then, initiate the payment process by invoking the readytopay function of the ignite payment client api private val mipccb = iignitepaymentclientconnectioncallback { connected -> log d tag, log_prefix + "onpaymentclientconnected $connected" if connected { val textsummary = session shoppingcart cartitems jointostring ", " { item -> item name } val ipr = ignitepaymentrequest builder setamount session shoppingcart gettotal * 100 setcurrencycode currencycode usd setpaymentoperation paymentoperation purchase setmerchantid constants merchant_id setordersummary ordersummary builder setordersummarybitmapimage bitmapfactory decoderesource carcontext resources, session shoppingcart store largeicon setordersummarylabel1 "${carcontext getstring r string pickupstore_app_title } ${session shoppingcart store title}" setordersummarysublabel1 session shoppingcart store address setordersummarylabel2 textsummary setordersummarysublabel2 carcontext getstring r string pickupstore_payment_sublabel2 build build try { mipc readytopay ipr, mipctcb } catch e exception { log d tag, log_prefix + "payment exception $e" e printstacktrace } catch e error { log d tag, log_prefix + "payment error $e" e printstacktrace } } } start the payment process and go back to previous screen after the transaction next, in the startpayment function, connect the ignite payment client and the connection callback to start the payment process mipc connect mipccb after the transaction is completed, the updatetemplate function refreshes the template used in the payment screen before calling the schedulegoback function modify the schedulegoback function to navigate back to the previous template screen shopping cart you can use the pop method of the screenmanager screenmanager pop start the navigation to the store to collect the paid pickup the shopping cart screen shows the pickup store location, details of the order, and go to store button after a successful payment go to kotlin + java > com harman ignite pickupstore > pickupstoresession kt modify the navigatetostore geofence geofence function to trigger the navigation to the pickup store when the go to store button is clicked you can use the intent carcontext action_navigate with geo schema rfc 5879 data, containing latitude and longitude e g , geo 12 345, 14 8767 to send the intent, use the carcontext startcarapp api call val geouristring = "geo ${geofence latitude},${geofence longitude}" val uri = uri parse geouristring val navintent = intent carcontext action_navigate, uri try { carcontext startcarapp navintent } catch e exception { log e tag, log_prefix + "navigatetostore exception starting navigation" e printstacktrace cartoast maketext carcontext, "failure starting navigation", cartoast length_short show } run the app on ignite aaos emulator run the pickup-store-app on ignite aaos emulator when the app starts for the first time, it requests for user permissions click grant permissions choose allow all the time for location permission and click the return button 4 browse the pickup store catalog and add items to shopping cart open the shopping cart and click pay you can also change the pickup store by clicking select store check the order summary and billing information then, click confirm and pay to process payment after a successful payment, the app returns to shopping cart screen with the updated transaction information click go to store to start the navigation to the store the app displays a notification when the car is near the store click the notification to show a reference qr code to present to the store upon pick up you're done! congratulations! you have successfully achieved the goal of this code lab topic now, you can create an aaos templated app, which supports payments by yourself! if you're having trouble, you may download this file aaos ignite shopping app complete code 11 7 mb learn more by going to the developer console section of the ignite store developer portal
Learn Code Lab
codelabget creative with weather data in watch face studio objective learn how to create a watch face that changes dynamically based on weather conditions using weather tags, bitmap font, and conditional lines overview watch face studio is a graphic authoring tool which provides a straightforward and easy-to-understand method of configuring the watch movement and adding watch components without the need of any coding you can use watch face studio to create custom watch faces for galaxy watch, and other watches running on wear os bitmap fonts are images that can be used to replace preset dynamic elements such as timestamps, dates, text, and digital clock components you can replace numbers, punctuation, clock, and calendar abbreviations tag expressions are conditions that let you change the rotation, placement, and opacity of a component based on tag values that represent watch data, such as the date and time, battery status, steps, or weather your watch face changes dynamically as the tag value changes you can configure its movement and data dynamically weather tags provide a variety of information about the weather such as weather conditions, current temperature, or uv index conditional lines let you show and hide components on a watch face and control the components' behavior use conditional lines to change the appearance of your watch face in response to certain conditions such as step count, battery, or weather set up your environment you will need the following watch face studio version 1 7 or higher galaxy watch or smartwatch running on wear os 5 or higher sample project here is a sample project for this code lab download it and start your learning experience! weather data sample project 574 3 kb start your project to load the sample project in watch face studio click open project locate the downloaded file and select weather data sample project check the availability of weather data when creating watch faces, always check the value of the [wthr_is_avail] tag before utilizing other weather tags in the sample project, it is already configured to display a no info text with a black background whenever the weather data is not available go to the run pane > weather to preview how your watch face appears with and without weather data notethe [wthr_is_avail] tag checks the availability of weather data and it returns either 0 no or 1 yes change the background using bitmap font watch face studio allows you to use bitmap font for text components you can use the bitmap font to change the background color of your watch face based on specific weather conditions such as sunny, rainy, or snowy using the weather condition tag [wthr_cond] as the value of the text field, you can change the background during a snowy weather select bg from the component list from the properties tab, go to font setting section click the gear icon of the bitmap font setting noteweather condition for bg is already set in the sample project for this bitmap, the default font size is set to 450 pixels which is the watch face size in addition, the [wthr_cond] tag has a value of 0 to 15, wherein the value of 7 indicates a snowy weather since the digit in the bitmap font settings only provides values from 0 to 9, the remaining values 10 to 15 are added in the custom tab to set the bitmap font for snowy weather, click the + sign for 7 to add a background image locate the image from the downloaded sample project in the resources folder, select the bg_snow png image using tag expression to set the background of your watch face during a rainy weather condition, use a tag expression under the bg_transparent group, select the bg_rain_transparent image component change the image visibility by toggling the eye icon from the properties tab, go to color and in its opacity click the tags button input [wthr_cond] == 6 ?0 -100 as the tag expression since the initial opacity value is 100, the expression indicates that the background image is set to 100% opacity when the weather is rainy and 0% opacity otherwise notethe [wthr_cond] tag has a value of 0 to 15, wherein the value of 6 indicates a rainy weather set the weather icon using conditional lines to add a weather icon, you can either use bitmap font or conditional lines in this part, use the conditional lines to set the icon based on weather conditions the conditional line is already added for all weather conditions except for the sunny weather click on the + sign to add the conditional lines for weather click the show/hide weather icon to show the conditional lines for weather under the icon group, select the sunny image component and set its condition under sunny add a temperature unit using bitmap font the weather data provides the current temperature in either celsius c or fahrenheit f as its temperature unit use the temperature unit tag [wthr_tem_unit] to change the text component to the unit based on preference notethe temperature unit tag [wthr_tem_unit] has the following values for celsius, the value is 1 for fahrenheit, the value is 2 use bitmap font to set the image of the temperature unit based on the value of [wthr_tem_unit] under the temperature group, select unit c/f from the component list from the properties tab, go to font setting section click the gear icon of the bitmap font setting to set bitmap font for the value of 2 fahrenheit , click the + sign to add an image locate the image from the downloaded sample project in the resources folder, select the fahrenheit png image notein the bitmap font setting, the default font size is set to 50 test the watch face go to the run panel > weather to test the watch face for different weather conditions by changing the values of the condition adjust the weather condition value to see how the watch face changes for sunny, rainy, and snow weather conditions you can also check whether the temperature unit changes to either celsius or fahrenheit for other weather conditions, the watch face displays the following you're done! congratulations! you have successfully achieved the goal of this code lab now, you can create a watch face that changes dynamically based on weather conditions in watch face studio all by yourself! if you're having trouble, you may download this file weather data complete project 665 6 kb to learn more about watch face studio, visit developer samsung com/watch-face-studio/
Learn Code Lab
codelabcustomize styles of a watch face with watch face studio objective learn how to easily customize the style of a watch face using the customization editor in watch face studio know how to make your watch face respond to your step count using conditional lines overview watch face studio is a graphic authoring tool that enables you to create watch faces for wear os it offers a simple and intuitive way to add images and components, and to configure the watch movement without any coding watch face studio supports watch faces for the galaxy watch4 or newer version, and other watch devices that run on the same platform the style in watch face studio allows you to modify the style of the selected layer you can define image styles and theme color palettes that the user can choose from to customize their watch the customization editor in wfs enables you to refine, organize, name, and preview the styles you have defined for the watch conditional lines let you show and hide components on your watch face and control the behavior of the components use conditional lines to change the look of your watch face in response to certain conditions, such as the time and event, such as unread notifications set up your environment you will need the following watch face studio galaxy watch4 or newer smart watch running on wear os3 or higher sample project here is a sample project for this code lab download it and start your learning experience! style customization sample project 385 30 kb start your project download the sample project file, and click open project in watch face studio locate the downloaded sample project, and then click open add styles to the watch hands and index styles can be added for image-based layers such as icons, index, and hand component layers the watch face supports up to 10 image styles in the style tab, add a file of the same type as the existing image in the layer select the watch hand named min_hand click on the style tab click the + button to add more minute hands simply select the first three images repeat the previous steps for the hour hand and index create style sets go to the style tab and click on customization editor select min_hand, hour_hand, and index_line merge these by using right-click on your mouse change the name of the style sets using text id click on text id of the previously merged style set then, click the add new button set the id name to id_time and the default value to time then, click ok now, you can change the name of your style set click again on the text id and search for the id name that you just set here, the name and default value for your style set are changed finally, repeat the same thing for the background merge the other components to make a single background using the text id, change the name of the style set to id_background and the default value to background modify the theme color palette the theme color palette is a set of colors that you can use on a specific design component each palette can have up to three colors the watch face supports up to 30 theme colors here, you add a new set of colors for the month component go to the style tab under the theme color palette, click the + button choose a color from the palette you can change the other two colors by clicking on the color box preview your watch face using customization editor at this point, you have created custom styles for the watch hands and index, background, and color you can use the run pane and customization editor to preview how the watch face looks like when changing different styles open the run pane in a separate window and click customization editor in the customization editor, you can see the three tabs background, color, and time go to each tab and preview the different custom styles that you’ve created use conditional lines for step count use the conditional lines to make the step count on your watch face respond to certain conditions here, you want to show different images depending on the step count percentage 0% to 20%, 21% to 80%, and 81% to 100% click on the + button and select steps as a conditional line click on the steps icon to view the default conditional lines for all components select the sc_initial component then, double-click on the layer of its conditional line a warning prompts you that any existing conditional lines will be overwritten, simply click ok now, you can start changing the conditional line for the sc_initial component drag the start of the bar to 0% and drag the end of the bar to 20% this sets the condition that the sc_initial image visually appears on the watch face when the step percentage is from 0% to 20% for the sc_moderate component, set the conditional line from 21% to 80%, and for the sc_good component, set it from 81% to 100% this makes the sc_moderate and sc_good images to visually appear on the mentioned step count percentages tipread apply conditional lines on watch faces to know more about conditional line test the watch face in the run pane, click the preview watch face icon and you can run the created watch face with different custom designs to test your watch face, you need to connect a watch device to the same network as your computer in watch face studio, select run on device select the connected watch device you want to test with if your device is not detected automatically, click scan devices to detect your device or enter its ip address manually by clicking the + button noteto run the watch face successfully, you may need to configure its always-on display to avoid any error when you run it on your watch for more details about testing your watch faces, click here you're done! congratulations! you have successfully achieved the goal of this code lab now, you can create a watch face using style and conditional lines in watch face studio by yourself! if you face any trouble, you may download this file style customization complete project 425 73 kb to learn more about watch face studio, visit developer samsung com/watch-face-studio
Learn Code Lab
codelabutilize the add to samsung wallet service for digital cards notescenes in the demo video are simulated and does not represent any real-world conditions or outcomes objective learn how to use the add to samsung wallet service so that users can store digital contents, such as boarding passes, tickets, and coupons, to their samsung wallet app partnership request to create, manage, and monitor performance of wallet cards with the samsung wallet partners site, you must become an official samsung partner once done, you can fully utilize this code lab you can learn more by visiting samsung wallet partner onboarding process, here in samsung developers overview samsung wallet is an application that securely stores essential items such as boarding passes, tickets, and coupons, making them easily accessible from anywhere with this app, users can access various partner wallet cards in one place, simply by swiping up from the bottom of the screen the add to samsung wallet service provides interfaces for users to conveniently add digital content to samsung wallet here are examples of the supported wallet cards boarding pass journey information such as flights, trains, and buses can be provided as notifications, allowing easy retrieval when checking in by configuring server synchronization, updates to journey information such as gate changes, schedule changes, or cancellations can be received by the users ticket notifications about events and additional information, including benefits, can be provided based on real-time utilization of performances, sports games, movies, and admission tickets, status updates related to expiration and availability can be provided gift card gift card, also referred to as a prepaid card, provides real-time balance and transaction history loyalty loyalty cards function as membership credentials, managing membership information through these cards, loyalty points can be administered and redeemed id id cards can fulfill identification verification purposes, such as identity cards, employee cards, and licenses physical documents can be represented through wallet cards, and near field communication nfc -based authentication can be provided reservation reservation cards can contain diverse online booking details, including rental cars, restaurants, and accommodations ongoing reservation information can be managed as a journey pay as you go pay as you go cards allow users to register services that can be charged and utilized according to their preference for convenient use generic card generic cards enable users to create customized cards by selecting preferred card template layouts and designing elements notedepending on your country or region, some card types are not supported if you need assistance, please contact us at developer samsung com/dashboard/support the image below shows the process of managing wallet cards for more information, refer to manage wallet cards set up your environment you will need the following latest version of samsung wallet app from galaxy store samsung galaxy device that supports samsung wallet access to samsung wallet partners site internet browser, such as chrome openssl intellij idea or any java ide optional start the onboarding process partners can manage wallet cards and monitor performance with the samsung wallet partners site to join as partner generate a private key and certificate signing request csr using the openssl command you can follow the instructions in security factors notea private key enables encryption and is the most important component of certificates while csr, which is a necessary factor to obtain a signed certificate, includes the public key and additional information like organization and country proceed to register in the samsung wallet partners site using your samsung account follow the samsung wallet partner onboarding process upload the generated csr for data encryption in encryption setting management section after registration, you will receive a welcome email noteupon receiving the certificates via email, be sure to keep the information safe from exposure and only use them for the following purposes signed certificate used along with the private key to sign data samsung certificate used to encrypt card data and validate authentication tokens in server api headers create a wallet card follow the steps below to create a wallet card in samsung wallet partners site click the wallet cards menu and choose create wallet card fill out the general information form with the details of the wallet card in wallet card template, choose a card type and sub type select the design type and click done you can choose from various types of wallet card templates optimized for partners after inputting all necessary details, click save to set the wallet card status to draft launch the wallet card you can launch and request activation of the card by clicking the launch button upon agreeing to proceed, the launch button text changes to launched and the card status becomes verifying add the card to samsung wallet using the test tool open a web browser on your computer or galaxy mobile device, and go to the following link partner walletsvc samsung com/addtowallettest go to add to wallet tab and click choose key file to upload your private key in the select card dropdown menu, select the created card to display the card details and populate sample data navigate to the form tab and modify the card data as desired notethe structure for configuring wallet cards follows the defined specification you can refer to the full list of card-specific attributes specification scroll down to the bottom of the page and click the add to samsung wallet button click done when a preview of the card shows on your mobile screen with a message indicating that the card has been added to your wallet once the card is added to your samsung wallet app, you can check its details by clicking on it noteyou can also go to the playground tab and add cards to the samsung wallet app even without creating a card on the wallet partners site update the status of the added card if a server api info partner get card data and partner send card state is registered in the wallet card, real-time updates of the user's registered cards can be provided notefor more information, see server interaction modify and update the card's status by utilizing the push notification feature of the test tool navigate to the push notification tab ensure that the correct private key is uploaded and the same card as in the add to wallet tab is selected copy the ref id value from the add to wallet tab and paste it into ref id field in the push notification tab in the status field, enter one of the following card states expired, redeemed, held, suspended, or deleted the current state is set to active then, click the request push notification button check the card in the samsung wallet app to confirm the change tokenize card data and implement the add to samsung wallet button to your service optional notethis step is optional, but if you want to learn how to integrate the add to samsung wallet button into your services like an android app, web app, or email, you can follow these steps the samsung wallet partners site provides generated add to samsung wallet scripts for each wallet card you create you can simply copy and paste these scripts into your partner apps web and android or include them in emails/mms messages to implement the add to wallet button, follow these steps go to the [add to wallet script guide] section of the card you created click show to view the available scripts and then copy the appropriate script for your service develop a program that can generate tokenized card data cdata the cdata represents the actual content of the wallet card and comes in different formats depending on the card type you can check the cdata generation sample code for reference the cdata is derived from the card data, which is in json format for testing purposes, you can utilize the generated json from the test tool follow the implementing atw button guide to determine where to incorporate the generated cdata and gain further insights into this process you're done! congratulations! you have successfully achieved the goal of this code lab topic now, you can utilize the add to samsung wallet service by yourself! to learn more about samsung wallet, visit developer samsung com/wallet
Learn Code Lab
codelabapply conditional lines on watch faces objective learn how to create a watch face that responds to time and notification using conditional lines in watch face studio overview watch face studio is a graphic authoring tool that enables you to create and design watch faces for watches running on wear os it offers a simple and intuitive way to add images and components, and to configure the watch movement without any coding watch face studio supports watch faces for the galaxy watch4 or newer version, and other watch devices that run on the same platform conditional lines in watch face studio lets users easily control components and its behaviors on watch faces you can make your watch faces change dynamically based on time, step-count, or battery using conditional lines now, with the latest version of watch face studio, you can also set conditional lines based from events such as low battery, unread notification, or scenarios without any events set up your environment you will need the following watch face studio latest version galaxy watch4 or newer any supported wear os watch sample project here is a sample project for this code lab download it and start your learning experience! conditional lines sample project 2 43 mb start your project download the sample project file, and click open project in watch face studio locate the downloaded file, then click open apply conditional lines based on time using conditional lines in watch face studio, your watch face can visually change its design based on the time of the day here, you can change the background image of the watch face based on certain time intervals by setting the timeline condition of two background images, named background_day and background_night click the show/hide timeline icon to show the frame area notice that there's a default conditional line based on time for every component each conditional line is represented by a bar in the timeline and you can adjust it using the slider at the end of the bar collapse the background group containing the two background images in the timeline area of background_day, click on its bar and hover your mouse at the start of the bar drag the start of the bar to 06 00 00h and drag the end of the bar to 18 00 00h this sets the condition that background_day visually appears on the watch face from 6 00 am until 6 00 pm tipto quickly navigate on the timeline, hold shift + mouse scroll learn more about keyboard shortcuts, by referring to this guide next, for background_night, set the first time condition from 00 00 00h to 06 00 00h by dragging its bar respectively at the start of 18 00 00h, double-click at the timeline area to create a 2nd bar at that specific time drag the end of the bar to 00 00 00h, at the rightmost part of the timeline this makes background_night to appear conditionally from 6 00 pm until 6 00am on your watch face now, it's time to check if your watch face responds correctly based on the time of the day click show/hide run button to open the run panel in watch face studio move the time control slider from 06 00 00h to 18 00 00h and the watch face should show background_day as its background similarly, check if the watch face changes its background to background_night when the time is from 18 00 00h to 06 00 00h set the unread notification event make your watch face change dynamically based on a specific device event in this step, add an event for unread notifications on notification_envelope, an animation component included in the sample project click + or add conditional line and select event noteto remove conditional line icons such as the battery, steps, 12h/ 24h, or event, simply right-click on it and select remove click show/hide event to start configuring the event-based conditional line for notification_envelope on the notification_envelope layer, double-click on the event frame in the warning window, click ok in this case, all existing conditional frames for this layer are deleted afterward, a bar is created for the event-based conditional line noteeach layer responds to only one type of condition next, drag the bar from no event to unread notification noteno event is used if there is no condition set on either battery low or unread notification events check if the notification_envelope animation component appears on your watch face whenever there's an unread notification click play run preview and move the unread notification slider in the run panel when the unread notification is set to a value of 1 or more, the animation component should visually appear on your watch face test the watch face to test your watch face, you need to connect a watch device to the same network as your computer in watch face studio, select run on device select the connected watch device you want to test with if your device is not detected automatically, click scan devices to detect your device or enter its ip address manually by clicking the + button notethe always-on display is already set in the project to run the watch face successfully, you may need to configure its always-on display to avoid any error when you run on device you're done! congratulations! you have successfully achieved the goal of this code lab now, you can use conditional lines in watch face studio, all by yourself! if you're having trouble, you may download this file conditional lines complete project 2 43 mb to learn more about watch face studio, visit developer samsung com/watch-face-studio
Learn Code Lab
codelabtest edge drivers using smartthings test suite objective learn how to identify and resolve issues when deploying edge drivers using smartthings test suite overview smartthings test suite is a tool for testing iot device integrations within the smartthings platform this solution provides a seamless certification process, allowing developers of smartthings hub connected devices to submit their products for certification without the need for manual testing this accelerates the certification timeline and offers a more cost-effective path to certifying these devices the key feature of this self-testing tool is it contains an automated testing suite that covers critical certification criteria, ranging from functionality to performance tests the tool also provides real-time feedback that gives detailed information on the device's compliance status, allowing for quick identification and resolution of any issues lastly, it has an intuitive and user-friendly interface that ensures a seamless experience for developers of all levels 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 smartthings v4 multipurpose sensor or lightify tunable white 60 light bulb notemake sure that your devices are connected to your smartthings app sample code here is a sample code for this code lab download it and start your learning experience! test suite sample code 185 4 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 notefor other operating systems, download the appropriate zipped binary and install it on your system path 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 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 file directory and click select folder once finished, the project files are seen on the explorer menu configure custom edge drivers open your command prompt or terminal and follow the corresponding instructions depending on your device availability make sure that the path directory in your cli contains the project file smartthings multipurpose sensor in the terminal, type the following command to build and upload your edge driver package to the smartthings cloud smartthings edge drivers package drivers/codelab-zigbee-contact create a new channel for your edge driver and enter the following channel details smartthings edge channels create channel name smartthings test suite demo channel description channel for sdc2024 channel terms of service url www smartthings com enroll your hub in your newly created channel and select the corresponding channel and hub smartthings edge channels enroll assign your driver to the created channel smartthings edge channels assign install the created edge driver from your channel to your own hub smartthings edge drivers install confirm that the correct version of the driver is present in your hub smartthings edge drivers installed select the edge driver for this device smartthings edge drivers switch lightify tunable white 60 bulb in the terminal, type the following command to build and upload your edge driver package to the smartthings cloud smartthings edge drivers package drivers/codelab-zigbee-switch create a new channel for your edge driver and enter the following channel details smartthings edge channels create channel name smartthings test suite demo channel description channel for sdc2024 channel terms of service url www smartthings com enroll your hub in your newly created channel and select the corresponding channel and hub smartthings edge channels enroll assign your driver to the created channel smartthings edge channels assign install the created edge driver from your channel to your own hub smartthings edge drivers install confirm that the correct version of the driver is present in your hub smartthings edge drivers installed select the edge driver for this device smartthings edge drivers switch test your device on your web browser, go to smartthings test suite, login to your samsung account and follow the corresponding instructions depending on your device availability smartthings multipurpose sensor on the test suite, look for your device, click menu icon > prepare new test under the compatible capabilities, select all capabilities except for battery, and click start during the test execution, perform the indicated user actions for every test case if there are any it might cause incorrect test results if user actions are not performed tipyou may view the real-time sensor states of the device in the smartthings mobile app view the test summary after the test it returns a failed test that you are going to resolve in the next step lightify tunable 60 white bulb on the test suite, look for your device, click menu icon > prepare new test under the compatible capabilities, select all capabilities after you've selected the capabilities, click start warningduring the test execution, observe the behavior of the bulb it might cause incorrect test results if automated tests are interrupted view the test summary after the test it returns a failed test that you are going to resolve in the next step resolve test failures smartthings multipurpose sensor the test logs contain basic information about the test results and specific test cases, providing technical context to users for efficient troubleshooting download the test logs by navigating to the bottom page of the test summary > show full test details > download log to understand the test logs, its structure follows this schema {execution timestamp} device node path node type [node state] {execution message} in the downloaded test log, two test cases failed with the following error [failed] initialize states following states were not set correctly [contact any other state than "open" on main contactsensor] [failed] send command and validate some events didn't happen [contact "closed" on main contactsensor] some states aren't final [contact "closed" on main contactsensor] in the first error log, it appears that the test suite cannot change the device's state to anything other than an open state in the second error log, the test suite tries to change its state to closed, but to no avail it is confirmed in the capability definition that the contact sensor has only two states open and closed therefore, the device is constantly in an open state and unable to change to a closed state with these information, you can start troubleshooting by going to drivers > codelab-zigbee-contact > multi-sensor > init lua and look for incorrect code implementation with these keywords open, closed, contactsensor it can be seen in the zone_status_change_handler and zone_status_handler functions that there are code blocks on comment this might be a result of someone developing this code have changed this part of code for debugging and forgot to uncomment this part uncomment this code block from zone_status_change_handler function if not device preferences["certifiedpreferences garagesensor"] then contactsensor_defaults ias_zone_status_change_handler driver, device, zb_rx end uncomment this code block from zone_status_handler function if not device preferences["certifiedpreferences garagesensor"] then contactsensor_defaults ias_zone_status_attr_handler driver, device, zone_status, zb_rx end remove this line of code from zone_status_change_handler and zone_status_handler functions device emit_event_for_endpoint zb_rx address_header src_endpoint_value, capabilities contactsensor contact open save the file and update the driver by invoking the same cli commands that were also used during the configuration of custom edge drivers smartthings edge drivers package drivers/codelab-zigbee-contact smartthings edge channels assign smartthings edge drivers install again, go to smartthings test suite, select your device, click menu > prepare new test ensure that all compatible capabilities are selected, with the exception for battery again, start the test and perform indicated user actions for every test case if there are any now, all tests are passed! lightify tunable white 60 bulb the test logs contain basic information about the test results and specific test cases, providing technical context to users for efficient troubleshooting download the test logs by navigating to the bottom page of the test summary > show full test details > download log to understand the test logs, its structure follows this schema {execution timestamp} device node path node type [node state] {execution message} in the downloaded test log, one test case failed with the following error [failed] send command and validate some events didn't happen [colortemperature maximum 7500k on main colortemperature] some states aren't final [colortemperature maximum 7500k on main colortemperature] in the error log, it directs to an issue for setting an incorrect maximum colortemperature value the configuration on your edge driver is set to 7500k you can start to troubleshoot by looking for the bulb's color temperature rating either from the device packaging or the device manufacturer website with these information, you can start troubleshooting by going to drivers > codelab-zigbee-switch > profiles > rgbw-bulb yml and look for lines that declares the colortemperature value change the colortemperature range declaration range [ 2700, 6500 ] save the file and update the driver by invoking the same cli commands that were also used during the configuration of custom edge drivers smartthings edge drivers package drivers/codelab-zigbee-switch smartthings edge channels assign smartthings edge drivers install again, go to smartthings test suite, select your device, click menu > prepare new test under the compatible capabilities, select all capabilities again, start the test and perform indicated user actions for every test case if there are any now, all tests are passed! you're done! congratulations! you have successfully achieved the goal of this code lab now, you can test your edge driver for smartthings devices using smartthings test suite! if you're having trouble, you may download this file test suite complete code 184 6 kb to learn more about smartthings test suite, visit smartthings edge architecture smartthings developer console
Learn Code Lab
codelabimplement flex mode on an unreal engine game objective learn how to implement flex mode on an unreal engine game using android jetpack windowmanager and raw java native interface jni 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 epic games launcher with unreal engine 4 or later visual studio or any source code editor samsung galaxy foldable device galaxy z fold2, z fold3, or newer galaxy z flip, z flip3, 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 create and set up your project after launching unreal engine from the epic games launcher, follow the steps below to start your project in the select or create new project window, choose games as a new project category and click next select third person as template, then click next to proceed noteyou can implement flex mode on any template or existing projects and use this code lab activity as a reference in the project settings window, set the following type of project c++ target platform mobile / tablet performance characteristics scalable 3d or 2d real-time raytracing raytracing disabled include an additional content pack no starter content project name tutorial_project click create project wait for the engine to finish loading and open the unreal editor once the project is loaded, go to edit > project settings > platforms > android click the configure now button if the project is not yet configured for the android platform then, proceed with the following apk packaging and build settings a apk packaging set target sdk version to 30 set orientation to full sensor change the maximum supported aspect ratio to 2 8 aspect ratio of galaxy z fold3 in decimal to prevent black bars from appearing on the cover display leave it if your game does not need to use the cover display enable use display cutout region?, to prevents black bars at the edge of the main screen otherwise, leave it unchecked b build disable support opengl es3 1 and enable support vulkan notecurrently, there is a problem with opengl es and the split-screen system being investigated the only option right now is to turn off opengl es and use vulkan instead enable native resize event the resize event of a game when switching between displays is disabled in the engine by default however, this behavior can be easily enabled by setting android enablenativeresizeevent=1 in the deviceprofile currently, the only way to create a profile for foldable devices is by creating a specific rule for each device to save time in this code lab, enable the native resize event for all android devices instead locate and open the tutorial_project > config folder in file explorer inside the config folder, create a new folder named android create a new file called androiddeviceprofiles ini and open this file in a text editor, such as visual studio copy below deviceprofile code to the newly created androiddeviceprofiles ini file [deviceprofiles] +deviceprofilenameandtypes=android,android [android deviceprofile] devicetype=android baseprofilename= +cvars=r mobilecontentscalefactor=1 0 +cvars=slate absoluteindices=1 +cvars=r vulkan delayacquirebackbuffer=2 +cvars=r vulkan robustbufferaccess=1 +cvars=r vulkan descriptorsetlayoutmode=2 ; don't enable vulkan by default specific device profiles can set this cvar to 0 to enable vulkan +cvars=r android disablevulkansupport=1 +cvars=r android disablevulkansm5support=1 ; pf_b8g8r8a8 +cvars=r defaultbackbufferpixelformat=0 +cvars=android enablenativeresizeevent=1 ; previewallowlistcvars and previewdenylistcvars are arrays of cvars that are included or excluded from being applied in mobile preview ; if any previewallowlistcvars is set, cvars are denied by default previewallowlistcvars=none this is a copy of the default android deviceprofile from the existing basedeviceprofiles ini file but with the enabled nativeresizeevent console variable cvars notethis step is not required when you only want to implement flex mode yet, it's recommended, to allow applications to run seamlessly from main to cover display without stretching and squashing the game, by enabling the nativeresizeevent create a new plugin and import the foldablehelper 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 5 64 kb to import the foldablehelper java file to the project, follow the steps below go to edit > plugins in the unreal editor click the new plugin button and select blank to create a blank plugin in the name field, type foldables_tutorial and click the create plugin button in file explorer, locate and open tutorial_project > plugins folder go to plugins > foldables_tutorial > source> foldables_tutorial > private and create a new folder called java copy the foldablehelper java file into java folder open the tutorial_project sln file in visual studio in the same private folder path, add a new filter called java right-click on the java filter and click add > existing item locate the foldablehelper java file, then click add to include this java file in the build modify java activity to use foldablehelper unreal plugin language upl is a simple xml-based language created by epic games for manipulating xml and returning strings using upl, you can utilize the foldablehelper java file by modifying the java activity and related gradle files as follows in visual studio, right-click on source > foldables_tutorial folder, then click add > new item > web > xml file xml create an xml file called foldables_tutorial_upl xml ensure that the file location is correct before clicking add in the newly created xml file, include the foldablehelper java file in the build by copying the java folder to the build directory <root xmlns android="http //schemas android com/apk/res/android"> <prebuildcopies> <copydir src="$s plugindir /private/java" dst="$s builddir /src/com/samsung/android/gamedev/foldable" /> </prebuildcopies> set up the gradle dependencies in the build gradle file by adding the following in the xml file <buildgradleadditions> <insert> dependencies { implementation filetree dir 'libs', include ['* jar'] implementation "org jetbrains kotlin kotlin-stdlib-jdk8 1 6 0" implementation "androidx core core 1 7 0" implementation "androidx core core-ktx 1 7 0" implementation "androidx appcompat appcompat 1 4 0" implementation "androidx window window 1 0 0" implementation "androidx window window-java 1 0 0" } android{ compileoptions{ sourcecompatibility javaversion version_1_8 targetcompatibility javaversion version_1_8 } } </insert> </buildgradleadditions> next, modify the gameactivity <gameactivityimportadditions> <insert> <!-- package name of foldablehelper --> import com samsung android gamedev foldable foldablehelper; </insert> </gameactivityimportadditions> <gameactivityoncreateadditions> <insert> foldablehelper init this ; </insert> </gameactivityoncreateadditions> <gameactivityonstartadditions> <insert> foldablehelper start this ; </insert> </gameactivityonstartadditions> <gameactivityonstopadditions> <insert> foldablehelper stop ; </insert> </gameactivityonstopadditions> </root> gameactivityimportadditions adds the com samsung android gamedev foldable foldablehelper into the gameactivity with the existing imports gameactivityoncreateadditions adds the code to the oncreate method inside the gameactivity gameactivityonstartadditions adds the code to the onstart method inside the gameactivity gameactivityonstopadditions adds the code to the onstop method inside the gameactivity save the xml file then, ensure that the engine uses the upl file by modifying the foldables_tutorial build cs script, located in the same folder as the foldables_tutorial_upl xml file after the dynamicallyloadedmodulenames addrange call, add the following if target platform == unrealtargetplatform android { additionalpropertiesforreceipt add "androidplugin", moduledirectory + "\\foldables_tutorial_upl xml" ; } this means that the game engine will use the upl file if the platform is android otherwise, the foldablehelper won’t work implement a storage struct the next thing to implement is a struct, the native version of java’s foldablelayoutinfo class to store the data retrieved from the java code using a struct, do the following in content browser of unreal editor, right-click on c++ classes > add/import content then, click new c++ class select none for the parent class and click next name the new class as foldablelayoutinfo assign it to the foldables_tutorial plugin then, click create class delete the created foldablelayoutinfo cpp file and only keep its header file in the header file called foldablelayoutinfo h, set up a struct to store all needed data from the windowmanager #pragma once #include "core h" enum efoldstate { undefined_state, flat, half_opened }; enum efoldorientation { undefined_orientation, horizontal, vertical }; enum efoldocclusiontype { undefined_occlusion, none, full }; struct ffoldablelayoutinfo { efoldstate state; efoldorientation orientation; efoldocclusiontype occlusiontype; fvector4 foldbounds; fvector4 currentmetrics; fvector4 maxmetrics; bool isseparating; ffoldablelayoutinfo state efoldstate undefined_state , orientation efoldorientation undefined_orientation , occlusiontype efoldocclusiontype undefined_occlusion , foldbounds -1, -1, -1, -1 , currentmetrics -1, -1, -1, -1 , maxmetrics -1, -1, -1, -1 , isseparating false { } }; implement jni code to implement jni, create a new c++ class with no parent and name it foldables_helper assign the class to the same plugin, then modify the c++ header and source files as follows in the created header file foldables_helper h , include foldablelayoutinfo h #include "foldablelayoutinfo h" then, declare a multicast_delegate to serve as a listener for passing the data from the java implementation to the rest of the engine declare_multicast_delegate_oneparam fonlayoutchangeddelegate, ffoldablelayoutinfo ; lastly, set up the methods and member variables class foldables_tutorial_api ffoldables_helper { public static void init ; static bool haslistener; static fonlayoutchangeddelegate onlayoutchanged; }; moving to the source file foldables_helper cpp , set up the definitions for the methods and member variables created in the header file bool ffoldables_helper haslistener = false; fonlayoutchangeddelegate ffoldables_helper onlayoutchanged; void ffoldables_helper init { haslistener = true; } now, in the same source file, create the native version of the onlayoutchanged function created in the foldablehelper java file since the java onlayoutchanged function only works on android, surround the function with an #if directive to ensure that it compiles only on android #if platform_android #endif within this directive, copy the code below to use the jni definition of the java onlayoutchanged function extern "c" jniexport void jnicall java_com_samsung_android_gamedev_foldable_foldablehelper_onlayoutchanged jnienv * env, jclass clazz, jobject jfoldablelayoutinfo { create the ffoldablelayoutinfo to store the data retrieved from java ffoldablelayoutinfo result; retrieve the field ids of the foldablelayoutinfo and rect objects created in the java file //java foldablelayoutinfo field ids jclass jfoldablelayoutinfocls = env->getobjectclass jfoldablelayoutinfo ; jfieldid currentmetricsid = env->getfieldid jfoldablelayoutinfocls, "currentmetrics", "landroid/graphics/rect;" ; jfieldid maxmetricsid = env->getfieldid jfoldablelayoutinfocls, "maxmetrics", "landroid/graphics/rect;" ; jfieldid hingeorientationid = env->getfieldid jfoldablelayoutinfocls, "hingeorientation", "i" ; jfieldid stateid = env->getfieldid jfoldablelayoutinfocls, "state", "i" ; jfieldid occlusiontypeid = env->getfieldid jfoldablelayoutinfocls, "occlusiontype", "i" ; jfieldid isseparatingid = env->getfieldid jfoldablelayoutinfocls, "isseparating", "z" ; jfieldid boundsid = env->getfieldid jfoldablelayoutinfocls, "bounds", "landroid/graphics/rect;" ; jobject currentmetricsrect = env->getobjectfield jfoldablelayoutinfo, currentmetricsid ; //java rect object field ids jclass rectcls = env->getobjectclass currentmetricsrect ; jfieldid leftid = env->getfieldid rectcls, "left", "i" ; jfieldid topid = env->getfieldid rectcls, "top", "i" ; jfieldid rightid = env->getfieldid rectcls, "right", "i" ; jfieldid bottomid = env->getfieldid rectcls, "bottom", "i" ; retrieve the current windowmetrics and store it in the ffoldablelayoutinfo as an fintvector4 // currentmetrics int left = env->getintfield currentmetricsrect, leftid ; int top = env->getintfield currentmetricsrect, topid ; int right = env->getintfield currentmetricsrect, rightid ; int bottom = env->getintfield currentmetricsrect, bottomid ; // store currentmetrics rect to fvector4 result currentmetrics = fintvector4{ left, top, right, bottom }; do the same for the other variables in the java foldablelayoutinfo // maxmetrics jobject maxmetricsrect = env->getobjectfield jfoldablelayoutinfo, maxmetricsid ; left = env->getintfield maxmetricsrect, leftid ; top = env->getintfield maxmetricsrect, topid ; right = env->getintfield maxmetricsrect, rightid ; bottom = env->getintfield maxmetricsrect, bottomid ; //store maxmetrics rect to fvector4 result maxmetrics = fintvector4{ left, top, right, bottom }; int hingeorientation = env->getintfield jfoldablelayoutinfo, hingeorientationid ; int state = env->getintfield jfoldablelayoutinfo, stateid ; int occlusiontype = env->getintfield jfoldablelayoutinfo, occlusiontypeid ; bool isseparating = env->getbooleanfield jfoldablelayoutinfo, isseparatingid ; // store the values to an object for unreal result orientation = tenumasbyte<efoldorientation> hingeorientation + 1 ; result state = tenumasbyte<efoldstate> state + 1 ; result occlusiontype = tenumasbyte<efoldocclusiontype> occlusiontype + 1 ; result isseparating = isseparating; // boundsrect jobject boundsrect = env->getobjectfield jfoldablelayoutinfo, boundsid ; left = env->getintfield boundsrect, leftid ; top = env->getintfield boundsrect, topid ; right = env->getintfield boundsrect, rightid ; bottom = env->getintfield boundsrect, bottomid ; // store maxmetrics rect to fvector4 result foldbounds = fintvector4{ left, top, right, bottom }; broadcast the result via the onlayoutchanged delegate for use in the engine if ffoldables_helper haslistener { ue_log logtemp, warning, text "broadcast" ; ffoldables_helper onlayoutchanged broadcast result ; } } create a player controller and two ui states this section focuses on adding a player controller and creating two user interface ui states for flat and flex modes these objects are needed for the flex mode logic implementation following are the steps to add a player controller and create two ui states add a new player controller blueprint in content browser, go to content > thirdpersoncpp and right-click on blueprints > add/import content > blueprint class pick player controller as its parent class rename it as flexplayercontroller notethe flexplayercontroller added is generic and can be replaced by your custom player controller in an actual project add a new c++ class with actor component as its parent class name it as foldables_manager and assign it to the foldables_tutorial plugin click the create class button open the flexplayercontroller blueprint by double-clicking it click open full blueprint editor attach the actor component to the flexplayercontroller in the left pane, click add component, then find and select the foldables_manager next, create a pair of userwidget classes for the ui layouts needed flat mode ui for the full screen or normal mode; and flex mode ui for split-screen in add c++ class window, select the show all classes checkbox find and pick userwidget as the parent class then, click next name the new user widget as flatui and attach it to the plugin click next repeat the process but name the new user widget as flexui you might get an error when trying to compile stating that the userwidget is an undeclared symbol to fix this, open the foldables_tutorial build cs file, and in the publicdependencymodulenames addrange call, add "inputcore" and "umg" to the list create a pair of blueprints made from subclasses of these two user widgets right-click on content and create a new folder called foldui inside the newly created folder, right-click to add a new blueprint class in all classes, choose flatui and click the select button rename the blueprint as bp_flatui in the same folder, repeat the process but choose the flexui class and rename the blueprint as bp_flexui double-click on bp_flatui and bp_flexui, then design your two uis like below to visualize switching between flat and flex mode flat ui flex ui notethis code lab activity does not cover the steps on how to create or design ui if you want to learn about how to create your own game design in unreal engine 4, refer to unreal motion graphics ui designer guide implement the flex mode logic after creating the flexplayercontroller and the two ui states bp_flatui and bp_flexui , you can now implement flex mode logic in the foldables_manager open the foldables_manager h and include the necessary c++ header files #pragma once #include "coreminimal h" #include "components/actorcomponent h" #include "engine h" #include "flatui h" #include "flexui h" #include "foldables_helper h" #include "foldables_manager generated h" remove the line below to save a little bit of performance as this component doesn't need to tick public // called every frame virtual void tickcomponent float deltatime, eleveltick ticktype, factorcomponenttickfunction* thistickfunction override; set up the functions needed in foldables_manager the constructor, a function to create the ui widgets the implementation of onlayoutchanged delegate public // sets default values for this component's properties ufoldables_manager ; void createwidgets ; protected // called when the game starts virtual void beginplay override; protected void onlayoutchanged ffoldablelayoutinfo foldablelayoutinfo ; then, set up the variables needed references to the flat and flex ui classes references to the flat and flex ui objects mark the pointers as uproperty to ensure that garbage collection does not delete the objects they point to tsubclassof<uuserwidget> flatuiclass; tsubclassof<uuserwidget> flexuiclass; uproperty class uflatui* flatui; uproperty class uflexui* flexui; finally, define a new private function restoreflatmode , to disable flex mode and return to normal mode private void restoreflatmode ; moving over to foldables_manager cpp, implement the constructor using the constructorhelpers, find the ui classes and set the variables to store these classes also, set the bcanevertick to false to prevent the component from ticking and remove the code block of tickcomponent function // sets default values for this component's properties ufoldables_manager ufoldables_manager { primarycomponenttick bcanevertick = false; static constructorhelpers fclassfinder<uflatui> flatuibpclass text "/game/foldui/bp_flatui" ; static constructorhelpers fclassfinder<uflexui> flexuibpclass text "/game/foldui/bp_flexui" ; if flatuibpclass succeeded { flatuiclass = flatuibpclass class; } if flexuibpclass succeeded { flexuiclass = flexuibpclass class; } } next, set up the beginplay function to link the delegate to the onlayoutchanged function, to initialize the foldables_helper, and to create the widgets ready for use in the first frame // called when the game starts void ufoldables_manager beginplay { super beginplay ; ffoldables_helper onlayoutchanged adduobject this, &ufoldables_manager onlayoutchanged ; ffoldables_helper init ; createwidgets ; } set up the createwidgets function to create the widgets using the ui classes acquired in the constructor add the flatui widget to the viewport, assuming the app opens in normal mode until it receives the foldablelayoutinfo void ufoldables_manager createwidgets { flatui = createwidget<uflatui> aplayercontroller* getowner , flatuiclass, fname text "flatui" ; flexui = createwidget<uflexui> aplayercontroller* getowner , flexuiclass, fname text "flexui" ; flatui->addtoviewport ; } afterward, create the onlayoutchanged function, which will be called via a delegate inside this function, check whether the device’s folded state is half_opened if so, check whether the orientation of the fold is horizontal void ufoldables_manager onlayoutchanged ffoldablelayoutinfo foldablelayoutinfo { //if state is now flex if foldablelayoutinfo state == efoldstate half_opened { if foldablelayoutinfo orientation == efoldorientation horizontal { notefor this third person template, splitting the screen vertically isn’t ideal from a user experience ux point of view for this code lab activity, split the screen only on the horizontal fold top and bottom screen if you want it vertically, you need to use the same principle in the next step but for the x-axis instead of the y-axis you must also ensure that you have a flex ui object for the vertical layout if the device is both on flex mode and horizontal fold, change the viewport to only render on the top screen using the normalized position of the folding feature then in an asynctask on the game thread, disable the flatui and enable the flexui however, if the device is on normal mode, then return to flat ui using restoreflatmode function //horizontal split float foldratio = float foldablelayoutinfo foldbounds y / foldablelayoutinfo currentmetrics w - foldablelayoutinfo currentmetrics y ; gengine->gameviewport->splitscreeninfo[0] playerdata[0] sizex = 1 0f; gengine->gameviewport->splitscreeninfo[0] playerdata[0] sizey = foldratio; asynctask enamedthreads gamethread, [=] { if flatui->isinviewport { flatui->removefromparent ; } if !flexui->isinviewport { flexui->addtoviewport 0 ; } } ; } else { restoreflatmode ; } } else { restoreflatmode ; } } reverse the flex mode implementation logic to create the restoreflatmode function by setting the viewport to fill the screen, then disable the flexui and enable the flatui void ufoldables_manager restoreflatmode { gengine->gameviewport->splitscreeninfo[0] playerdata[0] sizex = 1 0f; gengine->gameviewport->splitscreeninfo[0] playerdata[0] sizey = 1 0f; asynctask enamedthreads gamethread, [=] { if !flatui->isinviewport { flatui->addtoviewport 0 ; } if flexui->isinviewport { flexui->removefromparent ; } } ; } set up a game mode and attach the flexplayercontroller the game mode defines the game rules, scoring, and any game-specific behavior set up the game mode in unreal editor by creating a blueprint class in the content > thirdpersoncpp > blueprints folder pick game mode base as the parent class and rename it as flexgamemode double-click on flexgamemode in the drop-down menu next to player controller class, choose the flexplayercontroller lastly, go to edit > project settings > project > maps & modes and select flexgamemode as the default gamemode build and run the app go to edit > package project > android to build the apk ensure that the android development environment for unreal is already set up to your computer noteif the build failed due to corrupted build tools, consider downgrading the version to 30 or lower using the sdk manager or, simply rename d8 bat to the name of the missing file dx bat in sdk path > build-tools > version number directory and, in lib folder of the same directory, rename d8 jar to dx jar after packaging your android project, 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 unreal engine game app by yourself! if you're having trouble, you may download this file flex mode on unreal complete code 20 16 mb to learn more, visit www developer samsung com/galaxy-z www developer samsung com/galaxy-gamedev
Learn Code Lab
codelabadd samsung in-app purchase service to your app objective learn how to integrate samsung in-app purchase iap service into your app so that users can purchase digital consumable and non-consumable items within the app registered in the galaxy store overview the samsung in-app purchase iap service offers developers a robust solution for handling digital purchases within mobile apps it ensures a smooth and secure experience when purchasing digital goods or items, managing subscriptions, or dealing with refunds and consumed items the iap sdk makes integrating the iap functionality into your app simple, allowing you to configure iap settings, retrieve item details, offer and sell items, and manage purchased items effortlessly to successfully sell in-app items, follow these four basic steps download and integrate the samsung iap sdk into your application request for commercial seller status in the samsung galaxy store seller portal upload your application’s binary file in the seller portal add in-app items to your app in-app items can be categorized into three types consumable, non-consumable, and subscription consumable these items can be used only once and can be repurchased multiple times by the app user non-consumable non-consumable items can be used any number of times and cannot be repurchased subscription with subscription items, app users can access them any number of times throughout the duration of their subscription for more information, go to samsung iap set up your environment you will need the following android studio latest version recommended samsung iap sdk latest version samsung galaxy device android 6 0 or higher samsung galaxy store seller portal commercial seller account sample code here is a sample code for you to start coding in this code lab download it and start your learning experience! in-app purchase turbobike sample code 1 3 mb start your project in android studio, click open to open an existing project locate the downloaded android project turbobike_blank_code from the directory and click ok register the app and its items in the seller portal to register the sample app along with the in-app items in the samsung galaxy store seller portal, follow these steps sign in using your commercial seller account in android studio, modify the package name of the sample app navigate to app > kotlin + java > com example turbobike view, and in the mainactivity java file, refactor the application name turbobike from the package name com example turbobike for all directories notethe package name com example turbobike is already registered in the seller portal to avoid any conflicts, rename it with a different package name build the apk from android studio and upload the binary to the seller portal once the testing process is complete and the app functions smoothly as intended, return to this step and upload the final apk file under the in app purchase tab, add three items named bike, booster, and fuel these are item ids of the in-app items created in the sample app where the bike is a non-consumable item, while both booster and fuel are consumable items when adding the bike item, uncheck this item can be purchased multiple times checkbox refer to the step-by-step guide for detailed instructions lastly, add a licensed tester to enable purchasing within the app edit your seller portal profile and include your samsung account in the license test field on the test device, sign in with the same samsung account initialize the samsung iap sdk before using the samsung iap sdk library, certain configurations are necessary, which are already applied in the sample code provided the samsung-iap-6 3 0 aar library is added to the app > libs folder, and included as a dependency in the module-level build gradle file dependencies { … implementation filetree dir 'libs', include ['* aar'] } these necessary permissions are already added in the androidmanifest xml file com samsung android iap permission billing to connect to iap and enable in-app item registration in seller portal android permission internet because iap uses the internet <uses-permission android name="com samsung android iap permission billing" /> <uses-permission android name="android permission internet" /> go to mainactivity java and in the oncreate function, create an instance of the samsung iap sdk to utilize the functionalities it offers set the operating mode to operation_mode_test to purchase items without payment and enable only licensed testers to test without incurring charges iaphelper = iaphelper getinstance getapplicationcontext ; iaphelper setoperationmode helperdefine operationmode operation_mode_test ; notebefore submitting the app for beta testing or release, change the operating mode to operation_mode_production get the list of all items owned by the user the getownedlist function returns a list of items that the user has previously purchased, including consumable items that have not been reported as consumed non-consumable items subscription items that are in free trial and active state call the getownedlist function from the iaphelper class also, check if there are any consumable items in the returned list and call the handleconsumableitems function with the purchase id of each consumable item iaphelper getownedlist iaphelper product_type_all, new ongetownedlistlistener { @override public void ongetownedproducts @nonnull errorvo errorvo, @nonnull arraylist<ownedproductvo> arraylist { if errorvo geterrorcode == iaphelper iap_error_none { for ownedproductvo item arraylist { if item getisconsumable { // consume the purchased item handleconsumableitems item getpurchaseid ; } } } else { log d "getownedproducts failed ", errorvo tostring ; } } } ; notecall getownedlist whenever launching the application to check for unconsumed items or subscription availability report consumable items as consumed mark the consumable items returned from getownedlist and those successfully purchased with startpayment as consumed by calling the consumepurchaseditems function iaphelper consumepurchaseditems itemid, new onconsumepurchaseditemslistener { @override public void onconsumepurchaseditems @nonnull errorvo errorvo, @nonnull arraylist<consumevo> arraylist { if errorvo geterrorcode == iaphelper iap_error_none { toast maketext getapplicationcontext ,"consumed successfully now you can purchase another item ", toast length_short show ; } else { toast maketext getapplicationcontext , "consume failed " + errorvo geterrorstring , toast length_short show ; } } } ; this makes the items available for repurchase, regardless of whether they are used or not in the sample app, consumable items cannot be used and it only stores the total count of the items purchased get item details to retrieve information about some or all in-app items registered to the app, use the getproductsdetails function by specifying an item id such as bike or booster, you can fetch details for a particular in-app item to obtain information about all in-app items available in the seller portal for the user, pass an empty string "" as the argument iaphelper getproductsdetails "bike, booster, fuel", new ongetproductsdetailslistener { @override public void ongetproducts @nonnull errorvo errorvo, @nonnull arraylist<productvo> arraylist { if errorvo geterrorcode == iaphelper iap_error_none { for productvo item arraylist { if item getitemid equals itemid { // set product details value to ui product settext "product name " + item getitemname ; price settext "product price " + item getitempricestring ; currency settext "currency " + item getcurrencycode ; // click continue button to purchase dialogbutton setonclicklistener dialogbtnlistener ; } } } else { toast maketext getapplicationcontext , "getproductdetails failed " + errorvo geterrorstring , toast length_short show ; } } } ; handle item purchase and payment process to initiate a purchase and complete the payment transaction process, use the startpayment function the result of the purchase is specified in the onpaymentlistener interface, which includes the detailed purchase information purchasevo in case of a successful transaction if there's an error during the payment process, an error code -1003 indicates that the non-consumable item is already purchased for further information on error responses, refer to the documentation on response codes iaphelper startpayment itemid, string valueof 1 , new onpaymentlistener { @override public void onpayment @nonnull errorvo errorvo, @nullable purchasevo purchasevo { if errorvo geterrorcode == iaphelper iap_error_none { log d "purchaseid " , purchasevo getpurchaseid ; // non-consumable item, can purchase single time if itemid equals "bike" { purchasebikebtn settext "already purchased" ; } // consumable item, can purchase multiple time else if itemid equals "booster" { handleconsumableitems purchasevo getpurchaseid ; // update booster count in ui boostercount+=1; boostercountertv settext "⚡ "+boostercount+" ev" ; }else if itemid equals "fuel" { handleconsumableitems purchasevo getpurchaseid ; // update fuel count in ui fuelcount+=1; fuelcountertv settext "⛽ "+ fuelcount+" ltr" ; } }else { // non-consumable item, already purchase if errorvo geterrorcode == -1003 { purchasebikebtn settext "already purchased" ; } } } } ; upon successfully purchasing a consumable item, the consumepurchaseditems function is called through the handleconsumableitems function the total number of purchased boosters and fuel is displayed on the app ui using the boostercountertv settext and fuelcountertv settext methods respectively run the app after building the apk, install the app on a samsung galaxy device test the app by making purchases the turbo bike can only be bought once, while either the booster or fuel can be purchased multiple times after purchasing in-app items, the app shows that the bike has already been purchased along with the number of boosters and fuel bought you're done congratulations! you have successfully achieved the goal of this code lab now, you can integrate samsung iap sdk into your application by yourself! if you are having trouble, you may download this file in-app purchase turbobike complete code 1 3 mb to learn more about developing apps with samsung iap sdk, visit developer samsung com/iap
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.