1.移除READ_MEDIA_VIDEO 权限

2.移除READ_MEDIA_IMAGES 权限,选择照片改用谷歌官方Photo picker
This commit is contained in:
yezhiqiu
2026-06-02 16:39:39 +08:00
parent c0ab984a83
commit f3ccb1f4ec
17 changed files with 356 additions and 116 deletions

View File

@@ -4,7 +4,7 @@
<selectionStates> <selectionStates>
<SelectionState runConfigName="app"> <SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" /> <option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2026-05-28T06:43:50.390331300Z"> <DropdownSelection timestamp="2026-06-01T08:32:46.679728300Z">
<Target type="DEFAULT_BOOT"> <Target type="DEFAULT_BOOT">
<handle> <handle>
<DeviceId pluginId="PhysicalDevice" identifier="serial=GBG5T19625003301" /> <DeviceId pluginId="PhysicalDevice" identifier="serial=GBG5T19625003301" />

View File

@@ -28,9 +28,9 @@ android {
applicationId "com.abbidot.tracker" applicationId "com.abbidot.tracker"
minSdkVersion 23 minSdkVersion 23
targetSdkVersion 35 targetSdkVersion 35
versionCode 2207 versionCode 2209
// versionName "2.2.7" versionName "2.2.9"
versionName "2.2.7-Beta1" // versionName "2.2.9-Beta1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

View File

@@ -77,9 +77,10 @@
<uses-permission <uses-permission
android:name="android.permission.REQUEST_INSTALL_PACKAGES" android:name="android.permission.REQUEST_INSTALL_PACKAGES"
tools:node="remove" /> <!-- Android 13上一新增运行时权限 --> tools:node="remove" /> <!-- Android 13上一新增运行时权限 -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <!-- <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />-->
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" /> <!-- <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />-->
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> <!-- 通知权限 --> <!-- <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> -->
<!-- 通知权限 -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" /> <!-- Android 12新增权限适配 --> <uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" /> <!-- Android 12新增权限适配 -->
<uses-permission <uses-permission

View File

@@ -61,9 +61,6 @@ import com.abbidot.tracker.vm.FamilyViewModel
import com.abbidot.tracker.vm.LogBleReportViewModel import com.abbidot.tracker.vm.LogBleReportViewModel
import com.clj.fastble.BleManager import com.clj.fastble.BleManager
import com.google.android.material.navigation.NavigationBarView import com.google.android.material.navigation.NavigationBarView
import com.hjq.permissions.XXPermissions
import com.hjq.permissions.permission.PermissionLists
import com.huantansheng.easyphotos.EasyPhotos
import com.qmuiteam.qmui.widget.QMUITopBar import com.qmuiteam.qmui.widget.QMUITopBar
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@@ -215,21 +212,16 @@ class HomeV2Activity : BaseActivity<ActivityHomeV2Binding>(ActivityHomeV2Binding
//设置bugly的用户id //设置bugly的用户id
// CrashReport.setUserId(MMKVUtil.getString(MMKVKey.Email)) // CrashReport.setUserId(MMKVUtil.getString(MMKVKey.Email))
//预先加载相册,防止上传头像几千张照片加载慢 //预先加载相册,防止上传头像,几千张照片加载慢
XXPermissions.with(this).permission(PermissionLists.getReadMediaImagesPermission()) // XXPermissions.with(this).permission(PermissionLists.getReadMediaImagesPermission())
.request { _, deniedList -> // .request { _, deniedList ->
val allGranted = deniedList.isEmpty() // val allGranted = deniedList.isEmpty()
if (allGranted) { // if (allGranted) {
EasyPhotos.preLoad(this) // EasyPhotos.preLoad(this)
// {
// runOnUiThread {
// showToast("相册加载完成")
// } // }
// } // }
} }
} }
}
}
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
@@ -330,13 +322,14 @@ class HomeV2Activity : BaseActivity<ActivityHomeV2Binding>(ActivityHomeV2Binding
} }
//刷新下邀请家人数据 //刷新下邀请家人数据
XEventBus.observe(this, EventName.RefreshHomeList) { XEventBus.observe(this, EventName.RefreshHomeList) {
getPet(false)?.let { // getPet(false)?.let {
//套餐没有过期 // //套餐没有过期
if (it.availableOrder == ConstantInt.Type1) { // if (it.availableOrder == ConstantInt.Type1) {
// mDataViewModel.getHomeBindPetList(this)
// }
// }
mDataViewModel.getHomeBindPetList(this) mDataViewModel.getHomeBindPetList(this)
} }
}
}
//删除宠物 //删除宠物
XEventBus.observe(this, EventName.DeletePet) { XEventBus.observe(this, EventName.DeletePet) {
mSelectPetPosition = 0 mSelectPetPosition = 0
@@ -399,8 +392,21 @@ class HomeV2Activity : BaseActivity<ActivityHomeV2Binding>(ActivityHomeV2Binding
override fun onResult(any: Any) { override fun onResult(any: Any) {
LogUtil.e("HomeV2Activity------>>获取所有绑定宠物数据") LogUtil.e("HomeV2Activity------>>获取所有绑定宠物数据")
isRequestPetData = true isRequestPetData = true
if (mPetList.size > 0) {
it.getOrNull()?.apply {
for (oPet in mPetList) {
for (nPet in this) {
if (oPet.petId == nPet.petId) {
nPet.showDFUDialog = oPet.showDFUDialog
nPet.showNoWifiDialog = oPet.showNoWifiDialog
break
}
}
}
}
mPetList.clear() mPetList.clear()
mChangePetListDialogAdapter.setData(null) mChangePetListDialogAdapter.setData(null)
}
it.getOrNull()?.apply { it.getOrNull()?.apply {
setPetData(this) setPetData(this)
} }

View File

@@ -3,6 +3,8 @@ package com.abbidot.tracker.ui.activity.account
import android.content.Intent import android.content.Intent
import android.text.TextUtils import android.text.TextUtils
import android.view.View import android.view.View
import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels import androidx.activity.viewModels
import coil.load import coil.load
import com.abbidot.baselibrary.constant.EventName import com.abbidot.baselibrary.constant.EventName
@@ -99,8 +101,11 @@ class UserProfileActivity :
) )
// mUploadImageUrl = MMKVUtil.getString(MMKVKey.HeadUrl) // mUploadImageUrl = MMKVUtil.getString(MMKVKey.HeadUrl)
ViewUtil.instance.imageLoadUrl(mContext, ViewUtil.instance.imageLoadUrl(
ilUserProfileHeadLayout.ilPetProfileHead.appHeadImage, "", R.drawable.pic_avatar_df mContext,
ilUserProfileHeadLayout.ilPetProfileHead.appHeadImage,
"",
R.drawable.pic_avatar_df
) )
} }
@@ -144,7 +149,8 @@ class UserProfileActivity :
mViewBinding.ilUserProfileNameLayout.etInputContent.setText(info.userName) mViewBinding.ilUserProfileNameLayout.etInputContent.setText(info.userName)
mViewBinding.ilUserProfileEmailLayout.etInputContent.setText(info.email) mViewBinding.ilUserProfileEmailLayout.etInputContent.setText(info.email)
mUploadImageUrl = info.imgurl mUploadImageUrl = info.imgurl
ViewUtil.instance.imageLoadUrl(mContext, ViewUtil.instance.imageLoadUrl(
mContext,
mViewBinding.ilUserProfileHeadLayout.ilPetProfileHead.appHeadImage, mViewBinding.ilUserProfileHeadLayout.ilPetProfileHead.appHeadImage,
mUploadImageUrl, mUploadImageUrl,
R.drawable.pic_avatar_df R.drawable.pic_avatar_df
@@ -268,6 +274,18 @@ class UserProfileActivity :
} }
} }
private val pickSingleImage =
registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
if (uri != null) {
// 处理选中的单张照片
val photos = ArrayList<Photo>()
Photo(null, uri, "", 0, 0, 0, 0, 0, 0, null).apply {
photos.add(this)
}
mTakePhotoAndCompressViewModel.goCropAndCompressImage(photos)
}
}
override fun onClick(v: View?) { override fun onClick(v: View?) {
mViewBinding.apply { mViewBinding.apply {
when (v!!) { when (v!!) {
@@ -292,9 +310,17 @@ class UserProfileActivity :
} }
} }
ilUserProfileHeadLayout.ilPetProfileHead.appHeadImage -> ViewUtil.instance.goSelectPhoto( ilUserProfileHeadLayout.ilPetProfileHead.appHeadImage -> {
this@UserProfileActivity, ResultCode.ResultCode_1
) // val aa = isPhotoPickerAvailable(mContext)
// LogUtil.e("isPhotoPickerAvailable---:$aa")
pickSingleImage.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
// ViewUtil.instance.goSelectPhoto(
// this@UserProfileActivity,
// ResultCode.ResultCode_1
// )
}
// mRightImageButton -> closeAccount() // mRightImageButton -> closeAccount()
} }

