feat 可以拍照了

This commit is contained in:
huangkun 2024-01-24 17:05:13 +08:00
parent a184f20496
commit 1707daa21d
4 changed files with 148 additions and 17 deletions

View File

@ -2,7 +2,7 @@
<project version="4">
<component name="deploymentTargetDropDown">
<value>
<entry key="Unnamed">
<entry key="app">
<State />
</entry>
</value>

View File

@ -33,10 +33,16 @@ android {
kotlinOptions {
jvmTarget = "1.8"
}
}
dependencies {
implementation("androidx.camera:camera-core:1.2.1")
implementation("androidx.camera:camera-camera2:1.2.1")
implementation("androidx.camera:camera-lifecycle:1.2.1")
implementation("androidx.camera:camera-video:1.2.1")
implementation("androidx.camera:camera-view:1.2.1")
implementation("androidx.camera:camera-extensions:1.2.1")
implementation("androidx.core:core-ktx:1.10.1")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("com.google.android.material:material:1.9.0")

View File

@ -4,6 +4,11 @@
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature android:name="android.hardware.camera.any" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"

View File

@ -4,22 +4,32 @@ package com.bing89.travebing
import android.Manifest
import android.annotation.SuppressLint
import android.content.ContentValues
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.location.Location
import android.location.LocationListener
import android.location.LocationManager
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.provider.MediaStore
import android.util.Base64
import android.util.Log
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.annotation.RequiresPermission
import androidx.appcompat.app.AppCompatActivity
import androidx.camera.core.CameraSelector
import androidx.camera.core.ImageCapture
import androidx.camera.core.ImageCaptureException
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider
import com.bing89.travebing.R.*
import kotlinx.coroutines.*
@ -29,11 +39,13 @@ import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
class MainActivity : AppCompatActivity() {
private lateinit var startButton: Button
private lateinit var previewImageView: ImageView
private lateinit var gpsInfoTextView: TextView
private var imageCapture: ImageCapture? = null
private var isMonitoring = false
private var photoFilePath: String? = null
@ -46,7 +58,7 @@ class MainActivity : AppCompatActivity() {
startButton = findViewById(id.startButton)
previewImageView = findViewById(id.previewImageView)
gpsInfoTextView = findViewById(id.gpsInfoTextView)
startCamera()
startButton.setOnClickListener {
if (isMonitoring) {
stopMonitoring()
@ -61,25 +73,33 @@ class MainActivity : AppCompatActivity() {
private fun startMonitoring() {
isMonitoring = true
startButton.text = "休息"
val intervalMillis = 60000L // 间隔时间这里设置为1分钟
val handler = Handler(Looper.getMainLooper())
handler.post(object : Runnable {
override fun run() {
if (isMonitoring) {
capturePhotoAndUpload()
handler.postDelayed(this, intervalMillis)
}
}
})
// if(imageCapture == null ){
// startCamera()
// }
takePhoto()
getLocation()
// val intervalMillis = 60000L // 间隔时间这里设置为1分钟
// val handler = Handler(Looper.getMainLooper())
//
// handler.post(object : Runnable {
// override fun run() {
// if (isMonitoring) {
// getLocation()
//// capturePhotoAndUpload()
// takePhoto()
// handler.postDelayed(this, intervalMillis)
// }
// }
// })
}
private fun stopMonitoring() {
isMonitoring = false
startButton.text = "出发"
}
@RequiresPermission(
anyOf = [Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION],
)
@SuppressLint("QueryPermissionsNeeded")
private fun capturePhotoAndUpload() {
if (checkPermissions()) {
@ -98,7 +118,12 @@ class MainActivity : AppCompatActivity() {
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == PHOTO_REQUEST_CODE ) {
// doSomeOperations()
}
}
private fun checkPermissions(): Boolean {
val requiredPermissions = arrayOf(
Manifest.permission.CAMERA,
@ -126,6 +151,7 @@ class MainActivity : AppCompatActivity() {
return File.createTempFile("JPEG_${timeStamp}_", ".jpg", storageDir)
}
private fun getLocation() {
val locationListener = object : LocationListener {
override fun onLocationChanged(location: Location) {
@ -195,5 +221,99 @@ class MainActivity : AppCompatActivity() {
companion object {
private const val PERMISSION_REQUEST_CODE = 1001
private const val PHOTO_REQUEST_CODE = 1002
private const val TAG = "Travebing"
private const val FILENAME_FORMAT = "yyyy-MM-dd-HH-mm-ss-SSS"
private const val REQUEST_CODE_PERMISSIONS = 10
}
private fun startCamera() {
val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
cameraProviderFuture.addListener({
// Used to bind the lifecycle of cameras to the lifecycle owner
val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
// Preview
// val preview = Preview.Builder()
// .build()
// .also {
// it.setSurfaceProvider(viewBinding.viewFinder.surfaceProvider)
// }
// val recorder = Recorder.Builder()
// .setQualitySelector(QualitySelector.from(Quality.HIGHEST,
// FallbackStrategy.higherQualityOrLowerThan(Quality.SD)))
// .build()
// videoCapture = VideoCapture.withOutput(recorder)
imageCapture = ImageCapture.Builder().build()
/*
val imageAnalyzer = ImageAnalysis.Builder().build()
.also {
setAnalyzer(
cameraExecutor,
LuminosityAnalyzer { luma -> startCamera()
Log.d(TAG, "Average luminosity: $luma")
}
)
}
*/
// Select back camera as a default
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
try {
// Unbind use cases before rebinding
cameraProvider.unbindAll()
// Bind use cases to camera
cameraProvider.bindToLifecycle(
this, cameraSelector, imageCapture)
} catch(exc: Exception) {
Log.e(TAG, "Use case binding failed", exc)
}
}, ContextCompat.getMainExecutor(this))
}
private fun takePhoto() {
// Get a stable reference of the modifiable image capture use case
val imageCapture = imageCapture ?: return
Log.d(TAG, "================>>>>> now do capture photo")
// Create time stamped name and MediaStore entry.
val name = SimpleDateFormat(FILENAME_FORMAT, Locale.US)
.format(System.currentTimeMillis())
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, name)
put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/CameraX-Image")
}
// Create output options object which contains file + metadata
val outputOptions = ImageCapture.OutputFileOptions
.Builder(contentResolver,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
contentValues)
.build()
// Set up image capture listener, which is triggered after photo has
// been taken
imageCapture.takePicture(
outputOptions,
ContextCompat.getMainExecutor(this),
object : ImageCapture.OnImageSavedCallback {
override fun onError(exc: ImageCaptureException) {
Log.e(TAG, "+++++++++++Photo capture failed: ${exc.message}", exc)
}
override fun
onImageSaved(output: ImageCapture.OutputFileResults){
previewImageView.setImageURI(output.savedUri)
val msg = "--------- Photo capture succeeded: ${output.savedUri}"
Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
Log.d(TAG, msg)
}
}
)
}
}