[Modify]圖片保存到本地適配
This commit is contained in:
@@ -106,6 +106,7 @@ import org.greenrobot.eventbus.ThreadMode;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@@ -1461,6 +1462,20 @@ public class GiftDialog extends BottomSheetDialog implements View.OnClickListene
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (List<GiftInfoVm> page : pagerList) {
|
for (List<GiftInfoVm> page : pagerList) {
|
||||||
|
// Iterator<GiftInfoVm> iterator = page.iterator();
|
||||||
|
// while (iterator.hasNext()) {
|
||||||
|
// GiftInfoVm item = iterator.next();
|
||||||
|
// if (item.data.getGiftId() == giftId) {
|
||||||
|
// int count = item.data.getCount() - sendNum;
|
||||||
|
// if(count == 0){
|
||||||
|
// iterator.remove();
|
||||||
|
// }else {
|
||||||
|
// item.data.setCount(Math.max(count, 0));
|
||||||
|
// item.updateCount();
|
||||||
|
// }
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
for (GiftInfoVm item : page) {
|
for (GiftInfoVm item : page) {
|
||||||
if (item.data.getGiftId() == giftId) {
|
if (item.data.getGiftId() == giftId) {
|
||||||
int count = item.data.getCount() - sendNum;
|
int count = item.data.getCount() - sendNum;
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package com.yizhuan.erban.community.photo;
|
|||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
@@ -12,18 +11,19 @@ import com.yizhuan.erban.R;
|
|||||||
import com.yizhuan.erban.base.BaseActivity;
|
import com.yizhuan.erban.base.BaseActivity;
|
||||||
import com.yizhuan.erban.ui.widget.ButtonItem;
|
import com.yizhuan.erban.ui.widget.ButtonItem;
|
||||||
import com.yizhuan.erban.ui.widget.OnPageSelectedListener;
|
import com.yizhuan.erban.ui.widget.OnPageSelectedListener;
|
||||||
import com.yizhuan.xchat_android_core.community.download.DownloadModel;
|
import com.yizhuan.xchat_android_library.common.util.AlbumUtils;
|
||||||
import com.yizhuan.xchat_android_core.utils.DirectoryHelper;
|
import com.yizhuan.xchat_android_library.common.util.ExecutorCenter;
|
||||||
import com.yizhuan.xchat_android_library.utils.ResUtil;
|
import com.yizhuan.xchat_android_library.utils.ResUtil;
|
||||||
import com.zhihu.matisse.internal.entity.CustomItem;
|
import com.zhihu.matisse.internal.entity.CustomItem;
|
||||||
import com.zhihu.matisse.internal.ui.widget.PreviewViewPager;
|
import com.zhihu.matisse.internal.ui.widget.PreviewViewPager;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
|
import kotlin.Unit;
|
||||||
|
import kotlin.jvm.functions.Function1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* create by lvzebiao @2019/11/20
|
* create by lvzebiao @2019/11/20
|
||||||
@@ -155,36 +155,18 @@ public class BigPhotoActivity extends BaseActivity implements OnFragmentOptionLi
|
|||||||
if (item == null) {
|
if (item == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String format = item.getFormat();
|
|
||||||
if (format == null) {
|
ExecutorCenter.getInstance().post(() -> {
|
||||||
format = ".jpg";
|
AlbumUtils.INSTANCE.addUrlToAlbum(context, item.getPath(), new Function1<Boolean, Unit>() {
|
||||||
}
|
@Override
|
||||||
format = format.toLowerCase();
|
public Unit invoke(Boolean aBoolean) {
|
||||||
if (format.equals("jpeg")) {
|
if (aBoolean) {
|
||||||
format = ".jpg";
|
toast(ResUtil.getString(R.string.community_photo_bigphotoactivity_05));
|
||||||
} else {
|
}
|
||||||
format = "." + format;
|
return null;
|
||||||
}
|
}
|
||||||
String fileName = "dynamic_" + System.currentTimeMillis() + format;
|
});
|
||||||
File dir = DirectoryHelper.get().getAppAlubmDir();
|
});
|
||||||
if (dir == null) {
|
|
||||||
toast(ResUtil.getString(R.string.community_photo_bigphotoactivity_03));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LogUtil.print(ResUtil.getString(R.string.community_photo_bigphotoactivity_04));
|
|
||||||
LogUtil.print(dir);
|
|
||||||
LogUtil.print(fileName);
|
|
||||||
DownloadModel.get().download(
|
|
||||||
item.getPath(), dir.getPath(), fileName)
|
|
||||||
.doOnSuccess(s -> {
|
|
||||||
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
|
|
||||||
Uri uri = Uri.fromFile(new File(dir, fileName));
|
|
||||||
intent.setData(uri);
|
|
||||||
sendBroadcast(intent);
|
|
||||||
toast(ResUtil.getString(R.string.community_photo_bigphotoactivity_05));
|
|
||||||
})
|
|
||||||
.doOnError(throwable -> toast(ResUtil.getString(R.string.community_photo_bigphotoactivity_06)))
|
|
||||||
.subscribe();
|
|
||||||
|
|
||||||
}));
|
}));
|
||||||
getDialogManager().showCommonPopupDialog(listBtn, ResUtil.getString(R.string.community_photo_bigphotoactivity_07));
|
getDialogManager().showCommonPopupDialog(listBtn, ResUtil.getString(R.string.community_photo_bigphotoactivity_07));
|
||||||
|
|||||||
@@ -0,0 +1,313 @@
|
|||||||
|
package com.yizhuan.xchat_android_library.common.util
|
||||||
|
|
||||||
|
import android.content.ContentValues
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.Environment
|
||||||
|
import android.provider.MediaStore
|
||||||
|
import com.bumptech.glide.load.DataSource
|
||||||
|
import com.bumptech.glide.load.engine.GlideException
|
||||||
|
import com.bumptech.glide.request.RequestListener
|
||||||
|
import com.bumptech.glide.request.target.Target
|
||||||
|
import com.yizhuan.xchat_android_library.common.application.BaseApp
|
||||||
|
import com.yizhuan.xchat_android_library.common.file.FileHelper
|
||||||
|
import com.yizhuan.xchat_android_library.common.glide.GlideUtils
|
||||||
|
import java.io.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create by ysx 2020/9/25 0025
|
||||||
|
*文件工具类,为了适配android10,11
|
||||||
|
*/
|
||||||
|
object AlbumUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 兼容android Q
|
||||||
|
* 网络图片保存本地
|
||||||
|
* 返回是否保存成功
|
||||||
|
*/
|
||||||
|
fun addUrlToAlbum(context: Context?, url: String?, callback: (Boolean) -> Unit) {
|
||||||
|
if (url == null) {
|
||||||
|
callback.invoke(false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
getGlideImagePath(context, url) { glideImagePath ->
|
||||||
|
glideImagePath?.also {
|
||||||
|
val fileName: String
|
||||||
|
val imageType: String
|
||||||
|
if (glideImagePath.endsWith(".gif", true)) {
|
||||||
|
fileName = System.currentTimeMillis().toString() + ".gif"
|
||||||
|
imageType = "image/gif"
|
||||||
|
} else {
|
||||||
|
fileName = System.currentTimeMillis().toString() + ".jpg"
|
||||||
|
imageType = "image/jpeg"
|
||||||
|
}
|
||||||
|
|
||||||
|
val values = ContentValues()
|
||||||
|
values.put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
|
||||||
|
values.put(MediaStore.MediaColumns.MIME_TYPE, imageType)
|
||||||
|
values.put(MediaStore.MediaColumns.SIZE, 1)
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DCIM)
|
||||||
|
} else {
|
||||||
|
values.put(
|
||||||
|
MediaStore.MediaColumns.DATA,
|
||||||
|
"${Environment.getExternalStorageDirectory().path}/${Environment.DIRECTORY_DCIM}/$fileName"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val contentResolver = BaseApp.getContext().contentResolver
|
||||||
|
val uri =
|
||||||
|
contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
|
||||||
|
if (uri != null) {
|
||||||
|
try {
|
||||||
|
val oldFile = File(glideImagePath)
|
||||||
|
if (oldFile.exists()) { //文件存在时
|
||||||
|
val inStream = FileInputStream(glideImagePath) //读入原文件
|
||||||
|
val outputStream = contentResolver.openOutputStream(uri)
|
||||||
|
if (outputStream != null) {
|
||||||
|
val bos = BufferedOutputStream(outputStream)
|
||||||
|
val buffer = ByteArray(1024)
|
||||||
|
var bytes = inStream.read(buffer)
|
||||||
|
while (bytes >= 0) {
|
||||||
|
bos.write(buffer, 0, bytes)
|
||||||
|
bos.flush()
|
||||||
|
bytes = inStream.read(buffer)
|
||||||
|
}
|
||||||
|
bos.close()
|
||||||
|
callback.invoke(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback.invoke(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 兼容android Q
|
||||||
|
* 将bitmap保存到本地图库
|
||||||
|
* displayName 文件名 "xxx.jpg"
|
||||||
|
* mimeType "image/jpeg"
|
||||||
|
*/
|
||||||
|
@JvmOverloads
|
||||||
|
@JvmStatic
|
||||||
|
fun addBitmapToAlbum(
|
||||||
|
bitmap: Bitmap?,
|
||||||
|
displayName: String = "${System.currentTimeMillis()}.jpg",
|
||||||
|
mimeType: String = "image/jpeg",
|
||||||
|
compressFormat: Bitmap.CompressFormat = Bitmap.CompressFormat.JPEG
|
||||||
|
): Boolean {
|
||||||
|
if (bitmap == null) return false
|
||||||
|
val values = ContentValues()
|
||||||
|
values.put(MediaStore.MediaColumns.DISPLAY_NAME, displayName)
|
||||||
|
values.put(MediaStore.MediaColumns.MIME_TYPE, mimeType)
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DCIM)
|
||||||
|
} else {
|
||||||
|
values.put(
|
||||||
|
MediaStore.MediaColumns.DATA,
|
||||||
|
"${Environment.getExternalStorageDirectory().path}/${Environment.DIRECTORY_DCIM}/$displayName"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
var outputStream: OutputStream? = null
|
||||||
|
try {
|
||||||
|
val contentResolver = BaseApp.getContext().contentResolver
|
||||||
|
val uri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
|
||||||
|
if (uri != null) {
|
||||||
|
outputStream = contentResolver.openOutputStream(uri)
|
||||||
|
if (outputStream != null) {
|
||||||
|
bitmap.compress(compressFormat, 100, outputStream)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
outputStream?.close()
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 兼容android Q
|
||||||
|
* 本地缓存文件保存本地相册
|
||||||
|
* 返回是否保存成功
|
||||||
|
*/
|
||||||
|
fun addImageFileToAlbum(file: File?): Boolean {
|
||||||
|
if (file == null) return false
|
||||||
|
val start: Int = file.name.lastIndexOf(".")
|
||||||
|
val suffix: String = file.name.substring(start + 1)
|
||||||
|
val fileName: String
|
||||||
|
val imageType: String
|
||||||
|
if (suffix == "gif" || suffix == "GIF") {
|
||||||
|
fileName = System.currentTimeMillis().toString() + ".gif"
|
||||||
|
imageType = "image/gif"
|
||||||
|
} else {
|
||||||
|
fileName = System.currentTimeMillis().toString() + ".jpg"
|
||||||
|
imageType = "image/jpeg"
|
||||||
|
}
|
||||||
|
|
||||||
|
val values = ContentValues()
|
||||||
|
values.put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
|
||||||
|
values.put(MediaStore.MediaColumns.MIME_TYPE, imageType)
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DCIM)
|
||||||
|
} else {
|
||||||
|
values.put(
|
||||||
|
MediaStore.MediaColumns.DATA,
|
||||||
|
"${Environment.getExternalStorageDirectory().path}/${Environment.DIRECTORY_DCIM}/$fileName"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val contentResolver = BaseApp.getContext().contentResolver
|
||||||
|
val uri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
|
||||||
|
if (uri != null) {
|
||||||
|
var inStream: FileInputStream? = null
|
||||||
|
var outputStream: OutputStream? = null
|
||||||
|
var bos: BufferedOutputStream? = null
|
||||||
|
try {
|
||||||
|
if (file.exists()) { //文件存在时
|
||||||
|
inStream = FileInputStream(file) //读入原文件
|
||||||
|
outputStream = contentResolver.openOutputStream(uri)
|
||||||
|
if (outputStream != null) {
|
||||||
|
bos = BufferedOutputStream(outputStream)
|
||||||
|
val buffer = ByteArray(1024)
|
||||||
|
var bytes = inStream.read(buffer)
|
||||||
|
while (bytes >= 0) {
|
||||||
|
bos.write(buffer, 0, bytes)
|
||||||
|
bos.flush()
|
||||||
|
bytes = inStream.read(buffer)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
inStream?.close()
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
outputStream?.close()
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
bos?.close()
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Glide 获得图片路径
|
||||||
|
*/
|
||||||
|
private fun getGlideImagePath(context: Context?, imgUrl: String, callback: (String?) -> Unit) {
|
||||||
|
try {
|
||||||
|
GlideUtils.instance().downloadFromUrl(context, imgUrl, object : RequestListener<File?> {
|
||||||
|
override fun onLoadFailed(
|
||||||
|
e: GlideException?,
|
||||||
|
model: Any?,
|
||||||
|
target: Target<File?>?,
|
||||||
|
isFirstResource: Boolean
|
||||||
|
): Boolean {
|
||||||
|
callback.invoke("")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResourceReady(
|
||||||
|
resource: File?,
|
||||||
|
model: Any?,
|
||||||
|
target: Target<File?>?,
|
||||||
|
dataSource: DataSource?,
|
||||||
|
isFirstResource: Boolean
|
||||||
|
): Boolean {
|
||||||
|
callback.invoke(resource?.absolutePath)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} catch (e: Exception) {
|
||||||
|
callback.invoke("")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 动态获得h5图片路径
|
||||||
|
*/
|
||||||
|
fun getTrendImagePath(context: Context?, imgUrl: String, callback: (String?) -> Unit) {
|
||||||
|
try {
|
||||||
|
GlideUtils.instance().downloadFromUrl(context, imgUrl, object : RequestListener<File?> {
|
||||||
|
override fun onLoadFailed(
|
||||||
|
e: GlideException?,
|
||||||
|
model: Any?,
|
||||||
|
target: Target<File?>?,
|
||||||
|
isFirstResource: Boolean
|
||||||
|
): Boolean {
|
||||||
|
callback.invoke("")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResourceReady(
|
||||||
|
resource: File?,
|
||||||
|
model: Any?,
|
||||||
|
target: Target<File?>?,
|
||||||
|
dataSource: DataSource?,
|
||||||
|
isFirstResource: Boolean
|
||||||
|
): Boolean {
|
||||||
|
val fileDir =
|
||||||
|
FileHelper.getRootFilesDir(Environment.DIRECTORY_PICTURES).absolutePath + "/trend/test"
|
||||||
|
//获取到下载得到的图片,进行本地保存
|
||||||
|
//第二个参数为你想要保存的目录名称
|
||||||
|
val appDir = File(fileDir)
|
||||||
|
if (!appDir.exists()) {
|
||||||
|
appDir.mkdirs()
|
||||||
|
}
|
||||||
|
val fileName = System.currentTimeMillis().toString() + ".jpg"
|
||||||
|
val destFile = File(appDir, fileName)
|
||||||
|
//把gilde下载得到图片复制到定义好的目录中去
|
||||||
|
copy(resource, destFile) {
|
||||||
|
callback.invoke(destFile.absolutePath)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} catch (e: Exception) {
|
||||||
|
callback.invoke("")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复制文件
|
||||||
|
*
|
||||||
|
* @param source 输入文件
|
||||||
|
* @param target 输出文件
|
||||||
|
*/
|
||||||
|
fun copy(source: File?, target: File?, callback: () -> Unit) {
|
||||||
|
var fileInputStream: FileInputStream? = null
|
||||||
|
var fileOutputStream: FileOutputStream? = null
|
||||||
|
try {
|
||||||
|
fileInputStream = FileInputStream(source)
|
||||||
|
fileOutputStream = FileOutputStream(target)
|
||||||
|
val buffer = ByteArray(1024)
|
||||||
|
while (fileInputStream.read(buffer) > 0) {
|
||||||
|
fileOutputStream.write(buffer)
|
||||||
|
}
|
||||||
|
} catch (e: java.lang.Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
fileInputStream?.close()
|
||||||
|
fileOutputStream?.close()
|
||||||
|
callback.invoke()
|
||||||
|
} catch (e: IOException) {
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package com.yizhuan.xchat_android_library.common.util;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
public class ExecutorCenter {
|
||||||
|
private static final String TAG = "ExecutorCenter";
|
||||||
|
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
|
||||||
|
private static ExecutorCenter msInstance = null;
|
||||||
|
private static ScheduledExecutor mExecutor;
|
||||||
|
|
||||||
|
public static ExecutorCenter getInstance() {
|
||||||
|
if (null != msInstance) return msInstance;
|
||||||
|
synchronized (ExecutorCenter.class) {
|
||||||
|
if (null != msInstance) return msInstance;
|
||||||
|
msInstance = new ExecutorCenter();
|
||||||
|
return msInstance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ExecutorCenter() {
|
||||||
|
mExecutor = Pools.newScheduledThreadPoolExecutor("self-executor", CPU_COUNT + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Executor getExecutor() {
|
||||||
|
return mExecutor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void post(Runnable runnable) {
|
||||||
|
if (this.checkNull(runnable)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mExecutor.execute(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void postDelay(Runnable runnable, long delay) {
|
||||||
|
if (this.checkNull(runnable)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mExecutor.execute(runnable, delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Future submitDelay(Runnable runnable, long delay) {
|
||||||
|
if (this.checkNull(runnable)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return mExecutor.submit(runnable, delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkNull(Runnable runnable) {
|
||||||
|
if (null == runnable) {
|
||||||
|
Logger.error(TAG, "runnable null!!!!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package com.yizhuan.xchat_android_library.common.util;
|
||||||
|
|
||||||
|
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||||
|
import java.util.concurrent.ThreadFactory;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
public class Pools {
|
||||||
|
private static final String TAG = "Pools";
|
||||||
|
|
||||||
|
public static ScheduledExecutor newScheduledThreadPoolExecutor(String threadNamePrefix, int coreCount) {
|
||||||
|
return new ScheduledExecutorAdapter(new ScheduledThreadPoolExecutor(coreCount, new DefaultThreadFactory(threadNamePrefix)) {
|
||||||
|
@Override
|
||||||
|
protected void afterExecute(Runnable r, Throwable t) {
|
||||||
|
super.afterExecute(r, t);
|
||||||
|
if (t != null) {
|
||||||
|
Logger.error(TAG, String.valueOf(t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class DefaultThreadFactory implements ThreadFactory {
|
||||||
|
private static final AtomicInteger poolNumber = new AtomicInteger(1);
|
||||||
|
private final AtomicInteger threadNumber = new AtomicInteger(1);
|
||||||
|
private final String namePrefix;
|
||||||
|
|
||||||
|
DefaultThreadFactory(String threadNamePrefix) {
|
||||||
|
this.namePrefix = threadNamePrefix + poolNumber.getAndIncrement() + "-thread-";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Thread newThread(Runnable r) {
|
||||||
|
return new Thread(r, this.namePrefix + this.threadNumber.getAndIncrement());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.yizhuan.xchat_android_library.common.util;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
public interface ScheduledExecutor extends Executor {
|
||||||
|
void execute(Runnable runnable, long delay);
|
||||||
|
|
||||||
|
Future submit(Runnable runnable, long delay);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package com.yizhuan.xchat_android_library.common.util;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
public class ScheduledExecutorAdapter implements ScheduledExecutor {
|
||||||
|
private ScheduledExecutorService mExecutor;
|
||||||
|
|
||||||
|
public ScheduledExecutorAdapter(ScheduledExecutorService executor) {
|
||||||
|
if (null == executor) {
|
||||||
|
throw new NullPointerException("ScheduledThreadPoolExecutor may not be null");
|
||||||
|
}
|
||||||
|
this.mExecutor = executor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(Runnable command, long delay) {
|
||||||
|
this.mExecutor.schedule(command, delay, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(@NonNull Runnable command) {
|
||||||
|
this.mExecutor.execute(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Future submit(Runnable command, long delay) {
|
||||||
|
return this.mExecutor.schedule(command, delay, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,13 +1,11 @@
|
|||||||
package com.netease.nim.uikit.business.session.activity;
|
package com.netease.nim.uikit.business.session.activity;
|
||||||
|
|
||||||
import android.content.ContentValues;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.provider.MediaStore;
|
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@@ -29,11 +27,8 @@ import com.netease.nim.uikit.common.ui.dialog.CustomAlertDialog;
|
|||||||
import com.netease.nim.uikit.common.ui.dialog.CustomAlertDialog.onSeparateItemClickListener;
|
import com.netease.nim.uikit.common.ui.dialog.CustomAlertDialog.onSeparateItemClickListener;
|
||||||
import com.netease.nim.uikit.common.ui.imageview.BaseZoomableImageView;
|
import com.netease.nim.uikit.common.ui.imageview.BaseZoomableImageView;
|
||||||
import com.netease.nim.uikit.common.ui.imageview.ImageGestureListener;
|
import com.netease.nim.uikit.common.ui.imageview.ImageGestureListener;
|
||||||
import com.netease.nim.uikit.common.util.C;
|
|
||||||
import com.netease.nim.uikit.common.util.file.AttachmentStore;
|
|
||||||
import com.netease.nim.uikit.common.util.media.BitmapDecoder;
|
import com.netease.nim.uikit.common.util.media.BitmapDecoder;
|
||||||
import com.netease.nim.uikit.common.util.media.ImageUtil;
|
import com.netease.nim.uikit.common.util.media.ImageUtil;
|
||||||
import com.netease.nim.uikit.common.util.storage.StorageUtil;
|
|
||||||
import com.netease.nim.uikit.common.util.sys.TimeUtil;
|
import com.netease.nim.uikit.common.util.sys.TimeUtil;
|
||||||
import com.netease.nimlib.sdk.AbortableFuture;
|
import com.netease.nimlib.sdk.AbortableFuture;
|
||||||
import com.netease.nimlib.sdk.NIMClient;
|
import com.netease.nimlib.sdk.NIMClient;
|
||||||
@@ -47,6 +42,8 @@ import com.netease.nimlib.sdk.msg.constant.AttachStatusEnum;
|
|||||||
import com.netease.nimlib.sdk.msg.constant.MsgDirectionEnum;
|
import com.netease.nimlib.sdk.msg.constant.MsgDirectionEnum;
|
||||||
import com.netease.nimlib.sdk.msg.constant.MsgTypeEnum;
|
import com.netease.nimlib.sdk.msg.constant.MsgTypeEnum;
|
||||||
import com.netease.nimlib.sdk.msg.model.IMMessage;
|
import com.netease.nimlib.sdk.msg.model.IMMessage;
|
||||||
|
import com.yizhuan.xchat_android_library.common.util.AlbumUtils;
|
||||||
|
import com.yizhuan.xchat_android_library.common.util.ExecutorCenter;
|
||||||
import com.yizhuan.xchat_android_library.utils.ResUtil;
|
import com.yizhuan.xchat_android_library.utils.ResUtil;
|
||||||
import com.yizhuan.xchat_android_library.utils.SingleToastUtil;
|
import com.yizhuan.xchat_android_library.utils.SingleToastUtil;
|
||||||
|
|
||||||
@@ -55,6 +52,9 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import kotlin.Unit;
|
||||||
|
import kotlin.jvm.functions.Function1;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查看聊天消息原图
|
* 查看聊天消息原图
|
||||||
@@ -222,7 +222,7 @@ public class WatchMessagePictureActivity extends UI {
|
|||||||
@Override
|
@Override
|
||||||
public void onSuccess(List<IMMessage> param) {
|
public void onSuccess(List<IMMessage> param) {
|
||||||
for (IMMessage imMessage : param) {
|
for (IMMessage imMessage : param) {
|
||||||
if (!ImageUtil.isGif(((ImageAttachment) imMessage.getAttachment()).getExtension())){
|
if (!ImageUtil.isGif(((ImageAttachment) imMessage.getAttachment()).getExtension())) {
|
||||||
imageMsgList.add(imMessage);
|
imageMsgList.add(imMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -558,29 +558,41 @@ public class WatchMessagePictureActivity extends UI {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String srcFilename = attachment.getFileName();
|
ExecutorCenter.getInstance().post(() -> {
|
||||||
//默认jpg
|
AlbumUtils.INSTANCE.addUrlToAlbum(this, path, new Function1<Boolean, Unit>() {
|
||||||
String extension = TextUtils.isEmpty(attachment.getExtension()) ? "jpg" : attachment.getExtension();
|
@Override
|
||||||
srcFilename += ("." + extension);
|
public Unit invoke(Boolean aBoolean) {
|
||||||
|
if (aBoolean) {
|
||||||
|
SingleToastUtil.showToastShort(R.string.picture_save_to);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
String picPath = StorageUtil.getSystemImagePath();
|
// String srcFilename = attachment.getFileName();
|
||||||
String dstPath = picPath + srcFilename;
|
// //默认jpg
|
||||||
if (AttachmentStore.copy(path, dstPath) != -1) {
|
// String extension = TextUtils.isEmpty(attachment.getExtension()) ? "jpg" : attachment.getExtension();
|
||||||
try {
|
// srcFilename += ("." + extension);
|
||||||
ContentValues values = new ContentValues(2);
|
//
|
||||||
values.put(MediaStore.Images.Media.MIME_TYPE, C.MimeType.MIME_JPEG);
|
// String picPath = StorageUtil.getSystemImagePath();
|
||||||
values.put(MediaStore.Images.Media.DATA, dstPath);
|
// String dstPath = picPath + srcFilename;
|
||||||
getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
|
// if (AttachmentStore.copy(path, dstPath) != -1) {
|
||||||
// Toast.makeText(WatchMessagePictureActivity.this, getString(R.string.picture_save_to), Toast.LENGTH_LONG).show();
|
// try {
|
||||||
SingleToastUtil.showToastShort(R.string.picture_save_to);
|
// ContentValues values = new ContentValues(2);
|
||||||
} catch (Exception e) {
|
// values.put(MediaStore.Images.Media.MIME_TYPE, C.MimeType.MIME_JPEG);
|
||||||
// may be java.lang.UnsupportedOperationException
|
// values.put(MediaStore.Images.Media.DATA, dstPath);
|
||||||
// Toast.makeText(WatchMessagePictureActivity.this, getString(R.string.picture_save_fail), Toast.LENGTH_LONG).show();
|
// getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
|
||||||
SingleToastUtil.showToastShort(R.string.picture_save_fail);
|
//// Toast.makeText(WatchMessagePictureActivity.this, getString(R.string.picture_save_to), Toast.LENGTH_LONG).show();
|
||||||
}
|
// SingleToastUtil.showToastShort(R.string.picture_save_to);
|
||||||
} else {
|
// } catch (Exception e) {
|
||||||
// Toast.makeText(WatchMessagePictureActivity.this, getString(R.string.picture_save_fail), Toast.LENGTH_LONG).show();
|
// // may be java.lang.UnsupportedOperationException
|
||||||
SingleToastUtil.showToastShort(R.string.picture_save_fail);
|
//// Toast.makeText(WatchMessagePictureActivity.this, getString(R.string.picture_save_fail), Toast.LENGTH_LONG).show();
|
||||||
}
|
// SingleToastUtil.showToastShort(R.string.picture_save_fail);
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
//// Toast.makeText(WatchMessagePictureActivity.this, getString(R.string.picture_save_fail), Toast.LENGTH_LONG).show();
|
||||||
|
// SingleToastUtil.showToastShort(R.string.picture_save_fail);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user