Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
YDL-Component-Medical
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
杨凯
YDL-Component-Medical
Commits
3eaf2c42
Commit
3eaf2c42
authored
Aug 09, 2022
by
王佳洋
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
课程顾问-保存图片到相册加入权限适配,暂时关闭android10版本适配,因为应用还未适配到10
音频播放bug修复
parent
75cc4bd7
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
366 additions
and
122 deletions
+366
-122
DemoGlobalConfig.java
app/src/main/java/com/ydl/component/base/DemoGlobalConfig.java
+2
-2
WVClickAbstractListener.java
app/src/main/java/com/ydl/component/service/web/WVClickAbstractListener.java
+2
-1
config.gradle
config.gradle
+1
-1
CoursePosterActivity.kt
m-course/src/main/java/com/yidianling/course/CoursePosterActivity.kt
+2
-2
AudioPlayPresenter.kt
m-course/src/main/java/com/yidianling/course/coursePlay/presenter/AudioPlayPresenter.kt
+4
-6
ImageExt.kt
ydl-platform/src/main/java/com/ydl/ydlcommon/utils/ImageExt.kt
+256
-0
ImageUtil.java
ydl-platform/src/main/java/com/ydl/ydlcommon/utils/ImageUtil.java
+0
-109
ImageUtil.kt
ydl-platform/src/main/java/com/ydl/ydlcommon/utils/ImageUtil.kt
+96
-0
YDLShareDialog.kt
ydl-platform/src/main/java/com/ydl/ydlcommon/view/dialog/YDLShareDialog.kt
+3
-1
No files found.
app/src/main/java/com/ydl/component/base/DemoGlobalConfig.java
View file @
3eaf2c42
...
@@ -20,8 +20,8 @@ import java.util.List;
...
@@ -20,8 +20,8 @@ import java.util.List;
*/
*/
public
final
class
DemoGlobalConfig
implements
IConfigModule
{
public
final
class
DemoGlobalConfig
implements
IConfigModule
{
String
APP_DOMAIN
=
"https://api.github.com/"
;
String
APP_DOMAIN
=
"https://api.github.com/"
;
//
public static String appEnv = YDLConstants.ENV_TEST;
public
static
String
appEnv
=
YDLConstants
.
ENV_TEST
;
public
static
String
appEnv
=
YDLConstants
.
ENV_TEST
;
// public static String appEnv = YDLConstants.ENV_PROD
;
// public static String appEnv = YDLConstants.ENV_NEW_TEST;//配置未上传到maven库
// public static String appEnv = YDLConstants.ENV_NEW_TEST;//配置未上传到maven库
@Override
@Override
...
...
app/src/main/java/com/ydl/component/service/web/WVClickAbstractListener.java
View file @
3eaf2c42
...
@@ -14,6 +14,7 @@ import com.ydl.webview.H5JsBean;
...
@@ -14,6 +14,7 @@ import com.ydl.webview.H5JsBean;
import
com.ydl.webview.H5Params
;
import
com.ydl.webview.H5Params
;
import
com.ydl.webview.NewH5Activity
;
import
com.ydl.webview.NewH5Activity
;
import
com.ydl.ydlcommon.modular.ModularServiceManager
;
import
com.ydl.ydlcommon.modular.ModularServiceManager
;
import
com.ydl.ydlcommon.utils.ImageUtil
;
import
com.yidianling.common.tools.LogUtil
;
import
com.yidianling.common.tools.LogUtil
;
import
com.yidianling.common.tools.ToastUtil
;
import
com.yidianling.common.tools.ToastUtil
;
import
com.yidianling.consultant.preview.GPreviewBuilder
;
import
com.yidianling.consultant.preview.GPreviewBuilder
;
...
@@ -378,7 +379,7 @@ public class WVClickAbstractListener implements WebViewClientClickListener {
...
@@ -378,7 +379,7 @@ public class WVClickAbstractListener implements WebViewClientClickListener {
@Override
@Override
public
void
saveImage
(
H5JsBean
.
H5JsCmd
.
Params
jsData
)
{
public
void
saveImage
(
H5JsBean
.
H5JsCmd
.
Params
jsData
)
{
ImageUtil
.
Companion
.
savePicture
(
mContext
,
jsData
.
getImageBase64
());
}
}
@Override
@Override
...
...
config.gradle
View file @
3eaf2c42
ext
{
ext
{
dev_mode
=
true
//组件发布的时候需要设置为false
dev_mode
=
true
//组件发布的时候需要设置为false
ydl2PublishVersion
=
"0.2.0.
17
"
ydl2PublishVersion
=
"0.2.0.
20-wjy
"
ydlPublishVersion
=
[
ydlPublishVersion
=
[
// -------------- 业务模块 --------------
// -------------- 业务模块 --------------
//第三步 若干
//第三步 若干
...
...
m-course/src/main/java/com/yidianling/course/CoursePosterActivity.kt
View file @
3eaf2c42
...
@@ -5,12 +5,12 @@ import android.app.Activity
...
@@ -5,12 +5,12 @@ import android.app.Activity
import
android.content.Intent
import
android.content.Intent
import
android.graphics.Bitmap
import
android.graphics.Bitmap
import
android.graphics.Canvas
import
android.graphics.Canvas
import
androidx.viewpager.widget.PagerAdapter
import
androidx.viewpager.widget.ViewPager
import
android.text.TextUtils
import
android.text.TextUtils
import
android.view.View
import
android.view.View
import
android.view.ViewGroup
import
android.view.ViewGroup
import
android.view.WindowManager
import
android.view.WindowManager
import
androidx.viewpager.widget.PagerAdapter
import
androidx.viewpager.widget.ViewPager
import
com.alibaba.android.arouter.facade.annotation.Route
import
com.alibaba.android.arouter.facade.annotation.Route
import
com.ydl.ydlcommon.actions.share.ShareUtils
import
com.ydl.ydlcommon.actions.share.ShareUtils
import
com.ydl.ydlcommon.base.BaseActivity
import
com.ydl.ydlcommon.base.BaseActivity
...
...
m-course/src/main/java/com/yidianling/course/coursePlay/presenter/AudioPlayPresenter.kt
View file @
3eaf2c42
...
@@ -77,7 +77,7 @@ class AudioPlayPresenter : BasePresenter<IAudioPlayContract.View, IAudioPlayCont
...
@@ -77,7 +77,7 @@ class AudioPlayPresenter : BasePresenter<IAudioPlayContract.View, IAudioPlayCont
override
fun
getCoursePlayData
()
{
override
fun
getCoursePlayData
()
{
mView
.
showProgressDialog
()
mView
.
showProgressDialog
()
mModel
.
getCoursePlayData
(
mCourseId
)
mModel
.
getCoursePlayData
(
mCourseId
)
.
compose
(
RxUtils
.
applySchedulers
())
.
compose
(
RxUtils
.
applySchedulers
(
mView
))
.
subscribe
(
object
:
CommonObserver
<
BaseResponse
<
CourseMediaDetailBean
>>()
{
.
subscribe
(
object
:
CommonObserver
<
BaseResponse
<
CourseMediaDetailBean
>>()
{
override
fun
onError
(
s
:
String
?)
{
override
fun
onError
(
s
:
String
?)
{
mView
.
dismissProgressDialog
()
mView
.
dismissProgressDialog
()
...
@@ -91,10 +91,8 @@ class AudioPlayPresenter : BasePresenter<IAudioPlayContract.View, IAudioPlayCont
...
@@ -91,10 +91,8 @@ class AudioPlayPresenter : BasePresenter<IAudioPlayContract.View, IAudioPlayCont
mCourPlayBean
=
bean
mCourPlayBean
=
bean
setPlayList
(
bean
)
setPlayList
(
bean
)
if
(!
mPlayUrl
.
isNullOrEmpty
())
{
if
(!
mPlayUrl
.
isNullOrEmpty
())
{
val
regex
=
Regex
(
"(?<=video).*?(?=&token)"
)
val
playUrl
=
regex
.
find
(
mPlayUrl
!!
)
?.
value
val
position
=
mPlayList
.
indexOfLast
{
val
position
=
mPlayList
.
indexOfLast
{
playUrl
==
regex
.
find
(
it
.
url
)
?.
value
mPlayUrl
==
it
.
url
}
}
mCurrentPosition
=
if
(-
1
==
position
)
0
else
position
mCurrentPosition
=
if
(-
1
==
position
)
0
else
position
}
}
...
@@ -113,7 +111,7 @@ class AudioPlayPresenter : BasePresenter<IAudioPlayContract.View, IAudioPlayCont
...
@@ -113,7 +111,7 @@ class AudioPlayPresenter : BasePresenter<IAudioPlayContract.View, IAudioPlayCont
override
fun
getConsultantInfo
()
{
override
fun
getConsultantInfo
()
{
mModel
.
getConsultantInfo
(
mCourseId
)
mModel
.
getConsultantInfo
(
mCourseId
)
.
compose
(
RxUtils
.
applySchedulers
())
.
compose
(
RxUtils
.
applySchedulers
(
mView
))
.
subscribe
(
object
:
CommonObserver
<
BaseResponse
<
CourseConsultant
>>()
{
.
subscribe
(
object
:
CommonObserver
<
BaseResponse
<
CourseConsultant
>>()
{
override
fun
onError
(
s
:
String
?)
{}
override
fun
onError
(
s
:
String
?)
{}
...
@@ -200,7 +198,7 @@ class AudioPlayPresenter : BasePresenter<IAudioPlayContract.View, IAudioPlayCont
...
@@ -200,7 +198,7 @@ class AudioPlayPresenter : BasePresenter<IAudioPlayContract.View, IAudioPlayCont
if
(!
bean
.
isDemo
&&
!
extra
.
isBuy
)
{
if
(!
bean
.
isDemo
&&
!
extra
.
isBuy
)
{
if
(
mView
.
audioIsPlaying
())
mView
.
audioPausePlay
()
if
(
mView
.
audioIsPlaying
())
mView
.
audioPausePlay
()
mView
.
buyCourseTipDialog
()
mView
.
buyCourseTipDialog
()
}
else
if
(
bean
.
mediaType
==
COURSE_AUDIO
)
{
}
else
{
mCurrentPosition
=
playPosition
mCurrentPosition
=
playPosition
mView
.
setTitle
(
bean
.
title
)
mView
.
setTitle
(
bean
.
title
)
return
true
return
true
...
...
ydl-platform/src/main/java/com/ydl/ydlcommon/utils/ImageExt.kt
0 → 100644
View file @
3eaf2c42
@file
:
JvmName
(
"ImageExt"
)
@file
:
Suppress
(
"unused"
)
import
android.content.*
import
android.graphics.Bitmap
import
android.net.Uri
import
android.os.Build
import
android.os.Environment
import
android.provider.MediaStore
import
android.util.Log
import
com.ydl.ydlcommon.utils.extend.ifNotNull
import
java.io.File
import
java.io.FileNotFoundException
import
java.io.InputStream
import
java.io.OutputStream
import
java.util.*
private
const
val
TAG
=
"ImageExt"
private
val
ALBUM_DIR
=
Environment
.
DIRECTORY_PICTURES
private
class
OutputFileTaker
(
var
file
:
File
?
=
null
)
/**
* 复制图片文件到相册的Pictures文件夹
*
* @param context 上下文
* @param fileName 文件名。 需要携带后缀
* @param relativePath 相对于Pictures的路径
*/
fun
File
.
copyToAlbum
(
context
:
Context
,
fileName
:
String
,
relativePath
:
String
?):
Uri
?
{
if
(!
this
.
canRead
()
||
!
this
.
exists
())
{
Log
.
w
(
TAG
,
"check: read file error: $this"
)
return
null
}
return
this
.
inputStream
().
use
{
it
.
saveToAlbum
(
context
,
fileName
,
relativePath
)
}
}
/**
* 保存图片Stream到相册的Pictures文件夹
*
* @param context 上下文
* @param fileName 文件名。 需要携带后缀
* @param relativePath 相对于Pictures的路径
*/
fun
InputStream
.
saveToAlbum
(
context
:
Context
,
fileName
:
String
,
relativePath
:
String
?):
Uri
?
{
val
resolver
=
context
.
contentResolver
val
outputFile
=
OutputFileTaker
()
val
imageUri
=
resolver
.
insertMediaImage
(
fileName
,
relativePath
,
outputFile
)
if
(
imageUri
==
null
)
{
Log
.
w
(
TAG
,
"insert: error: uri == null"
)
return
null
}
(
imageUri
.
outputStream
(
resolver
)
?:
return
null
).
use
{
output
->
this
.
use
{
input
->
input
.
copyTo
(
output
)
imageUri
.
finishPending
(
context
,
resolver
,
outputFile
.
file
)
}
}
return
imageUri
}
/**
* 保存Bitmap到相册的Pictures文件夹
*
* https://developer.android.google.cn/training/data-storage/shared/media
*
* @param context 上下文
* @param fileName 文件名。 需要携带后缀
* @param relativePath 相对于Pictures的路径
* @param quality 质量
*/
fun
Bitmap
.
saveToAlbum
(
context
:
Context
,
fileName
:
String
,
relativePath
:
String
?
=
null
,
quality
:
Int
=
100
):
Uri
?
{
// 插入图片信息
val
resolver
=
context
.
contentResolver
val
outputFile
=
OutputFileTaker
()
val
imageUri
=
resolver
.
insertMediaImage
(
fileName
,
relativePath
,
outputFile
)
if
(
imageUri
==
null
)
{
Log
.
w
(
TAG
,
"insert: error: uri == null"
)
return
null
}
// 保存图片
(
imageUri
.
outputStream
(
resolver
)
?:
return
null
).
use
{
val
format
=
fileName
.
getBitmapFormat
()
this
@saveToAlbum
.
compress
(
format
,
quality
,
it
)
imageUri
.
finishPending
(
context
,
resolver
,
outputFile
.
file
)
}
return
imageUri
}
private
fun
Uri
.
outputStream
(
resolver
:
ContentResolver
):
OutputStream
?
{
return
try
{
resolver
.
openOutputStream
(
this
)
}
catch
(
e
:
FileNotFoundException
)
{
Log
.
e
(
TAG
,
"save: open stream error: $e"
)
null
}
}
private
fun
Uri
.
finishPending
(
context
:
Context
,
resolver
:
ContentResolver
,
outputFile
:
File
?
)
{
val
imageValues
=
ContentValues
()
// if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
if
(
outputFile
!=
null
)
{
imageValues
.
put
(
MediaStore
.
Images
.
Media
.
SIZE
,
outputFile
.
length
())
}
resolver
.
update
(
this
,
imageValues
,
null
,
null
)
// 通知媒体库更新
val
intent
=
Intent
(
@Suppress
(
"DEPRECATION"
)
Intent
.
ACTION_MEDIA_SCANNER_SCAN_FILE
,
this
)
context
.
sendBroadcast
(
intent
)
// } else {
// Android Q添加了IS_PENDING状态,为0时其他应用才可见
// imageValues.put(MediaStore.Images.Media.IS_PENDING, 0)
// resolver.update(this, imageValues, null, null)
// }
}
private
fun
String
.
getBitmapFormat
():
Bitmap
.
CompressFormat
{
val
fileName
=
this
.
toLowerCase
(
Locale
.
getDefault
())
return
when
{
fileName
.
endsWith
(
".png"
)
->
Bitmap
.
CompressFormat
.
PNG
fileName
.
endsWith
(
".jpg"
)
||
fileName
.
endsWith
(
".jpeg"
)
->
Bitmap
.
CompressFormat
.
JPEG
fileName
.
endsWith
(
".webp"
)
->
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
// Bitmap.CompressFormat.WEBP_LOSSLESS
// else
Bitmap
.
CompressFormat
.
WEBP
else
->
Bitmap
.
CompressFormat
.
PNG
}
}
private
fun
String
.
getMimeType
():
String
?
{
val
fileName
=
this
.
toLowerCase
(
Locale
.
getDefault
())
return
when
{
fileName
.
endsWith
(
".png"
)
->
"image/png"
fileName
.
endsWith
(
".jpg"
)
||
fileName
.
endsWith
(
".jpeg"
)
->
"image/jpeg"
fileName
.
endsWith
(
".webp"
)
->
"image/webp"
fileName
.
endsWith
(
".gif"
)
->
"image/gif"
else
->
null
}
}
/**
* 插入图片到媒体库
*/
private
fun
ContentResolver
.
insertMediaImage
(
fileName
:
String
,
relativePath
:
String
?,
outputFileTaker
:
OutputFileTaker
?
=
null
):
Uri
?
{
// 图片信息
val
imageValues
=
ContentValues
().
apply
{
val
mimeType
=
fileName
.
getMimeType
()
if
(
mimeType
!=
null
)
{
put
(
MediaStore
.
Images
.
Media
.
MIME_TYPE
,
mimeType
)
}
val
date
=
System
.
currentTimeMillis
()
/
1000
put
(
MediaStore
.
Images
.
Media
.
DATE_ADDED
,
date
)
put
(
MediaStore
.
Images
.
Media
.
DATE_MODIFIED
,
date
)
}
// 保存的位置
val
collection
:
Uri
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// val path = if (relativePath != null) "$ALBUM_DIR/${relativePath}" else ALBUM_DIR
// imageValues.apply {
// put(MediaStore.Images.Media.DISPLAY_NAME, fileName)
// put(MediaStore.Images.Media.RELATIVE_PATH, path)
// put(MediaStore.Images.Media.IS_PENDING, 1)
// }
// collection = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
// // 高版本不用查重直接插入,会自动重命名
// } else {
// 老版本
val
pictures
=
@Suppress
(
"DEPRECATION"
)
Environment
.
getExternalStoragePublicDirectory
(
ALBUM_DIR
)
val
saveDir
=
if
(
relativePath
!=
null
)
File
(
pictures
,
relativePath
)
else
pictures
if
(!
saveDir
.
exists
()
&&
!
saveDir
.
mkdirs
())
{
Log
.
e
(
TAG
,
"save: error: can't create Pictures directory"
)
return
null
}
// 文件路径查重,重复的话在文件名后拼接数字
var
imageFile
=
File
(
saveDir
,
fileName
)
val
fileNameWithoutExtension
=
imageFile
.
nameWithoutExtension
val
fileExtension
=
imageFile
.
extension
var
queryUri
=
this
.
queryMediaImage28
(
imageFile
.
absolutePath
)
var
suffix
=
1
while
(
queryUri
!=
null
)
{
val
newName
=
fileNameWithoutExtension
+
"(${suffix++})."
+
fileExtension
imageFile
=
File
(
saveDir
,
newName
)
queryUri
=
this
.
queryMediaImage28
(
imageFile
.
absolutePath
)
}
imageValues
.
apply
{
put
(
MediaStore
.
Images
.
Media
.
DISPLAY_NAME
,
imageFile
.
name
)
// 保存路径
val
imagePath
=
imageFile
.
absolutePath
Log
.
v
(
TAG
,
"save file: $imagePath"
)
put
(
@Suppress
(
"DEPRECATION"
)
MediaStore
.
Images
.
Media
.
DATA
,
imagePath
)
}
outputFileTaker
?.
file
=
imageFile
// 回传文件路径,用于设置文件大小
collection
=
MediaStore
.
Images
.
Media
.
EXTERNAL_CONTENT_URI
// }
// 插入图片信息
return
this
.
insert
(
collection
,
imageValues
)
}
/**
* Android Q以下版本,查询媒体库中当前路径是否存在
* @return Uri 返回null时说明不存在,可以进行图片插入逻辑
*/
private
fun
ContentResolver
.
queryMediaImage28
(
imagePath
:
String
):
Uri
?
{
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) return null
val
imageFile
=
File
(
imagePath
)
if
(
imageFile
.
canRead
()
&&
imageFile
.
exists
())
{
Log
.
v
(
TAG
,
"query: path: $imagePath exists"
)
// 文件已存在,返回一个file://xxx的uri
return
Uri
.
fromFile
(
imageFile
)
}
// 保存的位置
val
collection
=
MediaStore
.
Images
.
Media
.
EXTERNAL_CONTENT_URI
// 查询是否已经存在相同图片
val
query
=
this
.
query
(
collection
,
arrayOf
(
MediaStore
.
Images
.
Media
.
_ID
,
@Suppress
(
"DEPRECATION"
)
MediaStore
.
Images
.
Media
.
DATA
),
"${@Suppress("
DEPRECATION
") MediaStore.Images.Media.DATA} == ?"
,
arrayOf
(
imagePath
),
null
)
query
?.
use
{
while
(
it
.
moveToNext
())
{
val
idColumn
=
it
.
getColumnIndexOrThrow
(
MediaStore
.
Images
.
Media
.
_ID
)
val
id
=
it
.
getLong
(
idColumn
)
val
existsUri
=
ContentUris
.
withAppendedId
(
collection
,
id
)
Log
.
v
(
TAG
,
"query: path: $imagePath exists uri: $existsUri"
)
return
existsUri
}
}
return
null
}
ydl-platform/src/main/java/com/ydl/ydlcommon/utils/ImageUtil.java
deleted
100644 → 0
View file @
75cc4bd7
package
com
.
ydl
.
ydlcommon
.
utils
;
import
android.content.Context
;
import
android.content.Intent
;
import
android.graphics.Bitmap
;
import
android.net.Uri
;
import
android.os.Environment
;
import
android.util.Base64
;
import
com.yidianling.common.tools.ToastUtil
;
import
java.io.*
;
public
class
ImageUtil
{
public
static
boolean
savePicture
(
Context
context
,
String
base64DataStr
)
{
// 去掉base64中的前缀
// String base64Str = base64DataStr.substring(base64DataStr.indexOf(",")+1, base64DataStr.length());
File
appDir
=
new
File
(
Environment
.
getExternalStorageDirectory
(),
"Camera"
);
// 图片保存的文件夹的名称
if
(!
appDir
.
exists
())
{
appDir
.
mkdir
();
}
String
imgName
=
System
.
currentTimeMillis
()
+
".png"
;
File
fileTest
=
new
File
(
appDir
,
imgName
);
byte
[]
data
=
Base64
.
decode
(
base64DataStr
,
Base64
.
DEFAULT
);
for
(
int
i
=
0
;
i
<
data
.
length
;
i
++)
{
if
(
data
[
i
]
<
0
)
{
data
[
i
]
+=
256
;
//调整异常数据
}
}
OutputStream
os
=
null
;
try
{
os
=
new
FileOutputStream
(
fileTest
);
os
.
write
(
data
);
os
.
flush
();
os
.
close
();
// 通知系统刷新图库
updateAlbum
(
context
,
fileTest
);
ToastUtil
.
toastShort
(
"图片已保存至相册"
);
return
true
;
}
catch
(
FileNotFoundException
e
)
{
e
.
printStackTrace
();
ToastUtil
.
toastShort
(
"保存失败"
);
return
false
;
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
ToastUtil
.
toastShort
(
"保存失败"
);
return
false
;
}
}
/**
* 通知图库更新数据
* context
* fileName
* file
*/
private
static
void
updateAlbum
(
Context
context
,
File
file
)
{
// 最后通知图库更新
context
.
sendBroadcast
(
new
Intent
(
Intent
.
ACTION_MEDIA_SCANNER_SCAN_FILE
,
Uri
.
fromFile
(
file
)));
}
public
static
boolean
savePicture
(
Context
context
,
Bitmap
bitmap
)
{
if
(
bitmap
==
null
)
{
return
false
;
}
// 去掉base64中的前缀
// String base64Str = base64DataStr.substring(base64DataStr.indexOf(",")+1, base64DataStr.length());
File
appDir
=
new
File
(
Environment
.
getExternalStorageDirectory
(),
"Camera"
);
// 图片保存的文件夹的名称
if
(!
appDir
.
exists
())
{
appDir
.
mkdir
();
}
String
imgName
=
System
.
currentTimeMillis
()
+
".png"
;
File
fileTest
=
new
File
(
appDir
,
imgName
);
ByteArrayOutputStream
byteArrayOutputStream
=
new
ByteArrayOutputStream
();
bitmap
.
compress
(
Bitmap
.
CompressFormat
.
PNG
,
100
,
byteArrayOutputStream
);
byte
[]
data
=
byteArrayOutputStream
.
toByteArray
();
for
(
int
i
=
0
;
i
<
data
.
length
;
i
++)
{
if
(
data
[
i
]
<
0
)
{
data
[
i
]
+=
256
;
//调整异常数据
}
}
OutputStream
os
=
null
;
try
{
os
=
new
FileOutputStream
(
fileTest
);
os
.
write
(
data
);
os
.
flush
();
os
.
close
();
// 通知系统刷新图库
updateAlbum
(
context
,
fileTest
);
ToastUtil
.
toastShort
(
"图片已保存至相册"
);
return
true
;
}
catch
(
FileNotFoundException
e
)
{
e
.
printStackTrace
();
ToastUtil
.
toastShort
(
"保存失败"
);
return
false
;
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
ToastUtil
.
toastShort
(
"保存失败"
);
return
false
;
}
}
}
ydl-platform/src/main/java/com/ydl/ydlcommon/utils/ImageUtil.kt
0 → 100644
View file @
3eaf2c42
package
com.ydl.ydlcommon.utils
import
android.content.Context
import
android.graphics.Bitmap
import
android.graphics.BitmapFactory
import
android.util.Base64
import
com.hjq.permissions.Permission
import
com.hjq.permissions.XXPermissions
import
com.yidianling.common.tools.ToastUtil
import
io.reactivex.Observable
import
io.reactivex.disposables.Disposable
import
io.reactivex.schedulers.Schedulers
import
saveToAlbum
class
ImageUtil
{
companion
object
{
private
fun
saveToAlbum
(
context
:
Context
,
bitmap
:
Bitmap
?):
Disposable
{
return
Observable
.
create
<
Boolean
>
{
bitmap
?.
let
{
pic
->
pic
.
saveToAlbum
(
context
,
"${System.currentTimeMillis()}.png"
)
it
.
onNext
(
true
)
}
?:
let
{
_
->
it
.
onNext
(
false
)
}
}.
subscribeOn
(
Schedulers
.
io
())
.
subscribe
{
if
(
it
)
{
ToastUtil
.
toastShort
(
"图片已保存至相册"
)
}
else
ToastUtil
.
toastShort
(
"保存失败"
)
}
}
private
fun
convertBase64ToBitmap
(
base64
:
String
):
Bitmap
?
{
val
decode
=
Base64
.
decode
(
base64
,
Base64
.
DEFAULT
)
return
BitmapFactory
.
decodeByteArray
(
decode
,
0
,
decode
.
size
)
}
/**
* base64字符串
* 保存图片到相册
*/
fun
savePicture
(
context
:
Context
,
base64
:
String
?):
Disposable
?
{
var
disposable
:
Disposable
?
=
null
base64
?.
run
{
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// disposable = saveToAlbum(context, convertBase64ToPic(this))
// } else {
val
permissions
=
arrayOf
(
Permission
.
READ_EXTERNAL_STORAGE
,
Permission
.
WRITE_EXTERNAL_STORAGE
)
if
(
XXPermissions
.
isGrantedPermission
(
context
,
permissions
))
{
disposable
=
saveToAlbum
(
context
,
convertBase64ToBitmap
(
this
))
}
else
{
XXPermissions
.
with
(
context
)
.
permission
(
permissions
)
.
request
{
_
,
_
->
disposable
=
saveToAlbum
(
context
,
convertBase64ToBitmap
(
this
))
}
}
// }
}
return
disposable
}
/**
* bitmap
* 保存图片到相册
*/
fun
savePicture
(
context
:
Context
,
bitmap
:
Bitmap
?):
Disposable
?
{
var
disposable
:
Disposable
?
=
null
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// disposable = saveToAlbum(context, bitmap)
// } else {
val
permissions
=
arrayOf
(
Permission
.
READ_EXTERNAL_STORAGE
,
Permission
.
WRITE_EXTERNAL_STORAGE
)
if
(
XXPermissions
.
isGrantedPermission
(
context
,
permissions
))
{
disposable
=
saveToAlbum
(
context
,
bitmap
)
}
else
{
XXPermissions
.
with
(
context
)
.
permission
(
permissions
)
.
request
{
_
,
_
->
disposable
=
saveToAlbum
(
context
,
bitmap
)
}
}
// }
return
disposable
}
}
}
\ No newline at end of file
ydl-platform/src/main/java/com/ydl/ydlcommon/view/dialog/YDLShareDialog.kt
View file @
3eaf2c42
...
@@ -292,7 +292,9 @@ class YDLShareDialog : DialogFragment {
...
@@ -292,7 +292,9 @@ class YDLShareDialog : DialogFragment {
}
}
tv_save_pic
.
setOnClickListener
{
tv_save_pic
.
setOnClickListener
{
ImageUtil
.
savePicture
(
mActivity
,
base64DataStr
)
mActivity
?.
let
{
ImageUtil
.
savePicture
(
it
,
base64DataStr
)
}
}
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment