I'm trying to upload image to website, It was successful but app shows FETAL error.
issue seems like in AsyncTask as it might get executed to early.
I also upgraded SDK version 30 to 32 & ucrop:2.2.5
package com.myappname.dating.ui.home.profileImageUploading
import android.app.Activity
import android.content.Intent
import android.graphics.Color
import android.net.Uri
import android.os.AsyncTask
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.myappname.dating.R
import com.myappname.dating.data.db.CrushDataBase
import com.myappname.dating.data.network.ApiHelper
import com.myappname.dating.data.network.model.profileRespo.ProfileStatus
import com.myappname.dating.data.network.model.user.Mediafile
import com.myappname.dating.data.network.model.user.UserResponse
import com.myappname.dating.data.pref.AppPreferencesHelper
import com.myappname.dating.ui.login.LoginActivity
import com.myappname.dating.ui.utils.AppConstants
import com.myappname.dating.ui.utils.CommonUtil
import com.yalantis.ucrop.UCrop
import kotlinx.android.synthetic.main.activity_user_image_crop.*
import kotlinx.android.synthetic.main.activity_user_image_crop.pb_load
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody
import okhttp3.RequestBody.Companion.asRequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.io.File
@Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
class UserImageCropActivity : AppCompatActivity(), View.OnClickListener, CropImageView {
internal val IMAGE_REQUEST_CODE = 123
internal val CROP_IMAGE_NAME = "cropImage"
private lateinit var mImageCropPresenter : ImageCropPresenter
lateinit var from : String
var imageUriResultCrop: Uri? = null
var uriString: String? = null
lateinit var mPref: AppPreferencesHelper
var mCrushDataBase: CrushDataBase? = null
lateinit var userResponse: UserResponse;
override fun onCreate(savedInstanceState : Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_user_image_crop)
mPref = AppPreferencesHelper(applicationContext, AppConstants.PREF_NAME)
val view: View = findViewById(R.id.imageCropActivity)
mCrushDataBase = CrushDataBase.getDatabase(this)
mImageCropPresenter = ImageCropPresenterImpl(this, this, view)
if(intent != null){
from = intent.getStringExtra("From").toString()
}
if(from.equals("Signup")){
//Toast.makeText(applicationContext, "Uploaded", Toast.LENGTH_SHORT).show()
} else {
userResponse = getDataTask(this).execute().get()
}
val galleryIntent = Intent(Intent.ACTION_PICK)
galleryIntent.type = "image/*"
if(galleryIntent.resolveActivity(packageManager) != null) {
startActivityForResult(
Intent.createChooser(galleryIntent, "Select Picture"),
IMAGE_REQUEST_CODE
)
}
uploadBtn.setOnClickListener(this)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == IMAGE_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
val imageUri = data?.data
if (imageUri != null) {
startCrop(imageUri)
} else {
uploadBtn.visibility = View.GONE
finish()
// if (from == "") {
//
// }
// else if(from == "")
// {
//
// }
}
} else {
imageUriResultCrop = data?.let { UCrop.getOutput(it) }
uriString = imageUriResultCrop?.path
if (imageUriResultCrop != null) {
result_image.setImageURI(imageUriResultCrop)
uploadBtn.visibility = View.VISIBLE
} else {
uploadBtn.visibility = View.GONE
finish()
}
}
}
private fun startCrop(uri: Uri) {
var destinationFileName = CROP_IMAGE_NAME
destinationFileName = ".jpg"
val uCrop = UCrop.of(uri, Uri.fromFile(File(cacheDir, destinationFileName)))
uCrop.withAspectRatio(1F, 1F)
uCrop.withMaxResultSize(800, 800)
uCrop.withOptions(getCropOptions())
uCrop.start(this)
}
private fun getCropOptions() : UCrop.Options {
val options = UCrop.Options()
options.setHideBottomControls(false)
options.setFreeStyleCropEnabled(true)
options.setStatusBarColor(resources.getColor(R.color.colorPrimaryDark))
options.setToolbarColor(resources.getColor(R.color.colorPrimary))
return options
}
override fun onClick(v: View?) {
when (v?.id) {
R.id.uploadBtn -> {
if (uriString == null || uriString == "") {
Toast.makeText(applicationContext, "please select an image ", Toast.LENGTH_LONG)
.show()
return
} else {
val file = File(imageUriResultCrop?.path)
val requestFile = file.asRequestBody("multipart/form-data".toMediaTypeOrNull())
val body = MultipartBody.Part.createFormData("avater", file.name, requestFile)
val accessToken: String? = mPref.getAccessToken()
val requestBody = accessToken?.toRequestBody(MultipartBody.FORM)
if (from.equals("Signup")){
updateAvater(requestBody,body)
}else if(from.equals("ProfileAct")){
updateAvaterp(requestBody,body)
}else if(from.equals("userImage")){
updateAvaterG(requestBody,body)
}else if(from.equals("userImageD")){
updateAvaterGal(requestBody,body)
}
else{
mImageCropPresenter.imageCropUploadPresenter(requestBody, body)
}
}
uploadBtn.isClickable = false
uploadBtn.setBackgroundColor(Color.parseColor("#e4e6e8"))
}
}
}
fun updateAvaterp(
access_token: RequestBody?,
avater: MultipartBody.Part
) {
ApiHelper().updateAvaterImage(access_token, avater)
.enqueue(object : Callback<ProfileStatus> {
override fun onFailure(call: Call<ProfileStatus>, t: Throwable) {
Toast.makeText(applicationContext, "Failed to upload please select another image or check internet", Toast.LENGTH_SHORT)
.show()
uploadBtn.isClickable = true
uploadBtn.setBackgroundColor(Color.parseColor("#2196f3"))
}
override fun onResponse(
call: Call<ProfileStatus>,
response: Response<ProfileStatus>
) {
if (response.isSuccessful) {
val updateCheck = UpdateTaskA(
this@UserImageCropActivity, response.body()!!.picurl, userResponse.id ).execute().get()
Toast.makeText(applicationContext, "Profile Upload Successfully", Toast.LENGTH_SHORT).show()
finish()
}
}
})
}
fun updateAvaterG(
access_token: RequestBody?,
avater: MultipartBody.Part
) {
ApiHelper().updateAvaterImage(access_token, avater)
.enqueue(object : Callback<ProfileStatus> {
override fun onFailure(call: Call<ProfileStatus>, t: Throwable) {
Toast.makeText(applicationContext, "Failed to upload please select another image or check internet", Toast.LENGTH_SHORT)
.show()
}
override fun onResponse(
call: Call<ProfileStatus>,
response: Response<ProfileStatus>
) {
if (response.isSuccessful) {
val updateCheck = UpdateTaskG(this@UserImageCropActivity, response.body()!!.picurl, userResponse!!.id ).execute().get()
Toast.makeText(applicationContext, "Profile Upload Successfully", Toast.LENGTH_SHORT).show()
finish()
}
}
})
}
fun updateAvaterGal(
access_token: RequestBody?,
avater: MultipartBody.Part
) {
ApiHelper().uploadImage(access_token, avater)
.enqueue(object : Callback<ProfileStatus> {
override fun onFailure(call: Call<ProfileStatus>, t: Throwable) {
Toast.makeText(applicationContext, "Failed to upload please select another image or check internet", Toast.LENGTH_SHORT)
.show()
}
override fun onResponse(
call: Call<ProfileStatus>,
response: Response<ProfileStatus>
) {if (response.isSuccessful) {
// val updateCheck = UpdateTaskG(this@UserImageCropActivity, response.body()!!.picurl, userResponse!!.id ).execute().get()
Toast.makeText(applicationContext, "Image Upload Successfully", Toast.LENGTH_SHORT).show()
// finish()
// var lnk = response.body()!!.file_url
// response.body().picurl
val intent = Intent(applicationContext, UserImageGalleryActivity::class.java)
// intent.putExtra("fileurl", lnk)
// intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK
startActivity(intent)
//startActivity(Intent(this, UserImageGalleryActivity::class.java))
}
}
})
}
fun updateAvater(
access_token: RequestBody?,
avater: MultipartBody.Part
) {
ApiHelper().updateAvaterImage(access_token, avater)
.enqueue(object : Callback<ProfileStatus> {
override fun onFailure(call: Call<ProfileStatus>, t: Throwable) {
Toast.makeText(applicationContext, "Failed to upload please select another image or check internet", Toast.LENGTH_SHORT)
.show()
}
override fun onResponse(
call: Call<ProfileStatus>,
response: Response<ProfileStatus>
) {
if (response.isSuccessful) {
val intent = Intent(applicationContext, LoginActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK
startActivity(intent)
finish()
}
}
})
}
override fun showProgressBar() {
pb_load.visibility = View.VISIBLE
}
override fun hideProgressBar() {
pb_load.visibility = View.GONE
}
override fun onSuccess(id: String) {
var value: List<Mediafile>
// val updateCheck = UpdateTask(this,map).execute().get()
Toast.makeText(applicationContext, "Image Upload Successfully$id", Toast.LENGTH_LONG).show()
finish()
}
override fun onFailure(message: String) {
Toast.makeText(
applicationContext,
"Image not upload Something went wrong" message,
Toast.LENGTH_LONG
).show()
finish()
}
override fun backToActivity() {
val intent =
Intent(applicationContext, UserImageGalleryActivity::class.java)
intent.flags =
Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
startActivity(intent)
finish()
}
override fun onDestroy() {
super.onDestroy()
mImageCropPresenter.onDestroy()
}
private class UpdateTask(var context: UserImageCropActivity, var value: List<Mediafile>?) :
AsyncTask<Void, Void, Boolean>() {
override fun doInBackground(vararg params: Void?): Boolean {
context.mCrushDataBase!!.crushDao().updateMediaFile(value, 1)
return true
}
override fun onPostExecute(bool: Boolean?) {
if (bool!!) {
}
}
}
class UpdateTaskA(var context: UserImageCropActivity, var avatar: String,var id : Int) :
AsyncTask<Void, Void, Boolean>() {
override fun doInBackground(vararg params: Void?): Boolean {
val imageAvatar = CommonUtil.convertToString64(avatar)
context.mCrushDataBase!!.crushDao().updateAvatar(imageAvatar!!, id)
return true
}
override fun onPostExecute(bool: Boolean?) {
if (bool!!) {
}
}
}
class UpdateTaskG(var context: UserImageCropActivity, var avatar: String, var user: Int) :
AsyncTask<Void, Void, Boolean>() {
override fun doInBackground(vararg params: Void?): Boolean {
val imageAvatar = CommonUtil.convertToString64(avatar)
context.mCrushDataBase!!.crushDao().updateAvatar(imageAvatar!!, user)
return true
}
override fun onPostExecute(bool: Boolean?) {
if (bool!!) {
}
}
}
class getDataTask(var context: UserImageCropActivity) :
AsyncTask<Void, Void, UserResponse>() {
override fun doInBackground(vararg params: Void?): UserResponse {
var listOfdata = context.mCrushDataBase!!.crushDao().getData()
val data = listOfdata[0]
return data
}
override fun onPostExecute(userResponse: UserResponse?) {
}
}
}
Error was displayed in line
FATAL EXCEPTION: main
Process: com.myappname.dating, PID: 17170
java.lang.NullPointerException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkNotNullParameter,
parameter avatar
at com.myappname.dating.ui.home.profileImageUploading.UserImageCropActivity$UpdateTaskA.<init>(Unknown
Source:7)
at com.myappname.dating.ui.home.profileImageUploading.UserImageCropActivity$updateAvaterp$1.onResponse(UserImageCropActivity.kt:190)
CodePudding user response:
Your stacktrace is saying that you're passing null for the avatar
parameter in the UpdateTaskA
constructor, which is being called from the onResponse
function inside UpdateAvaterp
// avatar is a String, not a String? so it can't be null
class UpdateTaskA(var context: UserImageCropActivity, var avatar: String,var id : Int)
// inside your on onResponse function
UpdateTaskA(this@UserImageCropActivity, response.body()!!.picurl, userResponse.id )
So you're passing response.body()!!.picurl
as your avatar
parameter, but it's null. So your response doesn't have that value. You either need to handle the possibility that it's null, or if that should never happen (which is a risky assumption when calling an API that could change) then you need to work out what the problem is with the network call and fix it.
Easiest way is probably setting a breakpoint inside onResponse
and inspecting the response to see what it contains, and if there's any info about why you're not getting the data you want. If you haven't used the debugger before, here's an overview - it can save you a lot of time!
CodePudding user response:
I suggest not to use non-null assertion operator !!
in places where a variable can be null
. There is a safe call operator ?.
for that purpose:
val pictureUrl = response.body()?.picurl
pictureUrl?.let { picurl ->
// Execute this block of code only when `pictureUrl` is not null
val updateCheck = UpdateTaskA(
this@UserImageCropActivity,
picurl,
userResponse.id
).execute().get()
}
CodePudding user response:
Also as AsyncTask is long ago deprecated https://android-review.googlesource.com/c/platform/frameworks/base/ /1156409 I suggest to not to use it.
Instead you can use java.util.concurrent.Executors
or just Kotlin Coroutines to handle doing stuff asynchronously.