Learning Kotlin and stuck with ArrayAdapter - android

I am learning Kotlin and all was going well until it stopped working, the only thing I changed were the references.
I've tried to adjust the "this" parameter and it has not worked,
Here is my code:
package com.example.myweatherapp
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.ArrayAdapter
import android.widget.ListView
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
class ForecastActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_forecast)
var retriever = WeatherRetriever()
val callback = object : Callback<Weather> {
override fun onFailure(call: Call<Weather>?, t: Throwable) {
println("It failed")
}
override fun onResponse(
call: Call<Weather>?, response: Response<Weather>?) {
println("It wORKED")
println(response?.body()?.main)
title = response?.body()?.name
var forecasts = response?.body()?.main
var castListView = findViewById<ListView>(R.id.forecastListView)
var adapter = ArrayAdapter(this#ForecastActivity,android.R.layout.simple_list_item_1,forecasts)
castListView.adapter=adapter
}
}
retriever.getForecast(callback)
}
}
I am getting the following error: "None of the following functions can be called with the arguments supplied:"
Any help for a newbie?
Thanks a lot!
Edit: Here is the weather class
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.GET
import retrofit2.http.Query
interface weatherAPI{
#GET("weather?id=3621224&units=metric&appid=ff2563aab36fc89bc7a3c4fe58dd7f3e")
fun getForecast() : Call<Weather>
}
class Weather(val main: WeatherForecast, val name: String )
class WeatherForecast (val main: List<main>)
class main (val temp: String, val feels_like: String, val temp_min: String, val temp_max: String)
class WeatherRetriever {
val service : weatherAPI
init {
val retrofit= Retrofit.Builder().baseUrl("https://api.openweathermap.org/data/2.5/").addConverterFactory(GsonConverterFactory.create()).build()
service = retrofit.create(weatherAPI::class.java)
}
fun getForecast(callback : Callback<Weather>){
val call = service.getForecast()
call.enqueue(callback)
}
}

Related

Getting Error in building the project using Dao interface and room library

I am stuck with this issue since couple of days. I have gone through many threads where people faced similar issues but did not find any work around on this.
Im getting the error because of using suspend in dao interface but when i remove the error goes away but the app crashes when i try to open it after installation.
I have tried changing the version of room in gradle but that didnot work either.
have a look at my code.
The error message
kotlin.coroutines.Continuation<? super kotlin.Unit> continuation);
NotesDao.kt
package com.example.notes
import androidx.lifecycle.LiveData
import androidx.room.*
#Dao
interface NoteDao {
#Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insert(note : Note)
#Delete
suspend fun delete(note : Note)
#Query("Select * from notes_table order by id ASC")
fun getAllNotes() : LiveData <List<Note>>
}
NotesRCAdapter.kt
package com.example.notes
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
class NotesRVAdapter(private val context: Context, private val listner : INotesRVAdapter)
: RecyclerView.Adapter<NotesRVAdapter.NoteViewHolder>() {
val allNotes = arrayListOf<Note>()
class NoteViewHolder (itemview : View) : RecyclerView.ViewHolder(itemview){
val textView = itemView.findViewById<TextView>(R.id.tvNote)
val deleteButton = itemview.findViewById<ImageView>(R.id.ivDelete)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NoteViewHolder {
val viewHolder = NoteViewHolder( LayoutInflater.from(context)
.inflate(R.layout.item_note, parent, false))
viewHolder.deleteButton.setOnClickListener{
listner.onItemClicked(allNotes[viewHolder.adapterPosition])
}
return viewHolder
}
override fun onBindViewHolder(holder: NoteViewHolder, position: Int) {
val currentNote = allNotes[position]
holder.textView.text = currentNote.text
}
override fun getItemCount(): Int {
return allNotes.size
}
fun updateList(newList : List<Note>){
allNotes.clear()
allNotes.addAll(newList)
notifyDataSetChanged()
}
}
interface INotesRVAdapter{
fun onItemClicked(note: Note)
}
NotesDataBase.kt
package com.example.notes
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
#Database(entities = [Note::class], version = 1, exportSchema = false)
abstract class NoteDataBase: RoomDatabase() {
abstract fun getNoteDao(): NoteDao
companion object {
// Singleton prevents multiple instances of database opening at the
// same time.
#Volatile
private var INSTANCE: NoteDataBase? = null
fun getDatabase(context: Context): NoteDataBase {
// if the INSTANCE is not null, then return it,
// if it is, then create the database
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
NoteDataBase::class.java,
"note_database"
).build()
INSTANCE = instance
// return instance
instance
}
}
}
}
//after this we will create our repository
NotesRepository.kt
package com.example.notes
import androidx.lifecycle.LiveData
class NoteRepository(private val noteDao: NoteDao) {
val allNotes : LiveData<List<Note>> = noteDao.getAllNotes()
suspend fun insert(note: Note) {
noteDao.insert(note)
}
suspend fun delete(note: Note){
noteDao.delete(note)
}
}
NoteViewModel.kt
package com.example.notes
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class NoteViewModel(application: Application) : AndroidViewModel(application){
private val repository : NoteRepository
val allNotes : LiveData<List<Note>>
init {
val dao = NoteDataBase.getDatabase(application).getNoteDao()
repository = NoteRepository(dao)
allNotes = repository.allNotes
}
fun deleteNote(note: Note) = viewModelScope.launch(Dispatchers.IO) {
repository.delete(note)
}
fun insertNote(note: Note) = viewModelScope.launch(Dispatchers.IO) {
repository.insert(note)
}
}
Note.kt
package com.example.notes
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
#Entity(tableName = "notes_table") /
class Note(#ColumnInfo(name = "text")val text: String) {
#PrimaryKey(autoGenerate = true) var id = 0
}
MainActivity.kt
package com.example.notes
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.EditText
import android.widget.Toast
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
class MainActivity : AppCompatActivity(), INotesRVAdapter {
lateinit var viewModel: NoteViewModel
private val input = findViewById<EditText>(R.id.etInput)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val RecyclerView = findViewById<RecyclerView>(R.id.recyclerView)
RecyclerView.layoutManager = LinearLayoutManager(this)
val adapter = NotesRVAdapter(this, this)
RecyclerView.adapter = adapter
viewModel = ViewModelProvider(this,
ViewModelProvider.AndroidViewModelFactory.getInstance(application))
.get(NoteViewModel::class.java)
viewModel.allNotes.observe(this, Observer { list ->
list?.let {
adapter.updateList(it)
}
})
}
override fun onItemClicked(note: Note) {
viewModel.deleteNote(note)
Toast.makeText(this,"${note.text} Deleted", Toast.LENGTH_LONG).show()
}
fun submitData(view: View) {
val noteText = input.text.toString()
if (noteText.isNotEmpty()){
viewModel.insertNote(Note(noteText))
Toast.makeText(this,"$noteText Inserted", Toast.LENGTH_LONG).show()
}
}
}
immediate help will be appreciated in understanding the issue and where I went wrong.
Thanks.
Try changing class of entity to data class and also the id field
package com.example.notes
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
#Entity(tableName = "notes_table")
data class Note(
#ColumnInfo(name = "text")val text:
String),
#PrimaryKey(autoGenerate = true)
#ColumnInfo(name = "text_id")
var id = 0)

Object is not abstract and does not implement abstract member public abstract fun error

Am trying to run kotlin native code inside my flutter app ,, here is how my kotlin code look slike
package com.deliveryrunner.driver
import android.content.*
import io.flutter.embedding.android.FlutterActivity
import androidx.annotation.NonNull
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import android.content.Intent
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import android.location.Location
class MainActivity : FlutterActivity() {
private val LOCATION_CHANNEL = "com.deliveryrunner.driver/getCurrentLocation";
private lateinit var channel: MethodChannel
private lateinit var fusedLocationClient: FusedLocationProviderClient
override fun configureFlutterEngine(#NonNull flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterView, CHANNEL).setMethodCallHandler {
call, result ->
if (call.method == "currentLocation") {
val arguments = call.arguments() as Map<String, String>
val test = arguments["test"]
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
fusedLocationClient.lastLocation
.addOnSuccessListener { location: Location ->
result.success("got the loation")
}
}
}
}
}
but I am getting this error whenever I run the app
e: D:\Flutter\src\flutter\.pub-cache\hosted\pub.dartlang.org\workmanager-0.4.1\android\src\main\kotlin\be\tramckrijte\workmanager\BackgroundWorker.kt: (132, 21): Object is not abstract and does not implement abstract member public abstract fun error(p0: String, p1: String?, p2: Any?): Unit defined in io.flutter.plugin.common.MethodChannel.Result
e: D:\Flutter\src\flutter\.pub-cache\hosted\pub.dartlang.org\workmanager-0.4.1\android\src\main\kotlin\be\tramckrijte\workmanager\BackgroundWorker.kt: (137, 25): 'error' overrides nothing

Kotlin livedata observer not triggered

i'm practising a bit with kotlin and was testing Room and livedata, my app gets data from a json and the stores it in room, i want to move this network call to its own file and class, but if i do so the observer i set to get the changes don't trigger anymore, any help would be appreciated
here is a snipped of my mainactivity, if more is needed to know what happens please let me know
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView
import android.widget.Toast
import androidx.activity.viewModels
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.viewModelScope
import androidx.room.Room
import com.optiva.videoplayer.data.*
import com.optiva.videoplayer.network.GetData
import com.optiva.videoplayer.network.Networking
import com.optiva.videoplayer.network.RetrofitConnect
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val dbcategories = Room.databaseBuilder(applicationContext, CategoriesDatabase::class.java,"categories.db").build()
val dbvideo = Room.databaseBuilder(applicationContext, VideosDatabase::class.java,"videos.db").build()
val retrofitData = RetrofitConnect.retrofitInst?.create(GetData::class.java)
val categoriesList = retrofitData?.getAll()
categoriesList?.enqueue(object: Callback<DataList> {
override fun onResponse(
call: Call<DataList>,
response: Response<DataList>
) {
val test = response?.body()
val cat = test?.categories
val vid = test?.videos
lifecycleScope.launch(Dispatchers.IO) {
if (cat != null) {
for(c in cat){
dbcategories.categoriesDAO().insertAll(CategoriesEntity(c.id,c.title,c.type))
}
}
if (vid != null) {
for(v in vid){
dbvideo.VideosDAO().insertAll(VideosEntity(v.id,v.thumb,v.videoUrl,v.categoryId,v.name))
}
}
}
}
override fun onFailure(call: Call<DataList>, t: Throwable) {
Toast.makeText(applicationContext,"error", Toast.LENGTH_LONG).show()
}
})
val textView: TextView = findViewById(R.id.test) as TextView
dbcategories.categoriesDAO().getALL().observeForever({categories ->
if(categories.size>0){
textView.text= categories[0].title
}
})
dbcategories.categoriesDAO().getALL().observe(this, {categories ->
if(categories.size>0){
textView.text= categories[0].title
}
}
} ```

how to check whether asynctask is finshed or not from another class

i have one fragment which run asynctask to get data by parsing api and storing in array list.
but what i want to do is that i want to print that list from another class so that i can create search filter.
package com.example.rsquare_android_fixed.mywork.building
import android.os.AsyncTask
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.size
import androidx.fragment.app.Fragment
import com.example.rsquare_android_fixed.R
import com.example.test.mainF.Address_data
import kotlinx.android.synthetic.main.fragment_building.*
import org.json.JSONArray
import org.json.JSONObject
import java.net.HttpURLConnection
import java.net.URL
class buildingFragment: Fragment(){
private val list=ArrayList<Address_data>()
private val list2=ArrayList<Address_map>()
public var list3=ArrayList<Address_all>()
public var check_list3:Int = 0
override fun onCreateView(inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?): View? {
val inflate=inflater.inflate(R.layout.fragment_building, container, false)
val url="https://manage-dev.rsquare.co.kr/api/sample/buildings"
AsyncTaskHandleJson().execute(url)
return inflate
}
inner class AsyncTaskHandleJson: AsyncTask<String, String, String>(){
override fun doInBackground(vararg url: String?): String {
var text:String
val connection= URL(url[0]).openConnection() as HttpURLConnection
try{
connection.connect()
text=connection.inputStream.use{it.reader().use{reader->reader.readText()}}
}
finally{
connection.disconnect()
}
return text
}
override fun onPostExecute(result: String?) {
super.onPostExecute(result)
handleJson(result)
naverGeo()
}
//json parsing
private fun handleJson(jsonString: String?) {
val jsonArray= JSONArray(jsonString)
//val list=ArrayList<Address_data>()
var x=0
while(x<jsonArray.length()){
val jsonObject=jsonArray.getJSONObject(x)
list.add(
Address_data(
jsonObject.getString("address"),
jsonObject.getString("bunji"),
jsonObject.getString("streetAddress"),
jsonObject.getString("updateAt")
)
)
x++
}
val adapter=MW_Adapter_list(requireActivity(),list)
data_list.adapter=adapter
// val a = list[0]
// a.address
list.forEach { println(it) }
println("listsize1="+list.size)
}
}
fun naverGeo(){
println("naverGeo")
var query:String
println("listsize2="+list.size)
for(i in 0..list.size-1){
var a = list[i]
query=a.address
println("test : $i")
println("query : $query")
var url2 = "https://naveropenapi.apigw.ntruss.com/map-geocode/v2/geocode?X-NCP-APIGW-API-KEY-ID=key&X-NCP-APIGW-API-KEY=pw&query="+query
AsyncTaskNaver().execute(url2)
}
}
inner class AsyncTaskNaver:AsyncTask<String,String,String>(){
override fun doInBackground(vararg url2: String?): String {
var text:String
val connection=URL(url2[0]).openConnection() as HttpURLConnection
try{
connection.connect()
text=connection.inputStream.use{it.reader().use{reader->reader.readText()}}
}
finally{
connection.disconnect()
}
return text
}
override fun onPostExecute(result: String?) {
super.onPostExecute(result)
handleJson2(result)
//merge to longitude and latitude with original data
if(list2.size==30){
mergeList()
}
}
private fun handleJson2(jsonString: String?){
val jsonObj=JSONObject(jsonString)
val jsonArray=JSONArray(jsonObj.get("addresses").toString())
var x=0
while(x<jsonArray.length()){
val jsonObject=jsonArray.getJSONObject(x)
list2.add(
Address_map(
jsonObject.getString("roadAddress"),
jsonObject.getString("x"), //long
jsonObject.getString("y") //lat
)
)
x++
}
//println(list2.size)
}
}
fun mergeList(){
//println(list2.size)
for (i in 0..list.size-1){
var list_api=list[i]
var list_naver=list2[i]
var query_api=list_api.address
var query_naver=list_naver.raddress
var bunji_api=list_api.bunji
var street_api=list_api.streeetAddress
var long_naver=list_naver.x
var lat_naver=list_naver.y
//by comparing first 2 letters, last 3 letters from address to merge them into one
if(query_api.takeLast(3)==query_naver.takeLast(3)&&query_api.take(2)==query_naver.take(2)){
list3.add(
Address_all(
query_api,
bunji_api,
street_api,
long_naver,
lat_naver
)
)
}
}
check_list3=1
list3.forEach { println(it) }
}
}
and below is my another code where i want to print list
package com.example.rsquare_android_fixed.mywork.search
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import android.widget.ListView
import android.widget.TextView
import androidx.appcompat.widget.SearchView
import androidx.fragment.app.Fragment
import com.example.rsquare_android_fixed.R
import com.example.rsquare_android_fixed.mywork.building.MWFragment
import com.example.rsquare_android_fixed.mywork.building.MW_Adapter_list
import com.example.rsquare_android_fixed.mywork.building.buildingFragment
import com.naver.maps.geometry.LatLng
import com.naver.maps.geometry.LatLngBounds
import com.naver.maps.map.NaverMap
import com.naver.maps.map.NaverMapSdk
import com.naver.maps.map.overlay.Marker
import kotlinx.android.synthetic.main.fragment_building.*
import kotlinx.android.synthetic.main.fragment_search.*
import kotlinx.android.synthetic.main.list_search.*
class searchFragment: Fragment(){
private var list: ListView?=null
private var adapter:SearchAdapter?=null
private var editsearch:SearchView?=null
private var addrList:Array<String>?=null
//lateinit var naverMap:NaverMap
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view:View = inflater.inflate(R.layout.fragment_search, container, false)
//list=findViewById(R.id.search_list) as ListView
val a = buildingFragment()
if(a.check_list3==0){
println("nulnunlnlunlnl")
}
else{
println(a.list3)
println("not null")
//println(a.list3)
}
return view
}
/*override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
//NaverMapSdk.getInstance(requireContext()).client=NaverMapSdk.NaverCloudPlatformClient("dp3mci4foz")
val a = buildingFragment()
}
*/
}
i think my 2nd code is calling list before asynctask from 1st code is done. and this leads me to print null list.
so is there any method that 2nd code to notice that 1st code has finished asynctask?
(sry my code is way to dirty)
Create an interface
interface CallBack {
fun asyncompleted(list:ArrayList<Address_all>)
}
Implement in searchFragment.
class searchFragment: Fragment(), CallBack {
fun asyncCompleted(list:ArrayList<Address_all>) {
println(list)
}
}
Create a method in buildingFragment
var callback: CallBack
setCallback(value) { callback = value }
set callback after creating buildingFragment instance in searchFragment
val a = buildingFragment()
a.setCallback(this)
call asyncompleted method after setting list3
override fun onPostExecute(result: String?) {
super.onPostExecute(result)
handleJson2(result)
//merge to longitude and latitude with original data
if(list2.size==30){
mergeList()
}
callback.asyncompleted(list3)
}

Kotlin-android unresolved reference : queue

I imported retrofi2.Callback
and I still get this error unresolved reference: enqueue
this is the code of the login class
import android.content.Intent
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.provider.ContactsContract
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import com.cbmis.imageapp.Common.Common
import com.cbmis.imageapp.Model.APIResponse
import com.cbmis.imageapp.Remote.IMyAPI
import kotlinx.android.synthetic.main.activity_login.*
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
class LoginActivity : AppCompatActivity() {
internal lateinit var mService:IMyAPI
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
//initservice
mService = Common.api
//Event
txtregister.setOnClickListener { startActivity(Intent(this#LoginActivity,RegisterActivity::class.java))
finish()
}
btn_login.setOnClickListener { authentificateUser(findViewById<TextView>(R.id.email).text.toString(), findViewById<TextView>(R.id.password).text.toString()) }
}
private fun authentificateUser(email: String, password: String) {
mService.loginUser(email, password)
.enqueue(object :Callback<APIResponse> {
override fun onFailure(call: Call<APIResponse>?, t: Throwable?) {
Toast.makeText(this#LoginActivity,t!!.message,Toast.LENGTH_SHORT).show()
}
override fun onResponse(call: Call<APIResponse>?, response: Response<APIResponse>?) {
if (response!!.body()!!.error)
Toast.makeText(this#LoginActivity,response!!.body()!!.errr_msg,Toast.LENGTH_SHORT).show()
else
Toast.makeText(this#LoginActivity, "Login Success!",Toast.LENGTH_SHORT).show()
}
})
}
}
and this is the interface/
interface IMyAPI {
#FormUrlEncoded
#POST("signup.php")
fun registerUser(#Field("email") email:String,#Field("name")name:String,#Field("password") password:String,#Field("dateofbirth") dateofbirth:String,#Field("genderM") genderM:String,#Field("genderF") genderF:String):Class<APIResponse>
#FormUrlEncoded
#POST("login.php")
fun loginUser(#Field("email") email:String,#Field("password") password:String):Class<APIResponse>
}
Any solutions can be proposed to solve this problem
You should be returning a Retrofit Call from your API's functions:
interface IMyAPI {
#FormUrlEncoded
#POST("signup.php")
fun registerUser(/* params */) : Call<APIResponse>
#FormUrlEncoded
#POST("login.php")
fun loginUser(/* params */): Call<APIResponse>
}

Categories

Resources