У меня есть пользовательский работник, который выполняет выборку некоторых контактов из API, а затем сохраняет эти контакты в списке контактов телефона. Этот работник все еще замораживает пользовательский интерфейс. Буду признателен за любую помощь.
Это метод DoWork работника:
override fun doWork(): Result {
return try {
makeStatusNotification("Saving Contacts", applicationContext, "WorkRequest Starting")
//MAIN METHOD CALL
if (!checkContactListEmpty()) {
removeAllContacts()
}
connectAndGetApiData()
val x = Data.Builder()
Result.success(x.build())
} catch (e: Exception) {
Log.e("NoWork","Unable to save image to Gallery $e")
Result.failure()
}
}
Это метод connectAndGetApi:
fun connectAndGetApiData() {
val BASE_URL = "HTTP_URL"
val res = Data.Builder()
allNames = object : ArrayList<String>(){}
allNumbers = object : ArrayList<String>(){}
Log.d("entering", "connecting")
if (retrofit == null) {
retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(ScalarsConverterFactory.create())
.build()
}
val contactsApiService: RestApi? = retrofit?.create(RestApi::class.java)
val call: Call<ContactList>? = contactsApiService?.getAllContactDetails()
call?.enqueue(object : Callback<ContactList> {
override fun onResponse(
call: Call<ContactList>,
response: Response<ContactList>
) {
Log.d("AllContacts",response.message())
val contactList: ContactList = response.body()
if(contactList!= null){
Log.d("AllContacts", contactList.allContacts.size.toString())
for(x in contactList.allContacts){
addContact(x.name,x.phoneNo)
Thread.sleep(50)
}
}else{
Log.d("AllContacts", "contacts null")
}
}
override fun onFailure(
call: Call<ContactList>,
throwable: Throwable
) {
val TAG = "AllContacts"
Log.e(TAG, throwable.toString())
}
})
}
removeAllContacts () является стандартной функцией чтобы удалить все контакты
API дает набор из примерно 22000 контактов
Отредактировано:
Это метод addContact ()
private fun addContact(name:String?, number: String?) {
var finalName = ""
val finalNumber = number
if(name?.isEmpty() == true){
val tsLong = System.currentTimeMillis() / 1000
val ts = tsLong.toString()
finalName = "NoName$ts"
}else{
finalName = name.toString()
finalName = finalName.substring(1,(finalName.length - 2))
}
val ops = ArrayList<ContentProviderOperation>()
val rawContactID: Int = ops.size
ops.add(
ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null)
.build()
)
ops.add(
ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactID)
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, finalName)
.build()
)
ops.add(
ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, rawContactID)
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, finalNumber)
.withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE)
.build()
//
)
try { // Executing all the insert operations as a single database transaction
Log.d(
"AddingContact", "Name: $finalName Number: $finalNumber"
)
applicationContext.contentResolver.applyBatch(ContactsContract.AUTHORITY, ops)
Thread.sleep(50)
Log.d("Contact Saved","Saved")
} catch (e: RemoteException) {
e.printStackTrace()
} catch (e: OperationApplicationException) {
e.printStackTrace()
}
}