Kotlin app object does not exist at location on firebase on click - android

My code gives me below error
package com.example.productsadder
import android.app.Activity
import android.content.Intent
import android.content.Intent.ACTION_GET_CONTENT
import android.graphics.Bitmap
import android.net.Uri
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.lifecycle.lifecycleScope
import com.example.productsadder.databinding.ActivityMainBinding
import com.google.firebase.firestore.ktx.firestore
import com.google.firebase.ktx.Firebase
import com.google.firebase.storage.ktx.storage
import com.skydoves.colorpickerview.ColorEnvelope
import com.skydoves.colorpickerview.ColorPickerDialog
import com.skydoves.colorpickerview.listeners.ColorEnvelopeListener
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
import kotlinx.coroutines.tasks.await
import kotlinx.coroutines.withContext
import java.io.ByteArrayOutputStream
import java.lang.Exception
import java.util.UUID
class MainActivity : AppCompatActivity() {
private val binding by lazy { ActivityMainBinding.inflate(layoutInflater) }
private var selectedImages = mutableListOf<Uri>()
private val selectedColors = mutableListOf<Int>()
private val firestore = Firebase.firestore
private val productsStorage = Firebase.storage.reference
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
binding.buttonColorPicker.setOnClickListener{
ColorPickerDialog.Builder(this)
.setTitle("Product color")
.setPositiveButton("Select", object : ColorEnvelopeListener{
override fun onColorSelected(envelope: ColorEnvelope?, fromUser: Boolean) {
envelope?.let {
selectedColors.add(it.color)
updateColor()
}
}
})
.setNegativeButton("Cancel"){ colorPicker, _ ->
colorPicker.dismiss()
}.show()
}
val selectImagesActivityResult =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()){ result ->
if(result.resultCode == Activity.RESULT_OK){
val intent = result.data
if(intent?.clipData != null){
val count = intent.clipData?.itemCount ?: 0
(0 until count).forEach{
val imageUri = intent.clipData?.getItemAt(it)?.uri
imageUri?.let{
selectedImages.add(it)
}
}
} else {
val imageUri = intent?.data
imageUri?.let { selectedImages.add(it) }
}
updateImages()
}
}
binding.buttonImagesPicker.setOnClickListener{
val intent = Intent(ACTION_GET_CONTENT)
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
intent.type = "image/*"
selectImagesActivityResult.launch(intent)
}
}
private fun updateColor(){
var colors = ""
selectedColors.forEach{
colors = "$colors ${Integer.toHexString(it)}"
}
binding.tvSelectedColors.text = colors
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.toolbar_menu, menu)
return true
}
private fun updateImages(){
binding.tvSelectedImages.text = selectedImages.size.toString()
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if(item.itemId == R.id.saveProduct){
val productValidation = validateInformation()
if (!productValidation){
Toast.makeText(this, "Check your inputs", Toast.LENGTH_SHORT).show()
return false
}
saveProducts() {
Log.d("test", it.toString())
}
}
return super.onOptionsItemSelected(item)
}
private fun saveProducts(state: (Boolean) -> Unit){
val name = binding.edName.text.toString().trim()
val category = binding.edCategory.text.toString().trim()
val price = binding.edPrice.text.toString().trim()
val offerPercentage = binding.offerPercentage.text.toString().trim()
val description = binding.edDescription.text.toString().trim()
val sizes = getSizesList(binding.edSizes.text.toString().trim())
val imagesByteArrays = getImagesByteArrays()
val images = mutableListOf<String>()
lifecycleScope.launch(Dispatchers.IO){
withContext(Dispatchers.Main){
showLoading()
}
try{
async {
imagesByteArrays.forEach{
val id = UUID.randomUUID().toString()
launch {
val imageStorage = productsStorage.child("products/images/$id")
val result = imageStorage.putBytes(it).await()
val downloadUrl = result.storage.downloadUrl.await().toString()
images.add(downloadUrl)
}
}
}.await()
}catch (e: Exception){
e.printStackTrace()
withContext(Dispatchers.Main){
hideLoading()
}
}
val product = Product(
UUID.randomUUID().toString(),
name,
category,
price.toFloat(),
if(offerPercentage.isEmpty()) null else offerPercentage.toFloat(),
if(description.isEmpty()) null else description,
if (selectedColors.isEmpty()) null else selectedColors,
sizes,
images,
)
firestore.collection("Products").add(product).addOnSuccessListener {
hideLoading()
} .addOnFailureListener{
hideLoading()
Log.e("Error", it.message.toString())
}
}
}
private fun hideLoading() {
binding.progressbar.visibility = View.INVISIBLE
}
private fun showLoading() {
binding.progressbar.visibility = View.VISIBLE
}
private fun getImagesByteArrays(): List<ByteArray>{
val imagesByteArray = mutableListOf<ByteArray>()
selectedImages.forEach{
val stream = ByteArrayOutputStream()
val imageBmp = MediaStore.Images.Media.getBitmap(contentResolver,it)
if (imageBmp.compress(Bitmap.CompressFormat.JPEG,100,stream)){
imagesByteArray.add(stream.toByteArray())
}
}
return imagesByteArray
}
private fun getSizesList(sizesStr:String): List<String>? {
if (sizesStr.isEmpty())
return null
val sizesList = sizesStr.split(",")
return sizesList
}
private fun validateInformation(): Boolean{
if(binding.edPrice.text.toString().trim().isEmpty())
return false
if(binding.edName.text.toString().trim().isEmpty())
return false
if(binding.edCategory.text.toString().trim().isEmpty())
return false
if (selectedImages.isEmpty())
return false
return true
}
}
This is the error i get
E/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-1
Process: com.example.productsadder, PID: 20855
com.google.firebase.storage.StorageException: Object does not exist at location.
at com.google.firebase.storage.UploadTask.snapStateImpl(UploadTask.java:573)
at com.google.firebase.storage.UploadTask.snapStateImpl(UploadTask.java:57)
at com.google.firebase.storage.StorageTask.snapState(StorageTask.java:343)
at com.google.firebase.storage.StorageTask.getFinalResult(StorageTask.java:453)
at com.google.firebase.storage.StorageTask.getException(StorageTask.java:313)
at kotlinx.coroutines.tasks.TasksKt$awaitImpl$2$1.onComplete(Tasks.kt:142)
at com.google.firebase.storage.StorageTask.lambda$new$2$com-google-firebase-storage-StorageTask(StorageTask.java:143)
at com.google.firebase.storage.StorageTask$$ExternalSyntheticLambda11.raise(Unknown Source:6)
at com.google.firebase.storage.TaskListenerImpl.lambda$onInternalStateChanged$2$com-google-firebase-storage-TaskListenerImpl(TaskListenerImpl.java:90)
at com.google.firebase.storage.TaskListenerImpl$$ExternalSyntheticLambda0.run(Unknown Source:6)
at kotlinx.coroutines.tasks.DirectExecutor.execute(Tasks.kt:164)
at com.google.firebase.storage.internal.SmartHandler.callBack(SmartHandler.java:70)
at com.google.firebase.storage.TaskListenerImpl.onInternalStateChanged(TaskListenerImpl.java:90)
at com.google.firebase.storage.StorageTask.tryChangeState(StorageTask.java:392)
at com.google.firebase.storage.StorageTask.tryChangeState(StorageTask.java:426)
at com.google.firebase.storage.UploadTask.serverStateValid(UploadTask.java:361)
at com.google.firebase.storage.UploadTask.shouldContinue(UploadTask.java:324)
at com.google.firebase.storage.UploadTask.run(UploadTask.java:245)
at com.google.firebase.storage.StorageTask.lambda$getRunnable$7$com-google-firebase-storage-StorageTask(StorageTask.java:1072)
at com.google.firebase.storage.StorageTask$$ExternalSyntheticLambda7.run(Unknown Source:2)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
at java.lang.Thread.run(Thread.java:1012)
Suppressed: com.google.firebase.storage.StorageException: Object does not exist at location.
... 23 more
Caused by: java.io.IOException: The server has terminated the upload session
at com.google.firebase.storage.UploadTask.serverStateValid(UploadTask.java:358)
... 7 more
Caused by: java.io.IOException: { "error": { "code": 404, "message": "Not Found." }}
at com.google.firebase.storage.network.NetworkRequest.parseResponse(NetworkRequest.java:445)
at com.google.firebase.storage.network.NetworkRequest.parseErrorResponse(NetworkRequest.java:462)
at com.google.firebase.storage.network.NetworkRequest.processResponseStream(NetworkRequest.java:453)
at com.google.firebase.storage.network.NetworkRequest.performRequest(NetworkRequest.java:272)
at com.google.firebase.storage.network.NetworkRequest.performRequest(NetworkRequest.java:289)
at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(ExponentialBackoffSender.java:76)
at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(ExponentialBackoffSender.java:68)
at com.google.firebase.storage.UploadTask.sendWithRetry(UploadTask.java:526)
at com.google.firebase.storage.UploadTask.beginResumableUpload(UploadTask.java:292)
at com.google.firebase.storage.UploadTask.run(UploadTask.java:240)
... 5 more
Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [StandaloneCoroutine{Cancelling}#edc0c51, Dispatchers.IO]
Caused by: java.io.IOException: The server has terminated the upload session
at com.google.firebase.storage.UploadTask.serverStateValid(UploadTask.java:358)
... 7 more
Caused by: java.io.IOException: { "error": { "code": 404, "message": "Not Found." }}
E/AndroidRuntime: at com.google.firebase.storage.network.NetworkRequest.parseResponse(NetworkRequest.java:445)
at com.google.firebase.storage.network.NetworkRequest.parseErrorResponse(NetworkRequest.java:462)
at com.google.firebase.storage.network.NetworkRequest.processResponseStream(NetworkRequest.java:453)
at com.google.firebase.storage.network.NetworkRequest.performRequest(NetworkRequest.java:272)
at com.google.firebase.storage.network.NetworkRequest.performRequest(NetworkRequest.java:289)
at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(ExponentialBackoffSender.java:76)
at com.google.firebase.storage.internal.ExponentialBackoffSender.sendWithExponentialBackoff(ExponentialBackoffSender.java:68)
at com.google.firebase.storage.UploadTask.sendWithRetry(UploadTask.java:526)
at com.google.firebase.storage.UploadTask.beginResumableUpload(UploadTask.java:292)
at com.google.firebase.storage.UploadTask.run(UploadTask.java:240)
... 5 more

Related

How to set the visibility GONE after the download was successful, and visibility still VISIBLE if download was unsuccessful?

I am making a studymaterial app, where i want to add a functionality where - when a user download a particular chapter from recyclerview and after the successful download of that item the Download button visivity should make GONE of that item at that time.
I have implemented a method to do thisd but it only works when user finish the activity and come back again on that activity then the download button automatic not showing, but i want to implement at that point of time when user download something.
Here is my DownloadHandler.kt class
package com.tworoot2.class9thhistoryncert.downloadHandler
import android.app.AlertDialog
import android.app.ProgressDialog
import android.content.Context
import android.content.Intent
import android.widget.Toast
import com.downloader.*
import com.tworoot2.class9thhistoryncert.DownloadedFiles
import java.io.File
import com.tworoot2.class9thhistoryncert.R
class DownloadHandler {
lateinit var alertDialog: AlertDialog.Builder
lateinit var failed: AlertDialog.Builder
var progressDialog: ProgressDialog? = null
var fileDestination: File? = null
var down: Boolean = false
fun downloadFile(url: String?, fileName: String, context: Context, filePath: File): Boolean {
progressDialog = ProgressDialog(context)
progressDialog!!.setMessage("Downloading....")
progressDialog!!.setCancelable(false)
progressDialog!!.max = 100
progressDialog!!.setProgressStyle(ProgressDialog.STYLE_SPINNER)
progressDialog!!.show()
alertDialog = AlertDialog.Builder(context)
alertDialog.setTitle("Downloaded successfully")
alertDialog.setMessage("$fileName is downloaded successfully")
alertDialog.setIcon(R.drawable.check)
alertDialog.setPositiveButton(
"Open"
) { _, i ->
val intent = Intent(context, DownloadedFiles::class.java)
context.startActivity(intent)
}
failed = AlertDialog.Builder(context)
failed.setTitle("Downloading failed")
failed.setMessage("Your file is not downloaded successfully")
failed.setIcon(R.drawable.failed)
PRDownloader.download(url, filePath.path, fileName)
.build()
.setOnStartOrResumeListener { }
.setOnPauseListener { }
.setOnCancelListener { }
.setOnProgressListener { progress ->
val per = progress.currentBytes * 100 / progress.totalBytes
progressDialog!!.setMessage("Downloading : $per %")
}
.start(object : OnDownloadListener {
override fun onDownloadComplete() {
down = true
Toast.makeText(context, "Download completed ", Toast.LENGTH_SHORT).show()
progressDialog!!.dismiss()
alertDialog.show()
}
override fun onError(error: Error) {
down = false
Toast.makeText(context, "Something went wrong", Toast.LENGTH_SHORT).show()
failed.show()
progressDialog!!.dismiss()
}
})
return down
}
}
Adapter Class
package com.tworoot2.class9thhistoryncert.adapters
import android.content.Context
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.tworoot2.class9thhistoryncert.Interface.OnPDFSelectListener
import com.tworoot2.class9thhistoryncert.Interface.PDFDownloadListner
import com.tworoot2.class9thhistoryncert.PDFActivity
import com.tworoot2.class9thhistoryncert.R
import com.tworoot2.class9thhistoryncert.models.StudyMaterials
import java.io.File
import java.lang.String
import kotlin.Int
class MaterialsAdapter(
var context: Context,
var arrayList: List<StudyMaterials>,
var listener: PDFDownloadListner,
var pdfSelectListener: OnPDFSelectListener,
var folderLocations: File
) :
RecyclerView.Adapter<MaterialsAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.custom_materials, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.subjectHead.text = arrayList[position].chNo
holder.subjectName.text = arrayList[position].Title
val file =
File(
"$folderLocations/" + String.valueOf(
"Ch-" + arrayList[position].chNo + ". "
+ arrayList[position].Title + " [twoRoot2]" + ".pdf"
)
)
if (file.exists()) {
holder.downloadBtn.visibility = View.GONE
}
holder.itemView.setOnClickListener {
if (file.exists()) {
pdfSelectListener.onPDFSelected(file)
} else {
val intent = Intent(holder.itemView.context, PDFActivity::class.java)
intent.putExtra("link", arrayList[position].Link)
intent.putExtra("flag", "y")
intent.putExtra("title", arrayList[position].Title)
intent.putExtra("chNo", arrayList[position].chNo)
it.context.startActivity(intent)
}
}
holder.downloadBtn.setOnClickListener {
val downloaded = listener.onDownload(
arrayList[position].Link,
String.valueOf("Ch-" + arrayList[position].chNo)
.toString() + ". " + arrayList[position].Title
)
}
}
override fun getItemCount(): Int {
return arrayList.size
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val subjectName = itemView.findViewById<TextView>(R.id.subjectName);
val subjectHead = itemView.findViewById<TextView>(R.id.subjectHead);
val downloadBtn = itemView.findViewById<LinearLayout>(R.id.downloadBtn);
}
}
Activity Class
package com.tworoot2.class9thhistoryncert
import android.app.ProgressDialog
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.os.Environment
import android.view.MenuItem
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.tworoot2.class9thhistoryncert.Interface.OnPDFSelectListener
import com.tworoot2.class9thhistoryncert.Interface.PDFDownloadListner
import com.tworoot2.class9thhistoryncert.adapters.MaterialsAdapter
import com.tworoot2.class9thhistoryncert.application.MyApplicationClass
import com.tworoot2.class9thhistoryncert.downloadHandler.DownloadHandler
import com.tworoot2.class9thhistoryncert.viewModels.MainViewModel
import com.tworoot2.class9thhistoryncert.viewModels.MainViewModelFactory
import com.tworoot2.result10th_12th.Internetconnection.NetworkUtils
import java.io.File
class MaterialsActivity : AppCompatActivity(), PDFDownloadListner, OnPDFSelectListener {
lateinit var recyclerView: RecyclerView
lateinit var mainViewModel: MainViewModel
lateinit var file: File
lateinit var fileDestination: File
lateinit var downloadHandler: DownloadHandler
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_materials)
supportActionBar!!.setDisplayHomeAsUpEnabled(true)
supportActionBar!!.setDisplayShowHomeEnabled(true)
recyclerView = findViewById(R.id.recView)
recyclerView.layoutManager = LinearLayoutManager(this)
// download listener
downloadHandler = DownloadHandler()
file = File(getExternalFilesDir(null).toString() + "/" + "Class")
fileDestination = File(Environment.getExternalStorageDirectory(), "/Class")
if (!fileDestination.exists()) {
fileDestination.mkdirs()
}
if (!NetworkUtils.isInternetAvailable(this#MaterialsActivity)) {
Toast.makeText(this#MaterialsActivity, "No internet connection", Toast.LENGTH_SHORT)
.show()
}
val progressDialog = ProgressDialog(this)
progressDialog.setMessage("Loading....")
progressDialog.setCancelable(false)
progressDialog.show()
val medium = intent.getStringExtra("medium")
val repository = (application as MyApplicationClass).materialsRepo
mainViewModel =
ViewModelProvider(this, MainViewModelFactory(repository))[MainViewModel::class.java]
if (medium.equals("h")) {
mainViewModel.hisHinLiveData.observe(this) {
this#MaterialsActivity.runOnUiThread(java.lang.Runnable {
val adapter =
MaterialsAdapter(
this#MaterialsActivity, it!!.studyMaterialCS,
this, this, file
)
progressDialog.dismiss()
recyclerView.adapter = adapter
})
}
} else if (medium.equals("e")) {
mainViewModel.hisEngLiveData.observe(this) {
this#MaterialsActivity.runOnUiThread(java.lang.Runnable {
val adapter =
MaterialsAdapter(
this#MaterialsActivity, it!!.studyMaterialCS,
this, this, file
)
progressDialog.dismiss()
recyclerView.adapter = adapter
})
}
} else {
Toast.makeText(this#MaterialsActivity, "Everything is invalid", Toast.LENGTH_SHORT)
.show()
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
android.R.id.home -> {
finish()
return true
}
}
return super.onOptionsItemSelected(item)
}
override fun onDownload(url: String?, title: String?) {
val time = System.currentTimeMillis().toString()
val shortTime = time.substring(8, 12)
val fileName = "$title [twoRoot2]"
// downloadFile(url, fileName + ".pdf");
// downloadFile(url, fileName + ".pdf");
Toast.makeText(applicationContext, "Downloading....", Toast.LENGTH_SHORT).show()
val downloaded =
downloadHandler.downloadFile(url, "$fileName.pdf", this#MaterialsActivity, file)
// Toast.makeText(applicationContext, "D...." + downloaded, Toast.LENGTH_SHORT).show()
}
override fun onPDFSelected(file: File?) {
val intent = Intent(this#MaterialsActivity, PDFActivity::class.java)
intent.putExtra("path", file!!.absolutePath)
intent.putExtra("flag", "n")
startActivity(intent)
}
override fun onDelete(file: File?, position: Int) {
TODO("Not yet implemented")
}
override fun inExternalApp(file: File?, context: Context?) {
TODO("Not yet implemented")
}
}
Repository Class
package com.tworoot2.class9thhistoryncert.repository
import android.content.Context
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.tworoot2.class9thhistoryncert.api.MaterialsService
import com.tworoot2.class9thhistoryncert.models.MaterialsElist
import com.tworoot2.class9thhistoryncert.models.MaterialsList
import com.tworoot2.result10th_12th.Internetconnection.NetworkUtils
class MaterialsRepo(private val service: MaterialsService, private val context: Context) {
private val hisHinMutableLiveData = MutableLiveData<MaterialsList>()
private val hisEngMutableLiveData = MutableLiveData<MaterialsList>()
val hisHinLiveData: LiveData<MaterialsList>
get() = hisHinMutableLiveData
val hisEngLiveData: LiveData<MaterialsList>
get() = hisEngMutableLiveData
suspend fun getHisHindi() {
if (NetworkUtils.isInternetAvailable(context)) {
val result = service.getHistoryHindiFromAPI()
if (result.body() != null) {
hisHinMutableLiveData.postValue(result.body())
}
} else {
Log.e("InternetError", "No Internet Connection")
}
}
suspend fun getHisEnglish() {
if (NetworkUtils.isInternetAvailable(context)) {
val result = service.getHistoryEnglishFromAPI()
if (result.body() != null) {
hisEngMutableLiveData.postValue(result.body())
}
}else{
Log.e("InternetError", "No Internet Connection")
}
}
}
[Screen Shot 1]
[Screen Shot 2]
Maybe you want to use LiveData to handle realtime update UI for your case. After download thread run completed, let observer call update item in recyclerview.
Hope it help!

Profile Pic not displaying on Card View in Andorid Studio Kotlin

I am trying to get a users profile pic to be displayed beside their booking on a card in my recyclerview. The profile pic is displaying in my nav drawer, a default one for non-google users, or the profile pic of the Google user. However imageUri appears empty when I call it and the images are not being stored in my firebase storage bucket. I have linked my firebase and implemented the relevant SDK.
Here is my model.
#Parcelize
data class BookModel(
// var id : Long = 0,
var uid: String? = "",
var name: String = "N/A",
var phoneNumber: String = "N/A",
var email: String? = "N/A",
var date: String = "",
var bike: Int = 0,
var profilepic: String = "",
/*var lat: Double = 0.0,
var longitude: Double = 0.0,
var zoom: Float = 0f,*/
var pickup: String = "",
var dropoff: String = "",
var price: Double = 20.0,
/*var amount: Int = 0*/
) : Parcelable
{
#Exclude
fun toMap(): Map<String, Any?> {
return mapOf(
// "id" to id,
"uid" to uid,
"name" to name,
"phoneNumber" to phoneNumber,
"email" to email,
"date" to date,
"bike" to bike,
"profilepic" to profilepic,
"pickup" to pickup,
"dropoff" to dropoff,
"price" to price
)
}
}
#Parcelize
data class Location(
var lat: Double = 0.0,
var longitude: Double = 0.0,
var zoom: Float = 0f,
var depot: String = "Waterford"
) : Parcelable
Here is my FirebaseImageManager
package com.wit.mad2bikeshop.firebase
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.net.Uri
import android.widget.ImageView
import androidx.lifecycle.MutableLiveData
import com.google.firebase.storage.FirebaseStorage
import com.google.firebase.storage.UploadTask
import com.squareup.picasso.MemoryPolicy
import com.squareup.picasso.Picasso
import com.wit.mad2bikeshop.utils.customTransformation
import timber.log.Timber
import java.io.ByteArrayOutputStream
import com.squareup.picasso.Target
object FirebaseImageManager {
var storage = FirebaseStorage.getInstance().reference
var imageUri = MutableLiveData<Uri>()
fun checkStorageForExistingProfilePic(userid: String) {
val imageRef = storage.child("photos").child("${userid}.jpg")
val defaultImageRef = storage.child("ic_book_nav_header.png")
imageRef.metadata.addOnSuccessListener { //File Exists
imageRef.downloadUrl.addOnCompleteListener { task ->
imageUri.value = task.result!!
}
//File Doesn't Exist
}.addOnFailureListener {
imageUri.value = Uri.EMPTY
}
}
fun uploadImageToFirebase(userid: String, bitmap: Bitmap, updating : Boolean) {
// Get the data from an ImageView as bytes
val imageRef = storage.child("photos").child("${userid}.jpg")
//val bitmap = (imageView as BitmapDrawable).bitmap
val baos = ByteArrayOutputStream()
lateinit var uploadTask: UploadTask
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos)
val data = baos.toByteArray()
imageRef.metadata.addOnSuccessListener { //File Exists
if(updating) // Update existing Image
{
uploadTask = imageRef.putBytes(data)
uploadTask.addOnSuccessListener { ut ->
ut.metadata!!.reference!!.downloadUrl.addOnCompleteListener { task ->
imageUri.value = task.result!!
}
}
}
}.addOnFailureListener { //File Doesn't Exist
uploadTask = imageRef.putBytes(data)
uploadTask.addOnSuccessListener { ut ->
ut.metadata!!.reference!!.downloadUrl.addOnCompleteListener { task ->
imageUri.value = task.result!!
}
}
}
}
fun updateUserImage(userid: String, imageUri : Uri?, imageView: ImageView, updating : Boolean) {
Picasso.get().load(imageUri)
.resize(200, 200)
.transform(customTransformation())
.memoryPolicy(MemoryPolicy.NO_CACHE)
.centerCrop()
.into(object : Target {
override fun onBitmapLoaded(bitmap: Bitmap?,
from: Picasso.LoadedFrom?
) {
Timber.i("DX onBitmapLoaded $bitmap")
uploadImageToFirebase(userid, bitmap!!,updating)
imageView.setImageBitmap(bitmap)
}
override fun onBitmapFailed(e: java.lang.Exception?,
errorDrawable: Drawable?) {
Timber.i("DX onBitmapFailed $e")
}
override fun onPrepareLoad(placeHolderDrawable: Drawable?) {}
})
}
fun updateDefaultImage(userid: String, resource: Int, imageView: ImageView) {
Picasso.get().load(resource)
.into(object : Target {
override fun onBitmapLoaded(bitmap: Bitmap?,
from: Picasso.LoadedFrom?
) {
Timber.i("DX onBitmapLoaded $bitmap")
uploadImageToFirebase(userid, bitmap!!,false)
imageView.setImageBitmap(bitmap)
}
override fun onBitmapFailed(e: java.lang.Exception?,
errorDrawable: Drawable?) {
Timber.i("DX onBitmapFailed $e")
}
override fun onPrepareLoad(placeHolderDrawable: Drawable?) {}
})
}
}
My FirebaseAuthManager...
package com.wit.mad2bikeshop.firebase
import android.app.Application
import androidx.lifecycle.MutableLiveData
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
import com.google.android.gms.auth.api.signin.GoogleSignInClient
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import com.google.firebase.auth.GoogleAuthProvider
import com.wit.mad2bikeshop.R
import timber.log.Timber
class FirebaseAuthManager(application: Application) {
private var application: Application? = null
var firebaseAuth: FirebaseAuth? = null
var liveFirebaseUser = MutableLiveData<FirebaseUser>()
var loggedOut = MutableLiveData<Boolean>()
var errorStatus = MutableLiveData<Boolean>()
var googleSignInClient = MutableLiveData<GoogleSignInClient>()
init {
this.application = application
firebaseAuth = FirebaseAuth.getInstance()
if (firebaseAuth!!.currentUser != null) {
liveFirebaseUser.postValue(firebaseAuth!!.currentUser)
loggedOut.postValue(false)
errorStatus.postValue(false)
FirebaseImageManager.checkStorageForExistingProfilePic(
firebaseAuth!!.currentUser!!.uid)
}
configureGoogleSignIn()
}
fun login(email: String?, password: String?) {
firebaseAuth!!.signInWithEmailAndPassword(email!!, password!!)
.addOnCompleteListener(application!!.mainExecutor, { task ->
if (task.isSuccessful) {
liveFirebaseUser.postValue(firebaseAuth!!.currentUser)
errorStatus.postValue(false)
} else {
Timber.i("Login Failure: $task.exception!!.message")
errorStatus.postValue(true)
}
})
}
fun register(email: String?, password: String?) {
firebaseAuth!!.createUserWithEmailAndPassword(email!!, password!!)
.addOnCompleteListener(application!!.mainExecutor, { task ->
if (task.isSuccessful) {
liveFirebaseUser.postValue(firebaseAuth!!.currentUser)
errorStatus.postValue(false)
} else {
Timber.i("Registration Failure: $task.exception!!.message")
errorStatus.postValue(true)
}
})
}
fun logOut() {
firebaseAuth!!.signOut()
Timber.i( "firebaseAuth Signed out")
googleSignInClient.value!!.signOut()
Timber.i( "googleSignInClient Signed out")
loggedOut.postValue(true)
errorStatus.postValue(false)
}
private fun configureGoogleSignIn() {
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(application!!.getString(R.string.default_web_client_id))
.requestEmail()
.build()
googleSignInClient.value = GoogleSignIn.getClient(application!!.applicationContext,gso)
}
fun firebaseAuthWithGoogle(acct: GoogleSignInAccount) {
Timber.i( "DonationX firebaseAuthWithGoogle:" + acct.id!!)
val credential = GoogleAuthProvider.getCredential(acct.idToken, null)
firebaseAuth!!.signInWithCredential(credential)
.addOnCompleteListener(application!!.mainExecutor) { task ->
if (task.isSuccessful) {
// Sign in success, update with the signed-in user's information
Timber.i( "signInWithCredential:success")
liveFirebaseUser.postValue(firebaseAuth!!.currentUser)
} else {
// If sign in fails, display a message to the user.
Timber.i( "signInWithCredential:failure $task.exception")
errorStatus.postValue(true)
}
}
}
}
My Home activity
package com.wit.mad2bikeshop.ui.home
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.MenuItem
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import androidx.drawerlayout.widget.DrawerLayout
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.findNavController
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.*
import com.google.firebase.auth.FirebaseUser
import com.squareup.picasso.Picasso
import com.wit.mad2bikeshop.R
import com.wit.mad2bikeshop.databinding.HomeBinding
import com.wit.mad2bikeshop.databinding.NavHeaderBinding
import com.wit.mad2bikeshop.firebase.FirebaseImageManager
import com.wit.mad2bikeshop.ui.auth.LoggedInViewModel
import com.wit.mad2bikeshop.ui.auth.Login
import com.wit.mad2bikeshop.utils.customTransformation
import timber.log.Timber
class Home : AppCompatActivity() {
private lateinit var drawerLayout: DrawerLayout
private lateinit var homeBinding: HomeBinding
private lateinit var navHeaderBinding: NavHeaderBinding
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var loggedInViewModel: LoggedInViewModel
private lateinit var headerView : View
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
homeBinding = HomeBinding.inflate(layoutInflater)
setContentView(homeBinding.root)
drawerLayout = homeBinding.drawerLayout
val toolbar = findViewById<Toolbar>(R.id.toolbar)
setSupportActionBar(toolbar)
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
val navController = navHostFragment.navController
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
appBarConfiguration = AppBarConfiguration(
setOf(
R.id.bookFragment, R.id.bookingListFragment
), drawerLayout
)
setupActionBarWithNavController(navController, appBarConfiguration)
val navView = homeBinding.navView
navView.setupWithNavController(navController)
initNavHeader()
}
public override fun onStart() {
super.onStart()
loggedInViewModel = ViewModelProvider(this).get(LoggedInViewModel::class.java)
loggedInViewModel.liveFirebaseUser.observe(this, Observer { firebaseUser ->
if (firebaseUser != null)
updateNavHeader(firebaseUser)
})
loggedInViewModel.loggedOut.observe(this, Observer { loggedout ->
if (loggedout) {
startActivity(Intent(this, Login::class.java))
}
})
}
private fun initNavHeader() {
Timber.i("DX Init Nav Header")
headerView = homeBinding.navView.getHeaderView(0)
navHeaderBinding = NavHeaderBinding.bind(headerView)
}
private fun updateNavHeader(currentUser: FirebaseUser) {
FirebaseImageManager.imageUri.observe(this, { result ->
if(result == Uri.EMPTY) {
Timber.i("DX NO Existing imageUri")
if (currentUser.photoUrl != null) {
//if you're a google user
FirebaseImageManager.updateUserImage(
currentUser.uid,
currentUser.photoUrl,
navHeaderBinding.navHeaderImage,
false)
}
else
{
Timber.i("DX Loading Existing Default imageUri")
FirebaseImageManager.updateDefaultImage(
currentUser.uid,
R.drawable.ic_book_nav_header,
navHeaderBinding.navHeaderImage)
}
}
else // load existing image from firebase
{
Timber.i("DX Loading Existing imageUri")
FirebaseImageManager.updateUserImage(
currentUser.uid,
FirebaseImageManager.imageUri.value,
navHeaderBinding.navHeaderImage, false)
}
})
navHeaderBinding.navHeaderEmail.text = currentUser.email
if(currentUser.displayName != null)
navHeaderBinding.navHeaderName.text = currentUser.displayName
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment)
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
fun signOut(item: MenuItem) {
loggedInViewModel.logOut()
//Launch Login activity and clear the back stack to stop navigating back to the Home activity
val intent = Intent(this, Login::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)
}
}
My BookViewModel
package com.wit.mad2bikeshop.ui.book
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.google.firebase.auth.FirebaseUser
import com.wit.mad2bikeshop.firebase.FirebaseDBManager
import com.wit.mad2bikeshop.firebase.FirebaseImageManager
import com.wit.mad2bikeshop.model.BookManager
import com.wit.mad2bikeshop.model.BookModel
class BookViewModel : ViewModel() {
private val status = MutableLiveData<Boolean>()
val observableStatus: LiveData<Boolean>
get() = status
fun addBook(firebaseUser: MutableLiveData<FirebaseUser>,
booking: BookModel) {
status.value = try {
booking.profilepic = FirebaseImageManager.imageUri.value.toString()
FirebaseDBManager.create(firebaseUser,booking)
true
} catch (e: IllegalArgumentException) {
false
}
}
// fun updateBook(booking: BookModel){
// status.value = try {
// BookManager.update(booking)
// true
// } catch (e: IllegalArgumentException) {
// false
// }
// }
}
My BookAdapter
package com.wit.mad2bikeshop.adapters
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.net.toUri
import androidx.recyclerview.widget.RecyclerView
import com.squareup.picasso.MemoryPolicy
import com.squareup.picasso.Picasso
import com.wit.mad2bikeshop.R
import com.wit.mad2bikeshop.databinding.CardBookBinding
import com.wit.mad2bikeshop.model.BookModel
import com.wit.mad2bikeshop.utils.customTransformation
interface BookListener {
// fun onDeleteBooking(booking: BookModel)
// fun onUpdateBooking(booking: BookModel)
fun onBookingClick(booking: BookModel)
}
class BookAdapter constructor(
private var bookings: ArrayList<BookModel>,
private val listener: BookListener,
private val readOnly: Boolean)
: RecyclerView.Adapter<BookAdapter.MainHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MainHolder {
val binding = CardBookBinding
.inflate(LayoutInflater.from(parent.context), parent, false)
return MainHolder(binding, readOnly)
}
override fun onBindViewHolder(holder: MainHolder, position: Int) {
val booking = bookings[holder.adapterPosition]
holder.bind(booking, listener)
}
fun removeAt(position: Int) {
bookings.removeAt(position)
notifyItemRemoved(position)
}
override fun getItemCount(): Int = bookings.size
inner class MainHolder(val binding: CardBookBinding,private val readOnly : Boolean) :
RecyclerView.ViewHolder(binding.root) {
val readOnlyRow = readOnly
fun bind(booking: BookModel, listener: BookListener) {
binding.root.tag = booking
binding.booking = booking
binding.imageIcon.setImageResource(R.mipmap.ic_launcher_round)
Picasso.get().load(booking.profilepic.toUri())
.resize(200, 200)
.transform(customTransformation())
.centerCrop()
.into(binding.imageIcon)
//
// binding.name.text = booking.name
// binding.phoneNumber.text = booking.phoneNumber
// binding.date.text = booking.date
binding.root.setOnClickListener { listener.onBookingClick(booking) }
// binding.buttonDelete.setOnClickListener { listener.onDeleteBooking(booking) }
// binding.buttonUpdate.setOnClickListener { listener.onUpdateBooking(booking) }
binding.executePendingBindings()
/* binding.imageIcon.setImageResource(R.mipmap.ic_launcher_round)*/
}
}
}
I believe the problem stems from the (FirebaseImageManager.imageUri.value.toString()) on my BookAdapter, as if I run a Timber.I statement it doesn't return anything at all. If I run Timber.i(FirebaseImageManager.imageUri.value.toString()+ "test"), it only returns test.
Here is a link to the full project https://github.com/foxxxxxxx7/MAD2bikeshop
Apologies if I wasn't clear enough, I am a novice.
I figured it out, I had to modify my rules on the firebase storage.

