欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android kotlin上传头像实现

程序员文章站 2022-03-21 18:38:56
Android 上传头像基本上是每个app都有的功能,虽然看起来简单,但是作为新手的我实现起来却没有那么简单,实现如下从相册获取照片,代码如下 //从相册获取照片 private fun getFromAlbum() { val intent = Intent() intent.action = Intent.ACTION_GET_CONTENT intent.type = "image/*" startActivityFor...

Android 上传头像基本上是每个app都有的功能,虽然看起来简单,但是作为新手的我实现起来却没有那么简单,实现如下

  1. 从相册获取照片,代码如下
  //从相册获取照片
    private fun getFromAlbum() {
        val intent = Intent()
        intent.action = Intent.ACTION_GET_CONTENT
        intent.type = "image/*"
        startActivityForResult(intent, FROM_ALBUM_SUCCEED)
    }

2.拍照获取照片

//拍照获取照片
    @SuppressLint("SimpleDateFormat")
    private fun takePhotoTest() {
        val intent2 = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
        val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
        val imageFileName = "JPEG_$timeStamp"
        val file = File(Environment.getExternalStorageDirectory().path, "${imageFileName}.jpg")
        cameraImagePath = file.path
        val uri: Uri
        uri = if (Build.VERSION.SDK_INT >= 24) {
            FileProvider.getUriForFile(context!!, "com.wayeal.wateraffair.user.fileprovider", file)
        } else {
            Uri.fromFile(file)
        }
        camearImageUri = uri
        intent2.putExtra(MediaStore.EXTRA_OUTPUT, uri)
        startActivityForResult(intent2, CODE_TAKE_PHOTO)
    }

其中camearImageUri为拍照图片的uri
cameraImagePath为拍照图片的路径
在拍照过程中用到了fileprovider,如果对这一部分不了解的可以了解一下
3.在AndroidManifest.xml中添加下列语句

 <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.wayeal.wateraffair.user.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>

以上拍照和在相册获取照片就解决了,但是我们是拍照了,但是获取的图片在哪呢,不要急重写下列函数,获取结果

override  fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) {
            FROM_ALBUM_SUCCEED -> {//从相册获取成功
                try {
                        imageUri = data?.data
                        realPathFromUri = RealPathFromUriUtils.getRealPathFromUri(context, imageUri)
                        upImage(FROM_ALBUM)//这里实现文件上传服务器,如不需要可以直接设置显示
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
            CODE_TAKE_PHOTO -> {//拍照获取成功
                upImage(FROM_PHOTO)//这里实现文件上传服务器,如不需要可以直接设置显示
                if (resultCode == RESULT_CANCELED) {
                    context?.let { delteImageUri(it, imageUri) }
                    return
                }
            }
            else -> {
            }
        }
    }

在上传服务器是会出现文件找不到问题
在AndroidManifest.xml的application中添加下列语句

android:usesCleartextTraffic="true"

这样一个简单的上传头像就做完了
如果在上传服务器时由于图片太大而上传太慢,还可以进行图片压缩代码如下

/**
     * 压缩图片到目标大小以下
     * @param file
     * @param targetSize
     */
    open fun compressBmpFileToTargetSize(file: File, targetSize: Long) {
        Log.d(
            TAG,
            String.format(
                "compressBmpFileToTargetSize start file.length():%d",
                file.length()
            )
        )
        if (file.length() > targetSize) {
            // 每次宽高各缩小一半
            val ratio = 2
            // 获取图片原始宽高
            val options =
                BitmapFactory.Options()
            val bitmap =
                BitmapFactory.decodeFile(file.absolutePath, options)
            var targetWidth = options.outWidth / ratio
            var targetHeight = options.outHeight / ratio
            // 压缩图片到对应尺寸
            val baos = ByteArrayOutputStream()
            val quality = 100
            var result =
                generateScaledBmp(bitmap, targetWidth, targetHeight, baos, quality)
            // 计数保护,防止次数太多太耗时。
            var count = 0
            while (baos.size() > targetSize && count <= 10) {
                targetWidth /= ratio
                targetHeight /= ratio
                count++

                // 重置,不然会累加
                baos.reset()
                result = generateScaledBmp(result, targetWidth, targetHeight, baos, quality)
            }
            try {
                val fos = FileOutputStream(file)
                fos.write(baos.toByteArray())
                fos.flush()
                fos.close()
            } catch (e: java.lang.Exception) {
                e.printStackTrace()
            }
        }
        Log.d(
            TAG,
            String.format("compressBmpFileToTargetSize end file.length():%d", file.length())
        )
    }

    /**
     * 图片缩小一半
     *
     * @param srcBmp
     * @param targetWidth
     * @param targetHeight
     * @param baos
     * @param quality
     * @return
     */
    private fun generateScaledBmp(
        srcBmp: Bitmap,
        targetWidth: Int,
        targetHeight: Int,
        baos: ByteArrayOutputStream,
        quality: Int
    ): Bitmap {
        val result = Bitmap.createBitmap(
            targetWidth,
            targetHeight,
            Bitmap.Config.ARGB_8888
        )
        val canvas = Canvas(result)
        val rect = Rect(0, 0, result.width, result.height)
        canvas.drawBitmap(srcBmp, null, rect, null)
        if (!srcBmp.isRecycled) {
            srcBmp.recycle()
        }
        result.compress(Bitmap.CompressFormat.JPEG, quality, baos)
        return result
    }

这样就完成了简单的头像上传,小白记录学习日常,如有不对请指正

本文地址:https://blog.csdn.net/qq_44977215/article/details/107856719