extras.getString() returns null in Kotlin Android - android

The result is always return null, I don't know what mistake, I have seen other people problems I am not getting what I need exactly.
class DatabaseLists(private val context: Context?) {
private lateinit var database: SQLiteDatabase
val getPrayerContentList: ArrayList<PrayerModel>
#SuppressLint("Recycle")
get() {
database = DatabaseOpenHelper(context).readableDatabase
val cursor: Cursor = database.query(
"table_prayer",
null,
null,
null,
null,
null,
null,
null
)
val contentList = ArrayList<PrayerModel>()
if (cursor.moveToFirst()) {
while (!cursor.isAfterLast) {
val contents = PrayerModel(
cursor.getString(cursor.getColumnIndex("prayer_name")),
cursor.getString(cursor.getColumnIndex("ayah_name")),
cursor.getString(cursor.getColumnIndex("arabic")),
cursor.getString(cursor.getColumnIndex("latin")),
cursor.getString(cursor.getColumnIndex("translate")),
cursor.getString(cursor.getColumnIndex("description"))
)
contentList.add(contents)
cursor.moveToNext()
if (cursor.isClosed) {
cursor.close()
}
}
}
return contentList
}
class PrayerActivity : AppCompatActivity(), MainContract.MainView {
private lateinit var binding: ActivityPrayerBinding
private var database: SQLiteDatabase? = null
private lateinit var preferences: SharedPreferences
private lateinit var editor: SharedPreferences.Editor
lateinit var carlist: ArrayList<PrayerModel>
private lateinit var prayerContentList: MutableList<PrayerModel>
private lateinit var prayerAdapter: PrayerAdapter
private lateinit var mainPresenterImpl: MainPresenterImpl
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_prayer)
setSupportActionBar(binding.toolbar)
preferences = PreferenceManager.getDefaultSharedPreferences(this)
editor = preferences.edit()
PreferenceManager.getDefaultSharedPreferences(this)
database = DatabaseOpenHelper(this).readableDatabase
prayerContentList = DatabaseLists(this).getPrayerContentList
mainPresenterImpl = MainPresenterImpl(this, this)
initMainContent()
}
override fun initMainContent() {
val verticalLayout = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
binding.rvMainContent.layoutManager = verticalLayout
prayerAdapter = PrayerAdapter(this, prayerContentList)
binding.rvMainContent.adapter = prayerAdapter
}
}
data class PrayerModel (
val strPrayerName: String?,
val strAyahName: String?,
val strContentArabic: String?,
val strContentLatin: String?,
val strContentTranslation: String?,
val strContentDescription: String?)
myAdapter
class PrayerAdapter(context: Context, private val prayerContentList: MutableList<PrayerModel>) :
RecyclerView.Adapter<PrayerViewHolder>() {
private val context: Context? = null
private val inflater = LayoutInflater.from(context)
private var currentIndex: Int = -1
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PrayerViewHolder {
return PrayerViewHolder(inflater.inflate(R.layout.item_prayer_content, parent, false))
}
override fun getItemCount(): Int {
return prayerContentList.size
}
override fun onBindViewHolder(holder: PrayerViewHolder, position: Int) {
val strContentArabic = prayerContentList[position].strContentArabic
val strContentLatin = prayerContentList[position].strContentLatin
val strContentTranslation = prayerContentList[position].strContentTranslation
val strContentDescription = prayerContentList[position].strContentDescription
val strPrayerName = prayerContentList[position].strPrayerName
val strAyahName = prayerContentList[position].strAyahName
holder.tvContentPrayerName.text = strPrayerName
holder.tvContentAyahName.text = strAyahName
holder.itemView.setOnClickListener { v ->
val context: Context = v.context
val intent = Intent(context, PrayerReadActivity::class.java)
intent.putExtra("ARABIC_TEXT", strContentArabic?.get(position))
intent.putExtra("LATIN_TEXT", strContentLatin!![position])
intent.putExtra("TRANSLATION_TEXT", strContentTranslation!![position])
intent.putExtra("DESCRIPTION_TEXT", strContentDescription!![position])
context.startActivity(intent)
Log.d(TAG, "-->name = $strContentArabic")
}
}
}
my 2Activity can have code like this, and trying to get that string extra in another activity but is returning null?
class PrayerReadActivity() : AppCompatActivity() {
private var database: SQLiteDatabase? = null
private lateinit var prayerContentList: MutableList<PrayerModel>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_prayer_read)
LockOrientation(this).lock()
PreferenceManager.getDefaultSharedPreferences(this)
database = DatabaseOpenHelper(this).readableDatabase
prayerContentList = DatabaseLists(this).getPrayerContentList
val extras = intent.extras
if (null != extras) {
val arabic = extras.getString("ARABIC_TEXT").toString()
val latin = extras.getString("LATIN_TEXT").toString()
val translation = extras.getString("TRANSLATION_TEXT").toString()
val description = extras.getString("DESCRIPTION_TEXT").toString()
Log.d(ContentValues.TAG, "-->arabic = $arabic")
tvContentArabic2.text = arabic
tvContentLatin2.text = latin
tvContentTranslation2.text = translation
tvContentDescription2.text = description
Log.d(ContentValues.TAG, "-->arabic = $arabic")
Log.d(ContentValues.TAG, "-->latin = $latin")
Log.d(ContentValues.TAG, "-->translation = $translation")
Log.d(ContentValues.TAG, "-->description = $description")
}
I tried by replacing
val arabic = intent.getStringExtra("ARABIC_TEXT").toString()
also still it is returning null?
2021-07-22 22:31:16.411 9607-9607/com.example.yasiin D/ContentValues: -->arabic = null
2021-07-22 22:31:16.411 9607-9607/com.example.yasiin D/ContentValues: -->arabic = null
2021-07-22 22:31:16.411 9607-9607/com.example.yasiin D/ContentValues: -->latin = null
2021-07-22 22:31:16.411 9607-9607/com.example.yasiin D/ContentValues: -->translation = null
2021-07-22 22:31:16.411 9607-9607/com.example.yasiin D/ContentValues: -->description = null

Try replacing this
intent.putExtra("ARABIC_TEXT", strContentArabic?.get(position))
intent.putExtra("LATIN_TEXT", strContentLatin!![position])
intent.putExtra("TRANSLATION_TEXT", strContentTranslation!![position])
intent.putExtra("DESCRIPTION_TEXT", strContentDescription!![position])
With this
intent.putExtra("ARABIC_TEXT", strContentArabic)
intent.putExtra("LATIN_TEXT", strContentLatin)
intent.putExtra("TRANSLATION_TEXT", strContentTranslation)
intent.putExtra("DESCRIPTION_TEXT", strContentDescription)
You have already have the string, just put it in the extras.

Please just try the below line of code to update and check in your PrayerActivity, for this you can create one interface callback and call interface method(varargs with multiple params or string or pojo class) from adapter class where you are opening intent currently, then from PrayerActivity activity you can open it
val intent = Intent(this#PrayerActivity, PrayerReadActivity::class.java)
intent.putExtra("ARABIC_TEXT", strContentArabic?.get(position))
intent.putExtra("LATIN_TEXT", strContentLatin!![position])
intent.putExtra("TRANSLATION_TEXT", strContentTranslation!![position])
intent.putExtra("DESCRIPTION_TEXT", strContentDescription!![position])
startActivity(intent)
hope it may help you

Related

How can i delete something from cloud firestore database?

i'm trying to delete a document in my firestore database
i'm using a listview to list some things of my data base, the items of this listview have a delete button, what i want is: when the user presses the delete button, this thing gets deleted from the list and from the firestore, there what i'm trying:
this is my entire activity to do this:
class RigBuilderActivity : AppCompatActivity() {
lateinit var botaoAddPc: FloatingActionButton
lateinit var pcName:EditText
lateinit var infoButton:FloatingActionButton
lateinit var pcListView: ListView
companion object{
const val TAG = "RigBuilderActivity"
}
var pc = arrayListOf<PC>()
val pcAdapter = PcAdapter()
val db = Firebase.firestore
val userId = FirebaseAuth.getInstance().currentUser!!.uid
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_rig_builder)
botaoAddPc = findViewById(R.id.rig_builder_button_add_pc)
pcName = findViewById(R.id.rig_builder_text_input)
infoButton = findViewById(R.id.rig_builder_button_info)
pcListView = findViewById(R.id.rig_builder_pc_list)
botaoAddPc.setOnClickListener{
var pc_text :String = pcName.text.toString()
val computer = PC(UUID.randomUUID().toString(),pc_text)
db.collection("users").document(userId).collection("PC").add(computer.toHashmapPC()).addOnSuccessListener { task->
Log.d(TAG, "DocumentSnapshot added with ID: ${task.id}")
Toast.makeText(this,"Pc added",Toast.LENGTH_SHORT).show()
}.addOnFailureListener{ e->
Log.w(TAG,"Error Adding PC",e)
Toast.makeText(this,"Failed",Toast.LENGTH_SHORT).show()
}
}
pcListView.adapter = pcAdapter
db.collection("users").document(userId).collection("PC").addSnapshotListener{ value, e->
if (e!=null){
Log.w(TAG,"Listen failed.",e)
return#addSnapshotListener
}
pc.clear()
for (doc in value!!){
val pc = PC.fromQueryDoc(doc)
this.pc.add(pc)
}
pcAdapter.notifyDataSetChanged()
}
}
fun getPcName():String{
return pcName.toString()
}
inner class PcAdapter : BaseAdapter() {
override fun getCount(): Int {
return pc.size
}
override fun getItem(p0: Int): Any {
return pc[p0]
}
override fun getItemId(p0: Int): Long {
return 0
}
override fun getView(p0: Int, p1: View?, p2: ViewGroup?): View {
val rootView = layoutInflater.inflate(R.layout.pc_item_layout, p2,false )
val textViewPcName = rootView.findViewById<TextView>(R.id.pc_name)
val editButton = rootView.findViewById<ImageButton>(R.id.pc_edit_button)
val deleteButton = rootView.findViewById<FloatingActionButton>(R.id.pc_delete_button)
textViewPcName.text = pc[p0].counter.toString()
deleteButton.setOnClickListener{
val ref : DocumentReference = db.collection("users").document(userId).collection("PC").document(pc[p0].getPcId())
ref.delete().addOnSuccessListener {
Log.d(TAG,"Pc deleted with success")
Toast.makeText(this#RigBuilderActivity,"Deleted with success",Toast.LENGTH_SHORT).show()
}
pcAdapter.notifyDataSetChanged()
}
editButton.setOnClickListener{
}
textViewPcName.text = pc[p0].name
return rootView
}
}
}
in case of needing, this is my PC class, i'm just using one of the constructors to test the list and make the delete works:
class PC {
var id:String
var name : String? = null
var counter : Long? = null
lateinit var cpu :CPU
lateinit var gpu: GPU
lateinit var motherBoard: MotherBoard
/**
* Construtor de teste
*/
constructor(id:String, name:String?){
this.id = id
this.name = name
}
/**
* Construtor ainda a implementar
*/
constructor(id:String, name:String?, cpu: CPU,gpu: GPU,motherBoard: MotherBoard){
this.id = id
this.name = name
this.cpu = cpu
this.gpu = gpu
this.motherBoard = motherBoard
}
fun toHashmapPC() : HashMap <String, Any?>{
return hashMapOf(
"id" to id,
"name" to name
)
}
fun getPcId():String{
return id
}
companion object{
fun fromQueryDoc(documentSnapshot: DocumentSnapshot):PC{
return PC(
documentSnapshot["id"] as String,
documentSnapshot["name"] as String
)
}
}
}

Error adding to mutable list (NPE) Kotlin Android

---Data Class---
trying to add object to meals MutableList-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
data class YelpRestaurant(
val name: String,
val rating: Double,
val price: String,
#SerializedName("review_count") val numReviews: Int,
#SerializedName("image_url") val imageUrl: String,
val categories: List<YelpCategory>,
val location: YelpLocation,
val meals: MutableList<UserMeals>
)
----EDITED ACTIVITY----
class ThoughtsActivity : AppCompatActivity() {
lateinit var mealName: String
lateinit var mealPrice: String
lateinit var mealThought: String
lateinit var selected_Restaurant : YelpRestaurant
val meals = mutableListOf<UserMeals>()
#Subscribe(sticky = true)
fun getRest(selectedRestaurant : YelpRestaurant) {
selected_Restaurant = selectedRestaurant
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_thoughts)
thoughtBtn.setOnClickListener() {
mealName = m_name.text.toString()
mealPrice = m_price.text.toString()
mealThought = m_thought.text.toString()
var addedMeal = UserMeals(mealName, mealPrice.toDouble(), mealThought)
if (mealName.isNotEmpty()) {
selected_Restaurant.meals.add(addedMeal)
}
}
}
override fun onStart() {
super.onStart()
EventBus.getDefault().register(this)
}
override fun onStop() {
super.onStop()
EventBus.getDefault().unregister(this)
}
}
You have null pointer exception when accessing selected_Restaurant.meals to prevent NPE change meals to val and instantiate it when you declare it like this in selected_Restaurant:
val meals = mutableListOf<UserMeals>()

How do I change the viewmodel observable data in android?

I created a gridView that has an ArrayAdapter, the gridView contains only photos, I am fetching the image url in an Array and I am observing the array through my activity. Here is my viewmodel
class ProfileViewModel constructor(): ViewModel() {
var first_name: String? = null
var last_name: String? = null
var dob: String? = null
var address: String? = null
var organization: String? = null
var hobby: String? = null
var bio: String? = null
var imagePath: String = ""
private val imageList : MutableLiveData<ArrayList<ProfileViewModel>> = MutableLiveData()
constructor(photo : Photo) : this() {
this.imagePath = photo.imageUrl
}
fun getImageUrl() : String {
return imagePath
}
companion object {
#BindingAdapter("imageUrl")
#JvmStatic
fun loadImage(imageView: ImageView, imageUrl: String) {
Glide.with(imageView.context)
.load(imageUrl)
.apply(RequestOptions.centerCropTransform())
.placeholder(R.drawable.ic_add_icon)
.into(imageView)
}
}
val profileViewModels : MutableLiveData<ArrayList<ProfileViewModel>>
get() {
val profileViewModels = ArrayList<ProfileViewModel>()
val photo1 = Photo("")
val profileVM = ProfileViewModel(photo1)
repeat(6) {
profileViewModels.add(profileVM)
}
imageList.value = profileViewModels
return imageList
}
}
}
Here is my activity where I am observing the data
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityProfileBinding =
DataBindingUtil.setContentView(this, R.layout.activity_profile)
val viewModel = ViewModelProvider(this).get(ProfileViewModel::class.java)
viewModel.profileViewModels.observe(this,
Observer<ArrayList<ProfileViewModel>> { image_paths ->
Log.d("added", "$image_paths")
val imageAdapter = ImageAdapter(this#Profile, R.layout.image_card, image_paths!!)
gridView.adapter = imageAdapter
})
}
I am getting images in the gridView but I want to update the observable value on gridView Item click in the clicked position. How do I do that?
First, you can create a function in viewmodel, that you want to do when clicked. for example:
private fun doSomethingWhenClicked(listPosition: Int){
val clickedImage = profileViewModels[position]
//do something here for clicked image
//..
}
Then, initialize the viewmodel in adapter like this. So you can update your profileViewModels in onClickListener inside the ImageAdapter
viewmodel.doSomethingWhenClicked(position)
Hope this answer you!

Kotlin RecyclerView no adapter attached skipping layout

I don't know what the problem is but same code works fine in java
Here is my adapter class:
class MainAdapter(private val context: Context, private val firebaseVisionlabel: ArrayList<FirebaseVisionLabel>) : RecyclerView.Adapter<CustomViewHolder>() {
override fun getItemCount(): Int {
return firebaseVisionlabel.size
}
override fun onCreateViewHolder(p0: ViewGroup, p1: Int): CustomViewHolder {
val v = LayoutInflater.from(context).inflate(R.layout.list_items,p0,false)
return CustomViewHolder(v)
}
override fun onBindViewHolder(p0: CustomViewHolder, p1: Int) {
val firebaseVisionLabel = firebaseVisionlabel?.get(p1)
val label = firebaseVisionLabel?.label
val confidence =firebaseVisionLabel?.confidence.toString()
p0.itemView.textView.text = label
p0.itemView.confidence.text = confidence
}
}
class CustomViewHolder(v:View) : RecyclerView.ViewHolder(v)
MainActivity: (Global declaration)
var fileUri: Uri? = null
var TAG = "MainActivity"
var firebaseVisionLabels : ArrayList<FirebaseVisionLabel>? = null
In onCreate :
rec_view.layoutManager = LinearLayoutManager(this)
rec_view.setHasFixedSize(true)
Button :
detect_button.setOnClickListener{
imageRecognition()
}
Function :
private fun imageRecognition() {
var bitmap = MediaStore.Images.Media.getBitmap(this.contentResolver, fileUri)
var image = FirebaseVisionImage.fromBitmap(bitmap)
val labeler = FirebaseVision.getInstance().visionLabelDetector
labeler.detectInImage(image)
.addOnSuccessListener { labels ->
for (label in labels) {
val text = label.label
val entityId = label.entityId
val confidence = label.confidence
Log.d("TAG", "$text $confidence") //logcat works
firebaseVisionLabels?.add(label)
//Main problem??
rec_view.adapter = firebaseVisionLabels?.let { MainAdapter(this, it) }
}
}.addOnFailureListener { e ->
// Task failed with an exception
// ...
detect_button.isEnabled = true
Log.d(TAG,e.toString())
}
}
Logcat prints the expected outputs but I don't know what the problem is in recyclerview. I don't want to put bunch of camera and gallery intents codes, they works fine. Thanks for helping.
I solved by changing RecyclerView to BaseAdapter and the parameter to ArrayList. I guess RecyclerView can work same with the Basedapter by changing the parameter private val firebaseVisionlabel: ArrayList<FirebaseVisionLabel> to private val labeltext : ArrayList<String> I think it is a bug between FirebaseVisionLabel and Kotlin
Modified part for MainActivity :
for (label in labels) {
for(i in 1..1){
val text = label.label
val entityId = label.entityId
val confidence = label.confidence
new_list.add(text)
}
list_view.adapter =MainAdapter(this,new_list)

Typecasting Error in Kotlin: ArrayList

I am creating a music player app, In which there are a recycler view and many fragments. I am getting an error on my MainScreenFragment.kt file. I checked the error log and the error its shows is:
******Caused by: kotlin.TypeCastException: null cannot be cast to non-null type
kotlin.collections.ArrayList /* =
java.util.ArrayList */
at
com.thepanku.musicplayer.Fragments.MainScreenFragment.onCreateView(MainScreenFragment.kt:60)
at
android.support.v4.app.Fragment.performCreateView(Fragment.java:2354)******
what would be the reason for the error, any help would be appreciable. I am fed up with the error.
Here is the code:
class MainScreenFragment : Fragment() {
var getSongList : ArrayList<Songs>? = null
var nowPlayingBottomBar: RelativeLayout?=null
var playPauseButton: ImageView?=null
var songTitle: TextView?=null
var visibleLayout: RelativeLayout?=null
var noSongs: RelativeLayout?=null
var recyclerView: RecyclerView?= null
var myActivity:Activity?=null
var _mainScreenAdapter : MainScreenAdapter?=null
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
val view = inflater?.inflate(R.layout.content_main, container, false)
setHasOptionsMenu(true)
activity.title = "All songs"
visibleLayout = view?.findViewById<RelativeLayout>(R.id.visibleLayout)
noSongs = view?.findViewById<RelativeLayout>(R.id.noSongs)
nowPlayingBottomBar = view?.findViewById<RelativeLayout>(R.id.hiddenBarMainScreen)
songTitle = view?.findViewById<TextView>(R.id.songTitleMainScreen)
playPauseButton = view?.findViewById<ImageButton>(R.id.playpauseButton)
(nowPlayingBottomBar as RelativeLayout).isClickable = false
recyclerView = view?.findViewById<RecyclerView>(R.id.contentMain)
visibleLayout?.visibility = View.INVISIBLE
noSongs?.visibility = View.VISIBLE
//getting error on this line->
_mainScreenAdapter = MainScreenAdapter(getSongList as ArrayList<Songs>, activity)
val mLayoutManager = LinearLayoutManager(activity)
(recyclerView as RecyclerView).layoutManager = mLayoutManager
(recyclerView as RecyclerView).itemAnimator = DefaultItemAnimator()
(recyclerView as RecyclerView).adapter = _mainScreenAdapter
return view
}
fun getSongsFromPhone(): ArrayList<Songs>{
var arrayList = ArrayList<Songs>()
var contentResolver = myActivity?.contentResolver
var songUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
var songCursor = contentResolver?.query(songUri, null, null, null, null)
if(songCursor!=null && songCursor.moveToFirst()){
val songId = songCursor.getColumnIndex(MediaStore.Audio.Media._ID)
val SongTitle = songCursor.getColumnIndex((MediaStore.Audio.Media.TITLE))
val songArtist = songCursor.getColumnIndex(MediaStore.Audio.Media.ARTIST)
val songData = songCursor.getColumnIndex(MediaStore.Audio.Media.DATA)
val dateIndex = songCursor.getColumnIndex(MediaStore.Audio.Media.DATE_ADDED)
while(songCursor.moveToNext()){
var currentId = songCursor.getLong(songId)
var currentTitle = songCursor.getString(SongTitle)
var currentArtist = songCursor.getString(songArtist)
var currentData = songCursor.getString(songData)
var currentDate = songCursor.getString(dateIndex)
}
}
return arrayList
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
getSongList = getSongsFromPhone()
}
override fun onAttach(context: Context?) {
super.onAttach(context)
myActivity = context as Activity
}
override fun onAttach(activity: Activity?) {
super.onAttach(activity)
myActivity = activity
}
}// Required empty public constructor
You have
var getSongList : ArrayList<Songs>? = null
and then you say
getSongList as ArrayList<Songs>
Clearly, getSongList is null, but you insist on casting it into a not-null type ArrayList<Song>. Your hope is that it will be initialized in onCreateActivity, but apparently that callback's turn hasn't yet come at the point when your onCreateView got called.
I am sorry to hear that you are fed up with this error and hope you'll be able to provide a non-null value for your getSongList, for example by calling getSongsFromPhone().

Categories

Resources