Improved user profile image picking
This commit is contained in:
parent
607d1722da
commit
2c4b00edb9
7 changed files with 412 additions and 360 deletions
|
@ -1,38 +1,38 @@
|
|||
package code.name.monkey.retromusic.activities
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.ContextWrapper
|
||||
import android.content.Intent
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.Bitmap
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.provider.MediaStore.Images.Media
|
||||
import android.provider.MediaStore.Images.Media.getBitmap
|
||||
import android.text.TextUtils
|
||||
import android.view.MenuItem
|
||||
import android.widget.Toast
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
||||
import code.name.monkey.appthemehelper.util.MaterialUtil
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
||||
import code.name.monkey.retromusic.App
|
||||
import code.name.monkey.retromusic.Constants.USER_BANNER
|
||||
import code.name.monkey.retromusic.Constants.USER_PROFILE
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.activities.base.AbsBaseActivity
|
||||
import code.name.monkey.retromusic.extensions.accentColor
|
||||
import code.name.monkey.retromusic.extensions.applyToolbar
|
||||
import code.name.monkey.retromusic.util.Compressor
|
||||
import code.name.monkey.retromusic.util.ImageUtil.getResizedBitmap
|
||||
import code.name.monkey.retromusic.glide.ProfileBannerGlideRequest
|
||||
import code.name.monkey.retromusic.glide.UserProfileGlideRequest
|
||||
import code.name.monkey.retromusic.util.ImageUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.afollestad.materialdialogs.list.listItems
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
import com.bumptech.glide.request.RequestListener
|
||||
import com.bumptech.glide.request.target.Target
|
||||
import com.github.dhaval2404.imagepicker.ImagePicker
|
||||
import kotlinx.android.synthetic.main.activity_user_info.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.BufferedOutputStream
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
|
@ -46,53 +46,19 @@ class UserInfoActivity : AbsBaseActivity() {
|
|||
setNavigationbarColorAuto()
|
||||
setTaskDescriptionColorAuto()
|
||||
setLightNavigationBar(true)
|
||||
|
||||
applyToolbar(toolbar)
|
||||
|
||||
MaterialUtil.setTint(nameContainer, false)
|
||||
name.setText(PreferenceUtil.getInstance(this).userName)
|
||||
|
||||
if (PreferenceUtil.getInstance(this).profileImage.isNotEmpty()) {
|
||||
loadImageFromStorage(PreferenceUtil.getInstance(this).profileImage)
|
||||
}
|
||||
if (PreferenceUtil.getInstance(this).bannerImage.isNotEmpty()) {
|
||||
loadBannerFromStorage(PreferenceUtil.getInstance(this).bannerImage)
|
||||
}
|
||||
userImage.setOnClickListener {
|
||||
MaterialDialog(this).show {
|
||||
cornerRadius(PreferenceUtil.getInstance(this@UserInfoActivity).dialogCorner)
|
||||
title(text = getString(R.string.set_photo))
|
||||
listItems(
|
||||
items = listOf(
|
||||
getString(R.string.new_profile_photo),
|
||||
getString(R.string.remove_profile_photo)
|
||||
)
|
||||
) { _, position, _ ->
|
||||
when (position) {
|
||||
0 -> pickNewPhoto()
|
||||
1 -> PreferenceUtil.getInstance(this@UserInfoActivity).saveProfileImage("")
|
||||
}
|
||||
}
|
||||
}
|
||||
pickNewPhoto()
|
||||
}
|
||||
|
||||
bannerSelect.setOnClickListener {
|
||||
MaterialDialog(this).show {
|
||||
cornerRadius(PreferenceUtil.getInstance(this@UserInfoActivity).dialogCorner)
|
||||
title(R.string.select_banner_photo)
|
||||
listItems(
|
||||
items = listOf(
|
||||
getString(R.string.new_banner_photo),
|
||||
getString(R.string.remove_banner_photo)
|
||||
)
|
||||
)
|
||||
{ _, position, _ ->
|
||||
when (position) {
|
||||
0 -> selectBannerImage()
|
||||
1 -> PreferenceUtil.getInstance(this@UserInfoActivity)
|
||||
.setBannerImagePath("")
|
||||
}
|
||||
}
|
||||
}
|
||||
selectBannerImage()
|
||||
}
|
||||
|
||||
next.setOnClickListener {
|
||||
val nameString = name.text.toString().trim { it <= ' ' }
|
||||
if (TextUtils.isEmpty(nameString)) {
|
||||
|
@ -103,17 +69,26 @@ class UserInfoActivity : AbsBaseActivity() {
|
|||
setResult(Activity.RESULT_OK)
|
||||
finish()
|
||||
}
|
||||
next.backgroundTintList = ColorStateList.valueOf(ThemeStore.accentColor(this))
|
||||
ColorStateList.valueOf(
|
||||
MaterialValueHelper.getPrimaryTextColor(
|
||||
this,
|
||||
ColorUtil.isColorLight(ThemeStore.accentColor(this))
|
||||
)
|
||||
)
|
||||
.apply {
|
||||
next.setTextColor(this)
|
||||
next.iconTint = this
|
||||
}
|
||||
|
||||
val textColor =
|
||||
MaterialValueHelper.getPrimaryTextColor(this, ColorUtil.isColorLight(accentColor()))
|
||||
next.backgroundTintList = ColorStateList.valueOf(accentColor())
|
||||
next.iconTint = ColorStateList.valueOf(textColor)
|
||||
next.setTextColor(textColor)
|
||||
loadProfile()
|
||||
}
|
||||
|
||||
private fun loadProfile() {
|
||||
bannerImage?.let {
|
||||
ProfileBannerGlideRequest.Builder.from(
|
||||
Glide.with(this),
|
||||
ProfileBannerGlideRequest.getBannerModel()
|
||||
).build().into(it)
|
||||
}
|
||||
UserProfileGlideRequest.Builder.from(
|
||||
Glide.with(this),
|
||||
UserProfileGlideRequest.getUserModel()
|
||||
).build().into(userImage)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
|
@ -124,141 +99,138 @@ class UserInfoActivity : AbsBaseActivity() {
|
|||
}
|
||||
|
||||
private fun selectBannerImage() {
|
||||
val pickImageIntent = Intent(Intent.ACTION_PICK, Media.EXTERNAL_CONTENT_URI)
|
||||
pickImageIntent.type = "image/*"
|
||||
//pickImageIntent.putExtra("crop", "true")
|
||||
pickImageIntent.putExtra("outputX", 1290)
|
||||
pickImageIntent.putExtra("outputY", 720)
|
||||
pickImageIntent.putExtra("aspectX", 16)
|
||||
pickImageIntent.putExtra("aspectY", 9)
|
||||
pickImageIntent.putExtra("scale", true)
|
||||
//intent.setAction(Intent.ACTION_GET_CONTENT);
|
||||
startActivityForResult(
|
||||
Intent.createChooser(pickImageIntent, "Select Picture"),
|
||||
PICK_BANNER_REQUEST
|
||||
)
|
||||
ImagePicker.with(this)
|
||||
.compress(1024)
|
||||
.crop(16f, 9f)
|
||||
.start(PICK_BANNER_REQUEST)
|
||||
}
|
||||
|
||||
private fun pickNewPhoto() {
|
||||
val pickImageIntent = Intent(Intent.ACTION_PICK, Media.EXTERNAL_CONTENT_URI)
|
||||
pickImageIntent.type = "image/*"
|
||||
pickImageIntent.putExtra("crop", "true")
|
||||
pickImageIntent.putExtra("outputX", 512)
|
||||
pickImageIntent.putExtra("outputY", 512)
|
||||
pickImageIntent.putExtra("aspectX", 1)
|
||||
pickImageIntent.putExtra("aspectY", 1)
|
||||
pickImageIntent.putExtra("scale", true)
|
||||
startActivityForResult(
|
||||
Intent.createChooser(pickImageIntent, "Select Picture"),
|
||||
PICK_IMAGE_REQUEST
|
||||
)
|
||||
ImagePicker.with(this)
|
||||
.galleryOnly()
|
||||
.cropSquare()
|
||||
.compress(1024)
|
||||
.start(PICK_IMAGE_REQUEST)
|
||||
}
|
||||
|
||||
|
||||
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (resultCode == Activity.RESULT_OK && data != null) {
|
||||
when (requestCode) {
|
||||
PICK_IMAGE_REQUEST -> {
|
||||
try {
|
||||
data.data?.let {
|
||||
val bitmap = getResizedBitmap(
|
||||
getBitmap(contentResolver, it),
|
||||
PROFILE_ICON_SIZE
|
||||
)
|
||||
val profileImagePath = saveToInternalStorage(bitmap, USER_PROFILE)
|
||||
PreferenceUtil.getInstance(this).saveProfileImage(profileImagePath)
|
||||
loadImageFromStorage(profileImagePath)
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
if (resultCode == Activity.RESULT_OK && requestCode == PICK_IMAGE_REQUEST) {
|
||||
val fileUri = data?.data
|
||||
fileUri?.let { setAndSaveUserImage(it) }
|
||||
} else if (resultCode == Activity.RESULT_OK && requestCode == PICK_BANNER_REQUEST) {
|
||||
val fileUri = data?.data
|
||||
fileUri?.let { setAndSaveBannerImage(it) }
|
||||
} else if (resultCode == ImagePicker.RESULT_ERROR) {
|
||||
Toast.makeText(this, ImagePicker.getError(data), Toast.LENGTH_SHORT).show()
|
||||
} else {
|
||||
Toast.makeText(this, "Task Cancelled", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setAndSaveBannerImage(fileUri: Uri) {
|
||||
Glide.with(this)
|
||||
.load(fileUri)
|
||||
.asBitmap()
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.listener(object : RequestListener<Any, Bitmap> {
|
||||
override fun onException(
|
||||
e: java.lang.Exception?,
|
||||
model: Any?,
|
||||
target: Target<Bitmap>?,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
return false
|
||||
}
|
||||
PICK_BANNER_REQUEST -> {
|
||||
try {
|
||||
data.data?.let {
|
||||
val bitmap = getBitmap(contentResolver, it)
|
||||
val profileImagePath = saveToInternalStorage(bitmap, USER_BANNER)
|
||||
PreferenceUtil.getInstance(this).setBannerImagePath(profileImagePath)
|
||||
loadBannerFromStorage(profileImagePath)
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
override fun onResourceReady(
|
||||
resource: Bitmap?,
|
||||
model: Any?,
|
||||
target: Target<Bitmap>?,
|
||||
isFromMemoryCache: Boolean,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
resource?.let { saveBannerImage(it) }
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.into(bannerImage)
|
||||
}
|
||||
|
||||
private fun getImagePath(aUri: Uri, aSelection: String?): String? {
|
||||
var path: String? = null
|
||||
val cursor = App.getContext().contentResolver.query(aUri, null, aSelection, null, null)
|
||||
if (cursor != null) {
|
||||
if (cursor.moveToFirst()) {
|
||||
path = cursor.getString(cursor.getColumnIndex(Media.DATA))
|
||||
}
|
||||
cursor.close()
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
private fun loadBannerFromStorage(profileImagePath: String) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
val bitmap = Compressor(this@UserInfoActivity).setQuality(100)
|
||||
.setCompressFormat(Bitmap.CompressFormat.WEBP)
|
||||
.compressToBitmap(File(profileImagePath, USER_BANNER))
|
||||
withContext(Dispatchers.Main) { bannerImage.setImageBitmap(bitmap) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun loadImageFromStorage(path: String) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
val bitmap = Compressor(this@UserInfoActivity)
|
||||
.setMaxHeight(300)
|
||||
.setMaxWidth(300)
|
||||
.setQuality(75)
|
||||
.setCompressFormat(Bitmap.CompressFormat.WEBP)
|
||||
.compressToBitmap(File(path, USER_PROFILE))
|
||||
withContext(Dispatchers.Main) { userImage.setImageBitmap(bitmap) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveToInternalStorage(bitmapImage: Bitmap, userBanner: String): String {
|
||||
val cw = ContextWrapper(this)
|
||||
val directory = cw.getDir("imageDir", Context.MODE_PRIVATE)
|
||||
val myPath = File(directory, userBanner)
|
||||
var fos: FileOutputStream? = null
|
||||
try {
|
||||
fos = FileOutputStream(myPath)
|
||||
// Use the compress method on the BitMap object to write image to the OutputStream
|
||||
bitmapImage.compress(Bitmap.CompressFormat.WEBP, 100, fos)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
} finally {
|
||||
private fun saveBannerImage(bitmap: Bitmap) {
|
||||
CoroutineScope(Dispatchers.IO).launch() {
|
||||
val appDir = applicationContext.filesDir
|
||||
val file = File(appDir, USER_BANNER)
|
||||
var successful = false
|
||||
try {
|
||||
fos?.close()
|
||||
val os = BufferedOutputStream(FileOutputStream(file))
|
||||
successful = ImageUtil.resizeBitmap(bitmap, 2048)
|
||||
.compress(Bitmap.CompressFormat.WEBP, 100, os)
|
||||
os.close()
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
if (successful) {
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(this@UserInfoActivity, "Done", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setAndSaveUserImage(fileUri: Uri) {
|
||||
Glide.with(this)
|
||||
.load(fileUri)
|
||||
.asBitmap()
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.listener(object : RequestListener<Any, Bitmap> {
|
||||
override fun onException(
|
||||
e: java.lang.Exception?,
|
||||
model: Any?,
|
||||
target: Target<Bitmap>?,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onResourceReady(
|
||||
resource: Bitmap?,
|
||||
model: Any?,
|
||||
target: Target<Bitmap>?,
|
||||
isFromMemoryCache: Boolean,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
resource?.let { saveImage(it) }
|
||||
return false
|
||||
}
|
||||
})
|
||||
.into(userImage)
|
||||
}
|
||||
|
||||
private fun saveImage(bitmap: Bitmap) {
|
||||
CoroutineScope(Dispatchers.IO).launch() {
|
||||
val appDir = applicationContext.filesDir
|
||||
val file = File(appDir, USER_PROFILE)
|
||||
var successful = false
|
||||
try {
|
||||
val os = BufferedOutputStream(FileOutputStream(file))
|
||||
successful = ImageUtil.resizeBitmap(bitmap, 2048)
|
||||
.compress(Bitmap.CompressFormat.WEBP, 100, os)
|
||||
os.close()
|
||||
} catch (e: IOException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
if (successful) {
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(this@UserInfoActivity, "Done", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
return directory.absolutePath
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val PICK_IMAGE_REQUEST = 9002
|
||||
private const val PICK_BANNER_REQUEST = 9004
|
||||
private const val PROFILE_ICON_SIZE = 400
|
||||
}
|
||||
}
|
||||
|
||||
fun Activity.pickImage(requestCode: Int) {
|
||||
Intent(Intent.ACTION_GET_CONTENT).apply {
|
||||
addCategory(Intent.CATEGORY_OPENABLE)
|
||||
type = "image/*"
|
||||
startActivityForResult(this, requestCode)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue