Scope Approved Name : .../auth/fitness.sleep.read
Not able to fetch sleep hours for the day from google fit android.
val client = Fitness.getSessionsClient(this, getGoogleAccount())
val sessionReadRequest = SessionReadRequest.Builder()
.read(DataType.TYPE_SLEEP_SEGMENT)
.includeSleepSessions()
.readSessionsFromAllApps()
.setTimeInterval(periodStartMillis, periodEndMillis, TimeUnit.MILLISECONDS)
.build()
client.readSession(sessionReadRequest)
.addOnSuccessListener { response ->
for (session in response.sessions) {
val sessionStart = session.getStartTime(TimeUnit.MILLISECONDS)
val sessionEnd = session.getEndTime(TimeUnit.MILLISECONDS)
Log.i(TAG, "Sleep between $sessionStart and $sessionEnd")
// If the sleep session has finer granularity sub-components, extract them:
val dataSets = response.getDataSet(session)
for (dataSet in dataSets) {
for (point in dataSet.dataPoints) {
val sleepStageVal = point.getValue(Field.FIELD_SLEEP_SEGMENT_TYPE).asInt()
val sleepStage = SLEEP_STAGES[sleepStageVal]
val segmentStart = point.getStartTime(TimeUnit.MILLISECONDS)
val segmentEnd = point.getEndTime(TimeUnit.MILLISECONDS)
Log.i("TESTSLEEP", "\t* Type $sleepStage between $segmentStart and $segmentEnd")
}
}
}
Related
So I have been tackling this issue for a couple of days now. I have a Data class that is used to send information back into the API. In this instance, I have this x amount of fields. In these fields, there are three List fields with different types, as such.
The Data Classes
data class ApiSurveySiteUpdateBody(
#SerializedName("UserId") val userId: Int,
#SerializedName("SStatusId") val sStatusId: Int,
#SerializedName("SSId") val sSId: Int,
#SerializedName("SPONum") val sPoNum: Int,
#SerializedName("WorkPerformanceTypeId") val workPerformTypeId: Int,
#SerializedName("SSAddressId") val sSAddressId: Int,
#SerializedName("WorktoPerformDate") val workToBePerformedDate: String,
#SerializedName("CableRun") val cableRun: String,
#SerializedName("Entrance") val entranceInfo: String,
#SerializedName("DoorLockHardware") val doorLockHardware: String,
#SerializedName("HandicapOperator") val handicapOperator: String,
#SerializedName("DeviceComplete") val completedPrimaryDeviceList: List<Int>,
#SerializedName("TemplateId") val templateId: Int,
#SerializedName("NewDeviceList") val newDeviceList: List<ApiNewDeviceList> = emptyList(),
#SerializedName("UpdateDeviceList") val updateDeviceList: List<ApiUpdateDeviceList> = emptyList(),
#SerializedName("RemoveDeviceList") val removedDeviceList: List<ApiRemovedDeviceList> = emptyList()
)
The Converter function
private fun getSomeRequestBody(
dbInfo: DbFormWithEList,
apiSurveySiteMedias: List<ApiSSMediaInfo>
)
: ApiSSUpdateBody {
val updateRequestApi = ApiSSUpdateBody(
userId = dbInfo.sSDbInfo.userId,
sSId = dbInfo.sSDbInfo.sSId,
sStatusId = dbInfo.sStatusDbInfo.sSId,
sPoNum = dbInfo.sSDbInfo.sPoNumber,
workPerformTypeId = dbInfo.sSDbInfo.workPerformTypeId,
sSAddressId = dbInfo.sSDbInfo.sSAddressId,
workToBePerformedDate = dbInfo.sSDbInfo.workToBePerformedDate,
cableRun = dbInfo.sSDbInfo.cableRun,
entranceInfo = dbInfo.sSDbInfo.entranceInfo,
doorLockHardware = dbInfo.sSDbInfo.doorLockHardware,
handicapOperator = dbInfo.sSDbInfo.handicapOperator,
completedPrimaryDeviceList = dbInfo.sSDbInfo.completedPrimaryDeviceList.toIntList(),
templateId = dbInfo.sSDbInfo.templateId,
newDeviceList = List(dbInfo.equipmentList.size) { i -> // “NewDeviceList”
val dbEquipmentInfo = dbInfo.equipmentList[i].sSEquipmentDbInfo
Log.d(TAG, "NewDeviceListDB $dbEquipmentInfo")
val secondaryDeviceCheckedStatus = dbEquipmentInfo.secondaryDeviceCheckedStatus
val isDuplicateDeviceInUpdatePhase = dbEquipmentInfo.isDeviceUpdateMode
if (sDeviceCheckedS == CHECKED_YES && !isDuplicateDUP){
val newDeviceListRequestBody = ApiNewDeviceList(
secondaryDeviceId = dbEquipmentInfo.secondaryDeviceId,
deviceInstanceId = dbEquipmentInfo.deviceInstanceId.toString(),
mediaNameList = dbEquipmentInfo.mediaNames,
deviceSerialNumber = dbEquipmentInfo.deviceSerialNumber,
devicePartNumber = dbEquipmentInfo.devicePartNumber,
deviceManufacturerName = dbEquipmentInfo.deviceManufacturer,
deviceInstallationDate = DateUtil.dateToStringUTCSS(dbEquipmentInfo.deviceInstallationDate),
deviceLocation = dbEquipmentInfo.locationInfo,
deviceTechnicianNotes = dbEquipmentInfo.deviceTechnicianNotes
)
Log.d(TAG, "newDeviceListRequestBodyAPI $newDeviceListRequestBody")
newDeviceListRequestBody
}
else if (sDeviceCheckedS == CHECKED_NO){
apiDeviceListMapperUpdateSS.sendDeviceNotExistsInNewDeviceList(dbEquipmentInfo)
}
else {
apiDeviceListMapperUpdateSS.sendEmptyNewDeviceList()
}
},
updateDeviceList = (List(dbInfo.equipmentList.size) { i ->
val dbEquipmentInfo = dbInfo.equipmentList[i].sSEquipmentDbInfo
Log.d("UpdatingSiteSurvey", "UpdateDeviceListDB $dbEquipmentInfo")
val secondaryDeviceCheckedStatus = dbEquipmentInfo.secondaryDeviceCheckedStatus
val isDuplicateDeviceInUpdatePhase = dbEquipmentInfo.isDeviceUpdateMode
if (secondaryDeviceCheckedStatus == CHECKED_YES && isDuplicateDeviceInUpdatePhase){
val updateDeviceListRequestBody = ApiUpdateDeviceList(
deviceEquipmentId = dbEquipmentInfo.deviceEquipmentId,
secondaryDeviceId = dbEquipmentInfo.secondaryDeviceId,
deviceInstanceId = dbEquipmentInfo.deviceInstanceId.toString(),
deviceSerialNumber = dbEquipmentInfo.deviceSerialNumber,
devicePartNumber = dbEquipmentInfo.devicePartNumber,
deviceManufacturerName = dbEquipmentInfo.deviceManufacturer,
deviceInstallationDate = DateUtil.dateToStringUTCSiteSurvey(dbEquipmentInfo.deviceInstallationDate),
deviceLocation = dbEquipmentInfo.locationInfo,
deviceTechnicianNotes = dbEquipmentInfo.deviceTechnicianNotes
)
Log.d(TAG, "updateDeviceListRequestBodyAPI $updateDeviceListRequestBody")
updateDeviceListRequestBody
} else Unit.apply { } //<- the issue is here
}) as List<ApiUpdateDeviceList>,
removedDeviceList = List(dbInfo.sSDbInfo.removedDeviceList.size) { i ->
val dbRemovedMediaItem = dbInfo.sSDbInfo.removedDeviceList[i]
Log.d(TAG, "RemovedListDB $dbRemovedMediaItem")
if (dbRemovedMediaItem.removedDeviceEquipmentId == null && dbRemovedMediaItem.removedMediaName.isNullOrEmpty()){
val removeDevice = apiDeviceListMapperUpdateSiteSurvey.removeDevice(dbRemovedMediaItem)
Log.d(TAG, "removeDevice $removeDevice")
removeDevice
}else{
val removeMediaForExistingDevice = apiDeviceListMapperUpdateSS.removeMediaForExistingDevice(dbRemovedMediaItem)
Log.d(TAG, "removeMediaForExistingDevice $removeMediaForExistingDevice")
removeMediaForExistingDevice
}
}
)
Log.d(TAG, "MainUpdateRequestAPI $updateRequestApi")
return updateRequestApi
}
The goal is to have the else statement that is highlighted to return an emptyList "[]" to that updateDeviceList field. I have tried a few ways but never was able to return that exact empty list "[]". Any help will be appreciated. Thank you.
I can't tell if you want (1) the whole list to be invalidated and become empty if any item in the iteration fails the if check, or if you just want (2) to filter out items that fail the if check. But here's how I would approach each of those tasks.
I am breaking out the conversion between DbEquipmentInfo and ApiUpdateDeviceList into a separate extension function (fun DbEquipmentInfo.toApiUpdateDeviceList(): ApiUpdateDeviceList). Not just to avoid code repetition, but also to keep the logic code easy to read, and make the project's code more maintainable in general.
1.
val isValid = dbInfo.equipmentList.all { dbEquipmentInfo ->
val secondaryDeviceCheckedStatus = dbEquipmentInfo.secondaryDeviceCheckedStatus
val isDuplicateDeviceInUpdatePhase = dbEquipmentInfo.isDeviceUpdateMode
secondaryDeviceCheckedStatus == CHECKED_YES && isDuplicateDeviceInUpdatePhase
}
updateDeviceList =
if (isValid) dbInfo.equipmentList.map { it.toApiUpdateDeviceList() }
else emptyList()
updateDeviceList = dbInfo.equipmentList.filter { dbEquipmentInfo ->
val secondaryDeviceCheckedStatus = dbEquipmentInfo.secondaryDeviceCheckedStatus
val isDuplicateDeviceInUpdatePhase = dbEquipmentInfo.isDeviceUpdateMode
secondaryDeviceCheckedStatus == CHECKED_YES && isDuplicateDeviceInUpdatePhase
}.map { it.toApiUpdateDeviceList() }
I am not getting weekly data from google fit (Yes, There is data in google fit which I have track using watch), but Yes I am getting today's date data.
I am attaching code snippet.
Start date = "2022-09-13T00:00:00Z"
End date = "2022-09-20T23:59:59Z"
private fun readSleepSessions(startTime : Long , endTime : Long) {
val client = Fitness.getSessionsClient(requireContext(), getGoogleAccount())
val sessionReadRequest = SessionReadRequest.Builder()
.read(DataType.TYPE_SLEEP_SEGMENT)
.includeSleepSessions()
.readSessionsFromAllApps()
.enableServerQueries()
.setTimeInterval(1663027200000, 1663718399000, TimeUnit.MILLISECONDS)
.build()
client.readSession(sessionReadRequest)
.addOnSuccessListener {
Log.d(TAG, "readSleepSessions: $sessionReadRequest")
dumpSleepSessions(it)
}
.addOnFailureListener {
Log.e("MainScreen", "Unable to read sleep sessions", it)
}
}
private fun dumpSleepSessions(response: SessionReadResponse) {
if (response.sessions.isNotEmpty()){
for (session in response.sessions) {
dumpSleepSession(session, response.getDataSet(session))
Log.d(TAG, "dumpSleepSessions: ${response.sessions}")
}
}else{
Log.d(TAG, "dumpSleepSessionsResponse: ${response.status}")
}
}
private fun dumpSleepSession(session: Session, dataSets: List<DataSet>) {
dumpSleepSessionMetadata(session)
dumpSleepDataSets(dataSets)
}
private fun dumpSleepDataSets(dataSets: List<DataSet>) {
for (dataSet in dataSets) {
for (dataPoint in dataSet.dataPoints) {
val sleepStageOrdinal = dataPoint.getValue(Field.FIELD_SLEEP_SEGMENT_TYPE).asInt()
val sleepStage = sleepTargetName[sleepStageOrdinal]
val durationMillis =
dataPoint.getEndTime(TimeUnit.MILLISECONDS) - dataPoint.getStartTime(TimeUnit.MILLISECONDS)
val duration = TimeUnit.MILLISECONDS.toMinutes(durationMillis)
Log.d(TAG, "\t$sleepStage: $duration (minutes)")
}
}
I am trying to call get api using an AWS signing method but not able to get the response.
Below is my code.
val secretkey = "E+t5/nDf6/NKNJBjbsdjv"
val accesskey = "DJKSBDKSBNKFGNBFG"
val credentials: AWSCredentials = BasicAWSCredentials(accesskey, secretkey)
val API_GATEWAY_SERVICE_NAME = "s3"
val requestAws: Request<*> = DefaultRequest<Any?>(API_GATEWAY_SERVICE_NAME)
val uri = URI.create("https://s3.us-west-2.amazonaws.com/..../../sample")
requestAws.endpoint = uri
requestAws.resourcePath = "https://s3.us-west-2.amazonaws.com/..../../sample"
requestAws.httpMethod = HttpMethodName.GET
val signer = AWS4Signer() signer . setServiceName (API_GATEWAY_SERVICE_NAME)
signer.setRegionName("us-west-2")
signer.sign(requestAws, credentials)
val headers = requestAws.headers
val key: MutableList<String> = ArrayList()
val value: MutableList<String> = ArrayList()
for ((key1, value1) in headers)
{
key.add(key1) value . add (value1)
}
val httpClient = OkHttpClient()
val request: okhttp3.Request = okhttp3.Request.Builder()
.url("https://s3.us-west-2.amazonaws.com/..../../sample")
.addHeader(key[0], value[0])
.addHeader(key[1], value[1])
.addHeader(key[2], value[2])
.addHeader("X-Amz-Content-Sha256",
"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
.build()
val response: okhttp3.Response = httpClient.newCall(request).execute()
Log.i("LOG", response.body.toString())
Not able to figure out, what I am doing mistake.
Please help me out with this issue.
If you want to create an Android app written in Kotlin and invokes AWS Services, use the AWS SDK for Kotlin.
This SDK has strongly typed Service Clients that you can use in an Android Studio project that lets you invoke a given service. (as opposed to using okhttp3.Request, etc)
For example, here is Kotlin code that invoke SNS using a Strongly typed service client named SnsClient.
// Get all subscriptions.
fun getSubs(view: View) = runBlocking {
val subList = mutableListOf<String>()
val snsClient: SnsClient = getClient()
try {
val request = ListSubscriptionsByTopicRequest {
topicArn = topicArnVal
}
val response = snsClient.listSubscriptionsByTopic(request)
response.subscriptions?.forEach { sub ->
subList.add(sub.endpoint.toString())
}
val listString = java.lang.String.join(", ", subList)
showToast(listString)
} catch (e: SnsException) {
println(e.message)
snsClient.close()
}
}
fun getClient() : SnsClient{
val staticCredentials = StaticCredentialsProvider {
accessKeyId = "<Enter key>"
secretAccessKey = "<Enter key>"
}
val snsClient = SnsClient{
region = "us-west-2"
credentialsProvider = staticCredentials
}
return snsClient
}
TO learn how to use the AWS SDK for Kotlin, see
AWS SDK for Kotlin Developer Guide
val energy = enerjiText.text.toString()
if (energy < 50 .toString()){
progressBar.max = 1000
val currentProgress = 900
ObjectAnimator.ofInt(progressBar,"progress",currentProgress)
.setDuration(2000)
.start()
progressBar2.max = 1000
val currentProgress2 = 700
ObjectAnimator.ofInt(progressBar2,"progress",currentProgress2)
.setDuration(2000)
.start()
}
else{
progressBar.max = 1000
val currentProgress = 600
ObjectAnimator.ofInt(progressBar,"progress",currentProgress)
.setDuration(2000)
.start()
progressBar2.max = 1000
val currentProgress2 = 300
ObjectAnimator.ofInt(progressBar2,"progress",currentProgress2)
.setDuration(2000)
.start()
}
The id of the textView circled in black is enerjiText. In this textView I am printing the data that I have saved in firestore. But without checking the values in the if-else loop you see in the code, the progress bars inside the if push the screen. I gave the value of energy < 50 in the if, the answer is 227, but it shows the progress bar values in the if without going into the else loop. If I don't convert the enerjiText and the energy < 50 control to string I get the error "java lang numberformatexception For input string"
val panelC = binding.panelCount3.text.toString()
val landSl = binding.landSlope.text.toString()
val landS = binding.landSize3.text.toString()
val billT = binding.bill.text.toString()
if (panelC.isEmpty() || landSl.isEmpty() || landS.isEmpty() || billT.isEmpty()){
Toast.makeText(requireContext(),"Alanları Doldurun",Toast.LENGTH_LONG).show()
}
else{
val pco = panelC.toInt()
val lsl = landSl.toInt()
val ls = landS.toInt()
val b = billT.toInt()
val enerji = Math.round((((ls * pco) + (lsl * b)) / 100).toDouble())
val postMap = hashMapOf<String,Any>()
postMap.put("Panel Sayisi",binding.panelCount3.text.toString())
postMap.put("Arazi Eğimi",binding.landSlope.text.toString())
postMap.put("Arazi Boyutu",binding.panelCount3.text.toString())
postMap.put("Fatura",binding.bill.text.toString())
postMap.put("Enerji",enerji.toDouble())
postMap.put("date",com.google.firebase.Timestamp.now())
firestore.collection("Enerji").add(postMap).addOnSuccessListener {
}.addOnFailureListener {
Toast.makeText(requireContext(),it.localizedMessage,Toast.LENGTH_LONG).show()
}
These codes are the codes where the calculations of the number that should be written in enerjiText are made and saved in firestore.
private fun getData(){
db.collection("Enerji").addSnapshotListener { value, error ->
if (error!=null){
Toast.makeText(requireContext(),error.localizedMessage,Toast.LENGTH_LONG).show()
}else{
if (value !=null){
if (!value.isEmpty){
val documents = value.documents
for (document in documents){
val panelSayisi = document.get("Panel Sayisi") as String
val araziEgimi = document.get("Arazi Eğimi") as String
val araziBoyutu = document.get("Arazi Boyutu") as String
val faturaDegeri = document.get("Fatura") as String
val enerji = Enerji(panelSayisi, araziEgimi, araziBoyutu, faturaDegeri)
postArrayList.add(enerji)
}
}
}
}
val db = FirebaseFirestore.getInstance()
db.collection("Enerji").orderBy("date", Query.Direction.DESCENDING).limit(1)
.get()
.addOnCompleteListener {
val result : StringBuffer = StringBuffer()
if (it.isSuccessful){
for (document in it.result){
result.append(document.data.getValue("Enerji"))
}
enerjiText.setText(result)
}
}
}
These are the codes that I get the data I saved in firebase above and wrote into EnerjiText.
data class Enerji (val panelSayisi : String, val araziEgimi : String, val araziBoyutu : String, val faturaDegeri : String)
Finally, the Enerji class defined inside the postArrayList, which I think might be the source of the error.
Working on an Android application, using KOTLIN. Inside my activity, I'm accessing the Merriam-Webster Dictionary JSON file from a URL (Github). The file's pretty big, to say the least. I want to display the "Word Of The Day" randomly on my TextView, which means I have to get a random key from the JSON so I can display its value.
How do I do this?
Thank you in advance
DictionaryActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_dictionary)
fetchJson()
init()
}
private fun init(){
val email = intent.extras!!.getString("email", "")
welcomeTxv.text = "Welcome, " + email.substringBefore("#")
}
// Fetching (url) and searching through json.
private fun fetchJson(){
println("Attempting to fetch Json file")
val url = "https://raw.githubusercontent.com/matthewreagan/WebstersEnglishDictionary/master/dictionary.json"
val request = Request.Builder().url(url).build()
val client = OkHttpClient()
client.newCall(request).enqueue(object: Callback{
override fun onResponse(call: Call, response: Response) {
val body = response.body?.string()
#Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS") val jsonObject = JSONObject(body)
loadingCircle.visibility = if (loadingCircle.visibility == View.VISIBLE){
View.INVISIBLE
} else{
View.VISIBLE
}
searchBtn.setOnClickListener {
if (searchField.text.isNotEmpty() && jsonObject.has(searchField.text.toString())){
meaningTextView.setTextColor(WHITE)
meaningTextView.text = jsonObject.optString(searchField.text.toString())
databaseAction()
}else{
meaningTextView.setTextColor(RED)
meaningTextView.text = "The word you searched for could not be found."
}
}
}
override fun onFailure(call: Call, e: IOException) {
Toast.makeText(applicationContext, "Request failed", Toast.LENGTH_SHORT).show()
}
})
}
fun databaseAction(){
val email = intent.extras!!.getString("email", "")
val userIdentification = email.toString()
val database = FirebaseDatabase.getInstance()
val myRef = database.getReference(userIdentification.substringBefore("#"))
val sdf = SimpleDateFormat.getDateInstance()
val currentDate = sdf.format(Date())
val stf = SimpleDateFormat.getTimeInstance()
val currentTime = stf.format(Date())
myRef.push().setValue(searchField.text.toString() + " " + currentDate + " " + currentTime)
}
This does not work (crashes the application):
val keys = arrayOf(jsonObject.keys())
val randomNumber = (0..1000).random()
val randomKey = keys[randomNumber]
application crashed because index out of bound exception throws...
// keys() document from Android doc page
open fun keys(): MutableIterator<String!>
keys() return type of MutableIterator
for more info: Android JSON document link
keys type is array of a MutableIterator, and its' length is 1
so, the expression below may throw index out of bound exception if randomNumber is not 0
val randomKey = keys[randomNumber] // opps if randomNumber is not zero
to get the random key from keys:
// shuffled() will return a list with random order
// first() take the first element of the list
val randomKey = xxxx.keys.shuffled().first()
no Android environment in my hand, here is my guess
val randomKey = jsonObject.keys().asSequence().toList().shuffled().first()
hope this gives you a little help :)