Android圖片選擇,jsb調用圖片選擇及裁剪壓縮(含demo)

前言

最近有人來跟我要android的圖片選擇demo,而且需要將選擇結果回調給web.雖然這個功能在好久以前做過,但是在這次重寫的時候,發現很多東西都不太一樣了,例如以前使用的圖片選擇框架PhotoPicker現在沒有維護的,推薦了一個知乎的圖片選擇Matisse.

先說說傳給web的方案,demo中由於沒有服務器交互,所以回將選擇好的圖片轉換成base64字符串,通過jsb傳給web,這種方案在一些小圖選擇的情況下非常常見,但也有一定的弊端,這個在最後就給出修改建議.

demo工程:https://github.com/lewis-v/ImageSelect

選擇圖片

manifest中添加

<activity
            android:name="com.yalantis.ucrop.UCropActivity"
            android:screenOrientation="portrait"
            android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.lewis.imageselect"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/filepaths"/>
        </provider>

res目錄中添加xml目錄,創建文件filepaths.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <paths>
        <external-path
            name="my_images"
            path="Pictures"/>
    </paths>
</resources>

activity中的初始化操作

private val imageViewModel by lazy {
    ViewModelProvider(
        this,
        ViewModelProvider.AndroidViewModelFactory.getInstance(application)
    ).get(ImageViewModel::class.java)
}
override fun onCreate(savedInstanceState: Bundle?) {
    imageViewModel.imageErrorLiveData.observe(this, Observer {
        Toast.makeText(this, it, Toast.LENGTH_SHORT).show()
    })
    imageViewModel.imageSelectResultViewModel.observe(this, Observer {
        //圖片選擇結果
        Toast.makeText(this, "select success ${it.size}", Toast.LENGTH_SHORT).show()
    })
}

//權限處理
override fun onRequestPermissionsResult(
    requestCode: Int,
    permissions: Array<out String>,
    grantResults: IntArray
) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    if (permissions.isNotEmpty()) {
        imageViewModel.selectImage(this)
    }
}
//選擇回調
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    imageViewModel.onResult(this, requestCode, resultCode, data)
}

選擇圖片調用

if (PermissionUtil.checkAllPermission(this)) {
    //選擇一張圖片,不裁剪
    imageViewModel.selectImage(this, 1, null, ImageCompressionInfo())
}
if (PermissionUtil.checkAllPermission(this)) {
    //選擇1張圖片,裁剪
    imageViewModel.selectImage(this, 1, ImageCropInfo(), ImageCompressionInfo())
}

到此,圖片選擇的初始化和調用就完成的,具體的實現在ImageViewModel中.

回調給web

ImageJsbModul類中提供了jsb的方法調用
初始化

override fun onCreate(savedInstanceState: Bundle?) {
	imageJsbModul = ImageJsbModul(this, web)
	webView.addJavascriptInterface(imageJsbModul, "ImageSelect")//將jsb方法加入到js中
}

override fun onRequestPermissionsResult(
    requestCode: Int,
    permissions: Array<out String>,
    grantResults: IntArray
) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    if (permissions.isNotEmpty()) {
        imageJsbModul.onGetPermission()
    }
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    imageViewModel.onResult(this, requestCode, resultCode, data)
}

網頁調用圖片選擇的方法,在asset的js_webView.html有示例

window.ImageSelect.selectImage(num, '{"ratio":{"x":16.0,"y":9.0}}',true,"callBack");
//其中第一個參數num爲選擇圖片數量,
//第二個參數爲裁剪的配置(支持裁剪比例和大小)
//第三個參數爲是否壓縮
//第四個參數是選擇結果的回調方法

最後

圖片選擇到這裏結束啦,其實也沒什麼複雜的,就只是將各種框架結合在一起封裝一下就完事了(具體實現可見工程demo源碼, 主要的實現在ImageJsbModul和ImageViewModel中),但是這裏也有一些細節是沒有考慮的,例如在不保留活動下,選擇完圖片回來是否有問題等

建議

jsb的回調方式是將圖片轉成base64的形式,這裏最好不要這樣做,因爲文件轉成base64之後會很大,這裏會佔用很多內存,當然如果只是一張小頭像問題到不是很大,最好的做法是將選擇好的圖片上傳到服務器,將圖片鏈接傳給web.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章