View File

@@ -3,6 +3,8 @@ package com.abbidot.tracker.ui.activity.data
import android.content.Intent import android.content.Intent
import android.graphics.Bitmap import android.graphics.Bitmap
import android.view.View import android.view.View
import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import coil.load import coil.load
@@ -51,8 +53,8 @@ class SharePetActivityActivity :
intent.extras?.apply { intent.extras?.apply {
Util.getParcelableAdaptive(intent, ConstantString.Pet, PetBean::class.java)?.let { Util.getParcelableAdaptive(intent, ConstantString.Pet, PetBean::class.java)?.let {
ViewUtil.instance.setPetTypeHead(mContext, ViewUtil.instance.setPetTypeHead(
ilSharePetActivityPetHead.appHeadImage, it.imgurl, it.petType mContext, ilSharePetActivityPetHead.appHeadImage, it.imgurl, it.petType
) )
tvSharePetActivityPetName.text = it.petName tvSharePetActivityPetName.text = it.petName
} }
@@ -158,7 +160,8 @@ class SharePetActivityActivity :
private fun saveToPhoto() { private fun saveToPhoto() {
getBitmap { bitmap -> getBitmap { bitmap ->
val dir = FileUtil.getDiskCacheDirectory(mContext, FileUtil.SHARE_DIRECTORY_NAME) val dir = FileUtil.getDiskCacheDirectory(mContext, FileUtil.SHARE_DIRECTORY_NAME)
BitmapUtils.saveBitmapToDir(this, BitmapUtils.saveBitmapToDir(
this,
dir.path, dir.path,
FileUtil.SHARE_DIRECTORY_NAME, FileUtil.SHARE_DIRECTORY_NAME,
bitmap, bitmap,
@@ -242,7 +245,8 @@ class SharePetActivityActivity :
private fun shareImage() { private fun shareImage() {
getBitmap { bitmap -> getBitmap { bitmap ->
val dir = FileUtil.getDiskCacheDirectory(mContext, FileUtil.SHARE_DIRECTORY_NAME) val dir = FileUtil.getDiskCacheDirectory(mContext, FileUtil.SHARE_DIRECTORY_NAME)
BitmapUtils.saveBitmapToDir(this, BitmapUtils.saveBitmapToDir(
this,
dir.path, dir.path,
FileUtil.SHARE_DIRECTORY_NAME, FileUtil.SHARE_DIRECTORY_NAME,
bitmap, bitmap,
@@ -269,13 +273,27 @@ class SharePetActivityActivity :
} }
} }
private val pickSingleImage =
registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
if (uri != null) {
// 处理选中的单张照片
val photos = ArrayList<Photo>()
Photo(null, uri, "", 0, 0, 0, 0, 0, 0, null).apply {
photos.add(this)
}
mTakePhotoAndCompressViewModel.goCropAndCompressImage(photos)
}
}
override fun onClick(v: View?) { override fun onClick(v: View?) {
mViewBinding.apply { mViewBinding.apply {
when (v!!) { when (v!!) {
ivSharePetActivityChangePhotoBtn -> ViewUtil.instance.goSelectPhoto( ivSharePetActivityChangePhotoBtn -> {
this@SharePetActivityActivity, ResultCode.ResultCode_1 pickSingleImage.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
) // ViewUtil.instance.goSelectPhoto(
// this@SharePetActivityActivity, ResultCode.ResultCode_1
// )
}
mRightTextButton -> shareImage() mRightTextButton -> shareImage()
} }

View File

@@ -134,7 +134,7 @@ class DeleteTracker2Activity :
dialog.dismiss() dialog.dismiss()
} }
}, },
okTextResId = R.string.txt_sure, okTextResId = R.string.txt_ok,
cancelTextResId = R.string.txt_cancel cancelTextResId = R.string.txt_cancel
) )
} }

View File

@@ -56,8 +56,8 @@ class AddWifiPowerZone1Activity :
mViewBinding.apply { mViewBinding.apply {
mPetBean?.let { mPetBean?.let {
ViewUtil.instance.setPetTypeHead(mContext, ViewUtil.instance.setPetTypeHead(
ivAddWifiZone1PetHead.appHeadImage, it.imgurl, it.petType mContext, ivAddWifiZone1PetHead.appHeadImage, it.imgurl, it.petType
) )
} }
@@ -117,11 +117,21 @@ class AddWifiPowerZone1Activity :
object : BaseDialog.OnDialogOkListener { object : BaseDialog.OnDialogOkListener {
override fun onOkClick(dialog: BaseDialog<*>) { override fun onOkClick(dialog: BaseDialog<*>) {
dialog.dismiss() dialog.dismiss()
connectBle()
} }
}, },
okTextResId = R.string.txt_sure, okTextResId = R.string.txt_ok,
cancelTextResId = R.string.txt_cancel cancelTextResId = R.string.txt_cancel,
) cancelListener = object : BaseDialog.OnDialogCancelListener {
override fun onCancelClick(dialog: BaseDialog<*>) {
dialog.dismiss()
if (isFirstBind) {
startActivityFinish(Intent(mContext, HomeV2Activity::class.java))
} else {
finish()
}
}
})
} }
mViewBinding.ilAddWifiZone1BluetoothTips.trbBleConnectState.let { view -> mViewBinding.ilAddWifiZone1BluetoothTips.trbBleConnectState.let { view ->
ViewUtil.instance.bleConActionState(this, view, conState) ViewUtil.instance.bleConActionState(this, view, conState)

View File

@@ -2,7 +2,10 @@ package com.abbidot.tracker.ui.activity.help
import android.content.Intent import android.content.Intent
import android.text.TextUtils import android.text.TextUtils
import android.view.Gravity
import android.view.View import android.view.View
import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
@@ -19,6 +22,7 @@ import com.abbidot.tracker.bean.MenuTxtBean
import com.abbidot.tracker.constant.ConstantInt import com.abbidot.tracker.constant.ConstantInt
import com.abbidot.tracker.constant.GetResultCallback import com.abbidot.tracker.constant.GetResultCallback
import com.abbidot.tracker.databinding.ActivityFeedbackBinding import com.abbidot.tracker.databinding.ActivityFeedbackBinding
import com.abbidot.tracker.util.FileUtil
import com.abbidot.tracker.util.ViewUtil import com.abbidot.tracker.util.ViewUtil
import com.abbidot.tracker.vm.FeedbackViewModel import com.abbidot.tracker.vm.FeedbackViewModel
import com.abbidot.tracker.vm.TakePhotoAndCompressViewModel import com.abbidot.tracker.vm.TakePhotoAndCompressViewModel
@@ -272,6 +276,62 @@ class FeedbackActivity : BaseActivity<ActivityFeedbackBinding>(ActivityFeedbackB
} }
} }
/**
* 多张照片选择器
*/
private var pickMultipleVisualMedia = registerForActivityResult(
ActivityResultContracts.PickMultipleVisualMedia(mLimitPhotoCount)
) { uris ->
// Process URIs
LogUtil.e("Photo Picker URIs count:${uris.size}")
if (uris.isNotEmpty()) {
val count = mLimitPhotoCount - mFeedbackImageAdapter.getData().size
val newList = if (uris.size > count) {
showToast(
String.format(
getString(R.string.selector_reach_max_image_hint_easy_photos),
mLimitPhotoCount
), gravity = Gravity.CENTER
)
uris.take(count)
} else uris
val photos = ArrayList<Photo>()
for (uri in newList) {
FileUtil.uriToFile(mContext, uri)?.let {
Photo(null, uri, it.path, 0, 0, 0, 0, 0, 0, null).apply {
photos.add(this)
}
}
}
mTakePhotoAndCompressViewModel.dealCompressPhoto(mContext, photos)
}
}
/**
* 单张照片选择器
*/
private val pickSingleImage =
registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
if (uri != null) {
// 处理选中的单张照片
val photos = ArrayList<Photo>()
FileUtil.uriToFile(mContext, uri)?.let {
Photo(null, uri, it.path, 0, 0, 0, 0, 0, 0, null).apply {
photos.add(this)
}
}
mTakePhotoAndCompressViewModel.dealCompressPhoto(mContext, photos)
}
}
private fun launchMultiSelect(newMax: Int) {
if (newMax == 1) {
pickSingleImage.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
} else {
pickMultipleVisualMedia.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
}
}
override fun onClick(v: View?) { override fun onClick(v: View?) {
if (isLimitClick()) return if (isLimitClick()) return
mViewBinding.apply { mViewBinding.apply {
@@ -283,15 +343,16 @@ class FeedbackActivity : BaseActivity<ActivityFeedbackBinding>(ActivityFeedbackB
String.format( String.format(
getString(R.string.selector_reach_max_image_hint_easy_photos), getString(R.string.selector_reach_max_image_hint_easy_photos),
mLimitPhotoCount mLimitPhotoCount
) ), gravity = Gravity.CENTER
) )
return@apply return@apply
} }
ViewUtil.instance.goSelectPhoto( launchMultiSelect(mLimitPhotoCount - mFeedbackImageAdapter.getData().size)
this@FeedbackActivity, // ViewUtil.instance.goSelectPhoto(
ResultCode.ResultCode_1, // this@FeedbackActivity,
count = mLimitPhotoCount - mFeedbackImageAdapter.getData().size // ResultCode.ResultCode_1,
) // count = mLimitPhotoCount - mFeedbackImageAdapter.getData().size
// )
} }
} }
} }

