Google Play Developer reporting api crash rate not working (Kotlin) - kotlin

I'm trying to get crash rate of my app on play store by reporting api.
so, i threw some exception in downloaded app.
in google play console, crash was recorded.
but reporting api still gives nothing.
response code: 200
Json: {} (nothing in json)
how can i do that..
documentis here
and my code:
Main.kt
val metricRetrofit = Retrofit.Builder()
.baseUrl(BaseUrl.CRASH_RATE_BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(CoroutineCallAdapterFactory())
.client(OkHttpClient.Builder().build())
.build()
.create(MetricSetApi::class.java)
val startTime = DateTime(year = 2021, month = 11, day = 1,null,null,null,null)// time_zone = TimeZone())
val endTime = DateTime(year = 2022, month = 12, day = 6,null,null,null,null)// time_zone = TimeZone())
val crashMQueryBody = CrashRateQueryBody(
TimelineSpec(
aggregation_period = "DAILY",
startTime = startTime,//TimeZone()),
endTime = endTime//TimeZone())
), arrayListOf("apiLevel"), arrayListOf("crashRate")
)
val mBody = metricRetrofit.postCrashRageMetricSet("Bearer $token", "{my package name}", crashMQueryBody)
interface for retrofit
interface MetricSetApi {
#POST("{packageName}/crashRateMetricSet:query")
suspend fun postCrashRageMetricSet(
#Header("Authorization")
token:String,
#Path("packageName")
packageName:String,
#Body
body: CrashRateQueryBody
): Response<ResponseBody>
}
data class for body
data class TimelineSpec(
#SerializedName("aggregation_period")
val aggregation_period: String =
"DAILY",
#SerializedName("startTime")
val startTime: DateTime?,
#SerializedName("endTime")
val endTime: DateTime?
)
data class DateTime(
#SerializedName("year")
val year: Int = 0,
#SerializedName("month")
val month: Int = 0,
#SerializedName("day")
val day: Int = 0,
#SerializedName("hours")
val hours : Int?,
#SerializedName("minutes")
val minutes : Int?,
#SerializedName("seconds")
val seconds : Int?,
#SerializedName("nanos")
val nanos : Int?,
#SerializedName("utcOffset")
val utcOffset : String? = null,
#SerializedName("time_zone")
val time_zone: TimeZone? = null
)
data class TimeZone(
#SerializedName("id")
val id: String? =null,//"America/Los_Angeles",
#SerializedName("version")
val version: String?=null
)
data class CrashRateQueryBody(
#SerializedName("timeline_spec")
val timeline_spec: TimelineSpec,
#SerializedName("dimensions")
val dimensions: ArrayList<String>?,
#SerializedName("metrics")
val metrics: ArrayList<String>?,
#SerializedName("filter")
val filter: String?=null,
#SerializedName("pageSize")
val pageSize: Int=1000,
#SerializedName("pageToken")
val pageToken: String=""
)
i called google play developer reporting api, and i expected some crash rate record that i threw.
but they gives nothing

Related

Jackon JSON Adding deserializer module doesn't work, but annotation on class does

I am trying to implement a custom deserializer and when I try to install it on the ObjectMapper it never gets invoked, but when I use it directly as an annotation on the class, it does. Can someone explain why and how I can actually install it on the object mapper itself?
This is never invoked
val bug = ObjectMapper().registerModule(KotlinModule.Builder().build())
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.registerModule(SimpleModule().addDeserializer(Bug::class.java, BugDeserializer()))
.readValue(bugStream, Bug::class.java)
data class Bug(
#JsonProperty("rptno")
val id: Long,
#JsonProperty("status")
#JsonDeserialize(using = StatusDeserializer::class)
val status: Status,
#JsonProperty("reported_date")
val reportedDate:Instant,
#JsonProperty("updated_date")
val updatedDate: Instant,
// val pillar: String = "",
#JsonProperty("product_id")
#JsonDeserialize(using = ProductDeserializer::class)
val product: Product,
#JsonProperty("assignee")
val assignee: String,
// val serviceRequests: List<Long> = listOf(),
#JsonProperty("subject")
val title: String,
#JsonProperty("bug_type")
val type: String
)
But, this does:
val bug = ObjectMapper().registerModule(KotlinModule.Builder().build())
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.readValue(bugStream, Bug::class.java)
#JsonDeserialize(using = BugDeserializer::class)
data class Bug(
#JsonProperty("rptno")
val id: Long,
#JsonProperty("status")
#JsonDeserialize(using = StatusDeserializer::class)
val status: Status,
#JsonProperty("reported_date")
val reportedDate:Instant,
#JsonProperty("updated_date")
val updatedDate: Instant,
// val pillar: String = "",
#JsonProperty("product_id")
#JsonDeserialize(using = ProductDeserializer::class)
val product: Product,
#JsonProperty("assignee")
val assignee: String,
// val serviceRequests: List<Long> = listOf(),
#JsonProperty("subject")
val title: String,
#JsonProperty("bug_type")
val type: String
)
```kotlin

How to restrict Int values bound to database column?

data class:
// Entity of query
#Entity(tableName = TABLE_NAME)
data class HistoryItem(
#PrimaryKey(autoGenerate = true)
val id: Int,
#ColumnInfo(name = SEARCHED_DOMAIN)
val searchedDomain: String,
#ColumnInfo(name = STATUS)
val status: Int,
)
And object of statuses:
object Statuses {
const val FAILURE = 0
const val NOT_FOUND = 1
const val FOUND = 2
}
How to make val status: Int to always be FAILURE or NOT_FOUND or FOUND? I think it should looks like this:
#Status
#ColumnInfo(name = STATUS)
val status: Int
But how to do it?
I would recommend using an enum class for this:
enum class Status {
FAILURE, NOT_FOUND, FOUND;
}
#Entity(tableName = TABLE_NAME)
data class HistoryItem(
#PrimaryKey(autoGenerate = true)
val id: Int,
#ColumnInfo(name = SEARCHED_DOMAIN)
val searchedDomain: String,
#ColumnInfo(name = STATUS)
val status: Status
)
However, older versions of Android Room (prior to 2.3.0) do not automatically convert enum classes, so if you're using these you will need to use a type convertor:
class Converters {
#TypeConverter
fun toStatus(value: Int) = enumValues<Status>()[value]
#TypeConverter
fun fromStatus(value: Status) = value.ordinal
}
Which requires you to add the following to your database definition:
#TypeConverters(Converters::class)
See also this answer.

How to parse LinkedHashMap in moshi (kotlin)

I am trying to create a JSON adapter for the following json
{
"message": {
"affenpinscher": [],
"african": [],
"airedale": [],
"akita": [],
"appenzeller": [],
"australian": [
"shepherd"
]
},
"status": "success"
}
I have tried the following
#JsonClass(generateAdapter = true)
data class BreedList(
val message: HashMap<String,List<String>> = HashMap<String,List<String>>()
)
and
#JsonClass(generateAdapter = true)
data class BreedList(
val message: Breed
)
#JsonClass(generateAdapter = true)
data class Breed(
val breed: List<String>
)
But both scenarios give me the errors, is there a way to parse the following object, I need the key as well as the list from the response
There is no need to create a custom adapter.
To parse the JSON you posted:
data class Base (
#field:Json(name = "message")
val message : Message,
#field:Json(name = "status")
val status : String
)
data class Message (
#field:Json(name = "affenpinscher")
val affenpinscher : List<String>,
#field:Json(name = "african")
val african : List<String>,
#field:Json(name = "airedale")
val airedale : List<String>,
#field:Json(name = "akita")
val akita : List<String>,
#field:Json(name = "appenzeller")
val appenzeller : List<String>,
#field:Json(name = "australian")
val australian : List<String>
)
Note: instead of String you can use whatever data type you need or create custom classes like Message.

Get updated id from entity autogenerate primary key

I created Alarm class and annotate it as Entity on Android Studio.
In this class I have put id variable as Entity Primary Key and it is auto generate.
#Entity(tableName = "alarm_data_table")
class Alarm(
#ColumnInfo(name = "alarm_hour")
var alarmHour: Int,
#ColumnInfo(name = "alarm_min")
var alarmMin: Int,
#ColumnInfo(name = "is_am")
var isAM: Boolean,
var days: ArrayList<Int>?,
#ColumnInfo(name = "is_on")
var isOn: Boolean,
var label: String,
#PrimaryKey(autoGenerate = true)
val id: Int = 0
) {
fun setAlarmSchOnOff(isOn: Boolean, activity: Activity){
if (isOn){setAlarmScheduleOn(activity)}
if (!isOn){setAlarmScheduleOff(activity)}
}
fun setAlarmScheduleOn (activity: Activity) {
val alarmManager = activity.getSystemService(Context.ALARM_SERVICE) as AlarmManager
Log.d("ALARM ON", Integer.toString(id))
val alarmIntent = Intent(activity, AlarmReceiver::class.java).let { intent ->
intent.putExtra(Constants().ALARM_LABEL_KEY,label)
PendingIntent.getBroadcast(
activity,
id,
intent,
PendingIntent.FLAG_UPDATE_CURRENT
)
}
val calendar: Calendar = Calendar.getInstance().apply {
timeInMillis = System.currentTimeMillis()
set(Calendar.HOUR_OF_DAY, alarmHour)
set(Calendar.MINUTE, alarmMin)
}
days?.let {
it.forEach {
calendar.set(Calendar.DAY_OF_WEEK, it) }
alarmManager.setInexactRepeating(
AlarmManager.RTC_WAKEUP,
calendar.timeInMillis,
AlarmManager.INTERVAL_HOUR,
alarmIntent
)
} ?:run{
alarmManager.set(
AlarmManager.RTC_WAKEUP,
calendar.timeInMillis,
alarmIntent)
}
}
fun setAlarmScheduleOff(activity: Activity) {
val alarmManager = activity.getSystemService(Context.ALARM_SERVICE) as AlarmManager
Log.d("ALARM OFF", Integer.toString(alarmId))
val alarmIntent = Intent(activity, AlarmReceiver::class.java).let { intent ->
PendingIntent.getBroadcast(
activity,
id,
intent,
PendingIntent.FLAG_UPDATE_CURRENT
)}
alarmManager.cancel(alarmIntent)
}
}
The problem is every time I tried to retrieve id for setAlarm method it will always return 0.
2019-10-30 15:38:07.441 11066-11066/com.andreasgift.myclock D/ALARMĀ ON: 0
Is there any way to return the id value after Entity update the value/ successfully insert it into table.
Is there any way to return the id value after Entity update the value/
successfully insert it into table
Change to use (optional)
:-
#PrimaryKey(autoGenerate = true)
var id: Long = 0 /*<<<<<<<<<< var not val + Long instead of Int */
you should really use Long for id columns as
a) the SQliteDatabase insert method that is ultimately used, returns a long and
b) (which is why a is as it is)) a rowid (which is effectively what autogenerate uses ) can be a value larger then an Int can hold (i.e. a 64 bit signed integer).
If you wanted to use Int for id then you could use myAlarm.id = (alarmDao.insertAlarm(myAlarm)).toInt() instead of myAlarm.id = alarmDao.insertAlarm(myAlarm)
And use a Dao
#Insert
fun insertAlarm(alarm :Alarm) :Long
i.e. set it so that it returns :Long
The insert now returns the id (or -1 if the insert didn't insert the row). If you still use the Alarm object after the insert then you could use something like :-
myAlarm.id = alarmDao.insertAlarm(myAlarm) /*<<<<<<<<<< SET THE id according to the inserted id */

How to remove ZoneId?

Thank you always for your help.
I got a problem in my project.
I want to delete Zoned Id and leave only time.
How to remove zoned Id?
It is written using kotlin in Spring Boot Framework.
data class AvailableScheduleRequest (
val address: String,
val date: LocalDate,
val people: Long,
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'", timezone = "Asia/Seoul")
val hour: ZonedDateTime
)
#RestController
class Controller(
val newBookingElasticSearchService: NewBookingElasticSearchService
) {
#RequestMapping("/")
#ResponseBody
fun get(#RequestBody param: Map<String, Any>): List<AvailableRestaurant> {
val json = JacksonUtils.om.writeValueAsString(param)
val availableScheduleRequest =
JacksonUtils.om.readValue(json, AvailableScheduleRequest::class.java)
println(availableScheduleRequest.hour)
}
}
object JacksonUtils {
val om = ObjectMapper()
init {
val module = SimpleModule()
module.addDeserializer(String::class.java, JsonRawValueDeserializer.INSTANCE)
om.registerModule(JavaTimeModule())
om.registerModule(KotlinModule())
om.registerModule(module)
om.dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX")
om.setTimeZone(TimeZone.getDefault())
om.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
om.configure(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT, true)
om.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true)
om.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true)
}
This code outputs:
2019-10-02T07:00+09:00[Asia/Seoul]
But I wanna get this:
2019-10-02T07:00+09:00
How to get this?
Thank you for your efforts all the time!!
Instead of ZonedDateTime, you could use OffsetDateTime.