feat : 修改权限 , 新增 定制礼物, 去掉友盟取设备号的sdk , 明文请求修改

This commit is contained in:
eggmanQQQ
2024-09-25 19:06:52 +08:00
parent 892f7c3e70
commit c90a961e2f
41 changed files with 857 additions and 423 deletions

View File

@@ -51,9 +51,9 @@
tools:node="remove" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission tools:node="remove" android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission tools:node="remove" android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />

View File

@@ -3,6 +3,7 @@ package com.chwl.app.avroom.room_album
import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.app.AlertDialog
import android.app.Dialog
import android.content.Intent
import android.os.Build
@@ -11,6 +12,9 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
import androidx.fragment.app.activityViewModels
import androidx.recyclerview.widget.GridLayoutManager
@@ -25,12 +29,17 @@ import com.chwl.app.ui.utils.ImageLoadUtilsV2
import com.chwl.app.ui.widget.recyclerview.decoration.GridSpacingItemNewDecoration
import com.chwl.core.Constants
import com.chwl.core.gift.bean.GiftInfo
import com.chwl.core.utils.DialogUtil
import com.chwl.core.utils.MyUriUtils
import com.chwl.library.common.photo.PhotoProvider
import com.chwl.library.common.photo.PhotoProvider.photoProvider
import com.chwl.library.common.util.PhotoCompressUtil.compress
import com.chwl.library.common.util.PhotoCompressUtil.getCompressCachePath
import com.chwl.library.common.util.PhotosCompressCallback
import com.chwl.library.common.util.SPUtils
import com.chwl.library.constants.ConstantsLib
import com.chwl.library.easypermisssion.EasyPermissions
import com.netease.nim.uikit.common.ui.dialog.EasyAlertDialogHelper
import kotlinx.coroutines.Job
class UploadRoomAlbumDialogFragment : BottomSheetDialogFragment() {
@@ -45,7 +54,7 @@ class UploadRoomAlbumDialogFragment : BottomSheetDialogFragment() {
private var unlockedGift: GiftInfo? = null
private var compressJob: Job? = null
var pickMedia : ActivityResultLauncher<PickVisualMediaRequest>?=null
val dialogManager by lazy {
DialogManager(context)
}
@@ -55,6 +64,17 @@ class UploadRoomAlbumDialogFragment : BottomSheetDialogFragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, R.style.ErbanBottomSheetDialog)
if (ActivityResultContracts.PickVisualMedia.isPhotoPickerAvailable(requireContext())) {
pickMedia = registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
uri?.let {
val file = MyUriUtils.copyFile(requireContext(),uri)
if (file != null) {
compressPhotos(mutableListOf(file.path))
}
}
}
}
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
@@ -194,7 +214,7 @@ class UploadRoomAlbumDialogFragment : BottomSheetDialogFragment() {
return@setOnClickListener
}
dialogManager.showProgressDialog(context)
// dialogManager.showProgressDialog(context)
viewModel.upload(
list,
type,
@@ -204,7 +224,7 @@ class UploadRoomAlbumDialogFragment : BottomSheetDialogFragment() {
viewModel.uploadLiveData.observe(this) {
it?.getContentIfNotHandled()?.let { success ->
dialogManager.hideProgressDialog()
// dialogManager.hideProgressDialog()
if (success) {
dismiss()
@@ -219,28 +239,37 @@ class UploadRoomAlbumDialogFragment : BottomSheetDialogFragment() {
}
private fun checkStoragePermission() {
if (!EasyPermissions.hasPermissions(
requireContext(),
if (Build.VERSION.SDK_INT >= 33) Manifest.permission.READ_MEDIA_IMAGES
else Manifest.permission.READ_EXTERNAL_STORAGE
)
) {
EasyPermissions.requestPermissions(
this,
getString(R.string.permission_storage_rationale),
100,
if (Build.VERSION.SDK_INT >= 33) Manifest.permission.READ_MEDIA_IMAGES
else Manifest.permission.READ_EXTERNAL_STORAGE
)
} else {
photoProvider(
this,
7 - photoAdapter.data.size,
true,
200,
true
)
if (Build.VERSION.SDK_INT >= 33){
DialogUtil.getDialog(requireActivity(),object : EasyAlertDialogHelper.OnDialogActionListener {
override fun doCancelAction() {
}
override fun doOkAction() {
SPUtils.putBoolean(ConstantsLib.Key.Permissions_Img,true)
pickMedia?.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
}
})
}else{
if (!EasyPermissions.hasPermissions(requireContext(),Manifest.permission.READ_EXTERNAL_STORAGE)) {
EasyPermissions.requestPermissions(
this,
getString(R.string.permission_storage_rationale),
100,
Manifest.permission.READ_EXTERNAL_STORAGE
)
} else {
photoProvider(
this,
7 - photoAdapter.data.size,
true,
200,
true
)
}
}
}
@Deprecated("Deprecated in Java")

View File

@@ -1,279 +0,0 @@
package com.chwl.app.common.dialog
import android.Manifest
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.text.TextUtils
import android.view.Gravity
import android.view.Window
import android.view.WindowManager
import com.hjq.toast.ToastUtils
import com.chwl.app.R
import com.chwl.app.application.App
import com.chwl.app.databinding.PhotoDialogBinding
import com.chwl.app.ui.widget.dialog.CommonTipDialog
import com.chwl.library.common.base.BaseDialogFragment
import com.chwl.library.common.photo.PhotoProvider
import com.chwl.library.common.util.PhotoCompressCallback
import com.chwl.library.common.util.PhotoCompressUtil
import com.chwl.library.common.util.PhotosCompressCallback
import com.chwl.library.easypermisssion.EasyPermissions
import kotlinx.coroutines.Job
/**
* 该对话框的功能提供拍摄和选择图片
*/
class PhotoDialog : BaseDialogFragment<PhotoDialogBinding>(), EasyPermissions.PermissionCallbacks {
private var mOnResultCallBack: OnResultCallBack? = null
private var mJob: Job? = null
companion object {
private const val PERMISSION_CODE_CAMERA = 100
private const val REQUEST_CODE_CAMERA = 101
private const val PERMISSION_CODE_STORAGE_1 = 200
private const val REQUEST_CODE_STORAGE_1 = 201
private const val PERMISSION_CODE_STORAGE_2 = 202
private const val REQUEST_CODE_STORAGE_2 = 203
private const val REQUEST_CODE_OPEN_PHOTO_PROVIDER = 103
private const val REQUEST_CODE_OPEN_CAMERA_PROVIDER = 104
}
override fun initBefore(savedInstanceState: Bundle?) {
super.initBefore(savedInstanceState)
dialog?.requestWindowFeature(Window.FEATURE_NO_TITLE)
}
override fun setListener() {
binding?.tvTakePhoto?.setOnClickListener {
checkCameraPermission()
}
binding?.tvChoicePicture?.setOnClickListener {
checkStoragePermission1()
}
}
private fun initDialog() {
dialog?.window?.also {
it.decorView.setPadding(0, 0, 0, 0)
it.attributes = it.attributes.apply {
gravity = Gravity.BOTTOM
width = WindowManager.LayoutParams.MATCH_PARENT
}
it.setBackgroundDrawableResource(R.drawable.photo_dialog_bg)
}
}
override fun onStart() {
super.onStart()
initDialog()
}
private fun checkStoragePermission1() {
if (!EasyPermissions.hasPermissions(
App.gContext, if (Build.VERSION.SDK_INT >= 33) Manifest.permission.READ_MEDIA_IMAGES else Manifest.permission.READ_EXTERNAL_STORAGE
)
) {
EasyPermissions.requestPermissions(
this,
getString(R.string.permission_storage_rationale),
PERMISSION_CODE_STORAGE_1,
if (Build.VERSION.SDK_INT >= 33) Manifest.permission.READ_MEDIA_IMAGES else Manifest.permission.READ_EXTERNAL_STORAGE
)
} else {
PhotoProvider.photoProvider(this, resultCode = REQUEST_CODE_OPEN_PHOTO_PROVIDER)
}
}
private fun checkCameraPermission() {
if (!EasyPermissions.hasPermissions(
App.gContext,
Manifest.permission.CAMERA
)
) {
EasyPermissions.requestPermissions(
this,
getString(R.string.permission_camera_rationale),
PERMISSION_CODE_CAMERA,
Manifest.permission.CAMERA
)
} else {
checkStoragePermission2()
}
}
private fun checkStoragePermission2() {
if (!EasyPermissions.hasPermissions(
App.gContext, if (Build.VERSION.SDK_INT >= 33)
Manifest.permission.READ_MEDIA_IMAGES else Manifest.permission.READ_EXTERNAL_STORAGE
)
) {
EasyPermissions.requestPermissions(
this,
getString(R.string.permission_storage_rationale),
PERMISSION_CODE_STORAGE_2,
if (Build.VERSION.SDK_INT >= 33) Manifest.permission.READ_MEDIA_IMAGES else Manifest.permission.READ_EXTERNAL_STORAGE
)
} else {
PhotoProvider.photoCamera(this, REQUEST_CODE_OPEN_CAMERA_PROVIDER)
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this)
}
override fun onPermissionsGranted(requestCode: Int, perms: MutableList<String>) {
if (requestCode == PERMISSION_CODE_CAMERA) {
checkCameraPermission()
} else if (requestCode == PERMISSION_CODE_STORAGE_1) {
checkStoragePermission1()
} else if (requestCode == PERMISSION_CODE_STORAGE_2) {
checkStoragePermission2()
}
}
override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) {
if (requestCode == PERMISSION_CODE_STORAGE_1 || requestCode == PERMISSION_CODE_STORAGE_2 || requestCode == PERMISSION_CODE_CAMERA) {
val requestTip: String =
if (requestCode == PERMISSION_CODE_STORAGE_1 || requestCode == PERMISSION_CODE_STORAGE_2) {
getString(R.string.permission_storage_denied)
} else {
getString(R.string.permission_camera_denied)
}
val mPrivacyDialog = CommonTipDialog(context)
mPrivacyDialog.setTipMsg(requestTip)
mPrivacyDialog.setOkText(getString(R.string.room_perform_go_update))
mPrivacyDialog.setOnActionListener(
object : CommonTipDialog.OnActionListener {
override fun onOk() {
//同意跳到应用详情页面
val packageUri =
Uri.parse("package:${activity?.packageName}")
val intent = Intent(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
packageUri
)
if (requestCode == PERMISSION_CODE_STORAGE_1) {
startActivityForResult(
intent, REQUEST_CODE_STORAGE_1
)
} else if (requestCode == PERMISSION_CODE_STORAGE_2) {
startActivityForResult(
intent,
REQUEST_CODE_STORAGE_2
)
} else {
startActivityForResult(
intent, REQUEST_CODE_CAMERA
)
}
}
override fun onCancel() {
super.onCancel()
//取消跳到应用详情页面
if (requestCode == PERMISSION_CODE_STORAGE_1 || requestCode == PERMISSION_CODE_STORAGE_2) {
ToastUtils.show(getString(R.string.permission_storage_refused))
} else {
ToastUtils.show(getString(R.string.permission_camera_refused))
}
}
}
)
mPrivacyDialog.show()
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_CODE_STORAGE_1) {
checkStoragePermission1()
} else if (requestCode == REQUEST_CODE_STORAGE_2) {
checkStoragePermission2()
} else if (requestCode == REQUEST_CODE_CAMERA) {
checkCameraPermission()
} else
if (resultCode == RESULT_OK) {
when (requestCode) {
REQUEST_CODE_OPEN_CAMERA_PROVIDER -> {
if (mOnResultCallBack == null || data == null) return
PhotoProvider.getResultPathListAsync(data) { paths ->
val list = paths?.mapNotNull { it.path }?.toMutableList() ?: ArrayList()
val path = list[0]
if (!TextUtils.isEmpty(path)) {
mJob?.cancel()
mJob = PhotoCompressUtil.compress(
App.gContext,
path,
PhotoCompressUtil.getCompressCachePath(),
object : PhotoCompressCallback {
override fun onSuccess(compressedImg: String) {
mOnResultCallBack?.takePhotoCallBack(compressedImg)
}
override fun onFail(e: Throwable) {
mOnResultCallBack?.takePhotoCallBack(path)
}
})
} else {
mOnResultCallBack?.takePhotoCallBack(path)
}
}
}
REQUEST_CODE_OPEN_PHOTO_PROVIDER -> {
if (mOnResultCallBack == null || data == null) return
PhotoProvider.getResultPathListAsync(data) { list ->
val paths = list?.mapNotNull { it.path }?.toMutableList() ?: ArrayList()
if (paths.isEmpty()) {
mOnResultCallBack?.choicePhotoCallBack(paths)
} else {
mJob?.cancel()
mJob = PhotoCompressUtil.compress(
App.gContext,
paths,
PhotoCompressUtil.getCompressCachePath(),
object : PhotosCompressCallback {
override fun onSuccess(compressedImgList: ArrayList<String>) {
mOnResultCallBack?.choicePhotoCallBack(compressedImgList)
}
override fun onFail(e: Throwable) {
mOnResultCallBack?.choicePhotoCallBack(paths)
}
})
}
}
}
}
dismissAllowingStateLoss()
}
}
fun setOnResultCallBack(onResultCallBack: OnResultCallBack) {
mOnResultCallBack = onResultCallBack
}
override fun onWillDestroy() {
mJob?.cancel()
super.onWillDestroy()
}
interface OnResultCallBack {
fun takePhotoCallBack(path: String?)
fun choicePhotoCallBack(paths: List<String>?)
}
}

View File

@@ -6,10 +6,13 @@ import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.chwl.app.BuildConfig;
import com.chwl.app.application.App;
import com.chwl.core.auth.AuthModel;
import com.chwl.core.utils.LogUtils;
import com.chwl.library.common.util.CoreUtils;
import com.netease.nim.uikit.common.util.log.LogUtil;
/**
* Activity生命周期工具类
@@ -27,6 +30,9 @@ public class AppLifeCycleHelper implements Application.ActivityLifecycleCallback
@Override
public void onActivityStarted(@NonNull Activity activity) {
if (BuildConfig.DEBUG) {
LogUtils.d("当前Activity : "+ activity.getClass().getSimpleName());
}
if (++AppLifeCycleHelper.sActivityReferences == 1 && !AppLifeCycleHelper.sIsActivityChangingConfigurations) {
AppLifeCycleHelper.onForeground();

View File

@@ -4,7 +4,11 @@ import android.Manifest
import android.annotation.SuppressLint
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.widget.ImageView.ScaleType
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
@@ -16,10 +20,14 @@ import com.chwl.app.ui.utils.load
import com.chwl.app.ui.widget.dialog.CommonTipDialog
import com.chwl.core.file.FileModel
import com.chwl.core.home.bean.FeedbackTypeBean
import com.chwl.core.utils.DialogUtil
import com.chwl.core.utils.MyUriUtils
import com.chwl.library.common.photo.PhotoProvider
import com.chwl.library.common.photo.PhotoProvider.photoProvider
import com.chwl.library.common.util.PhotoCompressUtil
import com.chwl.library.common.util.PhotosCompressCallback
import com.chwl.library.common.util.SPUtils
import com.chwl.library.constants.ConstantsLib
import com.chwl.library.easypermisssion.EasyPermissions
import com.chwl.library.easyphoto.utils.settings.SettingsUtils
import com.chwl.library.utils.ResUtil
@@ -35,6 +43,7 @@ import com.google.android.flexbox.FlexboxLayoutManager
import com.google.android.flexbox.JustifyContent
import com.hjq.toast.ToastUtils
import com.netease.nim.uikit.StatusBarUtil
import com.netease.nim.uikit.common.ui.dialog.EasyAlertDialogHelper
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
@@ -52,6 +61,21 @@ class FeedbackActivity : BaseViewBindingActivity<FeedbackActivityBinding>(),
private var imagePath: String? = null
private var imageUrl: String? = null
var pickMedia : ActivityResultLauncher<PickVisualMediaRequest>?=null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (ActivityResultContracts.PickVisualMedia.isPhotoPickerAvailable(this)) {
pickMedia = registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
uri?.let {
val file = MyUriUtils.copyFile(this,uri)
if (file != null) {
compressPhotos(mutableListOf(file.path))
}
}
}
}
}
override fun init() {
initWhiteTitleBar(ResUtil.getString(R.string.feedback_title))
initView()
@@ -262,26 +286,37 @@ class FeedbackActivity : BaseViewBindingActivity<FeedbackActivityBinding>(),
}
private fun checkStoragePermission() {
if (!EasyPermissions.hasPermissions(
this,
if (Build.VERSION.SDK_INT >= 33) Manifest.permission.READ_MEDIA_IMAGES else Manifest.permission.READ_EXTERNAL_STORAGE
)
) {
EasyPermissions.requestPermissions(
this,
getString(R.string.permission_storage_rationale),
PERMISSION_CODE_STORAGE,
if (Build.VERSION.SDK_INT >= 33) Manifest.permission.READ_MEDIA_IMAGES else Manifest.permission.READ_EXTERNAL_STORAGE
)
} else {
photoProvider(
this,
1,
true,
REQUEST_CODE_OPEN_PHOTO_PROVIDER,
true,
true
)
if (Build.VERSION.SDK_INT >= 33){
DialogUtil.getDialog(this,object : EasyAlertDialogHelper.OnDialogActionListener {
override fun doCancelAction() {
}
override fun doOkAction() {
SPUtils.putBoolean(ConstantsLib.Key.Permissions_Img,true)
pickMedia?.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
}
})
}else{
if (!EasyPermissions.hasPermissions(
this,Manifest.permission.READ_EXTERNAL_STORAGE
)
) {
EasyPermissions.requestPermissions(
this,
getString(R.string.permission_storage_rationale),
PERMISSION_CODE_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE
)
} else {
photoProvider(
this,
1,
true,
REQUEST_CODE_OPEN_PHOTO_PROVIDER,
true,
true
)
}
}
}

View File

@@ -37,10 +37,12 @@ enum class PermissionEntity(
STORAGE(
ResUtil.getString(R.string.setting_bean_permissionentity_011), ResUtil.getString(R.string.setting_bean_permissionentity_012), R.drawable.icon_permission_storage,
arrayOf(
if (Build.VERSION.SDK_INT >= 33) Manifest.permission.READ_MEDIA_IMAGES else Manifest.permission.READ_EXTERNAL_STORAGE
Manifest.permission.READ_EXTERNAL_STORAGE
)
);
companion object {
fun fetchPermission(name: String): PermissionEntity? {
if (CoreTextUtils.isEmptyText(name)) return null

View File

@@ -11,6 +11,9 @@ import android.provider.Settings
import android.text.TextUtils
import android.view.View
import android.widget.ImageView
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager
import com.fourmob.datetimepicker.date.DatePickerDialog
@@ -42,13 +45,18 @@ import com.chwl.core.user.bean.UserDetailInfo
import com.chwl.core.user.bean.UserInfo
import com.chwl.core.user.bean.UserPhoto
import com.chwl.core.utils.CoreLogger
import com.chwl.core.utils.DialogUtil
import com.chwl.core.utils.LogUtils
import com.chwl.library.common.file.FileHelper
import com.chwl.library.common.photo.PhotoProvider
import com.chwl.library.common.util.PhotoCompressCallback
import com.chwl.library.common.util.PhotoCompressUtil
import com.chwl.library.common.util.SPUtils
import com.chwl.library.constants.ConstantsLib
import com.chwl.library.easypermisssion.EasyPermissions
import com.chwl.library.utils.ResUtil
import com.chwl.library.utils.TimeUtils
import com.netease.nim.uikit.common.ui.dialog.EasyAlertDialogHelper
import io.reactivex.Completable
import io.reactivex.SingleObserver
import io.reactivex.disposables.Disposable
@@ -95,10 +103,18 @@ class UserInfoModifyActivity : BaseViewBindingActivity<ActivityUserInfoModifyBin
userId = intent.getLongExtra("userId", 0)
}
var pickMedia : ActivityResultLauncher<PickVisualMediaRequest>?=null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
UserModel.get().getUserInfo(userId).subscribe(userInfoUpdateObserver)
PhotoCompressUtil.clearCompressCache()
if (ActivityResultContracts.PickVisualMedia.isPhotoPickerAvailable(this)) {
pickMedia = registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
crop(uri, 1, mUri)
}
}
}
override fun click(position: Int, userPhoto: UserPhoto, isOwner: Boolean) {
@@ -426,24 +442,30 @@ class UserInfoModifyActivity : BaseViewBindingActivity<ActivityUserInfoModifyBin
}
private fun checkStoragePermission() {
if (!EasyPermissions.hasPermissions(
this,
if (Build.VERSION.SDK_INT >= 33) Manifest.permission.READ_MEDIA_IMAGES else Manifest.permission.READ_EXTERNAL_STORAGE
)
) {
EasyPermissions.requestPermissions(
this,
getString(R.string.permission_storage_rationale),
PERMISSION_CODE_STORAGE,
if (Build.VERSION.SDK_INT >= 33) Manifest.permission.READ_MEDIA_IMAGES else Manifest.permission.READ_EXTERNAL_STORAGE
)
} else {
mUri = Uri.parse("file://${FileHelper.getRootCacheDir()?.path}/${getNowTime()}.jpg")
PhotoProvider.photoProvider(
this,
resultCode = REQUEST_CODE_OPEN_PHOTO_PROVIDER
)
if (Build.VERSION.SDK_INT >= 33){
DialogUtil.getDialog(this,object : EasyAlertDialogHelper.OnDialogActionListener {
override fun doCancelAction() {
}
override fun doOkAction() {
SPUtils.putBoolean(ConstantsLib.Key.Permissions_Img,true)
mUri = Uri.parse("file://${FileHelper.getRootCacheDir()?.path}/${getNowTime()}.jpg")
pickMedia?.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
}
})
}else{
if (!EasyPermissions.hasPermissions(this,Manifest.permission.READ_EXTERNAL_STORAGE)) {
EasyPermissions.requestPermissions(this, getString(R.string.permission_storage_rationale), PERMISSION_CODE_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE
)
} else {
mUri = Uri.parse("file://${FileHelper.getRootCacheDir()?.path}/${getNowTime()}.jpg")
PhotoProvider.photoProvider(this, resultCode = REQUEST_CODE_OPEN_PHOTO_PROVIDER)
}
}
}
private fun getNowTime(): String {
@@ -556,14 +578,16 @@ class UserInfoModifyActivity : BaseViewBindingActivity<ActivityUserInfoModifyBin
toast(R.string.text_bitmap_too_large)
return
}
if (sourceSize > 0) {
//不能上传图片的最小文件大小
CoreLogger.debug(TAG, "sourceSize: $sourceSize")
if (sourceSize < MIN_HEAD_PHOTO_SIZE) {
toast(R.string.text_bitmap_too_small)
return
}
}
// if (sourceSize > 0) {
// //不能上传图片的最小文件大小
// CoreLogger.debug(TAG, "sourceSize: $sourceSize")
// if (sourceSize < MIN_HEAD_PHOTO_SIZE) {
// toast(R.string.text_bitmap_too_small)
// return
// }
// }
val options = UCrop.Options().apply {
setCompressionQuality(100)
setShowCropGrid(false)

View File

@@ -11,6 +11,9 @@ import android.os.Bundle
import android.provider.Settings
import android.view.View
import android.widget.GridView
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
import com.hjq.toast.ToastUtils
import com.jph.takephoto.app.TakePhotoActivity
@@ -30,13 +33,17 @@ import com.chwl.core.user.UserModel
import com.chwl.core.user.bean.UserInfo
import com.chwl.core.user.bean.UserPhoto
import com.chwl.core.utils.CoreLogger
import com.chwl.core.utils.DialogUtil
import com.chwl.core.utils.net.BeanObserver
import com.chwl.library.common.file.FileHelper
import com.chwl.library.common.photo.PhotoProvider
import com.chwl.library.common.util.PhotoCompressCallback
import com.chwl.library.common.util.PhotoCompressUtil
import com.chwl.library.common.util.SPUtils
import com.chwl.library.constants.ConstantsLib
import com.chwl.library.easypermisssion.EasyPermissions
import com.chwl.library.utils.ResUtil
import com.netease.nim.uikit.common.ui.dialog.EasyAlertDialogHelper
import kotlinx.coroutines.Job
import java.io.FileNotFoundException
import java.text.SimpleDateFormat
@@ -57,6 +64,8 @@ class UserModifyPhotosActivity : TakePhotoActivity(), PhotoItemClickListener,
private var mUri: Uri? = null
private var mJob: Job? = null
var pickMedia : ActivityResultLauncher<PickVisualMediaRequest>?=null
companion object {
const val FLAG_CHANGE = "isChanged"
private const val TAG = "UserModifyPhotosActivit"
@@ -95,6 +104,14 @@ class UserModifyPhotosActivity : TakePhotoActivity(), PhotoItemClickListener,
if (userInfo != null) {
updateView()
}
if (ActivityResultContracts.PickVisualMedia.isPhotoPickerAvailable(this)) {
pickMedia = registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
uri?.let {
crop(it, 0, mUri)
}
}
}
}
private fun initView() {
@@ -219,24 +236,38 @@ class UserModifyPhotosActivity : TakePhotoActivity(), PhotoItemClickListener,
}
private fun checkStoragePermission() {
if (!EasyPermissions.hasPermissions(
this,
if (Build.VERSION.SDK_INT >= 33) Manifest.permission.READ_MEDIA_IMAGES else Manifest.permission.READ_EXTERNAL_STORAGE
)
) {
EasyPermissions.requestPermissions(
this,
getString(R.string.permission_storage_rationale),
PERMISSION_CODE_STORAGE,
if (Build.VERSION.SDK_INT >= 33) Manifest.permission.READ_MEDIA_IMAGES else Manifest.permission.READ_EXTERNAL_STORAGE
)
} else {
mUri = Uri.parse("file://${FileHelper.getRootCacheDir()?.path}/${getNowTime()}.jpg")
PhotoProvider.photoProvider(
this,
resultCode = REQUEST_CODE_OPEN_PHOTO_PROVIDER
)
if (Build.VERSION.SDK_INT >= 33){
DialogUtil.getDialog(this,object : EasyAlertDialogHelper.OnDialogActionListener {
override fun doCancelAction() {
}
override fun doOkAction() {
SPUtils.putBoolean(ConstantsLib.Key.Permissions_Img,true)
mUri = Uri.parse("file://${FileHelper.getRootCacheDir()?.path}/${getNowTime()}.jpg")
pickMedia?.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
}
})
}else{
if (!EasyPermissions.hasPermissions(
this, Manifest.permission.READ_EXTERNAL_STORAGE
)
) {
EasyPermissions.requestPermissions(
this,
getString(R.string.permission_storage_rationale),
PERMISSION_CODE_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE
)
} else {
mUri = Uri.parse("file://${FileHelper.getRootCacheDir()?.path}/${getNowTime()}.jpg")
PhotoProvider.photoProvider(
this,
resultCode = REQUEST_CODE_OPEN_PHOTO_PROVIDER
)
}
}
}
private fun getNowTime(): String {
@@ -309,14 +340,14 @@ class UserModifyPhotosActivity : TakePhotoActivity(), PhotoItemClickListener,
toast(R.string.text_bitmap_too_large)
return
}
if (sourceSize > 0) {
//不能上传图片的最小文件大小
CoreLogger.debug(TAG, "sourceSize: $sourceSize")
if (sourceSize < MIN_HEAD_PHOTO_SIZE) {
toast(R.string.text_bitmap_too_small)
return
}
}
// if (sourceSize > 0) {
// //不能上传图片的最小文件大小
// CoreLogger.debug(TAG, "sourceSize: $sourceSize")
// if (sourceSize < MIN_HEAD_PHOTO_SIZE) {
// toast(R.string.text_bitmap_too_small)
// return
// }
// }
val options = UCrop.Options().apply {
setCompressionQuality(100)
setShowCropGrid(false)

View File

@@ -2,6 +2,7 @@ package com.chwl.app.ui.widget;
import static com.chwl.app.ui.widget.magicindicator.GiftIndicator.TYPE_COUNTRY;
import static com.chwl.app.ui.widget.magicindicator.GiftIndicator.TYPE_CP;
import static com.chwl.app.ui.widget.magicindicator.GiftIndicator.TYPE_CUSTOM;
import static com.chwl.app.ui.widget.magicindicator.GiftIndicator.TYPE_LUCKY;
import static com.chwl.app.ui.widget.magicindicator.GiftIndicator.TYPE_NOBLE;
import static com.chwl.app.ui.widget.magicindicator.GiftIndicator.TYPE_NORMAL;
@@ -632,6 +633,8 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene
return TYPE_SUPER_LUCKY_24;
case GiftType.GIFT_TYPE_CP:
return TYPE_CP;
case GiftType.GIFT_TYPE_CUSTOM:
return TYPE_CUSTOM;
}
return TYPE_NORMAL;
}
@@ -729,6 +732,8 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene
currentGiftInfoList = getCountryGiftInfos();
}else if (position == TYPE_CP) {
currentGiftInfoList = getCpGiftInfos();
}else if (position == TYPE_CUSTOM) {
currentGiftInfoList = getCustomGiftInfos();
}
// 有贵族礼物才显示贵族礼物的tab
if (ListUtils.isListEmpty(nobleGiftInfos)) {
@@ -1240,6 +1245,12 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene
GiftType.GIFT_TYPE_CP);
}
private List<GiftInfo> getCustomGiftInfos() {
return GiftModel.get().getGiftInfosByType(
String.valueOf(AvRoomDataManager.get().getRoomUid()),
GiftType.GIFT_TYPE_CUSTOM);
}
private List<GiftInfo> getNobleGiftInfos() {
return GiftModel.get().getGiftInfoList(GiftType.GIFT_TYPE_VIP);
}

View File

@@ -84,6 +84,10 @@ public class GiftIndicator extends LinearLayout {
* cp礼物
*/
public static final int TYPE_CP = 10;
/**
* 定制礼物
*/
public static final int TYPE_CUSTOM = 11;
private List<GiftTab> tabList = new ArrayList<>();

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<base-config cleartextTrafficPermitted="false">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
@@ -10,6 +10,7 @@
<domain-config cleartextTrafficPermitted="true">
<!-- fengkongcloud.com 为默认值,如果通过 option.setUtl 设置的 url 为 http 连接(下小节将介绍),需要将此 url 如 proxy.example.com 添加到 domain-config 中 -->
<domain includeSubdomains="true">fengkongcloud.com</domain>
<domain includeSubdomains="true">beta.api.molistar.xyz</domain>
</domain-config>
</network-security-config>

View File

@@ -1,9 +1,12 @@
package com.chwl.app.community.publish.view;
import static androidx.core.content.ContentProviderCompat.requireContext;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.Editable;
@@ -18,17 +21,27 @@ import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.PickVisualMediaRequest;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityOptionsCompat;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.chwl.app.photo.BigPhotoActivity;
import com.chwl.app.photo.PagerOption;
import com.chwl.core.utils.CoreTextUtils;
import com.chwl.core.utils.DialogUtil;
import com.chwl.core.utils.MyUriUtils;
import com.chwl.library.common.util.SPUtils;
import com.chwl.library.constants.ConstantsLib;
import com.example.matisse.Matisse;
import com.google.android.flexbox.FlexboxLayout;
import com.hjq.toast.ToastUtils;
import com.netease.nim.uikit.StatusBarUtil;
import com.netease.nim.uikit.common.ui.dialog.EasyAlertDialogHelper;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.trello.rxlifecycle3.android.ActivityEvent;
import com.chwl.app.R;
@@ -60,6 +73,7 @@ import com.chwl.library.utils.ResUtil;
import com.chwl.library.utils.SingleToastUtil;
import com.example.matisse.internal.entity.CustomItem;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -111,6 +125,9 @@ public class PublishActivity extends BaseMvpActivity<IPublishView, PublishPresen
private Job mJob = null;
private ActivityResultLauncher<PickVisualMediaRequest> pickMedia;
public static void start(DialogManager manager, long worldId) {
if (beforeStart(manager)) {
return;
@@ -177,6 +194,66 @@ public class PublishActivity extends BaseMvpActivity<IPublishView, PublishPresen
// }
rlChooseGroup.setVisibility(View.GONE);
flGroup.setVisibility(View.GONE);
if (ActivityResultContracts.PickVisualMedia.isPhotoPickerAvailable(this)) {
pickMedia = registerForActivityResult(new ActivityResultContracts.PickVisualMedia(), new ActivityResultCallback<Uri>() {
@Override
public void onActivityResult(Uri uri) {
if (uri != null && uri.getPath() != null){
File file = MyUriUtils.INSTANCE.copyFile(PublishActivity.this, uri);
if (file != null) {
LogUtil.e("选择 file = "+file.getName());
LogUtil.e("选择 file = "+file.getPath());
if (mJob != null) {
mJob.cancel(null);
}
ArrayList<String> pathList = new ArrayList<>();
pathList.add(file.getPath());
mJob = PhotoCompressUtil.compress(PublishActivity.this, pathList,
PhotoCompressUtil.getCompressCachePath("publish")
, new PhotosCompressCallback() {
@Override
public void onSuccess(@NonNull ArrayList<String> compressedImgList) {
List<CustomItem> pathResult = new ArrayList<>();
for (int i = 0; i < compressedImgList.size(); i++) {
if (i < pathList.size()) {
List<String> fileInfo = MyUriUtils.INSTANCE.getFileInfo(file);
if (fileInfo != null) {
pathResult.add(new CustomItem(compressedImgList.get(i), CustomItem.IMAGE_NORMAL, fileInfo.get(2), Integer.parseInt(fileInfo.get(0)), Integer.parseInt(fileInfo.get(1))));
}
}
}
if (pathResult.size() == 0) {
return;
}
LogUtil.print(pathResult);
uploadList.addAll(pathResult);
updateImagesData();
isOriginalImage = false;
LogUtil.print("isOriginalImage:" + isOriginalImage);
SharedPreferenceUtils.put(KEY_SP_ORIGINAL_IMAGE, isOriginalImage);
}
@Override
public void onFail(@NonNull Throwable e) {
toast(getString(R.string.picker_image_error));
}
}, 200, false, Constants.UPLOAD_IMAGE_MAX_SIZE, Constants.UPLOAD_IMAGE_MAX_FILE_LENGTH);
}
}
}
});
}
}
private void findView() {
@@ -622,26 +699,36 @@ public class PublishActivity extends BaseMvpActivity<IPublishView, PublishPresen
}
private void checkStoragePermission() {
if (!EasyPermissions.hasPermissions(
this,
Build.VERSION.SDK_INT >= 33 ? Manifest.permission.READ_MEDIA_IMAGES : Manifest.permission.READ_EXTERNAL_STORAGE
)
) {
EasyPermissions.requestPermissions(
this,
getString(R.string.permission_storage_rationale),
PERMISSION_CODE_STORAGE,
Build.VERSION.SDK_INT >= 33 ? Manifest.permission.READ_MEDIA_IMAGES : Manifest.permission.READ_EXTERNAL_STORAGE
);
} else {
PhotoProvider.photoProvider(
this,
maxSelect - uploadList.size(),
true,
REQUEST_CODE_OPEN_PHOTO_PROVIDER,
true,
true
);
if (Build.VERSION.SDK_INT >= 33){
if (pickMedia != null){
DialogUtil.INSTANCE.getDialog(this,new EasyAlertDialogHelper.OnDialogActionListener() {
@Override
public void doCancelAction() {}
@Override
public void doOkAction() {
SPUtils.putBoolean(ConstantsLib.Key.Permissions_Img,true);
pickMedia.launch(new PickVisualMediaRequest.Builder().setMediaType(ActivityResultContracts.PickVisualMedia.ImageOnly.INSTANCE).build());
}
});
}
}else{
if (!EasyPermissions.hasPermissions(this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
EasyPermissions.requestPermissions(
this,
getString(R.string.permission_storage_rationale),
PERMISSION_CODE_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE
);
} else {
PhotoProvider.photoProvider(
this,
maxSelect - uploadList.size(),
true,
REQUEST_CODE_OPEN_PHOTO_PROVIDER,
true,
true
);
}
}
}

View File

@@ -3,11 +3,6 @@ package com.chwl.app.treasure_box.widget.dialog
import com.chwl.app.base.BaseDialogFragment
import com.chwl.app.databinding.DialogTreasureBoxBinding
import com.chwl.app.ui.pay.ChargeActivity
import com.chwl.app.ui.webview.CommonWebViewActivity
import com.chwl.core.Constants
import com.chwl.core.UriProvider
import com.chwl.library.common.util.DeviceUtil.getDeviceId
import com.chwl.library.utils.AppMetaDataUtil
/**
* author: wushaocheng

View File

@@ -47,7 +47,7 @@ android {
'src/model_treasure_box/java',
'src/model_sud_wrapper/java'
]
jniLibs.srcDirs = ['libs', 'umeng-app-libs/jniLibs']
// jniLibs.srcDirs = ['libs', 'umeng-app-libs/jniLibs']
}
}

View File

@@ -260,6 +260,9 @@ public class GiftModel extends BaseModel implements IGiftModel {
case GiftType.GIFT_TYPE_CP:
giftInfos = allGiftListInfo.getCpGift();
break;
case GiftType.GIFT_TYPE_CUSTOM:
giftInfos = allGiftListInfo.getCustomGift();
break;
}
return giftInfos == null ? new ArrayList<>() : giftInfos;
}

View File

@@ -22,5 +22,6 @@ public class GiftListInfo implements Serializable {
private List<GiftInfo> drawGift;
private List<GiftInfo> singlePopularGift;
private List<GiftInfo> cpGift;
private List<GiftInfo> customGift;
private String giftVersion;
}

View File

@@ -56,4 +56,9 @@ public class GiftType {
* cp礼物 - 支持连击
*/
public static final int GIFT_TYPE_CP = 19;
/**
* 定制礼物 - 支持连击
*/
public static final int GIFT_TYPE_CUSTOM = 20;
}

View File

@@ -35,6 +35,8 @@ public class TagsInfo implements Serializable {
return GiftType.GIFT_TYPE_SINGLE_ROOM;
} else if ("cpGift".equals(key)) {
return GiftType.GIFT_TYPE_CP;
}else if ("customGift".equals(key)) {
return GiftType.GIFT_TYPE_CUSTOM;
}
return 0;
}

View File

@@ -0,0 +1,32 @@
package com.chwl.core.utils
import android.app.Activity
import com.chwl.core.R
import com.chwl.library.common.util.SPUtils
import com.chwl.library.constants.ConstantsLib
import com.chwl.library.utils.ResUtil
import com.example.lib_utils.AppUtils
import com.netease.nim.uikit.common.ui.dialog.EasyAlertDialogHelper
object DialogUtil {
fun getDialog(activity: Activity, listener:EasyAlertDialogHelper.OnDialogActionListener){
if (!SPUtils.getBoolean(ConstantsLib.Key.Permissions_Img, false)) {
val dialog = EasyAlertDialogHelper.createOkCancelDiolag(
activity,
null,
ResUtil.getString(
R.string.dialot_permission_tips,
ResUtil.getString(R.string.app_name)
),
ResUtil.getString(R.string.Allow),
ResUtil.getString(R.string.No),
true,
listener
)
dialog.show()
} else {
listener.doOkAction()
}
}
}

View File

@@ -0,0 +1,74 @@
package com.chwl.core.utils
import android.content.Context
import android.database.Cursor
import android.graphics.BitmapFactory
import android.net.Uri
import android.provider.MediaStore
import androidx.activity.result.ActivityResultCallback
import java.io.File
import java.io.FileOutputStream
object MyUriUtils {
fun getName(context: Context, uri: Uri) : String?{
var fileName:String?=null
val projection = arrayOf(MediaStore.MediaColumns.DISPLAY_NAME)
val cursor : Cursor ? = context.contentResolver.query(
uri,
projection,
null,
null,
null
)
try {
cursor?.use {
if (it.moveToFirst()) {
fileName = it.getString(it.getColumnIndexOrThrow(MediaStore.MediaColumns.DISPLAY_NAME))
}
}
} catch (e: Exception) {
}
return fileName
}
fun copyFile(context: Context, uri: Uri) : File?{
val fileName = getName(context, uri)?:"defName.jpg"
val outPutDir = context.getExternalFilesDir(null)?:return null
val outPutFile = File(outPutDir,fileName)
if (!outPutDir.exists()) {
outPutDir.mkdirs()
}
context.contentResolver.openInputStream(uri)?.use { inS->
FileOutputStream(outPutFile).use{ outS->
inS.copyTo(outS)
}
return outPutFile
} ?: return null
}
fun getFileInfo(file: File) : MutableList<String>?{
var width = 0
var height = 0
var minType = "image/jpeg"
var data : MutableList<String> ?= null
BitmapFactory.Options().apply {
inJustDecodeBounds = true
BitmapFactory.decodeFile(file.absolutePath,this)
width = outWidth
height = outHeight
minType = outMimeType
}.let {
data =mutableListOf(width.toString(),height.toString(),minType)
}
return data
}
}

View File

@@ -684,4 +684,8 @@
<string name="pk_refuse">رفض الطرف الآخر طلب الـ PK</string>
<string name="common_operation_prompt_format">(%s)فشلت العملية</string>
<string name="dialot_permission_tips">" السماح لـ %s بالوصول إلى الصور على جهازك؟ ا"</string>
<string name="Allow">السماح</string>
<string name="No">لا</string>
<string name="Custom">مخصص</string>
</resources>

View File

@@ -672,4 +672,8 @@
<string name="pk_refuse">對方拒絕你的PK請求</string>
<string name="common_operation_prompt_format">操作失敗 (%s)</string>
<string name="dialot_permission_tips">允許 %s 存取裝置上的相片?</string>
<string name="Allow">允許</string>
<string name="No">不允許</string>
<string name="Custom">定制</string>
</resources>

View File

@@ -666,5 +666,12 @@
<string name="pk_refuse">The opponent rejected your PK request</string>
<string name="common_operation_prompt_format">operation failed (%s)</string>
<string name="dialot_permission_tips">Allow %s to access photos on your device?</string>
<string name="Allow">Allow</string>
<string name="No">No</string>
<string name="Custom">Custom</string>
</resources>

View File

@@ -105,7 +105,7 @@ dependencies {
api 'io.github.razerdp:BasePopup:3.2.1'
api 'com.umeng.sdk:utdid:1.1.5.3'
// api 'com.umeng.sdk:utdid:1.1.5.3'
// api 'com.facebook.android:facebook-android-sdk:16.2.0'
// api 'com.facebook.android:facebook-login:16.2.0'

View File

@@ -3,9 +3,9 @@
xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission tools:node="remove" android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission tools:node="remove" android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"

View File

@@ -0,0 +1,7 @@
package com.chwl.library.constants;
public @interface ConstantsLib {
public @interface Key{
String Permissions_Img = "Permissions_Img";
}
}

View File

@@ -8,9 +8,9 @@ import android.os.Process
import android.provider.Settings
import android.telephony.TelephonyManager
import android.text.TextUtils
import com.ut.device.UTDevice
import com.chwl.library.common.application.BaseApp
import java.io.RandomAccessFile
import java.nio.charset.StandardCharsets
import java.util.*
/**
@@ -163,7 +163,9 @@ object DeviceUtil {
if (!TextUtils.isEmpty(deviceId)) {
return deviceId
}
deviceId = UTDevice.getUtdid(context)
context?.let {
deviceId = getUUDeviceId(it)
}
if (TextUtils.isEmpty(deviceId)) {
deviceId = handyDevicesId
LibLogger.info(TAG, "use handy deviceId=$deviceId")
@@ -311,4 +313,24 @@ object DeviceUtil {
HIGH(2), LOW(1);
}
private var UU_DEVICE_ID by mmkv.notNullString()
@JvmStatic
@SuppressLint("HardwareIds")
fun getUUDeviceId(context: Context): String {
synchronized(DeviceUtil::class.java) {
if (UU_DEVICE_ID.isEmpty()) {
val androidId =
Settings.Secure.getString(context.contentResolver, Settings.Secure.ANDROID_ID)
val uuid = if ("9774d56d682e549c" != androidId) {
UUID.nameUUIDFromBytes(androidId.toByteArray(StandardCharsets.UTF_8))
} else {
UUID.randomUUID()
}
UU_DEVICE_ID = uuid.toString()
}
}
return UU_DEVICE_ID
}
}

View File

@@ -0,0 +1,120 @@
package com.chwl.library.common.util
import android.os.Parcelable
import com.tencent.mmkv.MMKV
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
/**
* @Author Vance
* Date2023/09/08 0008 17:53
*/
val mmkv by lazy {
MMKV.defaultMMKV()
}
private inline fun <T> MMKV.delegate(
key: String? = null,
defaultValue: T,
crossinline getter: MMKV.(String?, T) -> T?,
crossinline setter: MMKV.(String, T) -> Boolean
): ReadWriteProperty<Any, T> =
object : ReadWriteProperty<Any, T> {
override fun getValue(thisRef: Any, property: KProperty<*>): T =
getter(key ?: property.name, defaultValue) ?: defaultValue
override fun setValue(thisRef: Any, property: KProperty<*>, value: T) {
setter(key ?: property.name, value)
}
}
fun MMKV.boolean(
key: String? = null,
defaultValue: Boolean = false
): ReadWriteProperty<Any, Boolean> =
delegate(key, defaultValue, MMKV::decodeBool, MMKV::encode)
fun MMKV.int(key: String? = null, defaultValue: Int = 0): ReadWriteProperty<Any, Int> =
delegate(key, defaultValue, MMKV::decodeInt, MMKV::encode)
fun MMKV.long(key: String? = null, defaultValue: Long = 0L): ReadWriteProperty<Any, Long> =
delegate(key, defaultValue, MMKV::decodeLong, MMKV::encode)
fun MMKV.float(key: String? = null, defaultValue: Float = 0.0F): ReadWriteProperty<Any, Float> =
delegate(key, defaultValue, MMKV::decodeFloat, MMKV::encode)
fun MMKV.double(key: String? = null, defaultValue: Double = 0.0): ReadWriteProperty<Any, Double> =
delegate(key, defaultValue, MMKV::decodeDouble, MMKV::encode)
fun MMKV.notNullString(key: String? = null): ReadWriteProperty<Any, String> =
string(key, "")
fun MMKV.string(key: String? = null, defaultValue: String): ReadWriteProperty<Any, String> =
delegate(key, defaultValue, MMKV::decodeString, MMKV::encode)
fun MMKV.byteArray(
key: String? = null,
defaultValue: ByteArray
): ReadWriteProperty<Any, ByteArray> =
delegate(key, defaultValue, MMKV::decodeBytes, MMKV::encode)
fun MMKV.stringSet(
key: String? = null,
defaultValue: Set<String>
): ReadWriteProperty<Any, Set<String>> =
delegate(key, defaultValue, MMKV::decodeStringSet, MMKV::encode)
private inline fun <T> MMKV.nullableDelegate(
key: String? = null,
crossinline getter: MMKV.(String?, T?) -> T?,
crossinline setter: MMKV.(String, T?) -> Boolean
): ReadWriteProperty<Any, T?> =
object : ReadWriteProperty<Any, T?> {
override fun getValue(thisRef: Any, property: KProperty<*>): T? =
getter(key ?: property.name, null)
override fun setValue(thisRef: Any, property: KProperty<*>, value: T?) {
setter(key ?: property.name, value)
}
}
fun MMKV.byteArray(
key: String? = null,
): ReadWriteProperty<Any, ByteArray?> =
nullableDelegate(key, MMKV::decodeBytes, MMKV::encode)
fun MMKV.string(
key: String? = null,
): ReadWriteProperty<Any, String?> =
nullableDelegate(key, MMKV::decodeString, MMKV::encode)
fun MMKV.stringSet(
key: String? = null,
): ReadWriteProperty<Any, Set<String>?> =
nullableDelegate(key, MMKV::decodeStringSet, MMKV::encode)
inline fun <reified T : Parcelable> MMKV.parcelable(
key: String? = null,
defaultValue: T
): ReadWriteProperty<Any, T> =
object : ReadWriteProperty<Any, T> {
override fun getValue(thisRef: Any, property: KProperty<*>): T =
decodeParcelable(key ?: property.name, T::class.java, defaultValue)?:defaultValue
override fun setValue(thisRef: Any, property: KProperty<*>, value: T) {
encode(key ?: property.name, value)
}
}
inline fun <reified T : Parcelable> MMKV.parcelable(
key: String? = null,
): ReadWriteProperty<Any, T?> =
object : ReadWriteProperty<Any, T?> {
override fun getValue(thisRef: Any, property: KProperty<*>): T? =
decodeParcelable(key ?: property.name, T::class.java)
override fun setValue(thisRef: Any, property: KProperty<*>, value: T?) {
encode(key ?: property.name, value)
}
}

View File

@@ -60,8 +60,7 @@ public class AlbumModel {
public void query(Context context, final CallBack callBack) {
final Context appCxt = context.getApplicationContext();
if (PermissionChecker.checkSelfPermission(context,
Build.VERSION.SDK_INT >= 33 ? Manifest.permission.READ_MEDIA_IMAGES : Manifest.permission.READ_EXTERNAL_STORAGE) != PermissionChecker.PERMISSION_GRANTED) {
if (PermissionChecker.checkSelfPermission(context,Manifest.permission.READ_EXTERNAL_STORAGE) != PermissionChecker.PERMISSION_GRANTED) {
if (null != callBack) callBack.onAlbumWorkedCallBack();
return;
}

View File

@@ -40,6 +40,10 @@ public class Photo implements Parcelable {
this.selectedOriginal = false;
}
public Photo(String path) {
this.path = path;
}
@Override
public boolean equals(Object o) {
try {

View File

@@ -209,10 +209,9 @@ public class EasyPhotosActivity extends AppCompatActivity implements AlbumItemsA
protected String[] getNeedPermissions() {
if (Setting.isShowCamera) {
return new String[]{Manifest.permission.CAMERA,
Build.VERSION.SDK_INT >= 33 ? Manifest.permission.READ_MEDIA_IMAGES : Manifest.permission.READ_EXTERNAL_STORAGE};
return new String[]{Manifest.permission.CAMERA,Manifest.permission.READ_EXTERNAL_STORAGE};
} else {
return new String[]{Build.VERSION.SDK_INT >= 33 ? Manifest.permission.READ_MEDIA_IMAGES : Manifest.permission.READ_EXTERNAL_STORAGE};
return new String[]{Manifest.permission.READ_EXTERNAL_STORAGE};
}
}

View File

@@ -581,8 +581,7 @@ public class PuzzleActivity extends AppCompatActivity implements View.OnClickLis
}
protected String[] getNeedPermissions() {
return new String[]{Manifest.permission.CAMERA,
Build.VERSION.SDK_INT >= 33 ? Manifest.permission.READ_MEDIA_IMAGES : Manifest.permission.READ_EXTERNAL_STORAGE};
return new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE};
}
@Override

View File

@@ -2,6 +2,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:background="@color/easy_photos_bg_primary"
android:fitsSystemWindows="true">
@@ -39,7 +40,8 @@
android:paddingTop="8dp"
android:layout_below="@+id/degree_seek_bar"
android:orientation="horizontal"
android:visibility="gone">
android:visibility="gone"
tools:visibility="visible">
<ImageView
android:id="@+id/iv_replace"

View File

@@ -146,6 +146,12 @@
android:configChanges="keyboardHidden"
android:theme="@style/DarkTheme"/>
<!-- 33 以上选择图片 的 透明 Activity-->
<activity android:name=".common.activity.NimPhotoPickActivity"
android:configChanges="keyboardHidden"
android:launchMode="singleTop"
android:theme="@style/dialogactivity"/>
<provider
android:name="com.netease.nim.uikit.common.media.picker.model.GenericFileProvider"

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:background="@color/transparent"
android:layout_height="match_parent">
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -444,4 +444,9 @@
<string name="impl_customization_defaultrecentcustomization_08">[رسالة مخصصة]</string>
<string name="xchat_android_core_file_filemodel_01">الملف فارغ أو لا يوجد!</string>
<string name="dialot_permission_tips_nim">" السماح لـ %s بالوصول إلى الصور على جهازك؟ ا"</string>
<string name="Allow_nim">السماح</string>
<string name="No_nim">لا</string>
</resources>

View File

@@ -431,4 +431,10 @@
<string name="impl_customization_defaultrecentcustomization_08">[自定義消息] </string>
<string name="xchat_android_core_file_filemodel_01"> 為空或者該文件不存在!</string>
<string name="dialot_permission_tips_nim">允許 %s 存取裝置上的相片?</string>
<string name="Allow_nim">允許</string>
<string name="No_nim">不允許</string>
</resources>

View File

@@ -432,4 +432,10 @@
<string name="impl_customization_defaultrecentcustomization_08">[Custom Message] </string>
<string name="xchat_android_core_file_filemodel_01"> is empty or the file does not exist!</string>
<string name="dialot_permission_tips_nim">Allow %s to access photos on your device?</string>
<string name="Allow_nim">Allow</string>
<string name="No_nim">No</string>
</resources>

View File

@@ -49,4 +49,24 @@
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="dialogactivity" parent="Theme.AppCompat.Dialog">
<item name="android:windowFullscreen">true</item>
<!--设置dialog的背景-->
<item name="android:windowBackground">@android:color/transparent</item>
<!--设置Dialog的windowFrame框为无-->
<item name="android:windowFrame">@null</item>
<!--设置无标题-->
<item name="windowNoTitle">true</item>
<!--是否浮现在activity之上-->
<item name="android:windowIsFloating">true</item>
<!--是否半透明-->
<item name="android:windowIsTranslucent">true</item>
<!--设置窗口内容不覆盖-->
<item name="android:windowContentOverlay">@null</item>
<!--设置动画在这里使用让它继承系统的Animation.Dialog-->
<item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
<!--背景是否模糊显示-->
<item name="android:backgroundDimEnabled">true</item>
</style>
</resources>

View File

@@ -1,9 +1,9 @@
package com.netease.nim.uikit.business.session.actions
import android.content.Intent
import android.os.Build
import android.text.TextUtils
import com.netease.nim.uikit.R
import com.netease.nim.uikit.business.session.helper.SendImageHelper
import androidx.activity.result.contract.ActivityResultContracts
import com.chwl.library.common.application.BaseApp
import com.chwl.library.common.base.BaseDialogFragment
import com.chwl.library.common.photo.PhotoProvider
@@ -11,8 +11,12 @@ import com.chwl.library.common.util.PhotoCompressUtil
import com.chwl.library.common.util.PhotosCompressCallback
import com.chwl.library.utils.ResUtil
import com.chwl.library.utils.SingleToastUtil
import com.netease.nim.uikit.R
import com.netease.nim.uikit.business.session.helper.SendImageHelper
import com.netease.nim.uikit.common.activity.NimPhotoPickActivity
import java.io.File
/**
* Created by zhoujianghua on 2015/7/31.
*/
@@ -33,11 +37,15 @@ abstract class PickImageActionNew protected constructor(
}
private fun checkStoragePermission() {
PhotoProvider.photoProvider(
activity,
maxSelect = 9,
resultCode = makeRequestCode(REQUEST_CODE_OPEN_PHOTO_PROVIDER)
)
if (Build.VERSION.SDK_INT >= 33) {
activity.startActivityForResult(Intent(activity,NimPhotoPickActivity::class.java),makeRequestCode(REQUEST_CODE_OPEN_PHOTO_PROVIDER))
} else {
PhotoProvider.photoProvider(
activity,
maxSelect = 9,
resultCode = makeRequestCode(REQUEST_CODE_OPEN_PHOTO_PROVIDER)
)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
@@ -79,6 +87,8 @@ abstract class PickImageActionNew protected constructor(
}
}
/**
* 发送图片
*/

View File

@@ -0,0 +1,144 @@
package com.netease.nim.uikit.common.activity
import android.content.Context
import android.content.Intent
import android.database.Cursor
import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import android.view.Window
import android.view.WindowManager
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import com.chwl.library.common.util.SPUtils
import com.chwl.library.constants.ConstantsLib
import com.chwl.library.easyphoto.EasyPhotos
import com.chwl.library.easyphoto.models.album.entity.Photo
import com.chwl.library.easyphoto.setting.Setting
import com.chwl.library.utils.ResUtil
import com.example.lib_utils.AppUtils
import com.netease.nim.uikit.R
import com.netease.nim.uikit.common.ui.dialog.EasyAlertDialog
import com.netease.nim.uikit.common.ui.dialog.EasyAlertDialogHelper
import java.io.File
import java.io.FileOutputStream
class NimPhotoPickActivity : AppCompatActivity() {
var pickMedia : ActivityResultLauncher<PickVisualMediaRequest>?=null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.nim_photo_pick_activity)
// requestWindowFeature(Window.FEATURE_NO_TITLE)
// window.setFlags(
// WindowManager.LayoutParams.FLAG_FULLSCREEN,
// WindowManager.LayoutParams.FLAG_FULLSCREEN
// )
if (ActivityResultContracts.PickVisualMedia.isPhotoPickerAvailable(this)) {
pickMedia = registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
if (uri != null) {
val file = copyFile(this@NimPhotoPickActivity, uri)
if (file != null) {
val resultList = ArrayList<Photo>()
val data = Intent()
resultList.add(Photo(file.path))
data.putParcelableArrayListExtra(EasyPhotos.RESULT_PHOTOS, resultList)
setResult(RESULT_OK, data)
finish()
}
} else {
finish()
}
}
}
}
var isFirst = true
var dialog : EasyAlertDialog ?=null
override fun onResume() {
super.onResume()
if (!isFirst) {
finish()
return
}
if (!SPUtils.getBoolean(ConstantsLib.Key.Permissions_Img,false)){
dialog = EasyAlertDialogHelper.createOkCancelDiolag(
this,
null,
ResUtil.getString(
R.string.dialot_permission_tips_nim,
ResUtil.getString(R.string.app_name)
),
ResUtil.getString(R.string.Allow_nim),
ResUtil.getString(R.string.No_nim),
false,
object : EasyAlertDialogHelper.OnDialogActionListener {
override fun doCancelAction() {
finish()
}
override fun doOkAction() {
SPUtils.putBoolean(ConstantsLib.Key.Permissions_Img,true)
pickMedia?.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
}
})
if (dialog?.isShowing == false) {
dialog?.show()
}
}else{
pickMedia?.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))
}
isFirst = false
}
private fun getName(context: Context, uri: Uri) : String?{
var fileName:String?=null
val projection = arrayOf(MediaStore.MediaColumns.DISPLAY_NAME)
val cursor : Cursor? = context.contentResolver.query(
uri,
projection,
null,
null,
null
)
try {
cursor?.use {
if (it.moveToFirst()) {
fileName = it.getString(it.getColumnIndexOrThrow(MediaStore.MediaColumns.DISPLAY_NAME))
}
}
} catch (e: Exception) {
}
return fileName
}
private fun copyFile(context: Context, uri: Uri) : File?{
val fileName = getName(context, uri)?:"defName.jpg"
val outPutDir = context.getExternalFilesDir(null)?:return null
val outPutFile = File(outPutDir,fileName)
if (!outPutDir.exists()) {
outPutDir.mkdirs()
}
context.contentResolver.openInputStream(uri)?.use { inS->
FileOutputStream(outPutFile).use{ outS->
inS.copyTo(outS)
}
return outPutFile
} ?: return null
}
}