feat: 增加拍摄界面
This commit is contained in:
parent
acbc7c957b
commit
2337dfd8dd
@ -82,4 +82,15 @@ dependencies {
|
||||
implementation 'com.github.Gredicer:datetimepicker:V1.0.0'
|
||||
implementation 'com.google.code.gson:gson:2.10'
|
||||
implementation 'com.yanzhenjie.recyclerview:x:1.3.2'
|
||||
|
||||
// 动态权限申请 https://github.com/permissions-dispatcher/PermissionsDispatcher
|
||||
implementation "com.github.permissions-dispatcher:permissionsdispatcher:4.9.2"
|
||||
annotationProcessor "com.github.permissions-dispatcher:permissionsdispatcher-processor:4.9.2"
|
||||
|
||||
// 相机库 https://natario1.github.io/CameraView/about/getting-started
|
||||
implementation("com.otaliastudios:cameraview:2.7.2")
|
||||
// 图片压缩算法 https://github.com/Curzibn/Luban
|
||||
implementation 'top.zibin:Luban:1.1.8'
|
||||
// Android工具类库 https://github.com/l123456789jy/Lazy
|
||||
implementation 'com.github.lazylibrary:lazylibrary:1.0.2'
|
||||
}
|
||||
@ -1,6 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
<!--拍照-->
|
||||
<uses-permission android:name="android.permission.CAMERA" android:required="false"/>
|
||||
<!--网络请求-->
|
||||
<uses-permission android:name="android.permission.INTERNET" android:required="false"/>
|
||||
<!--录音-->
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" android:required="false"/>
|
||||
<!--读写文件-->
|
||||
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
|
||||
@ -1,18 +1,24 @@
|
||||
package com.navinfo.volvo
|
||||
|
||||
import android.Manifest
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.widget.Toast
|
||||
import com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.navigation.findNavController
|
||||
import androidx.navigation.ui.AppBarConfiguration
|
||||
import androidx.navigation.ui.setupWithNavController
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.navinfo.volvo.R
|
||||
import com.navinfo.volvo.databinding.ActivityMainBinding
|
||||
import permissions.dispatcher.*
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
|
||||
private lateinit var binding: ActivityMainBinding
|
||||
|
||||
@NeedsPermission(Manifest.permission.CAMERA)
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
@ -32,4 +38,29 @@ class MainActivity : AppCompatActivity() {
|
||||
// setupActionBarWithNavController(navController, appBarConfiguration)
|
||||
navView.setupWithNavController(navController)
|
||||
}
|
||||
|
||||
@OnShowRationale(Manifest.permission.CAMERA)
|
||||
fun showRationaleForCamera(request: PermissionRequest) {
|
||||
// showRationaleDialog(R.string.permission_camera_rationale, request)
|
||||
// Toast.makeText(context, "当前操作需要您授权相机权限!", Toast.LENGTH_SHORT).show()
|
||||
MaterialAlertDialogBuilder(this)
|
||||
.setTitle("提示")
|
||||
.setMessage("当前操作需要您授权读写SD卡权限!")
|
||||
.setPositiveButton("确定", DialogInterface.OnClickListener { dialogInterface, i ->
|
||||
dialogInterface.dismiss()
|
||||
// 在SD卡创建项目目录
|
||||
|
||||
})
|
||||
.show()
|
||||
}
|
||||
|
||||
@OnPermissionDenied(Manifest.permission.CAMERA)
|
||||
fun onCameraDenied() {
|
||||
Toast.makeText(this, "当前操作需要您授权读写SD卡权限!", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
@OnNeverAskAgain(Manifest.permission.CAMERA)
|
||||
fun onCameraNeverAskAgain() {
|
||||
Toast.makeText(this, "您已永久拒绝授权读写SD卡权限!", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,87 @@
|
||||
package com.navinfo.volvo.ui.camera
|
||||
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.navinfo.volvo.databinding.FragmentCameraBinding
|
||||
import com.otaliastudios.cameraview.CameraListener
|
||||
import com.otaliastudios.cameraview.CameraView
|
||||
import com.otaliastudios.cameraview.PictureResult
|
||||
import top.zibin.luban.Luban
|
||||
import top.zibin.luban.OnCompressListener
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
|
||||
class CameraFragment : Fragment() {
|
||||
|
||||
private var _binding: FragmentCameraBinding? = null
|
||||
|
||||
// This property is only valid between onCreateView and
|
||||
// onDestroyView.
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private val cameraLifeCycleObserver: CameraLifeCycleObserver by lazy {
|
||||
CameraLifeCycleObserver()
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
lifecycle.addObserver(cameraLifeCycleObserver)
|
||||
|
||||
val cameraViewModel =
|
||||
ViewModelProvider(this).get(CameraViewModel::class.java)
|
||||
|
||||
_binding = FragmentCameraBinding.inflate(inflater, container, false)
|
||||
val root: View = binding.root
|
||||
|
||||
val cameraView: CameraView = binding.camera
|
||||
cameraView.setLifecycleOwner(this)
|
||||
cameraView.addCameraListener(object:CameraListener() { // 添加拍照回调
|
||||
override fun onPictureTaken(result: PictureResult) {
|
||||
super.onPictureTaken(result)
|
||||
result.toFile()
|
||||
// 压缩图片文件
|
||||
Luban.with(context)
|
||||
.load<Any>(photos)
|
||||
.ignoreBy(100)
|
||||
.setTargetDir(getPath())
|
||||
.filter { path ->
|
||||
!(TextUtils.isEmpty(path) || path.lowercase(Locale.getDefault())
|
||||
.endsWith(".gif"))
|
||||
}
|
||||
.setCompressListener(object : OnCompressListener {
|
||||
override fun onStart() {
|
||||
// TODO 压缩开始前调用,可以在方法内启动 loading UI
|
||||
}
|
||||
|
||||
override fun onSuccess(file: File?) {
|
||||
// TODO 压缩成功后调用,返回压缩后的图片文件
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
// TODO 当压缩过程出现问题时调用
|
||||
}
|
||||
}).launch()
|
||||
}
|
||||
})
|
||||
// 点击拍照
|
||||
binding.imgStartCamera.setOnClickListener {
|
||||
cameraView.takePicture()
|
||||
}
|
||||
return root
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
lifecycle.removeObserver(cameraLifeCycleObserver)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
package com.navinfo.volvo.ui.camera
|
||||
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
|
||||
class CameraLifeCycleObserver: DefaultLifecycleObserver {
|
||||
|
||||
override fun onCreate(owner: LifecycleOwner) {
|
||||
super.onCreate(owner)
|
||||
}
|
||||
|
||||
override fun onStart(owner: LifecycleOwner) {
|
||||
super.onStart(owner)
|
||||
}
|
||||
|
||||
override fun onResume(owner: LifecycleOwner) {
|
||||
super.onResume(owner)
|
||||
}
|
||||
|
||||
override fun onPause(owner: LifecycleOwner) {
|
||||
super.onPause(owner)
|
||||
}
|
||||
|
||||
override fun onStop(owner: LifecycleOwner) {
|
||||
super.onStop(owner)
|
||||
}
|
||||
|
||||
override fun onDestroy(owner: LifecycleOwner) {
|
||||
super.onDestroy(owner)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
package com.navinfo.volvo.ui.camera
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
|
||||
class CameraViewModel : ViewModel() {
|
||||
|
||||
private val _text = MutableLiveData<String>().apply {
|
||||
value = "This is dashboard Fragment"
|
||||
}
|
||||
val text: LiveData<String> = _text
|
||||
}
|
||||
@ -1,15 +1,21 @@
|
||||
package com.navinfo.volvo.ui.message
|
||||
|
||||
import android.Manifest
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.gredicer.datetimepicker.DateTimePickerFragment
|
||||
import com.navinfo.volvo.databinding.FragmentObtainMessageBinding
|
||||
import com.navinfo.volvo.ui.markRequiredInRed
|
||||
import permissions.dispatcher.*
|
||||
import java.util.*
|
||||
|
||||
class ObtainMessageFragment: Fragment() {
|
||||
private var _binding: FragmentObtainMessageBinding? = null
|
||||
@ -59,10 +65,43 @@ class ObtainMessageFragment: Fragment() {
|
||||
}
|
||||
|
||||
// 点击按钮选择拍照
|
||||
binding.btnStartCamera.setOnClickListener {
|
||||
// 启动相机
|
||||
startCamera()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
@NeedsPermission(Manifest.permission.CAMERA)
|
||||
fun startCamera() {
|
||||
|
||||
}
|
||||
|
||||
@OnShowRationale(Manifest.permission.CAMERA)
|
||||
fun showRationaleForCamera(request: PermissionRequest) {
|
||||
// showRationaleDialog(R.string.permission_camera_rationale, request)
|
||||
// Toast.makeText(context, "当前操作需要您授权相机权限!", Toast.LENGTH_SHORT).show()
|
||||
MaterialAlertDialogBuilder(context!!)
|
||||
.setTitle("提示")
|
||||
.setMessage("当前操作需要您授权相机权限!")
|
||||
.setPositiveButton("确定", DialogInterface.OnClickListener { dialogInterface, i ->
|
||||
startCamera()
|
||||
dialogInterface.dismiss()
|
||||
})
|
||||
.show()
|
||||
}
|
||||
|
||||
@OnPermissionDenied(Manifest.permission.CAMERA)
|
||||
fun onCameraDenied() {
|
||||
Toast.makeText(context, "当前操作需要您授权相机权限!", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
@OnNeverAskAgain(Manifest.permission.CAMERA)
|
||||
fun onCameraNeverAskAgain() {
|
||||
Toast.makeText(context, "您已永久拒绝授权相机权限!", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
6
app/src/main/res/drawable/ic_baseline_camera_alt_24.xml
Normal file
6
app/src/main/res/drawable/ic_baseline_camera_alt_24.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<vector android:height="64dp" android:tint="#000000"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="64dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M12,12m-3.2,0a3.2,3.2 0,1 1,6.4 0a3.2,3.2 0,1 1,-6.4 0"/>
|
||||
<path android:fillColor="@android:color/white" android:pathData="M9,2L7.17,4L4,4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2h-3.17L15,2L9,2zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5z"/>
|
||||
</vector>
|
||||
21
app/src/main/res/layout/fragment_camera.xml
Normal file
21
app/src/main/res/layout/fragment_camera.xml
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<com.otaliastudios.cameraview.CameraView
|
||||
android:id="@+id/camera"
|
||||
android:keepScreenOn="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<com.google.android.material.imageview.ShapeableImageView
|
||||
android:id="@+id/img_start_camera"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="10dp"
|
||||
app:shapeAppearance="@style/CircleStyle"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:src="@drawable/ic_baseline_camera_alt_24"></com.google.android.material.imageview.ShapeableImageView>
|
||||
</RelativeLayout>
|
||||
@ -4,7 +4,7 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context="com.navinfo.volvo.ui.dashboard.DashboardFragment">
|
||||
tools:context="com.navinfo.volvo.ui.dashboard.CameraFragment">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_dashboard"
|
||||
|
||||
@ -82,6 +82,7 @@
|
||||
android:text="上传图片:"></TextView>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_start_camera"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/Widget.Material3.Button.ElevatedButton"
|
||||
@ -92,6 +93,7 @@
|
||||
android:layout_width="@dimen/default_widget_padding"
|
||||
android:layout_height="wrap_content"></Space>
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_start_photo"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/Widget.Material3.Button.ElevatedButton"
|
||||
@ -183,8 +185,7 @@
|
||||
android:id="@+id/edt_send_from"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/selector_bg_4_round_corner"
|
||||
tools:ignore="TouchTargetSizeCheck,SpeakableTextPresentCheck"></androidx.appcompat.widget.AppCompatEditText>
|
||||
android:background="@drawable/selector_bg_4_round_corner"></androidx.appcompat.widget.AppCompatEditText>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
@ -209,8 +210,7 @@
|
||||
android:id="@+id/edt_send_to"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/selector_bg_4_round_corner"
|
||||
tools:ignore="SpeakableTextPresentCheck,TouchTargetSizeCheck"></androidx.appcompat.widget.AppCompatEditText>
|
||||
android:background="@drawable/selector_bg_4_round_corner"></androidx.appcompat.widget.AppCompatEditText>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
|
||||
@ -33,4 +33,13 @@
|
||||
android:name="com.navinfo.volvo.ui.message.ObtainMessageFragment"
|
||||
android:label="问候编辑"
|
||||
tools:layout="@layout/fragment_obtain_message" />
|
||||
|
||||
<fragment
|
||||
android:id="@+id/navigation_camera"
|
||||
android:name="com.navinfo.volvo.ui.camera.CameraFragment"
|
||||
android:label="@string/title_dashboard"
|
||||
tools:layout="@layout/fragment_camera" />
|
||||
|
||||
<action android:id="@+id/nav_2_camera"
|
||||
app:destination="@id/nav_2_camera"></action>
|
||||
</navigation>
|
||||
@ -3,4 +3,10 @@
|
||||
<style name="default_line">
|
||||
<item name="android:padding">@dimen/default_widget_padding</item>
|
||||
</style>
|
||||
|
||||
<!--ShapeableImageView 圆 -->
|
||||
<style name="CircleStyle">
|
||||
<item name="cornerFamily">rounded</item>
|
||||
<item name="cornerSize">50%</item>
|
||||
</style>
|
||||
</resources>
|
||||
Loading…
x
Reference in New Issue
Block a user