700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 解决小米手机裁剪图片崩溃问题

解决小米手机裁剪图片崩溃问题

时间:2024-05-19 03:48:59

相关推荐

解决小米手机裁剪图片崩溃问题

这里写自定义目录标题

github地址 /JI577/ChoosePicture调用方式基本配置权限providerfile_path 封装 BasePhotoActivity Kotlin底部弹框 PopupWindow动画样式 stylesalpha_inalpha_out 裁剪方法

github地址 /JI577/ChoosePicture

调用方式

class MainActivity : BasePhotoActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)tvPic.setOnClickListener {if (checkPermission()) {showDialog()}}}override fun showDialog() {getPopView().showAtLocation(llAll, Gravity.BOTTOM, 0, 0)}override fun getHeadNet(file: File) {Log.e("jrq", "File path----" + file.absolutePath)tvContent.text = file!!.absolutePath}}

基本配置

权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.CAMERA" />

provider

<providerandroid:name="android.support.v4.content.FileProvider"android:authorities="com.wj577.choosepicture.FileProvider"android:exported="false"android:grantUriPermissions="true"><meta-dataandroid:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/file_path" /></provider>

file_path

<?xml version="1.0" encoding="utf-8"?><paths xmlns:android="/apk/res/android"><external-path name="rc_external_path" path="."/>

封装 BasePhotoActivity Kotlin

open abstract class BasePhotoActivity : FragmentActivity() {private val REQUESTCODE_PICK = 0x121 // 相册选图标记val RESULT_COD = 102var picDialog: SelectPicPopupwindow? = nullprivate val mFile_Pic: File? = null// 存储图片的文件private val permissions = arrayOf(Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE)private var dialog: AlertDialog? = nullprivate var mBitmap: Bitmap? = nullfun getPopView(): SelectPicPopupwindow {if (null == picDialog) {headPic()}return picDialog!!}fun checkPermission(): Boolean {// 版本判断。当手机系统大于 23 时,才有必要去判断权限是否获取if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {for (permission in permissions) {// 检查该权限是否已经获取val i = ContextCompat.checkSelfPermission(this, permission)// 权限是否已经 授权 GRANTED---授权 DINIED---拒绝if (i != PackageManager.PERMISSION_GRANTED) {// 如果没有授予该权限,就去提示用户请求showDialogTipUserRequestPermission()return false}}}return true}fun showDialogTipUserRequestPermission() {AlertDialog.Builder(this).setTitle("存储权限不可用").setMessage("由于选取照片和拍照需要手机的部分权限,否则您将不能使用该应用的全部功能").setPositiveButton("立即开启") {dialog, which -> startRequestPermission() }.setNegativeButton("取消") {dialog, which -> finish() }.setCancelable(false).show()}fun startRequestPermission() {ActivityCompat.requestPermissions(this, permissions, 321)}override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {super.onRequestPermissionsResult(requestCode, permissions, grantResults)if (requestCode == 321) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {// 判断用户是否 点击了不再提醒。(检测该权限是否还可以申请)val b = shouldShowRequestPermissionRationale(permissions[0])if (!b) {// 用户还是想用我的 APP 的// 提示用户去应用设置界面手动开启权限showDialogTipUserGoToAppSettting()} elsefinish()} else {//picDialog!!.showAtLocation(llAll, Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL, 0, 0)showDialog()}}}}fun showDialogTipUserGoToAppSettting() {dialog = AlertDialog.Builder(this).setTitle("存储权限不可用").setMessage("请在-应用设置-权限-中,允许本应用使用相机的相应权限来启用拍照等功能").setPositiveButton("立即开启") {dialog, which ->// 跳转到应用设置界面goToAppSetting()}.setNegativeButton("取消") {dialog, which -> finish() }.setCancelable(false).show()}fun headPic() {picDialog = SelectPicPopupwindow(this, View.OnClickListener {v ->when (v.id) {//拍照R.id.btn_take_photo -> getPicCamera()//相册R.id.btn_pick_photo -> selectPicture()}picDialog!!.dismiss()}, SelectPicPopupwindow.PHOTO)}private var mPictureFile: String? = nullprivate var filePath: String? = nullprivate val OPEN_RESULT2 = 0x124 // 打开相机2fun getPicCamera() {val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)intent.addCategory(Intent.CATEGORY_DEFAULT)// 取当前时间为照片名mPictureFile = DateFormat.format("yyyyMMdd_hhmmss",Calendar.getInstance(Locale.CHINA)).toString() + ".jpg"// Log.d("onactivity", "mPictureFile:" + mPictureFile);filePath = getPhotoPath() + mPictureFile!!// mFile_Pics[position] = getPhotoPath() + mPictureFile;// // 通过文件创建一个uri中// Uri imageUri = Uri.fromFile(new File(filePath));// // 保存uri对应的照片于指定路径// intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);// startActivityForResult(intent, OPEN_RESULT2);/*获取当前系统的android版本号*/val currentapiVersion = android.os.Build.VERSION.SDK_INTLog.e("jrq", "currentapiVersion====>$currentapiVersion")if (currentapiVersion < 24) {// 保存uri对应的照片于指定路径intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(File(filePath!!)))startActivityForResult(intent, OPEN_RESULT2)} else {val contentValues = ContentValues(1)contentValues.put(MediaStore.Images.Media.DATA, filePath)val uri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)intent.putExtra(MediaStore.EXTRA_OUTPUT, uri)startActivityForResult(intent, OPEN_RESULT2)}}/*** 获得照片路径** @return*/fun getPhotoPath(): String {return Environment.getExternalStorageDirectory().toString() + "/DCIM/"}fun goToAppSetting() {val intent = Intent()intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGSval uri = Uri.fromParts("package", packageName, null)intent.data = uristartActivityForResult(intent, 123)}/*** 选择图片*/fun selectPicture() {val intent = Intent()intent.action = Intent.ACTION_PICK//Pick an item from the dataintent.type = "image/*"//从所有图片中进行选择startActivityForResult(intent, REQUESTCODE_PICK)}override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {super.onActivityResult(requestCode, resultCode, data)if (requestCode == RESULT_COD) {//裁剪// if (data != null) {//setPicParam(data)// }setPicParam()}/**修改相机 */if (requestCode == OPEN_RESULT2) {if (resultCode == Activity.RESULT_OK) {var uri: Uri? = nullif (Build.VERSION.SDK_INT >= 24) {uri = FileProvider.getUriForFile(this, packageName + ".FileProvider", File(filePath))} else {uri = Uri.fromFile(File(filePath))}startPhotoZoom(uri)}}if (resultCode == Activity.RESULT_OK)when (requestCode) {REQUESTCODE_PICK//相册-> startPhotoZoom(data!!.data)}}var uritempFile :Uri?=nullprivate fun startPhotoZoom(uri: Uri) {val intent = Intent("com.android.camera.action.CROP")if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)}intent.setDataAndType(uri, "image/*")//是否可裁剪intent.putExtra("corp", "true")//裁剪器高宽比intent.putExtra("aspectY", 1)intent.putExtra("aspectX", 1)//设置裁剪框高宽intent.putExtra("outputX", 300)intent.putExtra("outputY", 300)//返回数据// intent.putExtra("return-data", true)uritempFile = Uri.parse("file://" + "/" + Environment.getExternalStorageDirectory().getPath() + "/" + "small.jpg");intent.putExtra(MediaStore.EXTRA_OUTPUT, uritempFile);intent.putExtra("outputFormat", pressFormat.JPEG.toString());startActivityForResult(intent, RESULT_COD)}private fun setPicParam(data: Intent) {val bundle = data.extrasif (bundle != null) {mBitmap = bundle.getParcelable<Bitmap>("data")Log.e("jrq","---mBitmap-------"+mBitmap)val file = compressImage(mBitmap!!)if (file.exists()) {getHeadNet(file)}}}private fun setPicParam() {mBitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uritempFile));Log.e("jrq","---mBitmap-------"+mBitmap)val file = compressImage(mBitmap!!)if (file.exists()) {getHeadNet(file)}}fun compressImage(bitmap: Bitmap): File {val baos = ByteArrayOutputStream()press(pressFormat.JPEG, 100, baos)//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中var options = 100while (baos.toByteArray().size / 1024 > 500) {//循环判断如果压缩后图片是否大于500kb,大于继续压缩baos.reset()//重置baos即清空baosoptions -= 10//每次都减少press(pressFormat.JPEG, options, baos)//这里压缩options%,把压缩后的数据存放到baos中val length = baos.toByteArray().size.toLong()}val format = SimpleDateFormat("yyyyMMddHHmmss")val date = Date(System.currentTimeMillis())val filename = format.format(date)val file = File(Environment.getExternalStorageDirectory(), "$filename.png")try {val fos = FileOutputStream(file)try {fos.write(baos.toByteArray())fos.flush()fos.close()} catch (e: IOException) {e.printStackTrace()}} catch (e: FileNotFoundException) {Log.e("jrq", e.message)e.printStackTrace()}recycleBitmap(bitmap)return file}fun recycleBitmap(vararg bitmaps: Bitmap) {if (bitmaps == null) {return}for (bm in bitmaps) {if (null != bm && !bm.isRecycled) {bm.recycle()}}}abstract fun showDialog()abstract fun getHeadNet(file: File)}

底部弹框 PopupWindow

public class SelectPicPopupwindow extends PopupWindow {private TextView btn_take_photo, btn_pick_photo, btn_cancel;private View mMenuView;public SelectPicPopupwindow(Context context, OnClickListener itemsOnClick, int option) {super(context);LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);mMenuView = inflater.inflate(R.layout.photo_window_view, null);btn_take_photo = (TextView) mMenuView.findViewById(R.id.btn_take_photo);btn_pick_photo = (TextView) mMenuView.findViewById(R.id.btn_pick_photo);btn_cancel = (TextView) mMenuView.findViewById(R.id.btn_cancel);// 取消按钮btn_cancel.setOnClickListener(new OnClickListener() {public void onClick(View v) {// 销毁弹出框dismiss();}});// 设置按钮监听btn_pick_photo.setOnClickListener(itemsOnClick);btn_take_photo.setOnClickListener(itemsOnClick);// 设置SelectPicPopupWindow的Viewthis.setContentView(mMenuView);// 设置SelectPicPopupWindow弹出窗体的宽this.setWidth(LayoutParams.MATCH_PARENT);// 设置SelectPicPopupWindow弹出窗体的高this.setHeight(LayoutParams.WRAP_CONTENT);// 设置SelectPicPopupWindow弹出窗体可点击this.setFocusable(true);// 设置SelectPicPopupWindow弹出窗体动画效果this.setAnimationStyle(R.style.popupAnimation);// 实例化一个ColorDrawable颜色为半透明ColorDrawable dw = new ColorDrawable(0xaa000000);// 设置SelectPicPopupWindow弹出窗体的背景this.setBackgroundDrawable(dw);// mMenuView添加OnTouchListener监听判断获取触屏位置如果在选择框外面则销毁弹出框}}

动画样式 styles

<!--淡入淡出popupwindow --><style name="popupAnimation" parent="android:Animation"><item name="android:windowEnterAnimation">@anim/alpha_in</item><item name="android:windowExitAnimation">@anim/alpha_out</item></style>

alpha_in

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="/apk/res/android"> <alpha android:fromAlpha="0.0"android:toAlpha="0.5"android:duration="0"/><translateandroid:duration="0"android:fromYDelta="100%p"android:toYDelta="0" /></set><!-- fromAlpha:开始时透明度 toAlpha:结束时透明度 duration:动画持续时间 淡入-->

alpha_out

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="/apk/res/android"><translateandroid:duration="0"android:fromYDelta="0"android:toYDelta="50%p" /><alphaandroid:duration="0"android:fromAlpha="0.5"android:toAlpha="0.0" /></set> <!-- fromAlpha:开始时透明度 toAlpha:结束时透明度 duration:动画持续时间 淡出-->

裁剪方法

private fun startPhotoZoom(uri: Uri) {val intent = Intent("com.android.camera.action.CROP")if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)}//intent.setDataAndType(uri, "image/*")//是否可裁剪intent.putExtra("corp", "true")//裁剪器高宽比intent.putExtra("aspectY", 1)intent.putExtra("aspectX", 1)//设置裁剪框高宽intent.putExtra("outputX", 300)intent.putExtra("outputY", 300)//返回数据intent.putExtra("return-data", true)uritempFile = Uri.parse("file://" + "/" + Environment.getExternalStorageDirectory().getPath() + "/" + "small.jpg");intent.putExtra(MediaStore.EXTRA_OUTPUT, uritempFile);intent.putExtra("outputFormat", pressFormat.JPEG.toString());startActivityForResult(intent, RESULT_COD)}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。