feat 可以拍照了
This commit is contained in:
parent
a184f20496
commit
1707daa21d
|
@ -2,7 +2,7 @@
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="deploymentTargetDropDown">
|
<component name="deploymentTargetDropDown">
|
||||||
<value>
|
<value>
|
||||||
<entry key="Unnamed">
|
<entry key="app">
|
||||||
<State />
|
<State />
|
||||||
</entry>
|
</entry>
|
||||||
</value>
|
</value>
|
||||||
|
|
|
@ -33,10 +33,16 @@ android {
|
||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
jvmTarget = "1.8"
|
jvmTarget = "1.8"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
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.core:core-ktx:1.10.1")
|
||||||
implementation("androidx.appcompat:appcompat:1.6.1")
|
implementation("androidx.appcompat:appcompat:1.6.1")
|
||||||
implementation("com.google.android.material:material:1.9.0")
|
implementation("com.google.android.material:material:1.9.0")
|
||||||
|
|
|
@ -4,6 +4,11 @@
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_FINE_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
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||||
|
|
|
@ -4,22 +4,32 @@ package com.bing89.travebing
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.ContentValues
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.location.Location
|
import android.location.Location
|
||||||
import android.location.LocationListener
|
import android.location.LocationListener
|
||||||
import android.location.LocationManager
|
import android.location.LocationManager
|
||||||
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.provider.MediaStore
|
import android.provider.MediaStore
|
||||||
import android.util.Base64
|
import android.util.Base64
|
||||||
|
import android.util.Log
|
||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.annotation.RequiresPermission
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
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.app.ActivityCompat
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.content.FileProvider
|
import androidx.core.content.FileProvider
|
||||||
import com.bing89.travebing.R.*
|
import com.bing89.travebing.R.*
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
|
@ -29,11 +39,13 @@ import java.text.SimpleDateFormat
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity() {
|
class MainActivity : AppCompatActivity() {
|
||||||
|
|
||||||
private lateinit var startButton: Button
|
private lateinit var startButton: Button
|
||||||
private lateinit var previewImageView: ImageView
|
private lateinit var previewImageView: ImageView
|
||||||
private lateinit var gpsInfoTextView: TextView
|
private lateinit var gpsInfoTextView: TextView
|
||||||
|
private var imageCapture: ImageCapture? = null
|
||||||
|
|
||||||
private var isMonitoring = false
|
private var isMonitoring = false
|
||||||
private var photoFilePath: String? = null
|
private var photoFilePath: String? = null
|
||||||
|
@ -46,7 +58,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
startButton = findViewById(id.startButton)
|
startButton = findViewById(id.startButton)
|
||||||
previewImageView = findViewById(id.previewImageView)
|
previewImageView = findViewById(id.previewImageView)
|
||||||
gpsInfoTextView = findViewById(id.gpsInfoTextView)
|
gpsInfoTextView = findViewById(id.gpsInfoTextView)
|
||||||
|
startCamera()
|
||||||
startButton.setOnClickListener {
|
startButton.setOnClickListener {
|
||||||
if (isMonitoring) {
|
if (isMonitoring) {
|
||||||
stopMonitoring()
|
stopMonitoring()
|
||||||
|
@ -61,25 +73,33 @@ class MainActivity : AppCompatActivity() {
|
||||||
private fun startMonitoring() {
|
private fun startMonitoring() {
|
||||||
isMonitoring = true
|
isMonitoring = true
|
||||||
startButton.text = "休息"
|
startButton.text = "休息"
|
||||||
|
// if(imageCapture == null ){
|
||||||
val intervalMillis = 60000L // 间隔时间,这里设置为1分钟
|
// startCamera()
|
||||||
val handler = Handler(Looper.getMainLooper())
|
// }
|
||||||
|
takePhoto()
|
||||||
handler.post(object : Runnable {
|
getLocation()
|
||||||
override fun run() {
|
// val intervalMillis = 60000L // 间隔时间,这里设置为1分钟
|
||||||
if (isMonitoring) {
|
// val handler = Handler(Looper.getMainLooper())
|
||||||
capturePhotoAndUpload()
|
//
|
||||||
handler.postDelayed(this, intervalMillis)
|
// handler.post(object : Runnable {
|
||||||
}
|
// override fun run() {
|
||||||
}
|
// if (isMonitoring) {
|
||||||
})
|
// getLocation()
|
||||||
|
//// capturePhotoAndUpload()
|
||||||
|
// takePhoto()
|
||||||
|
// handler.postDelayed(this, intervalMillis)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// })
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun stopMonitoring() {
|
private fun stopMonitoring() {
|
||||||
isMonitoring = false
|
isMonitoring = false
|
||||||
startButton.text = "出发"
|
startButton.text = "出发"
|
||||||
}
|
}
|
||||||
|
@RequiresPermission(
|
||||||
|
anyOf = [Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION],
|
||||||
|
)
|
||||||
@SuppressLint("QueryPermissionsNeeded")
|
@SuppressLint("QueryPermissionsNeeded")
|
||||||
private fun capturePhotoAndUpload() {
|
private fun capturePhotoAndUpload() {
|
||||||
if (checkPermissions()) {
|
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 {
|
private fun checkPermissions(): Boolean {
|
||||||
val requiredPermissions = arrayOf(
|
val requiredPermissions = arrayOf(
|
||||||
Manifest.permission.CAMERA,
|
Manifest.permission.CAMERA,
|
||||||
|
@ -126,6 +151,7 @@ class MainActivity : AppCompatActivity() {
|
||||||
return File.createTempFile("JPEG_${timeStamp}_", ".jpg", storageDir)
|
return File.createTempFile("JPEG_${timeStamp}_", ".jpg", storageDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun getLocation() {
|
private fun getLocation() {
|
||||||
val locationListener = object : LocationListener {
|
val locationListener = object : LocationListener {
|
||||||
override fun onLocationChanged(location: Location) {
|
override fun onLocationChanged(location: Location) {
|
||||||
|
@ -195,5 +221,99 @@ class MainActivity : AppCompatActivity() {
|
||||||
companion object {
|
companion object {
|
||||||
private const val PERMISSION_REQUEST_CODE = 1001
|
private const val PERMISSION_REQUEST_CODE = 1001
|
||||||
private const val PHOTO_REQUEST_CODE = 1002
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue