我读了this,以便在单击按钮时打开Camera
意向,并返回保存的图片文件和调用它的活动的路径,但是我的应用程序崩溃并重新启动无需打开相机的意图。
Manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:dist="http://schemas.android.com/apk/distribution"
package="com.oryx.geoop">
<uses-feature android:name="android.hardware.camera"
android:required="true" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA"/>
<application android:theme="@style/AppTheme">
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths">
</meta-data>
</provider>
<activity android:name=".AnotherActivity">
<intent-filter>
<action android:name="android.media.action.IMAGE_CAPTURE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
xml/file_paths
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
Activity
class AnotherActivity : AppCompatActivity() {
val REQUEST_TAKE_PHOTO = 1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_another)
// Grant permissions
Dexter.withActivity(this)
.withPermissions(
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.CAMERA
)
.withListener(object : MultiplePermissionsListener {
override fun onPermissionRationaleShouldBeShown(
permissions: MutableList<PermissionRequest>?,
token: PermissionToken?
) {
/* ... */
}
})
save_local.setOnClickListener { captureFromCamera(this) }
}
@Throws(IOException::class)
private fun createImageFile(): File {
val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
val dir =
"""${getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)}/geoOp/"""
val storageDir = File(dir)
storageDir.mkdirs()
return File.createTempFile(
"JPEG_${timeStamp}_", /* prefix */
".jpg", /* suffix */
storageDir /* directory */
).apply {
// Save a file: path for use with ACTION_VIEW intents
val currentPhotoPath = absolutePath
}
}
private fun captureFromCamera(context: Context) {
Intent(MediaStore.ACTION_IMAGE_CAPTURE).also { takePictureIntent ->
// Ensure that there's a camera activity to handle the intent
takePictureIntent.resolveActivity(context.packageManager)?.also {
// Create the File where the photo should go
val photoFile: File? = try {
createImageFile()
} catch (ex: IOException) {
// Error occurred while creating the File
null
}
// Continue only if the File was successfully created
photoFile?.also {
val photoURI: Uri = FileProvider.getUriForFile(
this,
"com.oryx.geoop.fileprovider",
it
)
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI)
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO)
}
}
}
}
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
// Result code is RESULT_OK only if the user captures an Image
if (resultCode == Activity.RESULT_OK && resultCode == RESULT_OK) {
Toast.makeText(this, "pic saved", Toast.LENGTH_SHORT).show()
println("pic saved")
}
}
}
更新
由于getExternalStoragePublicDirectory
在Android Q
中已弃用,并由以下代码代替,如here所示:
Kotlin
val resolver = context.contentResolver
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, "CuteKitten001")
put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
put(MediaStore.MediaColumns.RELATIVE_PATH, "DCIM/PerracoLabs")
}
val uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
resolver.openOutputStream(uri).use {
// TODO something with the stream
}
如何在上面的代码中使用它,请注意此更新会返回Uri, while original code return
文件以获取图像位置:
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
// return Uri
} else {
// return file
}