View File

@@ -3,6 +3,7 @@ package com.abbidot.tracker.ui.activity.pet
import android.content.Intent import android.content.Intent
import android.text.TextUtils import android.text.TextUtils
import android.view.View import android.view.View
import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
@@ -164,7 +165,7 @@ class PetProfileActivity :
mTakePhotoAndCompressViewModel.registerCropImageActivityResult(this) mTakePhotoAndCompressViewModel.registerCropImageActivityResult(this)
setPetData() setPetData()
mPetViewModel.getPetLabels(this) // mPetViewModel.getPetLabels(this)
setListenKeyboardChange(methodType = ConstantInt.Type1) setListenKeyboardChange(methodType = ConstantInt.Type1)
} }
@@ -580,13 +581,28 @@ class PetProfileActivity :
showSelectPetLabels() showSelectPetLabels()
} }
private val pickSingleImage =
registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
if (uri != null) {
// 处理选中的单张照片
val photos = ArrayList<Photo>()
Photo(null, uri, "", 0, 0, 0, 0, 0, 0, null).apply {
photos.add(this)
}
mTakePhotoAndCompressViewModel.goCropAndCompressImage(photos)
}
}
override fun onClick(v: View?) { override fun onClick(v: View?) {
mViewBinding.apply { mViewBinding.apply {
hideInputMethod(v!!) hideInputMethod(v!!)
when (v) { when (v) {
ilPetProfileHeadLayout.ilPetProfileHead.appHeadImage -> ViewUtil.instance.goSelectPhoto( ilPetProfileHeadLayout.ilPetProfileHead.appHeadImage -> {
this@PetProfileActivity, ResultCode.ResultCode_1 pickSingleImage.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
) // ViewUtil.instance.goSelectPhoto(
// this@PetProfileActivity, ResultCode.ResultCode_1
// )
}
ilPetProfileType.root, ilPetProfileType.ivInputRepresentImage -> showPetTypeDialog() ilPetProfileType.root, ilPetProfileType.ivInputRepresentImage -> showPetTypeDialog()
ilPetProfileBirthday.root, ilPetProfileBirthday.ivInputRepresentImage -> showBirthdayDialog() ilPetProfileBirthday.root, ilPetProfileBirthday.ivInputRepresentImage -> showBirthdayDialog()

View File

@@ -3,6 +3,8 @@ package com.abbidot.tracker.ui.activity.pet.first
import android.content.Intent import android.content.Intent
import android.text.TextUtils import android.text.TextUtils
import android.view.View import android.view.View
import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import coil.load import coil.load
@@ -268,13 +270,26 @@ class FirstPetProfileActivity :
mUserInfoViewModel.uploadImage(this@FirstPetProfileActivity, mSelectPetHeadPath) mUserInfoViewModel.uploadImage(this@FirstPetProfileActivity, mSelectPetHeadPath)
} }
} }
private val pickSingleImage =
registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
if (uri != null) {
// 处理选中的单张照片
val photos = ArrayList<Photo>()
Photo(null, uri, "", 0, 0, 0, 0, 0, 0, null).apply {
photos.add(this)
}
mTakePhotoAndCompressViewModel.goCropAndCompressImage(photos)
}
}
override fun onClick(v: View?) { override fun onClick(v: View?) {
mViewBinding.apply { mViewBinding.apply {
when (v!!) { when (v!!) {
ilFirstPetProfileHeadLayout.ilPetProfileHead.appHeadImage -> ViewUtil.instance.goSelectPhoto( ilFirstPetProfileHeadLayout.ilPetProfileHead.appHeadImage -> {
this@FirstPetProfileActivity, ResultCode.ResultCode_1 pickSingleImage.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
) // ViewUtil.instance.goSelectPhoto(
// this@FirstPetProfileActivity, ResultCode.ResultCode_1
// )
}
rlFirstPetProfileLabels -> mProfileCommon.showLabelDialog(this@FirstPetProfileActivity) rlFirstPetProfileLabels -> mProfileCommon.showLabelDialog(this@FirstPetProfileActivity)

View File

@@ -293,7 +293,6 @@ abstract class BaseBaiduMapFragment :
headUrl headUrl
} }
} }
LogUtil.e("mapKey=$mapKey")
bitmapDescriptor = MyApplication.mapPetHeadHashMap[mapKey] bitmapDescriptor = MyApplication.mapPetHeadHashMap[mapKey]
if (null == bitmapDescriptor || bitmapDescriptor !is BitmapDescriptor) { if (null == bitmapDescriptor || bitmapDescriptor !is BitmapDescriptor) {
bitmap = GoogleBitmapHelper.headToBitmap(context, headBgResId, headUrl, petType) bitmap = GoogleBitmapHelper.headToBitmap(context, headBgResId, headUrl, petType)

View File

@@ -189,7 +189,6 @@ object GoogleBitmapHelper {
headUrl headUrl
} }
} }
LogUtil.e("mapKey=$mapKey")
bitmapDescriptor = MyApplication.mapPetHeadHashMap[mapKey] bitmapDescriptor = MyApplication.mapPetHeadHashMap[mapKey]
if (null == bitmapDescriptor || bitmapDescriptor !is BitmapDescriptor) { if (null == bitmapDescriptor || bitmapDescriptor !is BitmapDescriptor) {
bitmap = headToBitmap(context, headBgResId, headUrl, petType) bitmap = headToBitmap(context, headBgResId, headUrl, petType)

View File

@@ -1,14 +1,19 @@
package com.abbidot.tracker.util package com.abbidot.tracker.util
import android.app.Activity import android.app.Activity
import android.content.ContentUris
import android.content.Context import android.content.Context
import android.database.Cursor
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Environment import android.os.Environment
import android.provider.DocumentsContract
import android.provider.MediaStore
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import com.abbidot.baselibrary.util.LogUtil import com.abbidot.baselibrary.util.LogUtil
import com.abbidot.tracker.BuildConfig import com.abbidot.tracker.BuildConfig
import java.io.File import java.io.File
import java.io.FileOutputStream
import java.math.BigDecimal import java.math.BigDecimal
/** /**
@@ -169,5 +174,105 @@ class FileUtil {
Uri.fromFile(file) Uri.fromFile(file)
} }
} }
/**
* Uri 转 File
*/
fun uriToFile(context: Context, uri: Uri): File? {
try {
// 1. 处理 File 类型 Uri
if ("file".equals(uri.scheme, ignoreCase = true)) {
return File(uri.path!!)
}
// 2. 处理 Content 类型 Uri最常用
if ("content".equals(uri.scheme, ignoreCase = true)) {
return getFileFromContentUri(context, uri)
}
} catch (e: Exception) {
e.printStackTrace()
}
return null
}
private fun getFileFromContentUri(context: Context, uri: Uri): File? {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// Android 10+ 无法直接获取真实路径,必须复制到应用沙盒
try {
val displayName = getFileName(context, uri)
val outputFile = File(context.cacheDir, displayName)
context.contentResolver.openInputStream(uri)?.use { input ->
FileOutputStream(outputFile).use { output ->
val buffer = ByteArray(1024 * 4)
var len: Int
while (input.read(buffer).also { len = it } != -1) {
output.write(buffer, 0, len)
}
}
}
return outputFile
} catch (e: Exception) {
e.printStackTrace()
}
} else {
// Android 10 以下,可以直接拿路径
val path = getRealPathFromUri(context, uri)
if (!path.isNullOrEmpty()) {
return File(path)
}
}
return null
}
private fun getFileName(context: Context, uri: Uri): String {
var name = "temp_file_${System.currentTimeMillis()}"
val cursor: Cursor? = context.contentResolver.query(uri, null, null, null, null)
cursor?.use {
if (it.moveToFirst()) {
val displayName =
it.getString(it.getColumnIndexOrThrow(MediaStore.MediaColumns.DISPLAY_NAME))
if (!displayName.isNullOrEmpty()) {
name = displayName
}
}
}
return name
}
private fun getRealPathFromUri(context: Context, uri: Uri): String? {
var path: String? = null
if (DocumentsContract.isDocumentUri(context, uri)) {
val docId = DocumentsContract.getDocumentId(uri)
if ("com.android.providers.media.documents" == uri.authority) {
val id = docId.split(":")[1]
val selection = MediaStore.Images.Media._ID + "=" + id
path = getImagePath(
context,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
selection
)
} else if ("com.android.providers.downloads.documents" == uri.authority) {
val contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), docId.toLong()
)
path = getImagePath(context, contentUri, null)
}
} else if ("content".equals(uri.scheme, ignoreCase = true)) {
path = getImagePath(context, uri, null)
}
return path
}
private fun getImagePath(context: Context, uri: Uri, selection: String?): String? {
var path: String? = null
val cursor = context.contentResolver.query(uri, null, selection, null, null)
cursor?.use {
if (it.moveToFirst()) {
path = it.getString(it.getColumnIndexOrThrow(MediaStore.Images.Media.DATA))
}
}
return path
}
} }
} }

View File

@@ -597,32 +597,6 @@ class ViewUtil private constructor() {
Toaster.show(R.string.txt_permissions_fail_tips) Toaster.show(R.string.txt_permissions_fail_tips)
} }
} }
// override fun onGranted(permissions: MutableList<IPermission>, allGranted: Boolean) {
// if (allGranted) {
// LogUtil.e("获取READ_MEDIA_IMAGES权限成功")
// EasyPhotos.createAlbum(activity, true, false, CoilEngine.instance)
// .setFileProviderAuthority(FileUtil.FILE_PROVIDER).setCount(count)
// .setPuzzleMenu(false).setCleanMenu(false).start(requestCode)
// //activity.overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left)
// } else {
// LogUtil.e("获取READ_MEDIA_IMAGES权限但部分权限未正常授予")
// Toaster.show(R.string.txt_permissions_fail_tips)
// }
// }
//
// override fun onDenied(
// permissions: MutableList<IPermission>, doNotAskAgain: Boolean
// ) {
// if (doNotAskAgain) {
// LogUtil.e("READ_MEDIA_IMAGES被永久拒绝授权请手动授予定位权限")
// // 如果是被永久拒绝就跳转到应用权限系统设置页面
// XXPermissions.startPermissionActivity(activity, permissions)
// } else {
// LogUtil.e("获取READ_MEDIA_IMAGES权限失败")
// Toaster.show(R.string.txt_permissions_fail_tips)
// }
// }
} }
} }

View File

@@ -10,9 +10,9 @@
android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
tools:ignore="ProtectedPermissions" /> tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <!-- <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />-->
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" /> <!-- <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />-->
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> <!-- <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />-->
<application <application

View File

@@ -240,8 +240,7 @@ public class EasyPhotosActivity extends AppCompatActivity implements AlbumItemsA
if (Setting.isShowCamera) { if (Setting.isShowCamera) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
return new String[]{Manifest.permission.CAMERA, return new String[]{Manifest.permission.CAMERA,
Manifest.permission.READ_MEDIA_IMAGES, Manifest.permission.READ_MEDIA_IMAGES};
Manifest.permission.READ_MEDIA_AUDIO, Manifest.permission.READ_MEDIA_VIDEO};
} }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
return new String[]{Manifest.permission.CAMERA, return new String[]{Manifest.permission.CAMERA,
@@ -252,8 +251,7 @@ public class EasyPhotosActivity extends AppCompatActivity implements AlbumItemsA
Manifest.permission.WRITE_EXTERNAL_STORAGE}; Manifest.permission.WRITE_EXTERNAL_STORAGE};
} else { } else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
return new String[]{Manifest.permission.READ_MEDIA_IMAGES, return new String[]{Manifest.permission.READ_MEDIA_IMAGES};
Manifest.permission.READ_MEDIA_AUDIO, Manifest.permission.READ_MEDIA_VIDEO};
} }
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
return new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, return new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
@@ -340,7 +338,8 @@ public class EasyPhotosActivity extends AppCompatActivity implements AlbumItemsA
private void toAndroidCamera(int requestCode) { private void toAndroidCamera(int requestCode) {
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (cameraIntent.resolveActivity(getPackageManager()) != null || this.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)) { if (cameraIntent.resolveActivity(getPackageManager()) != null || this.getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)) {
if (isQ) { if (isQ) {
photoUri = createImageUri(); photoUri = createImageUri();
@@ -363,11 +362,13 @@ public class EasyPhotosActivity extends AppCompatActivity implements AlbumItemsA
startActivityForResult(cameraIntent, requestCode); startActivityForResult(cameraIntent, requestCode);
} else { } else {
Toast.makeText(getApplicationContext(), Toast.makeText(getApplicationContext(),
R.string.camera_temp_file_error_easy_photos, Toast.LENGTH_SHORT).show(); R.string.camera_temp_file_error_easy_photos, Toast.LENGTH_SHORT)
.show();
} }
} else { } else {
Toast.makeText(getApplicationContext(), R.string.msg_no_camera_easy_photos, Toast.makeText(getApplicationContext(), R.string.msg_no_camera_easy_photos,
Toast.LENGTH_SHORT).show(); Toast.LENGTH_SHORT)
.show();
} }
} }
@@ -716,12 +717,14 @@ public class EasyPhotosActivity extends AppCompatActivity implements AlbumItemsA
if (albumModel.getAlbumItems().isEmpty()) { if (albumModel.getAlbumItems().isEmpty()) {
if (Setting.isOnlyVideo()) { if (Setting.isOnlyVideo()) {
Toast.makeText(getApplicationContext(), R.string.no_videos_easy_photos, Toast.makeText(getApplicationContext(), R.string.no_videos_easy_photos,
Toast.LENGTH_LONG).show(); Toast.LENGTH_LONG)
.show();
finish(); finish();
return; return;
} }
Toast.makeText(getApplicationContext(), R.string.no_photos_easy_photos, Toast.makeText(getApplicationContext(), R.string.no_photos_easy_photos,
Toast.LENGTH_LONG).show(); Toast.LENGTH_LONG)
.show();
if (Setting.isShowCamera) if (Setting.isShowCamera)
launchCamera(Code.REQUEST_CAMERA); launchCamera(Code.REQUEST_CAMERA);
else else
@@ -839,7 +842,8 @@ public class EasyPhotosActivity extends AppCompatActivity implements AlbumItemsA
} else if (R.id.tv_original == id) { } else if (R.id.tv_original == id) {
if (!Setting.originalMenuUsable) { if (!Setting.originalMenuUsable) {
Toast.makeText(getApplicationContext(), Setting.originalMenuUnusableHint, Toast.makeText(getApplicationContext(), Setting.originalMenuUnusableHint,
Toast.LENGTH_SHORT).show(); Toast.LENGTH_SHORT)
.show();
return; return;
} }
Setting.selectedOriginal = !Setting.selectedOriginal; Setting.selectedOriginal = !Setting.selectedOriginal;
@@ -1068,16 +1072,19 @@ public class EasyPhotosActivity extends AppCompatActivity implements AlbumItemsA
if (Setting.isOnlyVideo()) { if (Setting.isOnlyVideo()) {
Toast.makeText(getApplicationContext(), Toast.makeText(getApplicationContext(),
getString(R.string.selector_reach_max_video_hint_easy_photos, getString(R.string.selector_reach_max_video_hint_easy_photos,
Setting.count), Toast.LENGTH_SHORT).show(); Setting.count), Toast.LENGTH_SHORT)
.show();
} else if (Setting.showVideo) { } else if (Setting.showVideo) {
Toast.makeText(getApplicationContext(), Toast.makeText(getApplicationContext(),
getString(R.string.selector_reach_max_hint_easy_photos), getString(R.string.selector_reach_max_hint_easy_photos),
Toast.LENGTH_SHORT).show(); Toast.LENGTH_SHORT)
.show();
} else { } else {
Toast.makeText(getApplicationContext(), Toast.makeText(getApplicationContext(),
getString(R.string.selector_reach_max_image_hint_easy_photos, getString(R.string.selector_reach_max_image_hint_easy_photos,
Setting.count), Toast.LENGTH_SHORT).show(); Setting.count), Toast.LENGTH_SHORT)
.show();
} }
return; return;
} }
@@ -1085,17 +1092,20 @@ public class EasyPhotosActivity extends AppCompatActivity implements AlbumItemsA
case Result.PICTURE_OUT: case Result.PICTURE_OUT:
Toast.makeText(getApplicationContext(), Toast.makeText(getApplicationContext(),
getString(R.string.selector_reach_max_image_hint_easy_photos, getString(R.string.selector_reach_max_image_hint_easy_photos,
Setting.complexPictureCount), Toast.LENGTH_SHORT).show(); Setting.complexPictureCount), Toast.LENGTH_SHORT)
.show();
break; break;
case Result.VIDEO_OUT: case Result.VIDEO_OUT:
Toast.makeText(getApplicationContext(), Toast.makeText(getApplicationContext(),
getString(R.string.selector_reach_max_video_hint_easy_photos, getString(R.string.selector_reach_max_video_hint_easy_photos,
Setting.complexVideoCount), Toast.LENGTH_SHORT).show(); Setting.complexVideoCount), Toast.LENGTH_SHORT)
.show();
break; break;
case Result.SINGLE_TYPE: case Result.SINGLE_TYPE:
Toast.makeText(getApplicationContext(), Toast.makeText(getApplicationContext(),
getString(R.string.selector_single_type_hint_easy_photos), getString(R.string.selector_single_type_hint_easy_photos),
Toast.LENGTH_SHORT).show(); Toast.LENGTH_SHORT)
.show();
break; break;
} }