How to share bitmap from secoend activity to first activity

i m new to kotlin and i am trying to send bitmap. like i in recyclerview card i add an image and after that i have to edit the card so for that how can i send the bitmap there can anyone please help me in this. Thanks in advance.
here is my code:
MainActivity.kt:-
package com.example.itemgetset
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.os.Handler
import android.os.Message
import android.util.Log
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.Button
import android.widget.LinearLayout
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
#Suppress("DEPRECATION")
class MainActivity : AppCompatActivity() {
lateinit var activity: Activity
val userList = ArrayList<ProductInfoGetSet>()
private lateinit var btnProductAdd: Button
lateinit var llEmptyView: LinearLayout
lateinit var llMain: LinearLayout
lateinit var recyclerView: RecyclerView
private lateinit var llFab: LinearLayout
private lateinit var linearLayoutManager: LinearLayoutManager
private lateinit var gridLayoutManager: GridLayoutManager
private lateinit var adapter: CustomAdapter
companion object {
var handler: Handler = Handler()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
activity = this
initView()
onClicks()
setUpData()
handler = #SuppressLint("HandlerLeak")
object : Handler() {
override fun handleMessage(msg: Message) {
if (msg.what == 111) {
val temp: Temp = msg.obj as Temp
if (temp.id == "") {
userList.add(
ProductInfoGetSet(
(userList.size + 1).toString(),
temp.image,
temp.name,
temp.quantity,
temp.price,
temp.total
)
)
adapter = CustomAdapter(activity, userList)
recyclerView.adapter = adapter
} else {
for (i in userList.indices) {
if (userList[i].id == temp.id) {
userList[i].id = temp.id
userList[i].image = temp.image
userList[i].name = temp.name
userList[i].quantity = temp.quantity
userList[i].price = temp.price
userList[i].total = temp.total
}
}
adapter.notifyDataSetChanged()
}
}
if (userList.size > 0) {
llEmptyView.visibility = View.GONE
llMain.visibility = View.VISIBLE
} else {
llEmptyView.visibility = View.VISIBLE
llMain.visibility = View.GONE
}
}
}
}
private fun changeLayoutManager() {
if (recyclerView.layoutManager == linearLayoutManager) {
recyclerView.layoutManager = gridLayoutManager
} else {
recyclerView.layoutManager = linearLayoutManager
}
}
override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
if (hasFocus) Toast.makeText(applicationContext, "Phone Rotated", Toast.LENGTH_SHORT).show()
}
private fun initView() {
btnProductAdd = findViewById(R.id.btn_product_add)
llFab = findViewById(R.id.ll_fab)
llEmptyView = findViewById(R.id.llEmptyView)
llMain = findViewById(R.id.llMain)
recyclerView = findViewById(R.id.recycler_view)
recyclerView.layoutManager = LinearLayoutManager(this)
linearLayoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
gridLayoutManager = GridLayoutManager(this, 2)
}
private fun onClicks() {
btnProductAdd.setOnClickListener {
val intent = Intent(this#MainActivity, AddDetails::class.java)
intent.putExtra("isFor", "Add")
startActivity(intent)
}
llFab.setOnClickListener {
val intent = Intent(this#MainActivity, AddDetails::class.java)
intent.putExtra("isFor", "Add")
startActivity(intent)
}
}
private fun setUpData() {
if (userList.size > 0) {
llEmptyView.visibility = View.GONE
llMain.visibility = View.VISIBLE
} else {
llEmptyView.visibility = View.VISIBLE
llMain.visibility = View.GONE
}
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_main, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == R.id.menu_view) {
if (userList.size > 0) {
changeLayoutManager()
}
return true
}
return super.onOptionsItemSelected(item)
}
}
CustomeAdapter.kt: -
package com.example.itemgetset
import android.R.attr.bitmap
import android.app.Activity
import android.app.AlertDialog
import android.content.ContentValues.TAG
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.Bitmap.CompressFormat
import android.os.Build
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.PopupMenu
import android.widget.TextView
import androidx.annotation.RequiresApi
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.snackbar.Snackbar
import java.io.ByteArrayOutputStream
#Suppress("UNREACHABLE_CODE")
class CustomAdapter(
private var activity: Activity,
private val userList: ArrayList<ProductInfoGetSet>,
) :
RecyclerView.Adapter<CustomAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val itemview =
LayoutInflater.from(parent.context).inflate(R.layout.list_layout, parent, false)
return ViewHolder(itemview)
}
#RequiresApi(Build.VERSION_CODES.N)
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val productInfoGetSet: ProductInfoGetSet = userList[position]
holder.txtId.text = productInfoGetSet.id
holder.txtName.text = productInfoGetSet.name
holder.txtQuantity.text = productInfoGetSet.quantity
holder.txtPrice.text = productInfoGetSet.price
holder.txtTotal.text = productInfoGetSet.total
holder.imgList.setImageBitmap(productInfoGetSet.image)
val id = userList[position].id
Log.e(TAG, "List item ID: $id")
holder.buttonViewOption.setOnClickListener {
val popup = PopupMenu(activity, holder.buttonViewOption)
popup.inflate(R.menu.pop_menu)
popup.setOnMenuItemClickListener { item ->
when (item.itemId) {
R.id.edit -> {
val intent = Intent(activity, AddDetails::class.java)
intent.putExtra("isFor", "Update")
val bStream = ByteArrayOutputStream()
productInfoGetSet.image?.compress(CompressFormat.PNG, 100, bStream)
val byteArray = bStream.toByteArray()
intent.putExtra("imagebitmap", byteArray)
intent.putExtra("id", productInfoGetSet.id)
intent.putExtra("name", productInfoGetSet.name)
intent.putExtra("quantity", productInfoGetSet.quantity)
intent.putExtra("price", productInfoGetSet.price)
intent.putExtra("total", productInfoGetSet.total)
activity.startActivity(intent)
}
R.id.delete -> {
val builder = AlertDialog.Builder(activity)
builder.setTitle("Delete")
builder.setMessage("Do you want to delete the item?")
builder.setPositiveButton("Yes") { _, _ ->
userList.removeAt(position)
notifyItemRemoved(position)
val snack = Snackbar
.make(
holder.linearly,
"Item was removed from the list.",
Snackbar.LENGTH_SHORT
)
snack.show()
}
builder.setNegativeButton("No") { _, _ ->
}
val dialog: AlertDialog = builder.create()
dialog.show()
}
}
false
}
popup.show()
}
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getItemCount(): Int {
return userList.size
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val txtName = itemView.findViewById(R.id.txt_name) as TextView
val txtId = itemView.findViewById(R.id.txt_id) as TextView
var imgList = itemView.findViewById(R.id.img_list) as ImageView
val txtQuantity = itemView.findViewById(R.id.txt_quantity) as TextView
val txtPrice = itemView.findViewById(R.id.txt_price) as TextView
val txtTotal = itemView.findViewById(R.id.txt_result1) as TextView
val linearly: LinearLayout = itemView.findViewById(R.id.linearlayout)
val buttonViewOption = itemView.findViewById<View>(R.id.txt_Options) as TextView
}
}
AddDetails:-
package com.example.itemgetset
import android.annotation.SuppressLint
import android.content.Intent
import android.content.pm.PackageManager
import android.database.Cursor
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Message
import android.provider.MediaStore
import android.text.Editable
import android.text.TextWatcher
import android.util.Log
import android.widget.*
import androidx.appcompat.app.AppCompatActivity
#Suppress("DEPRECATION")
class AddDetails : AppCompatActivity() {
private lateinit var btnSubmit: Button
private lateinit var edtName: EditText
private lateinit var img_add: ImageView
private var edtQuantity: EditText? = null
private var edtPrice: EditText? = null
private var txtResult: TextView? = null
private var txtTotal: TextView? = null
private var bitmap: Bitmap? = null
companion object {
private const val IMAGE_PICK_CODE = 1000
private const val PERMISSION_CODE = 1001
}
#SuppressLint("SetTextI18n", "ResourceType")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.add_item)
supportActionBar?.hide()
findViewById()
onclick()
edtPrice?.addTextChangedListener(priceWatcher)
edtQuantity?.addTextChangedListener(textWatcher)
if (intent.getStringExtra("isFor").equals("Update")) {
val byteArray = intent.getByteArrayExtra("imagebitmap")
bitmap = byteArray?.size?.let { BitmapFactory.decodeByteArray(byteArray, 0, it) }
img_add.setImageBitmap(bitmap)
edtName.setText(intent.getStringExtra("name"))
edtQuantity?.setText(intent.getStringExtra("quantity"))
edtPrice?.setText(intent.getStringExtra("price"))
}
}
private fun findViewById() {
btnSubmit = findViewById(R.id.btn_submit)
txtResult = findViewById(R.id.txt_result)
txtTotal = findViewById(R.id.txt_final)
edtName = findViewById(R.id.edt_name)
edtQuantity = findViewById(R.id.edt_quantity)
edtPrice = findViewById(R.id.edt_price)
img_add = findViewById(R.id.img_add)
}
#SuppressLint("ResourceType")
private fun onclick() {
btnSubmit.setOnClickListener {
when {
edtName.text.trim().isEmpty() -> {
edtName.error = "Please Enter Product Name"
Toast.makeText(
applicationContext,
"Please Enter Product Name",
Toast.LENGTH_SHORT
)
.show()
}
edtQuantity?.text?.trim()?.isEmpty()!! -> {
edtQuantity?.error = "Please Enter Product Quantity"
Toast.makeText(
applicationContext,
"Please Enter Product Quantity",
Toast.LENGTH_SHORT
).show()
}
edtPrice?.text?.trim()?.isEmpty()!! -> {
edtPrice?.error = "Please Enter Product Price"
Toast.makeText(
applicationContext,
"Please Enter Product Price",
Toast.LENGTH_SHORT
)
.show()
}
else -> {
Toast.makeText(
applicationContext,
"Product Added Successfully ",
Toast.LENGTH_SHORT
).show()
val temp = Temp()
temp.image = bitmap
temp.name = edtName.text.toString()
temp.quantity = edtQuantity?.text.toString()
temp.price = edtPrice?.text.toString()
temp.total = txtResult?.text.toString()
if (intent.getStringExtra("isFor").equals("Update")) {
temp.id = intent.getStringExtra("id").toString()
}
val message: Message = Message.obtain()
message.what = 111
message.obj = temp
MainActivity.handler.sendMessage(message)
finish()
}
}
}
img_add.setOnClickListener {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE) ==
PackageManager.PERMISSION_DENIED
) {
val permissions = arrayOf(android.Manifest.permission.READ_EXTERNAL_STORAGE)
requestPermissions(permissions, PERMISSION_CODE)
} else {
pickImageFromGallery()
}
} else {
pickImageFromGallery()
}
}
}
private val priceWatcher = object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
override fun afterTextChanged(s: Editable?) {
val num1: String = edtPrice?.text.toString()
val mnum1 = num1.toIntOrNull()
val num2: String = edtQuantity?.text.toString()
val mnum2 = num2.toIntOrNull()
val res = mnum2?.let { mnum1?.times(it) }
Log.e("<><> res1", res.toString())
txtResult?.text = res.toString()
}
}
private val textWatcher = object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
override fun afterTextChanged(s: Editable?) {
val num1: String = edtPrice?.text.toString()
val mnum1 = num1.toIntOrNull()
val num2: String = edtQuantity?.text.toString()
val mnum2 = num2.toIntOrNull()
val res = mnum2?.let { mnum1?.times(it) }
Log.e("<><> res1", res.toString())
txtResult?.text = res.toString()
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray,
) {
when (requestCode) {
PERMISSION_CODE -> {
if (grantResults.isNotEmpty() && grantResults[0] ==
PackageManager.PERMISSION_GRANTED
) {
pickImageFromGallery()
} else {
Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show()
}
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
private fun pickImageFromGallery() {
val intent = Intent(Intent.ACTION_PICK)
intent.type = "image/*"
startActivityForResult(intent, IMAGE_PICK_CODE)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == IMAGE_PICK_CODE && resultCode == RESULT_OK && data != null) {
img_add.setImageURI(data.data)
val pickedImage: Uri? = data.data
val filePath = arrayOf(MediaStore.Images.Media.DATA)
val cursor: Cursor? =
pickedImage?.let { contentResolver.query(it, filePath, null, null, null) }
cursor?.moveToFirst()
val imagePath: String = cursor!!.getString(cursor.getColumnIndex(filePath[0]))
val options = BitmapFactory.Options()
options.inPreferredConfig = Bitmap.Config.ARGB_8888
bitmap = BitmapFactory.decodeFile(imagePath, options)
cursor.close()
}
}
}
Logcat: -
2020-09-14 19:46:21.834 26263-26263/? E/mple.itemgetse: Unknown bits set in runtime_flags: 0x28000
2020-09-14 19:46:43.406 26263-26263/com.example.itemgetset E/<><> res1: null
2020-09-14 19:46:43.754 26263-26263/com.example.itemgetset E/<><> res1: null
2020-09-14 19:46:45.992 26263-26263/com.example.itemgetset E/<><> res1: 32
2020-09-14 19:46:47.908 26263-26263/com.example.itemgetset E/<><> res1: null
2020-09-14 19:46:48.491 26263-26263/com.example.itemgetset E/<><> res1: 64
2020-09-14 19:46:51.002 26263-26263/com.example.itemgetset E/ContentValues: List item ID: 1
2020-09-14 19:46:54.533 26263-26263/com.example.itemgetset E/ContentValues: List item ID: 1
2020-09-14 19:46:55.167 26263-26263/com.example.itemgetset E/ContentValues: List item ID: 1
2020-09-14 19:47:02.993 26263-26263/com.example.itemgetset E/JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 16777976)
2020-09-14 19:47:02.995 26263-26263/com.example.itemgetset E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.itemgetset, PID: 26263
java.lang.RuntimeException: Failure from system
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1904)
at android.app.Activity.startActivityForResult(Activity.java:5215)
at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:676)
at android.app.Activity.startActivityForResult(Activity.java:5173)
at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:663)
at android.app.Activity.startActivity(Activity.java:5544)
at android.app.Activity.startActivity(Activity.java:5512)
at com.example.itemgetset.CustomAdapter$onBindViewHolder$1$1.onMenuItemClick(CustomAdapter.kt:69)
at android.widget.PopupMenu$1.onMenuItemSelected(PopupMenu.java:108)
at com.android.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:787)
at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:151)
at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:934)
at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:924)
at com.android.internal.view.menu.MenuPopup.onItemClick(MenuPopup.java:128)
at android.widget.AdapterView.performItemClick(AdapterView.java:330)
at android.widget.AbsListView.performItemClick(AbsListView.java:1257)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3265)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7707)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
Caused by: android.os.TransactionTooLargeException: data parcel size 16777976 bytes
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(BinderProxy.java:557)
at android.app.IActivityTaskManager$Stub$Proxy.startActivity(IActivityTaskManager.java:3887)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1898)
at android.app.Activity.startActivityForResult(Activity.java:5215) 
at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:676) 
at android.app.Activity.startActivityForResult(Activity.java:5173) 
at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:663) 
at android.app.Activity.startActivity(Activity.java:5544) 
at android.app.Activity.startActivity(Activity.java:5512) 
at com.example.itemgetset.CustomAdapter$onBindViewHolder$1$1.onMenuItemClick(CustomAdapter.kt:69) 
at android.widget.PopupMenu$1.onMenuItemSelected(PopupMenu.java:108) 
at com.android.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:787) 
at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:151) 
at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:934) 
at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:924) 
at com.android.internal.view.menu.MenuPopup.onItemClick(MenuPopup.java:128) 
at android.widget.AdapterView.performItemClick(AdapterView.java:330) 
at android.widget.AbsListView.performItemClick(AbsListView.java:1257) 
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3265) 
at android.os.Handler.handleCallback(Handler.java:883) 
at android.os.Handler.dispatchMessage(Handler.java:100) 
at android.os.Looper.loop(Looper.java:214) 
at android.app.ActivityThread.main(ActivityThread.java:7707) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950) 
From Customadpate to adddetails i have to send the bitmap.
In onActivityResult you receive the picked image Uri, this can then be passed from one activity to the next by converting the Uri to a string then attaching it to the intent with .putExtra(), as seen below:
val intent = Intent(this, Activity::class.java)
intent.putExtra("Uri", imageUri)
startActivity(intent)
The information can then be received in the next activity by:
if (intent.getStringExtra("Uri") != null){
val uri = intent.getStringExtra("Uri")
}
The Uri will be in string form so all you have to do is convert it back to Uri form.
To convert bitmap to Uri , use the code below:
public Uri getImageUri(Context inContext, Bitmap inImage) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
return Uri.parse(path);
}

Android application(Kotlin) crashing with no issue in the code

The application crashes as soon as it is run to the emulator. The main code runs perfectly but when it comes to the implementation in the emulator, it runs and the app crashes. The error is shown below:
2020-07-20 14:05:48.662 9135-9135/com.sam.sabinomeals E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.sam.sabinomeals, PID: 9135
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.sam.sabinomeals/net.sam.sabinomeals.SplashActivity}: java.lang.ClassNotFoundException: Didn't find class "net.sam.sabinomeals.SplashActivity" on path: DexPathList[[zip file "/data/app/com.sam.sabinomeals-QJkZ4ORKUV6qLdDBZZ2Jvw==/base.apk"],nativeLibraryDirectories=[/data/app/com.sam.sabinomeals-QJkZ4ORKUV6qLdDBZZ2Jvw==/lib/x86, /system/lib, /system/product/lib]]
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3194)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: java.lang.ClassNotFoundException: Didn't find class "net.sam.sabinomeals.SplashActivity" on path: DexPathList[[zip file "/data/app/com.sam.sabinomeals-QJkZ4ORKUV6qLdDBZZ2Jvw==/base.apk"],nativeLibraryDirectories=[/data/app/com.sam.sabinomeals-QJkZ4ORKUV6qLdDBZZ2Jvw==/lib/x86, /system/lib, /system/product/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:196)
at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:95)
at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:45)
at android.app.Instrumentation.newActivity(Instrumentation.java:1243)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3182)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409) 
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83) 
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016) 
at android.os.Handler.dispatchMessage(Handler.java:107) 
at android.os.Looper.loop(Looper.java:214) 
at android.app.ActivityThread.main(ActivityThread.java:7356) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) 
The code below is for the splashactivity, it seems to be sure but I think you can still go through it.
package com.sam.sabinomeals
import android.Manifest
import android.app.DatePickerDialog
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.text.TextUtils
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.WindowManager
import android.view.animation.AnimationUtils
import android.widget.Toast
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.textfield.TextInputEditText
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.auth.FirebaseUser
import com.google.firebase.database.*
import com.google.firebase.iid.FirebaseInstanceId
import com.karumi.dexter.Dexter
import com.karumi.dexter.MultiplePermissionsReport
import com.karumi.dexter.PermissionToken
import com.karumi.dexter.listener.PermissionRequest
import com.karumi.dexter.listener.multi.MultiplePermissionsListener
import com.sam.sabinomeals.Remote.ICloudFunctions
import com.sam.sabinomeals.Remote.RetrofitCloudClient
import com.sam.sabinomeals.commons.Common
import com.sam.sabinomeals.models.BraintreeToken
import com.sam.sabinomeals.models.UserModel
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.activity_splash.*
import net.sam.sabinomeals.R
import org.jetbrains.anko.longToast
import org.jetbrains.anko.toast
import java.util.*
class SplashActivity : AppCompatActivity() {
private lateinit var userReference: DatabaseReference
val SPLASH_SCREEN: Long = 5000
lateinit var handler: Handler
private var compositeDisposable: CompositeDisposable?= CompositeDisposable()
lateinit var cloudFunctions: ICloudFunctions
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState)
setContentView(R.layout.activity_splash)
cloudFunctions= RetrofitCloudClient.getInstance().create(
ICloudFunctions::class.java)
window.setFlags(
WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN)
userReference = FirebaseDatabase.getInstance().getReference(Common.USER_REFERENCE)
//Animation
val logo_animation = AnimationUtils.loadAnimation(this,
R.anim.top_animation)
val txt_animation = AnimationUtils.loadAnimation(this,
R.anim.bottom_animation)
logo_splash.animation = logo_animation
urbanfood.animation = txt_animation
handler = Handler()
checkInternet()
}
private fun checkInternet() {
Dexter.withActivity(this)
.withPermissions(Manifest.permission.INTERNET,
Manifest.permission.ACCESS_FINE_LOCATION)
.withListener(object :MultiplePermissionsListener{
#RequiresApi(Build.VERSION_CODES.M)
override fun onPermissionsChecked(p0: MultiplePermissionsReport?) {
if (isOnline(this#SplashActivity)) {
// showHome()
val currentUser = FirebaseAuth.getInstance().currentUser
if (currentUser != null) {
checkUserFromFirebase(currentUser)
} else {
longToast("Kindly Login")
showLogin()
}
} else {
longToast("Please ensure you are connected to the Internet")
handler.postDelayed({
finish()
}, SPLASH_SCREEN)
}
}
override fun onPermissionRationaleShouldBeShown(
p0: MutableList<PermissionRequest>?,
p1: PermissionToken?
) {
AlertDialog.Builder(this#SplashActivity)
.setTitle(R.string.internet_permission_title)
.setMessage(R.string.internet_permission_message)
.setNegativeButton(
android.R.string.cancel,
DialogInterface.OnClickListener { dialog, which ->
dialog.dismiss()
p1?.cancelPermissionRequest()
})
.setPositiveButton(
android.R.string.ok,
DialogInterface.OnClickListener { dialog, which ->
dialog.dismiss()
p1?.continuePermissionRequest()
}).show()
}
} ).check()
}
private fun checkUserFromFirebase(currentUser: FirebaseUser) {
userReference.child(currentUser.uid)
.addListenerForSingleValueEvent(object : ValueEventListener {
#RequiresApi(Build.VERSION_CODES.N)
override fun onCancelled(p0: DatabaseError) {
showRegisterDialog(currentUser)
finish()
}
#RequiresApi(Build.VERSION_CODES.N)
override fun onDataChange(p0: DataSnapshot) {
if (p0.exists()) {
val userModel = p0.getValue(UserModel::class.java)
if (userModel != null) {
FirebaseAuth.getInstance().currentUser!!
.getIdToken(true)
.addOnFailureListener{
exception -> Toast.makeText(this#SplashActivity,""+exception.message,Toast.LENGTH_SHORT).show()
}
.addOnCompleteListener{
Common.authorizeToken=it.result!!.token
val headers = HashMap<String,String>()
headers["Authorization"] = Common.buildToken(
Common.authorizeToken)
compositeDisposable!!.add(cloudFunctions.getToken(headers)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({braintreeToken: BraintreeToken? ->
goToHomeActivity(userModel,braintreeToken!!.token)
},{throwable: Throwable? ->
Toast.makeText(this#SplashActivity,""+throwable!!.message,Toast.LENGTH_SHORT).show()
}))
}
}
} else {
showRegisterDialog(currentUser)
}
}
})
}
#RequiresApi(Build.VERSION_CODES.M)
private fun isOnline(context: Context): Boolean {
val connectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val capabilities =
connectivityManager.getNetworkCapabilities(connectivityManager.activeNetwork)
if (capabilities != null) {
if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
Log.i("Internet", "NetworkCapabilities.TRANSPORT_CELLULAR")
return true
} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
Log.i("Internet", "NetworkCapabilities.TRANSPORT_WIFI")
return true
} else if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET)) {
Log.i("Internet", "NetworkCapabilities.TRANSPORT_ETHERNET")
return true
}
}
return false
}
private fun showLogin() {
handler.postDelayed({
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
finish()
}, SPLASH_SCREEN)
}
#RequiresApi(Build.VERSION_CODES.N)
private fun showRegisterDialog(currentUser: FirebaseUser?) {
val builder = AlertDialog.Builder(this)
builder.setTitle("Updated Profile")
builder.setMessage("Please fill in your information")
val itemView = LayoutInflater.from(this)
.inflate(R.layout.layout_register, null)
val edt_name = itemView.findViewById<TextInputEditText>(R.id.edt_name)
val birth_date = itemView.findViewById<TextInputEditText>(R.id.birth_date)
val edt_address = itemView.findViewById<TextInputEditText>(R.id.edt_address)
val edt_phone = itemView.findViewById<TextInputEditText>(R.id.edt_phone)
//setPhone
edt_phone.setText(currentUser!!.phoneNumber)
//Date
birth_date.setOnClickListener(View.OnClickListener {
val c = Calendar.getInstance()
val mYear = c.get(Calendar.YEAR)
val mMonth = c.get(Calendar.MONTH)
val mDay = c.get(Calendar.DAY_OF_MONTH)
val datePickerDialog =
DatePickerDialog(
this,
DatePickerDialog.OnDateSetListener { view, year, month, dayOfMonth ->
birth_date.setText("" + dayOfMonth + "/" + month + "/" + year)
},
mYear,
mMonth,
mDay
)
datePickerDialog.show()
})
builder.setView(itemView)
builder.setNegativeButton("Cancel") { dialog, which -> dialog.dismiss() }
builder.setPositiveButton("Record") { dialog, which ->
if (TextUtils.isDigitsOnly(edt_name.text.toString())) {
toast("Enter your name")
return#setPositiveButton
} else if (TextUtils.isDigitsOnly(edt_address.text.toString())) {
toast("Enter your address")
return#setPositiveButton
}
val userModel = UserModel()
userModel.uid = currentUser.uid
userModel.name = edt_name.text.toString()
userModel.address = edt_address.text.toString()
userModel.aniversaire = birth_date.text.toString()
userReference.child(currentUser.uid)
.setValue(userModel)
.addOnCompleteListener { task ->
if (task.isSuccessful) {
FirebaseAuth.getInstance().currentUser!!
.getIdToken(true)
.addOnFailureListener{
exception -> Toast.makeText(this,""+exception.message,Toast.LENGTH_SHORT).show()
}
.addOnCompleteListener{
Common.authorizeToken=it.result!!.token
val headers = HashMap<String,String>()
headers.put("Authorization",
Common.buildToken(
Common.authorizeToken))
compositeDisposable!!.add(cloudFunctions.getToken(headers)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({braintreeToken: BraintreeToken? ->
dialog.dismiss()
goToHomeActivity(userModel, braintreeToken!!.token)
},
{throwable: Throwable? ->
dialog.dismiss()
Toast.makeText(this,""+throwable!!.message,Toast.LENGTH_SHORT).show()
}))
}
}
}
}
//Important
val dialog = builder.create()
dialog.show()
}
private fun goToHomeActivity(
userModel: UserModel?,
token: String
) {
FirebaseInstanceId.getInstance()
.instanceId
.addOnFailureListener { exception ->
Toast.makeText(this,""+exception.message,Toast.LENGTH_SHORT).show()
Common.currentUser= userModel
Common.currentToken=token
startActivity(Intent(this, HomeActivity::class.java))
finish()
}
.addOnCompleteListener { task->
if(task.isSuccessful){
Common.currentUser= userModel
Common.currentToken=token
Common.updateToken(this,task.result!!.token)
startActivity(Intent(this, HomeActivity::class.java))
finish()
}
}
}
}
It's because your AndroidManifest.xml is looking for net.sam.sabinomeals.SplashActivity, but your activity is actually in com.sam.sabinomeals.SplashActivity

Problem with notifyDatasetChanged in Base Adapter

I have a problem using the method notifyDataSetChanged for a BaseAdapter. I think i don't really understand who it works. I want to add a new Item to the list of view to show a loading screen while an image is uploading. Once the image is uploaded, I remove the item and call the method but im receiving and error and I don't understand why.
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.drawable.BitmapDrawable
import android.net.Uri
import android.os.Build
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.provider.MediaStore
import android.support.v4.app.ActivityCompat
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.Toast
import com.google.android.gms.tasks.OnSuccessListener
import com.google.android.gms.tasks.Task
import com.google.firebase.database.DataSnapshot
import com.google.firebase.database.DatabaseError
import com.google.firebase.database.FirebaseDatabase
import com.google.firebase.database.ValueEventListener
import com.google.firebase.storage.FirebaseStorage
import com.squareup.picasso.Picasso
import kotlinx.android.synthetic.main.activity_login.*
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.add_ticket.*
import kotlinx.android.synthetic.main.add_ticket.view.*
import kotlinx.android.synthetic.main.tweets_ticket.view.*
import java.io.ByteArrayOutputStream
import java.lang.Exception
import java.text.SimpleDateFormat
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashMap
class MainActivity : AppCompatActivity() {
private var listofTweets = ArrayList<Ticket>()
var adapter:TweetsAdapter? = null
private val PICK_IMG_CODE:Int = 123
var myEmail:String? = null
var downloadUrl:String? = null
private var database = FirebaseDatabase.getInstance()
private var myRef = database.reference
var userID:String? = null
private val READIMAGE:Int = 253
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var b:Bundle = intent.extras
myEmail = b.getString("email")
userID = b.getString("uid")
listofTweets.add(Ticket("1", "My first tweet", "", "add"))
listofTweets.add(Ticket("2", "My third tweet", "https://firebasestorage.googleapis.com/v0/b/fir-demoapp-8edf3.appspot.com/o/imagesPost%2F160819173436.jpg?alt=media&token=29ac687e-0936-49d8-a42f-50ab0e751208", "normal"))
//listofTweets.add(Ticket("3", "My fourth tweet", "gs://fir-demoapp-8edf3.appspot.com/imagesPost/160819173436.jpg", "normal"))
//listofTweets.add(Ticket("4", "My fifth tweet", "http://i.imgur.com/DvpvklR.png", "normal"))
var adapter = TweetsAdapter(this, listofTweets)
lvTweets.adapter = adapter
loadPost()
}
inner class TweetsAdapter:BaseAdapter{
var listOfTweetsAdapter = ArrayList<Ticket>()
var context:Context? = null
constructor(context:Context, listOfTweetsAdapter:ArrayList<Ticket>):super(){
this.context = context
this.listOfTweetsAdapter = listOfTweetsAdapter
}
override fun getCount(): Int {
return listofTweets.size
}
override fun getItem(p0: Int): Any {
return listofTweets[p0]
}
override fun getItemId(p0: Int): Long {
return p0.toLong()
}
override fun getView(p0: Int, p1: View?, p2: ViewGroup?): View {
var tweet = listOfTweetsAdapter[p0]
if(tweet.tweetPersonUid.equals("add")) {
//Load add ticket
var myView = layoutInflater.inflate(R.layout.add_ticket, null)
myView.ivAttach.setOnClickListener {
//loadImage()
checkPermission()
}
myView.ivPost.setOnClickListener {
//Upload to the server
myRef.child("posts").push().setValue(
PostInfo(
userID.toString(), myView.etPost.text.toString(), downloadUrl.toString()
)
)
myView.etPost.setText("")
}
return myView
} else if (tweet.tweetPersonUid.equals("loading")) {
var myView = layoutInflater.inflate(R.layout.loading_ticket, null)
return myView
} else {
//Load tweet ticket
var myView = layoutInflater.inflate(R.layout.tweets_ticket, null)
myView.txt_tweet.setText(tweet.tweetText)
myView.txtUserName.setText(tweet.tweetPersonUid)
Picasso.get().load(tweet.tweetImageUrl).into(myView.tweet_picture)
myRef.child("Users").child(tweet.tweetPersonUid!!)
.addValueEventListener(object:ValueEventListener{
override fun onDataChange(p0: DataSnapshot) {
try {
var td = p0!!.value as HashMap<String, Any>
for (key in td.keys) {
var userInfo = td[key] as String
if(key.equals("profileImage")) {
Picasso.get().load(userInfo).into(myView.picture_path)
} else {
myView.txtUserName.setText(userInfo)
}
}
} catch (ex:Exception) {
}
}
override fun onCancelled(p0: DatabaseError) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
})
return myView
}
}
}
fun loadImage() {
var intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
startActivityForResult(intent, PICK_IMG_CODE)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if(requestCode == PICK_IMG_CODE && resultCode == Activity.RESULT_OK && data != null) {
val selectedImage = data.data
val filePathColumn = arrayOf(MediaStore.Images.Media.DATA)
val cursor = contentResolver.query(selectedImage, filePathColumn, null, null, null)
cursor.moveToFirst()
val columnIndex = cursor.getColumnIndex(filePathColumn[0])
val picturePath = cursor.getString(columnIndex)
cursor.close()
uploadImage(BitmapFactory.decodeFile(picturePath))
}
}
fun uploadImage(bitmap:Bitmap){
listofTweets.add(0, Ticket("0","him","url", "loading"))
adapter!!.notifyDataSetChanged()
val storage = FirebaseStorage.getInstance()
var storageRef = storage.getReferenceFromUrl("gs://fir-demoapp-8edf3.appspot.com/")
val df = SimpleDateFormat("ddMMyyHHmmss")
val dataObj = Date()
val imgPath = df.format(dataObj) + ".jpg"
val imgRef = storageRef.child("imagesPost/" + imgPath)
val baos = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos)
val data = baos.toByteArray()
val uploadTask = imgRef.putBytes(data)
uploadTask.addOnFailureListener{
Toast.makeText(applicationContext, it.toString(), Toast.LENGTH_LONG).show()
}.addOnSuccessListener { taskSnapshot ->
imgRef.downloadUrl.addOnCompleteListener() {taskSnapshot ->
downloadUrl = taskSnapshot.result.toString()
//listofTweets.removeAt(0)
//adapter!!.notifyDataSetChanged()
}
}
}
fun loadPost(){
myRef.child("posts")
.addValueEventListener(object:ValueEventListener{
override fun onDataChange(p0: DataSnapshot) {
try {
listofTweets.clear()
listofTweets.add(Ticket("1", "My first tweet", "", "add"))
var td = p0!!.value as HashMap<String, Any>
for (key in td.keys) {
var post = td[key] as HashMap<String, Any>
listofTweets.add(
Ticket(key,
post["text"] as String,
post["img"] as String,
post["userUID"] as String)
)
}
adapter!!.notifyDataSetChanged()
} catch (ex:Exception) {
}
}
override fun onCancelled(p0: DatabaseError) {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}
})
}
fun checkPermission() {
if(Build.VERSION.SDK_INT >= 23) {
if(ActivityCompat.checkSelfPermission(this,
android.Manifest.permission.READ_EXTERNAL_STORAGE) !=
PackageManager.PERMISSION_GRANTED) {
requestPermissions(arrayOf(android.Manifest.permission.READ_EXTERNAL_STORAGE), READIMAGE)
return
}
}
loadImage()
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
when(requestCode) {
READIMAGE -> {
if(grantResults[0] == PackageManager.PERMISSION_GRANTED) {loadImage()}
else {Toast.makeText(this, "Cannot acces your images", Toast.LENGTH_LONG).show()}
} else -> super.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
}
}
And the error log is (line 172 is adapter!!.notifyDataSetChanged()):
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=123, result=-1, data=Intent { dat=content://com.google.android.apps.photos.contentprovider/-1/1/content://media/external/images/media/113490/ORIGINAL/NONE/549404385 flg=0x1 clip={text/uri-list U:content://com.google.android.apps.photos.contentprovider/-1/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F113490/ORIGINAL/NONE/549404385} }} to activity {com.example.twitter/com.example.startup.MainActivity}: kotlin.KotlinNullPointerException
at android.app.ActivityThread.deliverResults(ActivityThread.java:4363)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4405)
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:49)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1811)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6694)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: kotlin.KotlinNullPointerException
at com.example.startup.MainActivity.uploadImage(MainActivity.kt:172)
at com.example.startup.MainActivity.onActivityResult(MainActivity.kt:165)
at android.app.Activity.dispatchActivityResult(Activity.java:7454)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4356)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4405) 
at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:49) 
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1811) 
at android.os.Handler.dispatchMessage(Handler.java:106) 
at android.os.Looper.loop(Looper.java:193) 
at android.app.ActivityThread.main(ActivityThread.java:6694) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) 
Thanks in advance.
Your are getting a null pointer exception.
// You have this class member
var adapter:TweetsAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) {
// During on create, you are creating the adapter
// However, you are holding the adapter in a local variable
var adapter = TweetsAdapter(this, listofTweets)
}
fun uploadImage(bitmap:Bitmap){
// Then, here, when you try to read the adapter, you are reading
// the class member adapter (which is still null)
adapter!!.notifyDataSetChanged()
}
In order to fix the null pointer, update your onCreate method:
From:
var adapter = TweetsAdapter(this, listofTweets)
To:
this.adapter = TweetsAdapter(this, listofTweets)

Categories

Resources