Android kotlin上传头像实现

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
    }

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

你可能感兴趣的:(Android,android,移动开发)