相机崩溃后退按钮
Back Button on Camera Crashes
我一直在寻找 Whosebug 上的各种解决方案,但似乎没有任何效果。我遇到一个问题,当用户启动相机然后按下 "back" 按钮取消相机时,应用程序崩溃。我认为下面的这段代码可以解决问题,但似乎不起作用。
else if (resultCode== Activity.RESULT_CANCELED) {
startActivity(Intent(this, MainActivity::class.java))
println("result cancelled")
return
}
MainActivity.kt
import android.annotation.SuppressLint
import android.app.Activity
import android.app.AlertDialog
import android.content.Intent
import android.content.pm.ActivityInfo
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.media.MediaScannerConnection
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
import android.view.View
import android.widget.Button
import android.widget.ImageView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory
import kotlinx.android.synthetic.main.activity_main.*
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.util.*
class MainActivity : AppCompatActivity() {
private var btn: Button? = null
private var imageview: ImageView? = null
private val GALLERY = 1
private val CAMERA = 2
@SuppressLint("SourceLockedOrientationActivity")
override fun onCreate(savedInstanceState:Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
btn = findViewById<View>(R.id.btn) as Button
imageview = findViewById<View>(R.id.iv) as ImageView
val wallpaperDirectory = File(getExternalFilesDir(null).toString() + IMAGE_DIRECTORY)
var listImages : Array<File>? = null
listImages = wallpaperDirectory.listFiles()
if(listImages != null && listImages.size!! > 0){
// iv.setImageBitmap(BitmapFactory.decodeFile(listImages[0].absolutePath))
val img2 = BitmapFactory.decodeFile(listImages[0].absolutePath)
val round = RoundedBitmapDrawableFactory.create(resources, img2)
round.isCircular = true
iv.setImageDrawable(round)
}
else {
val img = BitmapFactory.decodeResource(resources, R.mipmap.profile_image)
val round = RoundedBitmapDrawableFactory.create(resources, img)
round.isCircular = true
iv.setImageDrawable(round)
println("hit hit hit")
}
btn!!.setOnClickListener { showPictureDialog() }
}
private fun showPictureDialog() {
val pictureDialog = AlertDialog.Builder(this)
pictureDialog.setTitle("Select Action")
val pictureDialogItems = arrayOf("Select Photo From Gallery", "Capture Photo From Camera")
pictureDialog.setItems(pictureDialogItems
) { dialog, which ->
when (which) {
0 -> choosePhotoFromGallary()
1 -> takePhotoFromCamera()
}
}
pictureDialog.show()
}
fun choosePhotoFromGallary() {
val galleryIntent = Intent(Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
startActivityForResult(galleryIntent, GALLERY)
}
fun takePhotoFromCamera() {
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
startActivityForResult(intent, CAMERA)
}
public override fun onActivityResult(requestCode:Int, resultCode:Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == GALLERY)
{
if (data != null)
{
val contentURI = data.data
try
{
val bitmap = MediaStore.Images.Media.getBitmap(this.contentResolver, contentURI)
val round = RoundedBitmapDrawableFactory.create(resources, bitmap)
round.isCircular = true
val path = saveImage(bitmap)
Toast.makeText(this@MainActivity, "Image Saved!", Toast.LENGTH_SHORT).show()
imageview!!.setImageDrawable(round)
}
catch (e: IOException) {
e.printStackTrace()
Toast.makeText(this@MainActivity, "Failed!", Toast.LENGTH_SHORT).show()
}
}
}
else if (requestCode == CAMERA)
{
val thumbnail = data!!.extras!!.get("data") as Bitmap
val round = RoundedBitmapDrawableFactory.create(resources, thumbnail)
round.isCircular = true
imageview!!.setImageDrawable(round)
saveImage(thumbnail)
Toast.makeText(this@MainActivity, "Image Saved!", Toast.LENGTH_SHORT).show()
}
else if (resultCode== Activity.RESULT_CANCELED) {
startActivity(Intent(this, MainActivity::class.java))
println("result cancelled")
}
}
fun saveImage(myBitmap: Bitmap):String {
val bytes = ByteArrayOutputStream()
myBitmap.compress(Bitmap.CompressFormat.JPEG, 90, bytes)
val wallpaperDirectory = File(getExternalFilesDir(null).toString() + IMAGE_DIRECTORY)
wallpaperDirectory.deleteRecursively()
// have the object build the directory structure, if needed.
Log.d("fee",wallpaperDirectory.toString())
if (!wallpaperDirectory.exists())
{
wallpaperDirectory.mkdirs()
}
try
{
Log.d("heel",wallpaperDirectory.toString())
val f = File(wallpaperDirectory, ((Calendar.getInstance()
.getTimeInMillis()).toString() + ".jpg"))
f.createNewFile()
val fo = FileOutputStream(f)
fo.write(bytes.toByteArray())
MediaScannerConnection.scanFile(this,
arrayOf(f.getPath()),
arrayOf("image/jpeg"), null)
fo.close()
Log.d("TAG", "File Saved::--->" + f.getAbsolutePath())
return f.getAbsolutePath()
}
catch (e1: IOException) {
e1.printStackTrace()
}
return ""
}
companion object {
private val IMAGE_DIRECTORY = "/demonuts"
}
}
acitivity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:exported="true"
tools:context=".MainActivity">
<!-- android:text="Select or Capture Image" -->
<Button
android:id="@+id/btn"
android:layout_width="125dp"
android:layout_height="125dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="40dp"
android:width="2dp"
android:background="#00000000" />
<ImageView
android:id="@+id/iv"
android:layout_width="125dp"
android:layout_height="125dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="-150dp"
android:scaleType="fitXY"
android:src="@mipmap/profile_image" />
</LinearLayout>
错误日志:
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=2, result=0, data=null} to activity {com.example.pickimagetakeexamples/com.example.pickimagetakeexamples.MainActivity}: kotlin.KotlinNullPointerException
at android.app.ActivityThread.deliverResults(ActivityThread.java:4998)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:5041)
at android.app.ActivityThread.access00(ActivityThread.java:229)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1875)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7325)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Caused by: kotlin.KotlinNullPointerException
at com.example.pickimagetakeexamples.MainActivity.onActivityResult(MainActivity.kt:124)
at android.app.Activity.dispatchActivityResult(Activity.java:7165)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4994)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:5041)
at android.app.ActivityThread.access00(ActivityThread.java:229)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1875)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7325)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
根据您的日志,我可以说应用程序崩溃的原因是,您没有捕获图像,而是按下后退按钮,returns null 作为您的 onActivityResult 的数据,您需要在您的 onActivityResult 中指定如果结果 returns 为 null 时要做什么。只需添加默认参数或 if data==null 并处理这种情况。
你应该添加if条件。[=11=]
相机打开,用户 returns 返回。使用 resultCode == Activity.RESULT_CANCELED 调用 onActivityResult()。同样,用户从相机拍摄照片。使用 resultCode == Activity.RESULT_OK.
调用 onActivityResult
您检查了 if 条件中的 RequestCode 但没有检查 ResultCode。在下面更改您的 if 条件:
if (Activity.RESULT_OK == resultCode && requestCode == GALLERY)
if (Activity.RESULT_OK == resultCode && requestCode == CAMERA)
我一直在寻找 Whosebug 上的各种解决方案,但似乎没有任何效果。我遇到一个问题,当用户启动相机然后按下 "back" 按钮取消相机时,应用程序崩溃。我认为下面的这段代码可以解决问题,但似乎不起作用。
else if (resultCode== Activity.RESULT_CANCELED) {
startActivity(Intent(this, MainActivity::class.java))
println("result cancelled")
return
}
MainActivity.kt
import android.annotation.SuppressLint
import android.app.Activity
import android.app.AlertDialog
import android.content.Intent
import android.content.pm.ActivityInfo
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.media.MediaScannerConnection
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
import android.view.View
import android.widget.Button
import android.widget.ImageView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory
import kotlinx.android.synthetic.main.activity_main.*
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.util.*
class MainActivity : AppCompatActivity() {
private var btn: Button? = null
private var imageview: ImageView? = null
private val GALLERY = 1
private val CAMERA = 2
@SuppressLint("SourceLockedOrientationActivity")
override fun onCreate(savedInstanceState:Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
btn = findViewById<View>(R.id.btn) as Button
imageview = findViewById<View>(R.id.iv) as ImageView
val wallpaperDirectory = File(getExternalFilesDir(null).toString() + IMAGE_DIRECTORY)
var listImages : Array<File>? = null
listImages = wallpaperDirectory.listFiles()
if(listImages != null && listImages.size!! > 0){
// iv.setImageBitmap(BitmapFactory.decodeFile(listImages[0].absolutePath))
val img2 = BitmapFactory.decodeFile(listImages[0].absolutePath)
val round = RoundedBitmapDrawableFactory.create(resources, img2)
round.isCircular = true
iv.setImageDrawable(round)
}
else {
val img = BitmapFactory.decodeResource(resources, R.mipmap.profile_image)
val round = RoundedBitmapDrawableFactory.create(resources, img)
round.isCircular = true
iv.setImageDrawable(round)
println("hit hit hit")
}
btn!!.setOnClickListener { showPictureDialog() }
}
private fun showPictureDialog() {
val pictureDialog = AlertDialog.Builder(this)
pictureDialog.setTitle("Select Action")
val pictureDialogItems = arrayOf("Select Photo From Gallery", "Capture Photo From Camera")
pictureDialog.setItems(pictureDialogItems
) { dialog, which ->
when (which) {
0 -> choosePhotoFromGallary()
1 -> takePhotoFromCamera()
}
}
pictureDialog.show()
}
fun choosePhotoFromGallary() {
val galleryIntent = Intent(Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
startActivityForResult(galleryIntent, GALLERY)
}
fun takePhotoFromCamera() {
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
startActivityForResult(intent, CAMERA)
}
public override fun onActivityResult(requestCode:Int, resultCode:Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == GALLERY)
{
if (data != null)
{
val contentURI = data.data
try
{
val bitmap = MediaStore.Images.Media.getBitmap(this.contentResolver, contentURI)
val round = RoundedBitmapDrawableFactory.create(resources, bitmap)
round.isCircular = true
val path = saveImage(bitmap)
Toast.makeText(this@MainActivity, "Image Saved!", Toast.LENGTH_SHORT).show()
imageview!!.setImageDrawable(round)
}
catch (e: IOException) {
e.printStackTrace()
Toast.makeText(this@MainActivity, "Failed!", Toast.LENGTH_SHORT).show()
}
}
}
else if (requestCode == CAMERA)
{
val thumbnail = data!!.extras!!.get("data") as Bitmap
val round = RoundedBitmapDrawableFactory.create(resources, thumbnail)
round.isCircular = true
imageview!!.setImageDrawable(round)
saveImage(thumbnail)
Toast.makeText(this@MainActivity, "Image Saved!", Toast.LENGTH_SHORT).show()
}
else if (resultCode== Activity.RESULT_CANCELED) {
startActivity(Intent(this, MainActivity::class.java))
println("result cancelled")
}
}
fun saveImage(myBitmap: Bitmap):String {
val bytes = ByteArrayOutputStream()
myBitmap.compress(Bitmap.CompressFormat.JPEG, 90, bytes)
val wallpaperDirectory = File(getExternalFilesDir(null).toString() + IMAGE_DIRECTORY)
wallpaperDirectory.deleteRecursively()
// have the object build the directory structure, if needed.
Log.d("fee",wallpaperDirectory.toString())
if (!wallpaperDirectory.exists())
{
wallpaperDirectory.mkdirs()
}
try
{
Log.d("heel",wallpaperDirectory.toString())
val f = File(wallpaperDirectory, ((Calendar.getInstance()
.getTimeInMillis()).toString() + ".jpg"))
f.createNewFile()
val fo = FileOutputStream(f)
fo.write(bytes.toByteArray())
MediaScannerConnection.scanFile(this,
arrayOf(f.getPath()),
arrayOf("image/jpeg"), null)
fo.close()
Log.d("TAG", "File Saved::--->" + f.getAbsolutePath())
return f.getAbsolutePath()
}
catch (e1: IOException) {
e1.printStackTrace()
}
return ""
}
companion object {
private val IMAGE_DIRECTORY = "/demonuts"
}
}
acitivity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:exported="true"
tools:context=".MainActivity">
<!-- android:text="Select or Capture Image" -->
<Button
android:id="@+id/btn"
android:layout_width="125dp"
android:layout_height="125dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="40dp"
android:width="2dp"
android:background="#00000000" />
<ImageView
android:id="@+id/iv"
android:layout_width="125dp"
android:layout_height="125dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="-150dp"
android:scaleType="fitXY"
android:src="@mipmap/profile_image" />
</LinearLayout>
错误日志:
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=2, result=0, data=null} to activity {com.example.pickimagetakeexamples/com.example.pickimagetakeexamples.MainActivity}: kotlin.KotlinNullPointerException
at android.app.ActivityThread.deliverResults(ActivityThread.java:4998)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:5041)
at android.app.ActivityThread.access00(ActivityThread.java:229)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1875)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7325)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Caused by: kotlin.KotlinNullPointerException
at com.example.pickimagetakeexamples.MainActivity.onActivityResult(MainActivity.kt:124)
at android.app.Activity.dispatchActivityResult(Activity.java:7165)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4994)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:5041)
at android.app.ActivityThread.access00(ActivityThread.java:229)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1875)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7325)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
根据您的日志,我可以说应用程序崩溃的原因是,您没有捕获图像,而是按下后退按钮,returns null 作为您的 onActivityResult 的数据,您需要在您的 onActivityResult 中指定如果结果 returns 为 null 时要做什么。只需添加默认参数或 if data==null 并处理这种情况。
你应该添加if条件。[=11=]
相机打开,用户 returns 返回。使用 resultCode == Activity.RESULT_CANCELED 调用 onActivityResult()。同样,用户从相机拍摄照片。使用 resultCode == Activity.RESULT_OK.
调用 onActivityResult您检查了 if 条件中的 RequestCode 但没有检查 ResultCode。在下面更改您的 if 条件:
if (Activity.RESULT_OK == resultCode && requestCode == GALLERY)
if (Activity.RESULT_OK == resultCode && requestCode == CAMERA)