Complete beginner, trying this on kotlin. I am trying to capture a photo and save it and then load it on room database. I also need tag the photo and load it according to that. But there is an error like "Caused by: java.lang.NullPointerException: findViewById(R.id.metin) must not be null". How I can solve it? Thanks in advance.
class MainActivity : AppCompatActivity() {
private val cameraRequest = 1888
lateinit var imageView: ImageView
lateinit var textbox : EditText
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
var dao_object = ImageDatabase.getInstance(application).MyDao()
textbox = findViewById(R.id.metin)
setContentView(R.layout.activity_main)
if (ContextCompat.checkSelfPermission(applicationContext, Manifest.permission.CAMERA)
== PackageManager.PERMISSION_DENIED
)
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.CAMERA),
cameraRequest
)
imageView = findViewById(R.id.imageView)
// var textbox: EditText = findViewById(R.id.text)
val photoButton: Button = findViewById(R.id.capture_button)
photoButton.setOnClickListener {
val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
startActivityForResult(cameraIntent, cameraRequest)
}
val saveButton: Button= findViewById(R.id.save_button)
saveButton.setOnClickListener{
val takenPhoto: ByteArray = DbBitmapUtility.getBytes(imageView.drawingCache)
dao_object.insertImage(MyDatabase(takenPhoto, textbox.text.toString()))
}
val loadButton: Button= findViewById(R.id.load_button)
loadButton.setOnClickListener {
var displayPhoto: ByteArray = dao_object.getImageByTag(textbox.text.toString())
imageView.setImageBitmap(DbBitmapUtility.getImage(displayPhoto))
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == cameraRequest) {
val photo: Bitmap = data?.extras?.get("data") as Bitmap
imageView.setImageBitmap(photo)
}
}
object DbBitmapUtility {
// convert from bitmap to byte array
fun getBytes(bitmap: Bitmap): ByteArray {
val stream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.PNG, 0, stream)
return stream.toByteArray()
}
// convert from byte array to bitmap
fun getImage(image: ByteArray): Bitmap {
return BitmapFactory.decodeByteArray(image, 0, image.size)
}
}
}
Change the arrangement of the code. Rather than doing the following
textbox = findViewById(R.id.metin)
setContentView(R.layout.activity_main)
do:
setContentView(R.layout.activity_main)
textbox = findViewById(R.id.metin)
setContentView must first be called before you can attempt any manipulation on the activity's view.
You can't use findViewById before you've called setContentView(). There is no View to search in for your view yet at that point.
Related
Using Kotlin in Android Studio, I created a form where user can fill in necessary details AND click an imageButton to launch the camera, take picture and submit the form. I want to add a validation where the user is prevented from submitting the form if they did not take a photo.
I have tried to validate by using imageButton.drawable == null but it did not display the error toast.
Here are the relevant parts of my codes:
class FormActivity : AppCompatActivity() {
var selectedPhotoUri : Uri? = null
companion object {
const val REQUEST_FROM_CAMERA = 1001
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_artactivity)
...
val imageButton = findViewById<ImageButton>(R.id.imageButton)
// launch camera
imageButton.setOnClickListener {
takePhotoUsingCamera()
}
val submitButton = findViewById<Button>(R.id.submitButton)
submitButton.setOnClickListener {
submitForm(userId.toString(), HRWAnswer, ResultAnswer)
}
}
private fun takePhotoUsingCamera(){
ImagePicker.with(this).cameraOnly()
.crop()
.start(REQUEST_FROM_CAMERA)
}
// to access the image captured
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK) {
when (requestCode){
REQUEST_FROM_CAMERA -> {
selectedPhotoUri = data!!.data
val bitmap = MediaStore.Images.Media.getBitmap(contentResolver, selectedPhotoUri)
val bitmapDrawable = BitmapDrawable(bitmap)
val imageButton = findViewById<ImageButton>(R.id.imageButton)
imageButton.setImageDrawable(bitmapDrawable)
}
}
}
}
fun submitForm(userId : String, TestOption: String, ResultOption: String){
...
val imageButton = findViewById<ImageButton>(R.id.imageButton)
if (imageButton.drawable == null) {
Toast.makeText(this, "Image of your Test result is required!", Toast.LENGTH_LONG).show()
imageButton.requestFocus()
}
...
}
}
Check this may it helps you.
class FormActivity : AppCompatActivity() {
lateinit var imageButton : ImageButton//HERE YOU NEED TO ADD BUTTON.Dont add buttons initialization multiple time in once class.
var selectedPhotoUri : Uri? = null
companion object {
const val REQUEST_FROM_CAMERA = 1001
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_artactivity)
...
imageButton = findViewById<ImageButton>(R.id.imageButton)
// launch camera
imageButton.setOnClickListener {
takePhotoUsingCamera()
}
val submitButton = findViewById<Button>(R.id.submitButton)
submitButton.setOnClickListener {
submitForm(userId.toString(), HRWAnswer, ResultAnswer)
}
}
private fun takePhotoUsingCamera(){
ImagePicker.with(this).cameraOnly()
.crop()
.start(REQUEST_FROM_CAMERA)
}
// to access the image captured
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK) {
when (requestCode){
REQUEST_FROM_CAMERA -> {
selectedPhotoUri = data!!.data
val bitmap = MediaStore.Images.Media.getBitmap(contentResolver, selectedPhotoUri)
val bitmapDrawable = BitmapDrawable(bitmap)
val imageButton = findViewById<ImageButton>(R.id.imageButton)
imageButton.setImageDrawable(bitmapDrawable)
}
}
}
}
fun submitForm(userId : String, TestOption: String, ResultOption: String){
...
if (imageButton.drawable == null) {
Toast.makeText(this, "Image of your Test result is required!", Toast.LENGTH_LONG).show()
imageButton.requestFocus()
}
...
}
}
as stated by Mike M. in the comment above, it will never be null due to its drawable set layout. i have changed my approach to achieve my target outcome.
I'm trying to upload a image to a server as taken from camera with FAN. I've tried to convert into PNG and JPEG and encoded to image but adding multipart file it always shows me errors
Here's a fragent of my code while trying.
After taken the photo:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == CAMERA_REQUEST_CODE && resultCode == RESULT_OK){
bitmap = data!!.extras!!["data"] as Bitmap?
encodeBitmap(bitmap)
}
super.onActivityResult(requestCode, resultCode, data)
}
The function to encode bitmap
private fun encodeBitmap(bitmap: Bitmap?){
val byteArrayOutputStream = ByteArrayOutputStream()
bitmap!!.compress(Bitmap.CompressFormat.JPEG, 100, byteArrayOutputStream)
val byteofimages = byteArrayOutputStream.toByteArray()
encodedimage = Base64.encodeToString(byteofimages, Base64.DEFAULT)
confirmarEntrega()
}
And the atempt to upload with FAN
private fun confirmarEntrega(){
val uploadURL ="http://192.168.1.229/sistema.com/API/upload.php"
val requestQueue = Volley.newRequestQueue(this)
val txtNombre = findViewById<TextView>(R.id.txtClientName)
val txtDireccion= findViewById<TextView>(R.id.txtDireccion)
val txtProducto = findViewById<TextView>(R.id.txtProducto)
val txtTelefono = findViewById<TextView>(R.id.txtTelefono)
val scannerTextview = findViewById<TextView>(R.id.scannerTextView)
val btnConfirmar = findViewById<Button>(R.id.btnConfirmar)
progressDialog!!.setMessage("Espere un segundo")
progressDialog!!.show()
AndroidNetworking.upload(uploadURL)
.addMultipartFile("image", encodedimage) //Here's where im lost
.setPriority(Priority.HIGH)
.build()
.setUploadProgressListener(object : UploadProgressListener{
override fun onProgress(bytesUploaded: Long, totalBytes: Long) {
}
})
.getAsJSONObject(object : JSONObjectRequestListener{
override fun onResponse(response: JSONObject?) {
}
override fun onError(anError: ANError?) {
}
})
}
My application checks whether the new selected image is the same as the previous one so that I don't need to update the cloud data, but newBitmap.sameAs(oldBitmap) always return false even though I pick the same photo.
Piece of my code:
private lateinit var oldBitmap: Bitmap
private lateinit var newBitmap: Bitmap
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_my_profile)
myProfilePictureUrl = intent.getStringExtra("myProfilePictureUrl")!!
if (myProfilePictureUrl.isNotEmpty()) {
Picasso.get().load(myProfilePictureUrl).into(my_profile_imageView)
}
oldBitmap = (my_profile_imageView.drawable as BitmapDrawable).bitmap //for later comparison
my_profile_imageView.setOnClickListener {
val intent = Intent(Intent.ACTION_PICK)
intent.type = "image/*"
startActivityForResult(intent, RESULT_CODE_PICK_IMAGE)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == RESULT_CODE_PICK_IMAGE && resultCode == Activity.RESULT_OK) {
val inputStream = contentResolver.openInputStream(data!!.data!!)
val bitmap = BitmapFactory.decodeStream(inputStream)
newBitmap = bitmap //for comparison
my_profile_imageView.setImageBitmap(bitmap)
}
}
And when the user click on the "save" button on the action bar will it first check whether they are the same photo:
private fun updateProfile(nickname: String) {
if (this::newBitmap.isInitialized && !newBitmap.sameAs(oldBitmap)) { //here
//upload task code
}
}
THE PROBLEM IS:
!newBitmap.sameAs(oldBitmap) always return false even they are the same photo, may be the problem of PICASSO? Or the way I used to compare is not right. Any help would be appreciated.
Users can show their photo on the imageView button. Codes are given below.
The problem is, savedInstanceState returns null since photo on the imageView is obtained in the onActivityResult function.
Therefore, if users click on btnRegistration and come back to this app again, they lose photo on the imageView.
Could you please help, how to edit these codes to solve this problem
private var iv_crop: ImageView = null
public var tmpResultUri: Uri?=null
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) {
val cimg = CropImage.getActivityResult(data)
iv_crop.setImageURI(cimg.uri)
val resultUri = cimg.uri
tmpResultUri = resultUri
}}
#RequiresApi(Build.VERSION_CODES.O)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (savedInstanceState != null) {
var strResultUri: String?= null
strResultUri = savedInstanceState.getString(strResultUri)
// var drawable: BitmapDrawable = iv_crop.getDrawable() as BitmapDrawable
//var bitmapImgCropped = drawable.getBitmap()
}
else {
iv_crop.setOnClickListener {
CropImage.activity().start(this) // <== Starts a new activity here.
}
}
btnRegistration?.setOnClickListener {
val intent = Intent()
intent.setClassName( "com.mylab.myApp","com.mylab.myApp.MainActivity")
startActivity(intent) // <== Starts a new activity here.
finish()}
}
override fun onSaveInstanceState(outState:Bundle ) {
outState.run{
outState.putString(tmpResultUri.toString(), tmpResultUri.toString())
}
super.onSaveInstanceState(outState)
}
override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
super.onRestoreInstanceState(savedInstanceState!!)
savedInstanceState.run {
val strtmpResultUri = getString(tmpResultUri.toString())
}
}
You need to store your image URI using a static key. Something like this.
companion object {
private const val ARG_IMAGE_URI = "imageuri"
}
Then when you save and retrieve your URI, use this value as your key and not the uri.
override fun onSaveInstanceState(outState:Bundle ) {
outState.putString(ARG_IMAGE_URI, tmpResultUri.toString())
super.onSaveInstanceState(outState)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (savedInstanceState != null) {
val strResultUri: String?= savedInstanceState.getString(ARG_IMAGE_URI)
}
}
How to pass Image selected in ImageView to another Activity in Android using Kotlin ?
This is the way to select the Image inside the ImageView using internal Storage and I need to pass the image to another activity
fun Loadimage()
{
var intent = Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
startActivityForResult(intent,ImageCode)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode==ImageCode && data!=null && resultCode== Activity.RESULT_OK)
{
val selectedImage = data.data
val filepath = arrayOf(MediaStore.Images.Media.DATA)
val cursor = contentResolver.query(selectedImage,filepath,null,null,null)
cursor.moveToFirst()
val Index = cursor.getColumnIndex(filepath[0])
val Picture = cursor.getString(Index)
cursor.close()
imageView.setImageBitmap(BitmapFactory.decodeFile(Picture))
}
}
You can pass Picture variable to next activity using Intents like below
val intent = Intent(this, NextActivity::class.java)
intent.putExtra("picture", Picture)
startActivity(intent)
Then in NextActivity, in onCreate method, you can get picture using
val Picture = getIntent().getStringExtra("picture")
In the NextActivity:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val postImage = findViewById<ImageView>(R.id.post_image)
myPic = postImage
}
companion object {
lateinit var myPic: ImageView()
}
And in the first Activity:
NextActivity.myPic = Picture