Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
Sobot_module_Dev
Project
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
sobot_android
Sobot_module_Dev
Commits
a64a3da5
Commit
a64a3da5
authored
May 17, 2024
by
zhengnw@sobot.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
widget 1.2.6
parent
b943125c
Show whitespace changes
Inline
Side-by-side
Showing
37 changed files
with
1595 additions
and
120 deletions
+1595
-120
build.gradle
app/build.gradle
+1
-2
AndroidManifest.xml
app/src/main/AndroidManifest.xml
+1
-0
MainActivity.java
app/src/main/java/com/sobot/moduletest/MainActivity.java
+35
-45
MyApp.java
app/src/main/java/com/sobot/moduletest/MyApp.java
+2
-0
build.gradle
sobot_album/build.gradle
+2
-1
sobot-album_publish-mavencentral.gradle
sobot_album/sobot-album_publish-mavencentral.gradle
+1
-1
SobotAlbumActivity.java
...ain/java/com/sobot/album/activity/SobotAlbumActivity.java
+1
-1
AlbumActivity.java
...rc/main/java/com/sobot/album/app/album/AlbumActivity.java
+1
-5
GalleryActivity.java
.../main/java/com/sobot/album/app/album/GalleryActivity.java
+1
-1
NullActivity.java
...src/main/java/com/sobot/album/app/album/NullActivity.java
+1
-1
CameraActivity.java
.../main/java/com/sobot/album/app/camera/CameraActivity.java
+1
-1
GalleryActivity.java
...ain/java/com/sobot/album/app/gallery/GalleryActivity.java
+1
-1
GalleryAlbumActivity.java
...ava/com/sobot/album/app/gallery/GalleryAlbumActivity.java
+1
-1
build.gradle
sobot_widget/build.gradle
+2
-1
sobot-widget-publish-mavencentral.gradle
sobot_widget/sobot-widget-publish-mavencentral.gradle
+1
-1
AndroidManifest.xml
sobot_widget/src/main/AndroidManifest.xml
+6
-0
SobotRecyclerCallBack.java
...widget/refresh/layout/callback/SobotRecyclerCallBack.java
+25
-0
SobotBaseActivity.java
...main/java/com/sobot/widget/ui/base/SobotBaseActivity.java
+130
-58
SobotAlbumFile.java
.../sobot/widget/ui/base/picandroidvideo/SobotAlbumFile.java
+308
-0
SobotMediaReaderScanUtils.java
...et/ui/base/picandroidvideo/SobotMediaReaderScanUtils.java
+186
-0
SobotSelectPicAndVideoActivity.java
.../base/picandroidvideo/SobotSelectPicAndVideoActivity.java
+166
-0
SobotSelectPicAndVideoAdapter.java
...i/base/picandroidvideo/SobotSelectPicAndVideoAdapter.java
+251
-0
SpaceItemDecoration.java
...t/widget/ui/base/picandroidvideo/SpaceItemDecoration.java
+281
-0
sobot_normal_btn_bg.xml
...idget/src/main/res/drawable-night/sobot_normal_btn_bg.xml
+5
-0
sobot_album_tag_video_white.png
...c/main/res/drawable-xhdpi/sobot_album_tag_video_white.png
+0
-0
sobot_icon_add.png
sobot_widget/src/main/res/drawable-xhdpi/sobot_icon_add.png
+0
-0
sobot_photo_selected.png
...dget/src/main/res/drawable-xhdpi/sobot_photo_selected.png
+0
-0
sobot_photo_unselected.png
...et/src/main/res/drawable-xhdpi/sobot_photo_unselected.png
+0
-0
sobot_bg_checkbox.xml
sobot_widget/src/main/res/drawable/sobot_bg_checkbox.xml
+8
-0
sobot_custom_scroll_style.xml
...idget/src/main/res/drawable/sobot_custom_scroll_style.xml
+13
-0
sobot_normal_btn_bg.xml
sobot_widget/src/main/res/drawable/sobot_normal_btn_bg.xml
+5
-0
sobot_activity_select_pic_and_video.xml
...c/main/res/layout/sobot_activity_select_pic_and_video.xml
+72
-0
sobot_select_pic_and_video_item.xml
...t/src/main/res/layout/sobot_select_pic_and_video_item.xml
+65
-0
strings.xml
sobot_widget/src/main/res/values-en/strings.xml
+5
-0
colors.xml
sobot_widget/src/main/res/values-night/colors.xml
+6
-0
colors.xml
sobot_widget/src/main/res/values/colors.xml
+6
-0
strings.xml
sobot_widget/src/main/res/values/strings.xml
+5
-0
No files found.
app/build.gradle
View file @
a64a3da5
...
...
@@ -35,13 +35,12 @@ dependencies {
implementation
'com.google.android.material:material:1.4.+'
implementation
project
(
':sobot_common'
)
implementation
project
(
':sobot_widget'
)
implementation
project
(
':sobot_album'
)
//
implementation project(':sobot_album')
// implementation 'com.sobot.library:widget:0.3'
// api 'com.sobot.library:sobotcommon:1.0'
// api 'com.sobot.library:sobotcommon_x:1.0'
implementation
'com.github.bumptech.glide:glide:4.9.0'
implementation
'com.sobot.chat:sobotsupport-glidev4:2.3'
// implementation 'com.facebook.fresco:fresco:1.13.0'
//android x 可以用这个 ,普通版不能用这个
// implementation 'com.facebook.fresco:fresco:2.6.0'
...
...
app/src/main/AndroidManifest.xml
View file @
a64a3da5
...
...
@@ -20,6 +20,7 @@
<activity
android:name=
".MainActivity"
android:exported=
"true"
android:theme=
"@style/sobot_activity_def_theme"
android:configChanges=
"orientation|keyboardHidden|screenSize|touchscreen|navigation|locale|fontScale|uiMode|screenLayout|smallestScreenSize"
>
<intent-filter>
<action
android:name=
"android.intent.action.MAIN"
/>
...
...
app/src/main/java/com/sobot/moduletest/MainActivity.java
View file @
a64a3da5
...
...
@@ -9,14 +9,6 @@ import android.net.Uri;
import
android.widget.ImageView
;
import
android.widget.TextView
;
import
androidx.annotation.NonNull
;
import
com.sobot.album.Action
;
import
com.sobot.album.AlbumConfig
;
import
com.sobot.album.AlbumFile
;
import
com.sobot.album.SobotAlbum
;
import
com.sobot.album.SobotMediaLoader
;
import
com.sobot.album.api.widget.Widget
;
import
com.sobot.common.login.SobotLoginTools
;
import
com.sobot.common.login.callback.SobotResultBlock
;
import
com.sobot.common.login.callback.SobotResultCode
;
...
...
@@ -32,14 +24,11 @@ import com.sobot.widget.refresh.layout.footer.ClassicsFooter;
import
com.sobot.widget.refresh.layout.header.ClassicsHeader
;
import
com.sobot.widget.ui.SobotMarkConfig
;
import
com.sobot.widget.ui.base.SobotBaseActivity
;
import
com.sobot.widget.ui.permission.SobotPermissionListenerImpl
;
import
com.sobot.widget.ui.rich.HtmlToolUtils
;
import
com.sobot.widget.ui.toast.SobotToastUtil
;
import
java.io.File
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.Locale
;
import
java.util.Map
;
public
class
MainActivity
extends
SobotBaseActivity
{
...
...
@@ -285,42 +274,43 @@ public class MainActivity extends SobotBaseActivity {
// }
// openAlbum();
// selectPicFromLocal();
}
private
void
openAlbum
()
{
SobotAlbum
.
album
(
MainActivity
.
this
)
.
multipleChoice
()
.
columnCount
(
4
)
.
selectCount
(
4
)
.
camera
(
false
)
.
cameraVideoQuality
(
1
)
.
cameraVideoLimitDuration
(
Integer
.
MAX_VALUE
)
.
cameraVideoLimitBytes
(
Integer
.
MAX_VALUE
)
.
checkedList
(
mAlbumFiles
)
.
widget
(
Widget
.
newDarkBuilder
(
MainActivity
.
this
)
.
title
(
""
)
.
build
()
)
.
onResult
(
new
Action
<
ArrayList
<
AlbumFile
>>()
{
@Override
public
void
onAction
(
@NonNull
ArrayList
<
AlbumFile
>
result
)
{
if
(
result
.
size
()
>
0
)
{
}
}
})
.
onCancel
(
new
Action
<
String
>()
{
@Override
public
void
onAction
(
@NonNull
String
result
)
{
//取消选择
}
})
.
start
();
}
private
ArrayList
<
AlbumFile
>
mAlbumFiles
=
new
ArrayList
<>();
//编辑的图片地址
//
private void openAlbum() {
//
SobotAlbum.album(MainActivity.this)
//
.multipleChoice()
//
.columnCount(4)
//
.selectCount(4)
//
.camera(false)
//
.cameraVideoQuality(1)
//
.cameraVideoLimitDuration(Integer.MAX_VALUE)
//
.cameraVideoLimitBytes(Integer.MAX_VALUE)
//
.checkedList(mAlbumFiles)
//
.widget(
//
Widget.newDarkBuilder(MainActivity.this)
//
.title("")
//
.build()
//
)
//
.onResult(new Action<ArrayList<AlbumFile>>() {
//
@Override
//
public void onAction(@NonNull ArrayList<AlbumFile> result) {
//
if (result.size() > 0) {
//
//
//
}
//
}
//
})
//
.onCancel(new Action<String>() {
//
@Override
//
public void onAction(@NonNull String result) {
//
//取消选择
//
}
//
})
//
.start();
//
}
//
//
private ArrayList<AlbumFile> mAlbumFiles = new ArrayList<>();//编辑的图片地址
@Override
protected
void
initData
()
{
...
...
app/src/main/java/com/sobot/moduletest/MyApp.java
View file @
a64a3da5
...
...
@@ -23,6 +23,7 @@ public class MyApp extends MultiDexApplication {
SobotCommonApi
.
setShowLogDebug
(
true
);
SobotWidgetApi
.
setSwitchMarkStatus
(
SobotMarkConfig
.
LANDSCAPE_SCREEN
,
false
);
SobotWidgetApi
.
setSwitchMarkStatus
(
SobotMarkConfig
.
DISPLAY_INNOTCH
,
false
);
SobotWidgetApi
.
setSwitchMarkStatus
(
SobotMarkConfig
.
SHOW_PERMISSION_TIPS_POP
,
false
);
}
}
\ No newline at end of file
sobot_album/build.gradle
View file @
a64a3da5
...
...
@@ -22,7 +22,8 @@ dependencies {
compileOnly
'com.google.android.material:material:1.4.+'
compileOnly
'androidx.appcompat:appcompat:1.0.0'
compileOnly
'androidx.recyclerview:recyclerview:1.0.0'
api
'com.sobot.library:widget_x:1.2.3'
api
'com.sobot.library:widget_x:1.2.6'
// implementation project(':sobot_widget')
api
'com.sobot.library:picture_x:1.2.0'
}
...
...
sobot_album/sobot-album_publish-mavencentral.gradle
View file @
a64a3da5
...
...
@@ -12,7 +12,7 @@ task androidSourcesJar(type: Jar) {
ext
{
PUBLISH_GROUP_ID
=
"com.sobot.library"
//项目包名
PUBLISH_ARTIFACT_ID
=
'album'
//项目名
PUBLISH_VERSION
=
'1.0.
3
'
//版本号
PUBLISH_VERSION
=
'1.0.
4
'
//版本号
}
...
...
sobot_album/src/main/java/com/sobot/album/activity/SobotAlbumActivity.java
View file @
a64a3da5
...
...
@@ -60,7 +60,7 @@ public class SobotAlbumActivity extends SobotBaseActivity {
}
@Override
protected
void
initView
()
throws
InterruptedException
{
protected
void
initView
()
{
mTvMessage
=
findViewById
(
R
.
id
.
tv_message
);
recyclerView
=
findViewById
(
R
.
id
.
recycler_view
);
recyclerView
.
setLayoutManager
(
new
GridLayoutManager
(
this
,
3
));
...
...
sobot_album/src/main/java/com/sobot/album/app/album/AlbumActivity.java
View file @
a64a3da5
package
com
.
sobot
.
album
.
app
.
album
;
import
android.Manifest
;
import
android.content.Intent
;
import
android.content.pm.PackageManager
;
import
android.content.res.Configuration
;
import
android.os.Bundle
;
import
android.os.Handler
;
import
android.text.TextUtils
;
import
android.view.View
;
import
android.widget.CompoundButton
;
...
...
@@ -14,7 +11,6 @@ import android.widget.CompoundButton;
import
androidx.annotation.NonNull
;
import
androidx.annotation.Nullable
;
import
androidx.appcompat.widget.PopupMenu
;
import
androidx.core.content.ContextCompat
;
import
com.sobot.album.Action
;
import
com.sobot.album.AlbumFile
;
...
...
@@ -100,7 +96,7 @@ public class AlbumActivity extends SobotBaseActivity implements
}
@Override
protected
void
initView
()
throws
InterruptedException
{
protected
void
initView
(){
setTitle
(
R
.
string
.
sobot_album_select_images
);
getLeftMenu
().
setOnClickListener
(
new
View
.
OnClickListener
()
{
@Override
...
...
sobot_album/src/main/java/com/sobot/album/app/album/GalleryActivity.java
View file @
a64a3da5
...
...
@@ -62,7 +62,7 @@ public class GalleryActivity extends SobotBaseActivity implements Contract.Galle
}
@Override
protected
void
initView
()
throws
InterruptedException
{
protected
void
initView
(){
mView
=
new
GalleryView
<>(
this
,
getSupportFragmentManager
(),
this
);
Bundle
argument
=
getIntent
().
getExtras
();
assert
argument
!=
null
;
...
...
sobot_album/src/main/java/com/sobot/album/app/album/NullActivity.java
View file @
a64a3da5
...
...
@@ -35,7 +35,7 @@ public class NullActivity extends SobotAlbumBaseActivity implements Contract.Nul
}
@Override
protected
void
initView
()
throws
InterruptedException
{
protected
void
initView
(){
mView
=
new
NullView
(
this
,
this
);
Bundle
argument
=
getIntent
().
getExtras
();
...
...
sobot_album/src/main/java/com/sobot/album/app/camera/CameraActivity.java
View file @
a64a3da5
...
...
@@ -104,7 +104,7 @@ public class CameraActivity extends SobotAlbumBaseActivity {
}
@Override
protected
void
initView
()
throws
InterruptedException
{
protected
void
initView
(){
}
...
...
sobot_album/src/main/java/com/sobot/album/app/gallery/GalleryActivity.java
View file @
a64a3da5
...
...
@@ -38,7 +38,7 @@ public class GalleryActivity extends SobotAlbumBaseActivity implements Contract.
}
@Override
protected
void
initView
()
throws
InterruptedException
{
protected
void
initView
(){
mView
=
new
GalleryView
<>(
this
,
getSupportFragmentManager
(),
this
);
Bundle
argument
=
getIntent
().
getExtras
();
...
...
sobot_album/src/main/java/com/sobot/album/app/gallery/GalleryAlbumActivity.java
View file @
a64a3da5
...
...
@@ -51,7 +51,7 @@ public class GalleryAlbumActivity extends SobotAlbumBaseActivity implements Cont
}
@Override
protected
void
initView
()
throws
InterruptedException
{
protected
void
initView
(){
mView
=
new
GalleryView
<>(
this
,
getSupportFragmentManager
(),
this
);
Bundle
argument
=
getIntent
().
getExtras
();
...
...
sobot_widget/build.gradle
View file @
a64a3da5
...
...
@@ -25,9 +25,10 @@ android {
dependencies
{
api
fileTree
(
include:
[
'*.jar'
],
dir:
'libs'
)
compileOnly
'androidx.appcompat:appcompat:1.0.0'
api
'androidx.appcompat:appcompat:1.0.0'
compileOnly
'androidx.recyclerview:recyclerview:1.0.0'
api
'com.sobot.library:utils:1.1.3'
api
'com.sobot.library:picture_x:1.2.0'
}
...
...
sobot_widget/sobot-widget-publish-mavencentral.gradle
View file @
a64a3da5
...
...
@@ -12,7 +12,7 @@ task androidSourcesJar(type: Jar) {
ext
{
PUBLISH_GROUP_ID
=
"com.sobot.library"
//项目包名
PUBLISH_ARTIFACT_ID
=
'widget_x'
//项目名
PUBLISH_VERSION
=
'1.2.
4
'
//版本号
PUBLISH_VERSION
=
'1.2.
6
'
//版本号
}
...
...
sobot_widget/src/main/AndroidManifest.xml
View file @
a64a3da5
...
...
@@ -32,5 +32,10 @@
android:screenOrientation=
"behind"
android:theme=
"@style/sobot_activity_def_theme"
android:windowSoftInputMode=
"adjustResize"
/>
<activity
android:name=
".ui.base.picandroidvideo.SobotSelectPicAndVideoActivity"
android:configChanges=
"orientation|keyboardHidden|screenSize|touchscreen|navigation|locale|fontScale|uiMode|screenLayout|smallestScreenSize"
android:launchMode=
"singleTask"
android:theme=
"@style/sobot_activity_def_theme"
/>
</application>
</manifest>
\ No newline at end of file
sobot_widget/src/main/java/com/sobot/widget/refresh/layout/callback/SobotRecyclerCallBack.java
0 → 100644
View file @
a64a3da5
package
com
.
sobot
.
widget
.
refresh
.
layout
.
callback
;
import
android.view.View
;
/**
* 回调处理
*/
public
interface
SobotRecyclerCallBack
{
/**
* 点击事件
*
* @param view 点击的view
* @param position view的位置
*/
void
onItemClickListener
(
View
view
,
int
position
);
/**
* 长按事件
*
* @param view 长按的view
* @param position view的位置
*/
void
onItemLongClickListener
(
View
view
,
int
position
);
}
sobot_widget/src/main/java/com/sobot/widget/ui/base/SobotBaseActivity.java
View file @
a64a3da5
...
...
@@ -2,6 +2,7 @@ package com.sobot.widget.ui.base;
import
android.Manifest
;
import
android.content.Context
;
import
android.content.Intent
;
import
android.content.pm.ActivityInfo
;
import
android.content.pm.PackageManager
;
import
android.content.res.Configuration
;
...
...
@@ -12,12 +13,6 @@ import android.hardware.Camera;
import
android.os.Build
;
import
android.os.Bundle
;
import
android.os.LocaleList
;
import
androidx.annotation.Nullable
;
import
androidx.core.app.ActivityCompat
;
import
androidx.fragment.app.FragmentActivity
;
import
androidx.core.content.ContextCompat
;
import
android.text.TextUtils
;
import
android.util.DisplayMetrics
;
import
android.view.View
;
...
...
@@ -28,13 +23,20 @@ import android.widget.LinearLayout;
import
android.widget.RelativeLayout
;
import
android.widget.TextView
;
import
com.sobot.utils.SobotLogUtils
;
import
androidx.annotation.Nullable
;
import
androidx.appcompat.app.AppCompatActivity
;
import
androidx.appcompat.app.AppCompatDelegate
;
import
androidx.core.app.ActivityCompat
;
import
androidx.core.content.ContextCompat
;
import
androidx.fragment.app.FragmentActivity
;
import
com.sobot.utils.SobotSharedPreferencesUtil
;
import
com.sobot.utils.SobotSystemUtils
;
import
com.sobot.widget.R
;
import
com.sobot.widget.SobotWidgetApi
;
import
com.sobot.widget.ui.SobotBaseConstant
;
import
com.sobot.widget.ui.SobotMarkConfig
;
import
com.sobot.widget.ui.base.picandroidvideo.SobotSelectPicAndVideoActivity
;
import
com.sobot.widget.ui.image.SobotRCImageView
;
import
com.sobot.widget.ui.notchlib.SobotINotchScreen
;
import
com.sobot.widget.ui.notchlib.SobotNotchScreenManager
;
...
...
@@ -47,6 +49,7 @@ import com.sobot.widget.ui.utils.SobotResourceUtils;
import
com.sobot.widget.ui.utils.SobotWidgetUtils
;
import
java.io.File
;
import
java.util.Arrays
;
import
java.util.Locale
;
/**
...
...
@@ -93,7 +96,7 @@ public abstract class SobotBaseActivity extends FragmentActivity {
}
setUpToolBar
();
getWindow
().
setSoftInputMode
(
WindowManager
.
LayoutParams
.
SOFT_INPUT_STATE_HIDDEN
);
View
toolBar
=
findViewById
(
getResId
(
"sobot_layout_titlebar"
)
);
View
toolBar
=
findViewById
(
R
.
id
.
sobot_layout_titlebar
);
if
(
toolBar
!=
null
)
{
setUpToolBarLeftMenu
();
...
...
@@ -516,19 +519,32 @@ public abstract class SobotBaseActivity extends FragmentActivity {
switch
(
requestCode
)
{
case
SobotBaseConstant
.
REQUEST_CODE_PICTURE
:
try
{
//判断是否选择部分的权限
// SobotLogUtils.d("=====判断是否选择部分的权限=======");
//单独处理android 14 部分权限,如果允许是部分权限,跳转到回显界面
if
(
grantResults
.
length
>
1
&&
permissions
.
length
>
0
)
{
//是否有全部权限
boolean
isAllGranted
=
true
;
for
(
int
i
=
0
;
i
<
grantResults
.
length
;
i
++)
{
if
(
permissions
[
i
]
!=
null
&&
permissions
[
i
].
equals
(
Manifest
.
permission
.
READ_MEDIA_VISUAL_USER_SELECTED
))
{
// SobotLogUtils.d("=====android 14权限===="+permissions[i].equals(Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED)+"====="+grantResults[i]);
if
(
grantResults
[
i
]
==
PackageManager
.
PERMISSION_GRANTED
)
{
if
(
permissionListener
!=
null
)
{
permissionListener
.
onPermissionSuccessListener
();
if
(
grantResults
[
i
]
!=
PackageManager
.
PERMISSION_GRANTED
)
{
isAllGranted
=
false
;
}
}
if
(!
isAllGranted
)
{
for
(
int
i
=
0
;
i
<
grantResults
.
length
;
i
++)
{
if
(
permissions
[
i
]
!=
null
&&
permissions
[
i
].
equals
(
Manifest
.
permission
.
READ_MEDIA_VISUAL_USER_SELECTED
)
&&
grantResults
[
i
]
==
PackageManager
.
PERMISSION_GRANTED
)
{
int
selectType
;
if
(
Arrays
.
asList
(
permissions
).
contains
(
Manifest
.
permission
.
READ_MEDIA_IMAGES
)
&&
Arrays
.
asList
(
permissions
).
contains
(
Manifest
.
permission
.
READ_MEDIA_VIDEO
))
{
selectType
=
3
;
//部分视频和图片
}
else
if
(
Arrays
.
asList
(
permissions
).
contains
(
Manifest
.
permission
.
READ_MEDIA_VIDEO
))
{
selectType
=
2
;
//部分视频
}
else
{
selectType
=
1
;
//部分图片
}
openSelectPic
(
selectType
);
return
;
}
}
}
}
for
(
int
i
=
0
;
i
<
grantResults
.
length
;
i
++)
{
//判断权限的结果,如果有被拒绝,就return
if
(
grantResults
[
i
]
!=
PackageManager
.
PERMISSION_GRANTED
)
{
...
...
@@ -608,53 +624,99 @@ public abstract class SobotBaseActivity extends FragmentActivity {
}
/**
* android 14 部分权限情况下,回显照片或者视频
*
* @param selectType 1:部分图片 2:部分视频 3:部分视频和图片
*/
private
void
openSelectPic
(
int
selectType
)
{
Intent
intent
=
new
Intent
(
getSobotBaseActivity
(),
SobotSelectPicAndVideoActivity
.
class
);
intent
.
putExtra
(
"selectType"
,
selectType
);
startActivityForResult
(
intent
,
SobotBaseConstant
.
REQUEST_CODE_PICTURE
);
}
/**
* 检查存储权限
*
* @param checkType 0:图片权限 1:视频权限,
2:音频权限,3:选文件,图片、视频、录音所有细分的权限 4:图片和视频权限,读取相册图片和视频
* @param checkType 0:图片权限 1:视频权限,
3,所有细分的权限, android 13 使用
* @return true, 已经获取权限;false,没有权限,尝试获取
*/
protected
boolean
checkStoragePermission
(
int
checkType
)
{
//如果是升级Android13之前就已经具有读写SDK的权限,那么升级到13之后,自己具有上述三个权限。
//如果是升级Android13之后新装的应用,并且targetSDK小于33,则申请READ_EXTERNAL_STORAGE权限时,会自动转化为对上述三个权限的申请,权限申请框只一个
//如果是升级Android13之后新装的应用,并且targetSDK大于等于33,则申请READ_EXTERNAL_STORAGE权限时会自动拒绝。
//如果是升级Android13之后新装的应用,并且targetSDK大于等于33,则申请READ_EXTERNAL_STORAGE权限时会自动拒绝(同理WRITE_EXTERNAL_STORAGE也是一样)。
//如果是android14 没有图片或者视频权限,还需要判断是否有部分权限,如果有部分权限,跳转允许图片视频界面,选择可以访问的上传,或者打开设置申请永久权限
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
TIRAMISU
)
{
if
(
checkType
==
0
)
{
return
true
;
}
else
if
(
checkType
==
1
)
{
return
true
;
}
else
if
(
checkType
==
2
)
{
if
(
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_AUDIO
)
//检测是否有图片权限
if
(
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_IMAGES
)
!=
PackageManager
.
PERMISSION_GRANTED
)
{
//申请音频权限
this
.
requestPermissions
(
new
String
[]{
Manifest
.
permission
.
READ_MEDIA_AUDIO
},
SobotBaseConstant
.
REQUEST_CODE_PICTURE
);
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
UPSIDE_DOWN_CAKE
)
{
//android 14
if
(
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_VISUAL_USER_SELECTED
)
==
PackageManager
.
PERMISSION_GRANTED
&&
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_VIDEO
)
!=
PackageManager
.
PERMISSION_GRANTED
)
{
//有部分图片权限,直接打开允许访问图片视频列表界面
openSelectPic
(
1
);
//照片
return
false
;
}
}
else
if
(
checkType
==
3
)
{
//为适配Android 14
if
(
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_IMAGES
)
!=
PackageManager
.
PERMISSION_GRANTED
||
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_VIDEO
)
!=
PackageManager
.
PERMISSION_GRANTED
||
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_AUDIO
)
!=
PackageManager
.
PERMISSION_GRANTED
)
{
//申请:图片权限 视频权限 音频权限
this
.
requestPermissions
(
new
String
[]{
Manifest
.
permission
.
READ_MEDIA_AUDIO
,
Manifest
.
permission
.
READ_MEDIA_IMAGES
,
Manifest
.
permission
.
READ_MEDIA_VIDEO
},
SobotBaseConstant
.
REQUEST_CODE_PICTURE
);
}
else
{
this
.
requestPermissions
(
new
String
[]{
Manifest
.
permission
.
READ_MEDIA_IMAGES
,
Manifest
.
permission
.
READ_MEDIA_VISUAL_USER_SELECTED
},
SobotBaseConstant
.
REQUEST_CODE_PICTURE
);
return
false
;
}
}
else
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
UPSIDE_DOWN_CAKE
&&
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_VISUAL_USER_SELECTED
)
==
PackageManager
.
PERMISSION_GRANTED
)
{
return
true
;
//申请图片权限
this
.
requestPermissions
(
new
String
[]{
Manifest
.
permission
.
READ_MEDIA_IMAGES
},
SobotBaseConstant
.
REQUEST_CODE_PICTURE
);
return
false
;
}
}
if
(
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_IMAGES
)
!=
PackageManager
.
PERMISSION_GRANTED
||
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_VIDEO
)
!=
PackageManager
.
PERMISSION_GRANTED
)
{
}
else
if
(
checkType
==
1
)
{
if
(
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_VIDEO
)
!=
PackageManager
.
PERMISSION_GRANTED
)
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
UPSIDE_DOWN_CAKE
)
{
//申请:图片权限 视频权限 音频权限
this
.
requestPermissions
(
new
String
[]{
Manifest
.
permission
.
READ_MEDIA_IMAGES
,
Manifest
.
permission
.
READ_MEDIA_VIDEO
,
Manifest
.
permission
.
READ_MEDIA_VISUAL_USER_SELECTED
},
SobotBaseConstant
.
REQUEST_CODE_PICTURE
);
//android 14
if
(
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_VISUAL_USER_SELECTED
)
==
PackageManager
.
PERMISSION_GRANTED
&&
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_IMAGES
)
!=
PackageManager
.
PERMISSION_GRANTED
)
{
//有部分视频权限,直接打开允许访问图片视频列表界面
openSelectPic
(
2
);
//视频
return
false
;
}
else
{
this
.
requestPermissions
(
new
String
[]{
Manifest
.
permission
.
READ_MEDIA_VIDEO
,
Manifest
.
permission
.
READ_MEDIA_VISUAL_USER_SELECTED
},
SobotBaseConstant
.
REQUEST_CODE_PICTURE
);
return
false
;
}
}
else
{
//申请视频权限
this
.
requestPermissions
(
new
String
[]{
Manifest
.
permission
.
READ_MEDIA_VIDEO
},
SobotBaseConstant
.
REQUEST_CODE_PICTURE
);
return
false
;
}
}
return
true
;
}
else
{
//申请:图片权限 视频权限 音频权限
this
.
requestPermissions
(
new
String
[]{
Manifest
.
permission
.
READ_MEDIA_IMAGES
,
Manifest
.
permission
.
READ_MEDIA_VIDEO
},
SobotBaseConstant
.
REQUEST_CODE_PICTURE
);
if
(
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_IMAGES
)
!=
PackageManager
.
PERMISSION_GRANTED
||
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_VIDEO
)
!=
PackageManager
.
PERMISSION_GRANTED
||
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_AUDIO
)
!=
PackageManager
.
PERMISSION_GRANTED
)
{
if
(
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_IMAGES
)
==
PackageManager
.
PERMISSION_GRANTED
&&
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_AUDIO
)
!=
PackageManager
.
PERMISSION_GRANTED
)
{
//有图片和视频但是 没有音频权限
this
.
requestPermissions
(
new
String
[]{
Manifest
.
permission
.
READ_MEDIA_AUDIO
},
SobotBaseConstant
.
REQUEST_CODE_PICTURE
);
return
false
;
}
else
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
UPSIDE_DOWN_CAKE
)
{
//android 14
if
(
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_VISUAL_USER_SELECTED
)
==
PackageManager
.
PERMISSION_GRANTED
)
{
//有部分视频权限,直接打开允许访问图片视频列表界面
openSelectPic
(
3
);
//视频
return
false
;
}
else
{
this
.
requestPermissions
(
new
String
[]{
Manifest
.
permission
.
READ_MEDIA_IMAGES
,
Manifest
.
permission
.
READ_MEDIA_VIDEO
,
Manifest
.
permission
.
READ_MEDIA_AUDIO
,
Manifest
.
permission
.
READ_MEDIA_VISUAL_USER_SELECTED
},
SobotBaseConstant
.
REQUEST_CODE_PICTURE
);
return
false
;
}
}
else
{
//申请图片、视频、语音三个权限
this
.
requestPermissions
(
new
String
[]{
Manifest
.
permission
.
READ_MEDIA_IMAGES
,
Manifest
.
permission
.
READ_MEDIA_VIDEO
,
Manifest
.
permission
.
READ_MEDIA_AUDIO
,},
SobotBaseConstant
.
REQUEST_CODE_PICTURE
);
return
false
;
}
}
}
}
else
if
(
Build
.
VERSION
.
SDK_INT
>=
23
&&
SobotSystemUtils
.
getTargetSdkVersion
(
getSobotBaseActivity
().
getApplicationContext
())
>=
23
)
{
if
(
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_EXTERNAL_STORAGE
)
!=
PackageManager
.
PERMISSION_GRANTED
)
{
...
...
@@ -667,39 +729,49 @@ public abstract class SobotBaseActivity extends FragmentActivity {
}
/**
* 判断是否有存储卡权限
* 判断是否有存储卡权限
,android 14 部分权限有的话也返回true
*
* @param checkPermissionType 0:图片权限 1:视频权限,2:音频权限,3
:选文件,图片、视频、录音所有细分的权限 4:图片和视频权限,读取相册图片和视频
* @param checkPermissionType 0:图片权限 1:视频权限,2:音频权限,3
,所有细分的权限, android 13 使用
* @return true, 已经获取权限;false,没有权限
*/
protected
boolean
isHasStoragePermission
(
int
checkPermissionType
)
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
TIRAMISU
)
{
if
(
checkPermissionType
==
0
)
{
return
true
;
}
else
if
(
checkPermissionType
==
1
)
{
return
true
;
}
else
if
(
checkPermissionType
==
2
)
{
if
(
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_AUDIO
)
if
(
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_IMAGES
)
!=
PackageManager
.
PERMISSION_GRANTED
)
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
UPSIDE_DOWN_CAKE
)
{
//android 14 有部分权限就不弹权限提示框了
if
(
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_VISUAL_USER_SELECTED
)
==
PackageManager
.
PERMISSION_GRANTED
)
{
return
true
;
}
}
return
false
;
}
}
else
if
(
checkPermissionType
==
3
)
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
UPSIDE_DOWN_CAKE
&&
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_VISUAL_USER_SELECTED
)
==
PackageManager
.
PERMISSION_GRANTED
)
{
}
else
if
(
checkPermissionType
==
1
)
{
if
(
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_VIDEO
)
!=
PackageManager
.
PERMISSION_GRANTED
)
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
UPSIDE_DOWN_CAKE
)
{
//android 14 有部分权限就不弹权限提示框了
if
(
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_VISUAL_USER_SELECTED
)
==
PackageManager
.
PERMISSION_GRANTED
)
{
return
true
;
}
if
(
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_IMAGES
)
!=
PackageManager
.
PERMISSION_GRANTED
||
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_VIDEO
)
!=
PackageManager
.
PERMISSION_GRANTED
||
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_AUDIO
)
!=
PackageManager
.
PERMISSION_GRANTED
)
{
}
return
false
;
}
}
else
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
UPSIDE_DOWN_CAKE
&&
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_VISUAL_USER_SELECTED
)
==
PackageManager
.
PERMISSION_GRANTED
)
{
if
(
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_IMAGES
)
!=
PackageManager
.
PERMISSION_GRANTED
||
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_VIDEO
)
!=
PackageManager
.
PERMISSION_GRANTED
||
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_AUDIO
)
!=
PackageManager
.
PERMISSION_GRANTED
)
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
UPSIDE_DOWN_CAKE
)
{
//android 14 有部分权限就不弹权限提示框了
if
(
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_VISUAL_USER_SELECTED
)
==
PackageManager
.
PERMISSION_GRANTED
)
{
return
true
;
}
if
(
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_IMAGES
)
!=
PackageManager
.
PERMISSION_GRANTED
||
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_VIDEO
)
!=
PackageManager
.
PERMISSION_GRANTED
)
{
}
return
false
;
}
}
...
...
sobot_widget/src/main/java/com/sobot/widget/ui/base/picandroidvideo/SobotAlbumFile.java
0 → 100644
View file @
a64a3da5
/*
* Copyright 2017 Yan Zhenjie.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
com
.
sobot
.
widget
.
ui
.
base
.
picandroidvideo
;
import
android.net.Uri
;
import
android.os.Parcel
;
import
android.os.Parcelable
;
import
androidx.annotation.IntDef
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
public
class
SobotAlbumFile
implements
Parcelable
,
Comparable
<
SobotAlbumFile
>
{
public
static
final
int
TYPE_IMAGE
=
1
;
public
static
final
int
TYPE_VIDEO
=
2
;
public
static
final
int
TYPE_ADD
=
3
;
@Retention
(
RetentionPolicy
.
SOURCE
)
@IntDef
({
TYPE_IMAGE
,
TYPE_VIDEO
,
TYPE_ADD
})
public
@interface
MediaType
{
}
/**
* 本地文件路径.
*/
private
String
mPath
;
/**
* 本地的uri
*/
private
Uri
uri
;
private
String
fileNumKey
;
/**
* 远程的地址
*/
private
String
fileUrl
;
/**
* 文件名字.
*/
private
String
fileName
;
/**
* 文件夹名字.
*/
private
String
mBucketName
;
/**
* 文件扩展类型.
*/
private
String
mMimeType
;
/**
* 添加日期.
*/
private
long
mAddDate
;
/**
* Latitude
*/
private
float
mLatitude
;
/**
* Longitude.
*/
private
float
mLongitude
;
/**
* 大小.
*/
private
long
mSize
;
/**
* Duration.
*/
private
long
mDuration
;
/**
* Thumb path.
*/
private
String
mThumbPath
;
/**
* MediaType.
*/
private
int
mMediaType
;
/**
* Checked.
*/
private
boolean
isChecked
;
/**
* Enabled.
*/
private
boolean
isDisable
;
public
SobotAlbumFile
()
{
}
public
Uri
getUri
()
{
return
uri
;
}
public
void
setUri
(
Uri
uri
)
{
this
.
uri
=
uri
;
}
public
String
getFileName
()
{
return
fileName
;
}
public
void
setFileName
(
String
fileName
)
{
this
.
fileName
=
fileName
;
}
@Override
public
int
compareTo
(
SobotAlbumFile
o
)
{
long
time
=
o
.
getAddDate
()
-
getAddDate
();
if
(
time
>
Integer
.
MAX_VALUE
)
return
Integer
.
MAX_VALUE
;
else
if
(
time
<
-
Integer
.
MAX_VALUE
)
return
-
Integer
.
MAX_VALUE
;
return
(
int
)
time
;
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
obj
!=
null
&&
obj
instanceof
SobotAlbumFile
)
{
SobotAlbumFile
o
=
(
SobotAlbumFile
)
obj
;
String
inPath
=
o
.
getPath
();
if
(
mPath
!=
null
&&
inPath
!=
null
)
{
return
mPath
.
equals
(
inPath
);
}
}
return
super
.
equals
(
obj
);
}
@Override
public
int
hashCode
()
{
return
mPath
!=
null
?
mPath
.
hashCode
()
:
super
.
hashCode
();
}
public
String
getPath
()
{
return
mPath
;
}
public
void
setPath
(
String
path
)
{
mPath
=
path
;
}
public
String
getBucketName
()
{
return
mBucketName
;
}
public
void
setBucketName
(
String
bucketName
)
{
mBucketName
=
bucketName
;
}
public
String
getMimeType
()
{
return
mMimeType
;
}
public
void
setMimeType
(
String
mimeType
)
{
mMimeType
=
mimeType
;
}
public
long
getAddDate
()
{
return
mAddDate
;
}
public
void
setAddDate
(
long
addDate
)
{
mAddDate
=
addDate
;
}
public
float
getLatitude
()
{
return
mLatitude
;
}
public
void
setLatitude
(
float
latitude
)
{
mLatitude
=
latitude
;
}
public
float
getLongitude
()
{
return
mLongitude
;
}
public
void
setLongitude
(
float
longitude
)
{
mLongitude
=
longitude
;
}
public
long
getSize
()
{
return
mSize
;
}
public
void
setSize
(
long
size
)
{
mSize
=
size
;
}
public
long
getDuration
()
{
return
mDuration
;
}
public
void
setDuration
(
long
duration
)
{
mDuration
=
duration
;
}
public
String
getThumbPath
()
{
return
mThumbPath
;
}
public
void
setThumbPath
(
String
thumbPath
)
{
mThumbPath
=
thumbPath
;
}
@MediaType
public
int
getMediaType
()
{
return
mMediaType
;
}
public
void
setMediaType
(
@MediaType
int
mediaType
)
{
mMediaType
=
mediaType
;
}
public
boolean
isChecked
()
{
return
isChecked
;
}
public
void
setChecked
(
boolean
checked
)
{
isChecked
=
checked
;
}
public
boolean
isDisable
()
{
return
isDisable
;
}
public
void
setDisable
(
boolean
disable
)
{
this
.
isDisable
=
disable
;
}
public
String
getFileNumKey
()
{
return
fileNumKey
;
}
public
void
setFileNumKey
(
String
fileNumKey
)
{
this
.
fileNumKey
=
fileNumKey
;
}
public
String
getFileUrl
()
{
return
fileUrl
;
}
public
void
setFileUrl
(
String
fileUrl
)
{
this
.
fileUrl
=
fileUrl
;
}
protected
SobotAlbumFile
(
Parcel
in
)
{
mPath
=
in
.
readString
();
mBucketName
=
in
.
readString
();
mMimeType
=
in
.
readString
();
mAddDate
=
in
.
readLong
();
mLatitude
=
in
.
readFloat
();
mLongitude
=
in
.
readFloat
();
mSize
=
in
.
readLong
();
mDuration
=
in
.
readLong
();
mThumbPath
=
in
.
readString
();
mMediaType
=
in
.
readInt
();
isChecked
=
in
.
readByte
()
!=
0
;
isDisable
=
in
.
readByte
()
!=
0
;
}
@Override
public
void
writeToParcel
(
Parcel
dest
,
int
flags
)
{
dest
.
writeString
(
mPath
);
dest
.
writeString
(
mBucketName
);
dest
.
writeString
(
mMimeType
);
dest
.
writeLong
(
mAddDate
);
dest
.
writeFloat
(
mLatitude
);
dest
.
writeFloat
(
mLongitude
);
dest
.
writeLong
(
mSize
);
dest
.
writeLong
(
mDuration
);
dest
.
writeString
(
mThumbPath
);
dest
.
writeInt
(
mMediaType
);
dest
.
writeByte
((
byte
)
(
isChecked
?
1
:
0
));
dest
.
writeByte
((
byte
)
(
isDisable
?
1
:
0
));
}
@Override
public
int
describeContents
()
{
return
0
;
}
public
static
final
Creator
<
SobotAlbumFile
>
CREATOR
=
new
Creator
<
SobotAlbumFile
>()
{
@Override
public
SobotAlbumFile
createFromParcel
(
Parcel
in
)
{
return
new
SobotAlbumFile
(
in
);
}
@Override
public
SobotAlbumFile
[]
newArray
(
int
size
)
{
return
new
SobotAlbumFile
[
size
];
}
};
}
\ No newline at end of file
sobot_widget/src/main/java/com/sobot/widget/ui/base/picandroidvideo/SobotMediaReaderScanUtils.java
0 → 100644
View file @
a64a3da5
package
com
.
sobot
.
widget
.
ui
.
base
.
picandroidvideo
;
import
android.content.ContentResolver
;
import
android.content.ContentUris
;
import
android.content.Context
;
import
android.database.Cursor
;
import
android.net.Uri
;
import
android.os.Build
;
import
android.provider.MediaStore
;
import
androidx.annotation.WorkerThread
;
import
com.sobot.utils.SobotLogUtils
;
import
java.util.ArrayList
;
import
java.util.List
;
//android 14 用于部分权限的 图片、视频扫描
public
class
SobotMediaReaderScanUtils
{
/**
* Image attribute.
*/
private
static
final
String
[]
IMAGES
=
{
MediaStore
.
Images
.
Media
.
DATA
,
MediaStore
.
Images
.
Media
.
BUCKET_DISPLAY_NAME
,
MediaStore
.
Images
.
Media
.
MIME_TYPE
,
MediaStore
.
Images
.
Media
.
DATE_ADDED
,
MediaStore
.
Images
.
Media
.
LATITUDE
,
MediaStore
.
Images
.
Media
.
LONGITUDE
,
MediaStore
.
Images
.
Media
.
SIZE
,
MediaStore
.
Images
.
Media
.
_ID
};
/**
* Scan for image files.
*/
@WorkerThread
public
static
List
<
SobotAlbumFile
>
scanImageFile
(
Context
mContext
)
{
List
<
SobotAlbumFile
>
albumFileList
=
new
ArrayList
<>();
Uri
collection
;
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
Q
)
{
collection
=
MediaStore
.
Images
.
Media
.
getContentUri
(
MediaStore
.
VOLUME_EXTERNAL
);
}
else
{
collection
=
MediaStore
.
Images
.
Media
.
EXTERNAL_CONTENT_URI
;
}
ContentResolver
contentResolver
=
mContext
.
getContentResolver
();
Cursor
cursor
=
contentResolver
.
query
(
collection
,
IMAGES
,
null
,
null
,
null
);
if
(
cursor
!=
null
)
{
SobotLogUtils
.
d
(
"======图片总数======="
+
cursor
.
getCount
());
while
(
cursor
.
moveToNext
())
{
String
path
=
cursor
.
getString
(
0
);
String
bucketName
=
cursor
.
getString
(
1
);
String
mimeType
=
cursor
.
getString
(
2
);
long
addDate
=
cursor
.
getLong
(
3
);
float
latitude
=
cursor
.
getFloat
(
4
);
float
longitude
=
cursor
.
getFloat
(
5
);
long
size
=
cursor
.
getLong
(
6
);
long
id
=
cursor
.
getLong
(
7
);
SobotAlbumFile
imageFile
=
new
SobotAlbumFile
();
imageFile
.
setMediaType
(
SobotAlbumFile
.
TYPE_IMAGE
);
imageFile
.
setPath
(
path
);
imageFile
.
setBucketName
(
bucketName
);
imageFile
.
setMimeType
(
mimeType
);
imageFile
.
setAddDate
(
addDate
);
imageFile
.
setLatitude
(
latitude
);
imageFile
.
setLongitude
(
longitude
);
imageFile
.
setSize
(
size
);
Uri
contentUri
=
ContentUris
.
withAppendedId
(
MediaStore
.
Images
.
Media
.
EXTERNAL_CONTENT_URI
,
id
);
imageFile
.
setUri
(
contentUri
);
albumFileList
.
add
(
imageFile
);
}
cursor
.
close
();
}
return
albumFileList
;
}
/**
* Video attribute.
*/
private
static
final
String
[]
VIDEOS
=
{
MediaStore
.
Video
.
Media
.
DATA
,
MediaStore
.
Video
.
Media
.
BUCKET_DISPLAY_NAME
,
MediaStore
.
Video
.
Media
.
MIME_TYPE
,
MediaStore
.
Video
.
Media
.
DATE_ADDED
,
MediaStore
.
Video
.
Media
.
LATITUDE
,
MediaStore
.
Video
.
Media
.
LONGITUDE
,
MediaStore
.
Video
.
Media
.
SIZE
,
MediaStore
.
Video
.
Media
.
DURATION
,
MediaStore
.
Video
.
Media
.
_ID
};
/**
* Scan for image files.
*/
@WorkerThread
public
static
List
<
SobotAlbumFile
>
scanVideoFile
(
Context
mContext
)
{
List
<
SobotAlbumFile
>
albumFileList
=
new
ArrayList
<>();
Uri
collection
;
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
Q
)
{
collection
=
MediaStore
.
Video
.
Media
.
getContentUri
(
MediaStore
.
VOLUME_EXTERNAL
);
}
else
{
collection
=
MediaStore
.
Video
.
Media
.
EXTERNAL_CONTENT_URI
;
}
ContentResolver
contentResolver
=
mContext
.
getContentResolver
();
Cursor
cursor
=
contentResolver
.
query
(
collection
,
VIDEOS
,
null
,
null
,
null
);
SobotLogUtils
.
d
(
"======scanVideoFile======="
+
(
cursor
==
null
));
if
(
cursor
!=
null
)
{
SobotLogUtils
.
d
(
"======视频总数======="
+
cursor
.
getCount
());
while
(
cursor
.
moveToNext
())
{
String
path
=
cursor
.
getString
(
0
);
String
bucketName
=
cursor
.
getString
(
1
);
String
mimeType
=
cursor
.
getString
(
2
);
long
addDate
=
cursor
.
getLong
(
3
);
float
latitude
=
cursor
.
getFloat
(
4
);
float
longitude
=
cursor
.
getFloat
(
5
);
long
size
=
cursor
.
getLong
(
6
);
long
duration
=
cursor
.
getLong
(
7
);
long
id
=
cursor
.
getLong
(
8
);
SobotAlbumFile
videoFile
=
new
SobotAlbumFile
();
videoFile
.
setMediaType
(
SobotAlbumFile
.
TYPE_VIDEO
);
videoFile
.
setPath
(
path
);
videoFile
.
setBucketName
(
bucketName
);
videoFile
.
setMimeType
(
mimeType
);
videoFile
.
setAddDate
(
addDate
);
videoFile
.
setLatitude
(
latitude
);
videoFile
.
setLongitude
(
longitude
);
videoFile
.
setSize
(
size
);
videoFile
.
setDuration
(
duration
);
Uri
contentUri
=
ContentUris
.
withAppendedId
(
MediaStore
.
Video
.
Media
.
EXTERNAL_CONTENT_URI
,
id
);
videoFile
.
setUri
(
contentUri
);
albumFileList
.
add
(
videoFile
);
}
cursor
.
close
();
}
return
albumFileList
;
}
@WorkerThread
public
static
List
<
SobotAlbumFile
>
getAllMedia
(
Context
mContext
,
int
type
)
{
List
<
SobotAlbumFile
>
list
=
new
ArrayList
<>();
if
(
type
==
3
)
{
//图片和视频
List
<
SobotAlbumFile
>
scannedImageFileList
=
scanImageFile
(
mContext
);
if
(
scannedImageFileList
!=
null
)
{
list
.
addAll
(
scannedImageFileList
);
}
List
<
SobotAlbumFile
>
scannedVideoFileList
=
scanVideoFile
(
mContext
);
if
(
scannedVideoFileList
!=
null
)
{
list
.
addAll
(
scannedVideoFileList
);
}
}
else
if
(
type
==
2
)
{
//视频
List
<
SobotAlbumFile
>
scannedVideoFileList
=
scanVideoFile
(
mContext
);
if
(
scannedVideoFileList
!=
null
)
{
list
.
addAll
(
scannedVideoFileList
);
}
}
else
{
//图片
List
<
SobotAlbumFile
>
scannedImageFileList
=
scanImageFile
(
mContext
);
if
(
scannedImageFileList
!=
null
)
{
list
.
addAll
(
scannedImageFileList
);
}
}
return
list
;
}
}
\ No newline at end of file
sobot_widget/src/main/java/com/sobot/widget/ui/base/picandroidvideo/SobotSelectPicAndVideoActivity.java
0 → 100644
View file @
a64a3da5
package
com
.
sobot
.
widget
.
ui
.
base
.
picandroidvideo
;
import
android.Manifest
;
import
android.content.Intent
;
import
android.content.pm.PackageManager
;
import
android.net.Uri
;
import
android.os.Build
;
import
android.provider.Settings
;
import
android.view.View
;
import
android.widget.Button
;
import
android.widget.TextView
;
import
androidx.core.content.ContextCompat
;
import
androidx.recyclerview.widget.GridLayoutManager
;
import
androidx.recyclerview.widget.RecyclerView
;
import
com.sobot.utils.SobotDensityUtil
;
import
com.sobot.widget.R
;
import
com.sobot.widget.refresh.layout.callback.SobotRecyclerCallBack
;
import
com.sobot.widget.ui.SobotBaseConstant
;
import
com.sobot.widget.ui.base.SobotBaseActivity
;
import
java.util.ArrayList
;
import
java.util.List
;
/**
* android 14 部分权限 允许后的回显界面
*/
public
class
SobotSelectPicAndVideoActivity
extends
SobotBaseActivity
{
private
TextView
tv_go_to_settring
;
private
RecyclerView
sobot_rcy
;
private
Button
sobot_btn_submit
;
private
SobotSelectPicAndVideoAdapter
picAdapter
;
private
List
<
SobotAlbumFile
>
albumFileList
;
private
int
selectType
=
1
;
@Override
protected
int
getContentViewResId
()
{
return
R
.
layout
.
sobot_activity_select_pic_and_video
;
}
@Override
protected
void
onNewIntent
(
Intent
intent
)
{
super
.
onNewIntent
(
intent
);
if
(
albumFileList
==
null
)
{
albumFileList
=
new
ArrayList
<>();
}
albumFileList
.
clear
();
albumFileList
=
SobotMediaReaderScanUtils
.
getAllMedia
(
getSobotBaseActivity
(),
selectType
);
if
(
albumFileList
==
null
)
{
albumFileList
=
new
ArrayList
<>();
}
albumFileList
.
add
(
new
SobotAlbumFile
());
if
(
picAdapter
!=
null
)
{
picAdapter
.
setmSelectedPos
(-
1
);
picAdapter
.
updateList
(
albumFileList
);
}
else
{
finish
();
}
}
@Override
protected
void
onResume
()
{
super
.
onResume
();
if
(
selectType
==
1
)
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
UPSIDE_DOWN_CAKE
&&
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_IMAGES
)
==
PackageManager
.
PERMISSION_GRANTED
)
{
//如果android 14 手机有永久权限 直接关闭当前界面
finish
();
}
}
else
if
(
selectType
==
2
){
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
UPSIDE_DOWN_CAKE
&&
ContextCompat
.
checkSelfPermission
(
getSobotBaseActivity
(),
Manifest
.
permission
.
READ_MEDIA_VIDEO
)
==
PackageManager
.
PERMISSION_GRANTED
)
{
//如果android 14 手机有永久权限 直接关闭当前界面
finish
();
}
}
}
@Override
protected
void
initView
()
{
tv_go_to_settring
=
findViewById
(
R
.
id
.
tv_go_to_settring
);
sobot_rcy
=
findViewById
(
R
.
id
.
sobot_rcy
);
sobot_btn_submit
=
findViewById
(
R
.
id
.
sobot_btn_submit
);
sobot_btn_submit
.
setAlpha
(
0.5f
);
sobot_btn_submit
.
setClickable
(
false
);
setTitle
(
getString
(
R
.
string
.
sobot_str_select_pic_video
));
displayInNotch
(
sobot_rcy
);
tv_go_to_settring
.
setOnClickListener
(
new
View
.
OnClickListener
()
{
@Override
public
void
onClick
(
View
v
)
{
//去设置打开权限
Uri
packageURI
=
Uri
.
parse
(
"package:"
+
getPackageName
());
Intent
intent
=
new
Intent
(
Settings
.
ACTION_APPLICATION_DETAILS_SETTINGS
,
packageURI
);
startActivity
(
intent
);
}
});
}
protected
void
initData
()
{
selectType
=
getIntent
().
getIntExtra
(
"selectType"
,
1
);
albumFileList
=
SobotMediaReaderScanUtils
.
getAllMedia
(
getSobotBaseActivity
(),
selectType
);
if
(
albumFileList
==
null
)
{
albumFileList
=
new
ArrayList
<>();
}
albumFileList
.
add
(
new
SobotAlbumFile
());
picAdapter
=
new
SobotSelectPicAndVideoAdapter
(
this
,
albumFileList
,
new
SobotRecyclerCallBack
()
{
@Override
public
void
onItemClickListener
(
View
view
,
int
position
)
{
}
@Override
public
void
onItemLongClickListener
(
View
view
,
int
position
)
{
}
});
picAdapter
.
setClickListener
(
new
SobotSelectPicAndVideoAdapter
.
myClickListener
()
{
@Override
public
void
onClickOtherListener
()
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
M
)
{
if
(
selectType
==
3
)
{
requestPermissions
(
new
String
[]{
Manifest
.
permission
.
READ_MEDIA_IMAGES
,
Manifest
.
permission
.
READ_MEDIA_VIDEO
,
Manifest
.
permission
.
READ_MEDIA_AUDIO
,
Manifest
.
permission
.
READ_MEDIA_VISUAL_USER_SELECTED
},
SobotBaseConstant
.
REQUEST_CODE_PICTURE
);
}
else
if
(
selectType
==
2
)
{
requestPermissions
(
new
String
[]{
Manifest
.
permission
.
READ_MEDIA_VIDEO
,
Manifest
.
permission
.
READ_MEDIA_VISUAL_USER_SELECTED
},
SobotBaseConstant
.
REQUEST_CODE_PICTURE
);
}
else
{
requestPermissions
(
new
String
[]{
Manifest
.
permission
.
READ_MEDIA_IMAGES
,
Manifest
.
permission
.
READ_MEDIA_VISUAL_USER_SELECTED
},
SobotBaseConstant
.
REQUEST_CODE_PICTURE
);
}
}
}
@Override
public
void
onCheckListener
()
{
if
(
picAdapter
.
getmSelectedPos
()
>
-
1
)
{
sobot_btn_submit
.
setAlpha
(
1
f
);
sobot_btn_submit
.
setClickable
(
true
);
}
else
{
sobot_btn_submit
.
setAlpha
(
0.5f
);
sobot_btn_submit
.
setClickable
(
false
);
}
}
});
sobot_rcy
.
setAdapter
(
picAdapter
);
GridLayoutManager
gridlayoutmanager
=
new
GridLayoutManager
(
SobotSelectPicAndVideoActivity
.
this
,
4
);
sobot_rcy
.
addItemDecoration
(
new
SpaceItemDecoration
(
SobotDensityUtil
.
dp2px
(
SobotSelectPicAndVideoActivity
.
this
,
3
),
SobotDensityUtil
.
dp2px
(
SobotSelectPicAndVideoActivity
.
this
,
1.5f
),
0
,
SpaceItemDecoration
.
GRIDLAYOUT
));
sobot_rcy
.
setLayoutManager
(
gridlayoutmanager
);
sobot_btn_submit
.
setOnClickListener
(
new
View
.
OnClickListener
()
{
@Override
public
void
onClick
(
View
v
)
{
if
(
albumFileList
!=
null
&&
albumFileList
.
size
()
>
0
&&
picAdapter
!=
null
&&
picAdapter
.
getmSelectedPos
()
>
-
1
)
{
SobotAlbumFile
albumFile
=
albumFileList
.
get
(
picAdapter
.
getmSelectedPos
());
Intent
intent
=
new
Intent
();
intent
.
setData
(
albumFile
.
getUri
());
setResult
(
RESULT_OK
,
intent
);
finish
();
}
}
});
}
}
\ No newline at end of file
sobot_widget/src/main/java/com/sobot/widget/ui/base/picandroidvideo/SobotSelectPicAndVideoAdapter.java
0 → 100644
View file @
a64a3da5
package
com
.
sobot
.
widget
.
ui
.
base
.
picandroidvideo
;
import
android.content.Context
;
import
android.view.LayoutInflater
;
import
android.view.View
;
import
android.view.ViewGroup
;
import
android.widget.CheckBox
;
import
android.widget.ImageView
;
import
android.widget.LinearLayout
;
import
android.widget.TextView
;
import
androidx.annotation.IntRange
;
import
androidx.annotation.NonNull
;
import
androidx.recyclerview.widget.RecyclerView
;
import
com.sobot.pictureframe.SobotBitmapUtil
;
import
com.sobot.widget.R
;
import
com.sobot.widget.refresh.layout.callback.SobotRecyclerCallBack
;
import
java.util.List
;
/**
* android 14 部分权限 允许后的回显界面
*/
public
class
SobotSelectPicAndVideoAdapter
extends
RecyclerView
.
Adapter
<
SobotSelectPicAndVideoAdapter
.
ViewHolder
>
{
private
Context
mContext
;
private
List
<
SobotAlbumFile
>
list
;
private
SobotRecyclerCallBack
callBack
;
private
int
mSelectedPos
=
-
1
;
//保存当前选中的position 重点!
private
myClickListener
clickListener
;
public
SobotSelectPicAndVideoAdapter
(
Context
context
,
List
<
SobotAlbumFile
>
list
,
SobotRecyclerCallBack
callBack
)
{
mContext
=
context
;
this
.
list
=
list
;
this
.
callBack
=
callBack
;
}
//得到当前选中的位置
public
int
getmSelectedPos
()
{
return
mSelectedPos
;
}
public
void
setmSelectedPos
(
int
mSelectedPos
)
{
this
.
mSelectedPos
=
mSelectedPos
;
}
@Override
public
int
getItemCount
()
{
return
list
==
null
?
0
:
list
.
size
();
}
/**
* 设置监听
*
* @param holder 监听对象
*/
public
void
setListener
(
RecyclerView
.
ViewHolder
holder
)
{
// 设置监听
holder
.
itemView
.
setOnClickListener
(
new
View
.
OnClickListener
()
{
@Override
public
void
onClick
(
View
v
)
{
callBack
.
onItemClickListener
(
v
,
(
Integer
)
v
.
getTag
());
}
});
holder
.
itemView
.
setOnLongClickListener
(
new
View
.
OnLongClickListener
()
{
@Override
public
boolean
onLongClick
(
View
v
)
{
callBack
.
onItemLongClickListener
(
v
,
(
Integer
)
v
.
getTag
());
return
true
;
}
});
}
@Override
public
ViewHolder
onCreateViewHolder
(
ViewGroup
parent
,
int
viewType
)
{
View
itemView
=
LayoutInflater
.
from
(
mContext
).
inflate
(
R
.
layout
.
sobot_select_pic_and_video_item
,
parent
,
false
);
ViewHolder
viewHolder
=
new
ViewHolder
(
mContext
,
itemView
);
setListener
(
viewHolder
);
//设置监听
return
viewHolder
;
}
@Override
public
void
onBindViewHolder
(
final
ViewHolder
viewHolder
,
int
position
)
{
final
ViewHolder
contact
=
(
ViewHolder
)
viewHolder
;
final
int
finalPosition
=
position
;
SobotAlbumFile
albumFile
=
(
SobotAlbumFile
)
list
.
get
(
position
);
if
(
albumFile
!=
null
)
{
if
(
position
==
(
list
.
size
()
-
1
))
{
contact
.
ll_open_other
.
setVisibility
(
View
.
VISIBLE
);
contact
.
sobot_iv_img
.
setVisibility
(
View
.
GONE
);
contact
.
check_box
.
setVisibility
(
View
.
GONE
);
contact
.
tv_duration
.
setVisibility
(
View
.
GONE
);
contact
.
ll_open_other
.
setOnClickListener
(
new
View
.
OnClickListener
()
{
@Override
public
void
onClick
(
View
v
)
{
if
(
clickListener
!=
null
)
{
clickListener
.
onClickOtherListener
();
}
}
});
}
else
{
contact
.
ll_open_other
.
setOnClickListener
(
null
);
contact
.
ll_open_other
.
setVisibility
(
View
.
GONE
);
contact
.
sobot_iv_img
.
setVisibility
(
View
.
VISIBLE
);
contact
.
check_box
.
setVisibility
(
View
.
VISIBLE
);
contact
.
tv_duration
.
setVisibility
(
View
.
VISIBLE
);
if
(
albumFile
.
getUri
()
!=
null
)
{
SobotBitmapUtil
.
display
(
mContext
,
albumFile
.
getUri
(),
contact
.
sobot_iv_img
);
}
if
(
albumFile
.
getMediaType
()
==
SobotAlbumFile
.
TYPE_VIDEO
)
{
contact
.
tv_duration
.
setVisibility
(
View
.
VISIBLE
);
contact
.
tv_duration
.
setText
(
convertDuration
(
albumFile
.
getDuration
()));
}
else
{
contact
.
tv_duration
.
setVisibility
(
View
.
GONE
);
}
}
if
(
mSelectedPos
==
position
)
{
contact
.
check_box
.
setChecked
(
true
);
contact
.
view_masking_select
.
setVisibility
(
View
.
VISIBLE
);
}
else
{
contact
.
check_box
.
setChecked
(
false
);
contact
.
view_masking_select
.
setVisibility
(
View
.
GONE
);
}
contact
.
itemView
.
setOnClickListener
(
new
View
.
OnClickListener
()
{
@Override
public
void
onClick
(
View
v
)
{
if
(
mSelectedPos
!=
finalPosition
)
{
//当前选中的position和上次选中不是同一个position 执行
contact
.
check_box
.
setChecked
(
true
);
contact
.
view_masking_select
.
setVisibility
(
View
.
VISIBLE
);
if
(
mSelectedPos
!=
-
1
)
{
//判断是否有效 -1是初始值 即无效 第二个参数是Object 随便传个int 这里只是起个标志位
notifyItemChanged
(
mSelectedPos
,
0
);
}
mSelectedPos
=
finalPosition
;
}
else
{
//点击是选中的本身,取消选中
mSelectedPos
=
-
1
;
contact
.
check_box
.
setChecked
(
false
);
contact
.
view_masking_select
.
setVisibility
(
View
.
VISIBLE
);
}
if
(
clickListener
!=
null
)
{
clickListener
.
onCheckListener
();
}
}
});
}
}
@Override
public
void
onBindViewHolder
(
@NonNull
ViewHolder
holder
,
int
position
,
@NonNull
List
<
Object
>
payloads
)
{
//payloads即有效负载,当首次加载或调用notifyDatasetChanged() ,notifyItemChange(int position)进行刷新时,payloads为empty 即空
if
(
payloads
.
isEmpty
())
{
//如果payloads没数据,说明不是局部刷新,下面这句是关键,通过源码看 会执行不带payloads参数的onBindViewHolder
onBindViewHolder
(
holder
,
position
);
}
else
{
//当调用notifyItemChange(int position, Object payload)进行布局刷新时,payloads不会empty ,所以真正的布局刷新应该在这里实现 重点!
if
(
mSelectedPos
==
position
)
{
holder
.
check_box
.
setChecked
(
true
);
holder
.
view_masking_select
.
setVisibility
(
View
.
VISIBLE
);
}
else
{
holder
.
check_box
.
setChecked
(
false
);
holder
.
view_masking_select
.
setVisibility
(
View
.
GONE
);
}
}
}
class
ViewHolder
extends
RecyclerView
.
ViewHolder
{
private
ImageView
sobot_iv_img
;
private
TextView
tv_duration
;
private
CheckBox
check_box
;
private
LinearLayout
ll_open_other
;
private
View
view_masking_select
;
public
ViewHolder
(
Context
context
,
View
itemView
)
{
super
(
itemView
);
this
.
sobot_iv_img
=
itemView
.
findViewById
(
R
.
id
.
sobot_iv_img
);
this
.
tv_duration
=
itemView
.
findViewById
(
R
.
id
.
tv_duration
);
check_box
=
itemView
.
findViewById
(
R
.
id
.
check_box
);
ll_open_other
=
itemView
.
findViewById
(
R
.
id
.
ll_open_other
);
view_masking_select
=
itemView
.
findViewById
(
R
.
id
.
view_masking_select
);
}
}
public
List
<
SobotAlbumFile
>
getList
()
{
return
list
;
}
public
void
updateList
(
List
<
SobotAlbumFile
>
albumFileList
)
{
list
.
clear
();
list
.
addAll
(
albumFileList
);
notifyDataSetChanged
();
}
public
interface
myClickListener
{
void
onClickOtherListener
();
void
onCheckListener
();
}
public
myClickListener
getClickListener
()
{
return
clickListener
;
}
public
void
setClickListener
(
myClickListener
clickListener
)
{
this
.
clickListener
=
clickListener
;
}
public
String
convertDuration
(
@IntRange
(
from
=
1
)
long
duration
)
{
duration
/=
1000
;
int
hour
=
(
int
)
(
duration
/
3600
);
int
minute
=
(
int
)
((
duration
-
hour
*
3600
)
/
60
);
int
second
=
(
int
)
(
duration
-
hour
*
3600
-
minute
*
60
);
String
hourValue
=
""
;
String
minuteValue
;
String
secondValue
;
if
(
hour
>
0
)
{
if
(
hour
>=
10
)
{
hourValue
=
Integer
.
toString
(
hour
);
}
else
{
hourValue
=
"0"
+
hour
;
}
hourValue
+=
":"
;
}
if
(
minute
>
0
)
{
if
(
minute
>=
10
)
{
minuteValue
=
Integer
.
toString
(
minute
);
}
else
{
minuteValue
=
"0"
+
minute
;
}
}
else
{
minuteValue
=
"00"
;
}
minuteValue
+=
":"
;
if
(
second
>
0
)
{
if
(
second
>=
10
)
{
secondValue
=
Integer
.
toString
(
second
);
}
else
{
secondValue
=
"0"
+
second
;
}
}
else
{
secondValue
=
"00"
;
}
return
hourValue
+
minuteValue
+
secondValue
;
}
}
\ No newline at end of file
sobot_widget/src/main/java/com/sobot/widget/ui/base/picandroidvideo/SpaceItemDecoration.java
0 → 100644
View file @
a64a3da5
package
com
.
sobot
.
widget
.
ui
.
base
.
picandroidvideo
;
import
android.graphics.Canvas
;
import
android.graphics.Rect
;
import
android.view.View
;
import
androidx.annotation.IntDef
;
import
androidx.recyclerview.widget.GridLayoutManager
;
import
androidx.recyclerview.widget.RecyclerView
;
import
androidx.recyclerview.widget.StaggeredGridLayoutManager
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.RetentionPolicy
;
public
class
SpaceItemDecoration
extends
RecyclerView
.
ItemDecoration
{
public
static
final
int
LINEARLAYOUT
=
0
;
public
static
final
int
GRIDLAYOUT
=
1
;
public
static
final
int
STAGGEREDGRIDLAYOUT
=
2
;
//限定为LINEARLAYOUT,GRIDLAYOUT,STAGGEREDGRIDLAYOUT
@IntDef
({
LINEARLAYOUT
,
GRIDLAYOUT
,
STAGGEREDGRIDLAYOUT
})
//表示注解所存活的时间,在运行时,而不会存在. class 文件.
@Retention
(
RetentionPolicy
.
SOURCE
)
public
@interface
LayoutManager
{
public
int
type
()
default
LINEARLAYOUT
;
}
private
int
leftRight
;
private
int
topBottom
;
/**
* 头布局个数
*/
private
int
headItemCount
;
/**
* 边距
*/
private
int
space
;
/**
* 是否包含边距
*/
private
boolean
includeEdge
;
/**
* 列数
*/
private
int
spanCount
;
private
@LayoutManager
int
layoutManager
;
/**
* GridLayoutManager or StaggeredGridLayoutManager spacing
*
* @param leftRight
* @param topBottom
* @param headItemCount
* @param layoutManager
*/
public
SpaceItemDecoration
(
int
leftRight
,
int
topBottom
,
int
headItemCount
,
@LayoutManager
int
layoutManager
)
{
this
.
leftRight
=
leftRight
;
this
.
topBottom
=
topBottom
;
this
.
headItemCount
=
headItemCount
;
this
.
layoutManager
=
layoutManager
;
}
/**
* GridLayoutManager or StaggeredGridLayoutManager spacing
*
* @param space
* @param includeEdge
* @param layoutManager
*/
public
SpaceItemDecoration
(
int
space
,
boolean
includeEdge
,
@LayoutManager
int
layoutManager
)
{
this
(
space
,
0
,
includeEdge
,
layoutManager
);
}
/**
* GridLayoutManager or StaggeredGridLayoutManager spacing
*
* @param space
* @param headItemCount
* @param includeEdge
* @param layoutManager
*/
public
SpaceItemDecoration
(
int
space
,
int
headItemCount
,
boolean
includeEdge
,
@LayoutManager
int
layoutManager
)
{
this
.
space
=
space
;
this
.
headItemCount
=
headItemCount
;
this
.
includeEdge
=
includeEdge
;
this
.
layoutManager
=
layoutManager
;
}
/**
* GridLayoutManager or StaggeredGridLayoutManager spacing
*
* @param space
* @param headItemCount
* @param layoutManager
*/
public
SpaceItemDecoration
(
int
space
,
int
headItemCount
,
@LayoutManager
int
layoutManager
)
{
this
(
space
,
headItemCount
,
true
,
layoutManager
);
}
/**
* LinearLayoutManager or GridLayoutManager or StaggeredGridLayoutManager spacing
*
* @param space
* @param layoutManager
*/
public
SpaceItemDecoration
(
int
space
,
@LayoutManager
int
layoutManager
)
{
this
(
space
,
0
,
true
,
layoutManager
);
}
@Override
public
void
onDraw
(
Canvas
c
,
RecyclerView
parent
,
RecyclerView
.
State
state
)
{
super
.
onDraw
(
c
,
parent
,
state
);
}
@Override
public
void
getItemOffsets
(
Rect
outRect
,
View
view
,
RecyclerView
parent
,
RecyclerView
.
State
state
)
{
switch
(
layoutManager
)
{
case
LINEARLAYOUT:
setLinearLayoutSpaceItemDecoration
(
outRect
,
view
,
parent
,
state
);
break
;
case
GRIDLAYOUT:
GridLayoutManager
gridLayoutManager
=
(
GridLayoutManager
)
parent
.
getLayoutManager
();
//列数
spanCount
=
gridLayoutManager
.
getSpanCount
();
// setNGridLayoutSpaceItemDecoration(outRect, view, parent, state);
setGridlayoutSpaceItemDecorition2
(
outRect
,
view
,
parent
,
state
);
break
;
case
STAGGEREDGRIDLAYOUT:
StaggeredGridLayoutManager
staggeredGridLayoutManager
=
(
StaggeredGridLayoutManager
)
parent
.
getLayoutManager
();
//列数
spanCount
=
staggeredGridLayoutManager
.
getSpanCount
();
setNGridLayoutSpaceItemDecoration
(
outRect
,
view
,
parent
,
state
);
break
;
default
:
break
;
}
}
/**
* LinearLayoutManager spacing
*
* @param outRect
* @param view
* @param parent
* @param state
*/
private
void
setLinearLayoutSpaceItemDecoration
(
Rect
outRect
,
View
view
,
RecyclerView
parent
,
RecyclerView
.
State
state
)
{
outRect
.
left
=
space
;
outRect
.
right
=
space
;
outRect
.
bottom
=
space
;
if
(
parent
.
getChildLayoutPosition
(
view
)
==
0
)
{
outRect
.
top
=
space
;
}
else
{
outRect
.
top
=
0
;
}
}
/**
* GridLayoutManager or StaggeredGridLayoutManager spacing
*
* @param outRect
* @param view
* @param parent
* @param state
*/
private
void
setNGridLayoutSpaceItemDecoration
(
Rect
outRect
,
View
view
,
RecyclerView
parent
,
RecyclerView
.
State
state
)
{
int
position
=
parent
.
getChildAdapterPosition
(
view
)
-
headItemCount
;
if
(
headItemCount
!=
0
&&
position
==
-
headItemCount
)
{
return
;
}
int
column
=
position
%
spanCount
;
if
(
includeEdge
)
{
outRect
.
left
=
space
-
column
*
space
/
spanCount
;
outRect
.
right
=
(
column
+
1
)
*
space
/
spanCount
;
if
(
position
<
spanCount
)
{
outRect
.
top
=
space
;
}
outRect
.
bottom
=
space
;
}
else
{
outRect
.
left
=
column
*
space
/
spanCount
;
outRect
.
right
=
space
-
(
column
+
1
)
*
space
/
spanCount
;
if
(
position
>=
spanCount
)
{
outRect
.
top
=
space
;
}
}
}
/**
* GridLayoutManager设置间距(此方法最左边和最右边间距为设置的一半)
*
* @param outRect
* @param view
* @param parent
* @param state
*/
private
void
setGridLayoutSpaceItemDecoration
(
Rect
outRect
,
View
view
,
RecyclerView
parent
,
RecyclerView
.
State
state
)
{
GridLayoutManager
layoutManager
=
(
GridLayoutManager
)
parent
.
getLayoutManager
();
//判断总的数量是否可以整除
int
totalCount
=
layoutManager
.
getItemCount
();
int
surplusCount
=
totalCount
%
layoutManager
.
getSpanCount
();
int
childPosition
=
parent
.
getChildAdapterPosition
(
view
);
//竖直方向的
if
(
layoutManager
.
getOrientation
()
==
GridLayoutManager
.
VERTICAL
)
{
if
(
surplusCount
==
0
&&
childPosition
>
totalCount
-
layoutManager
.
getSpanCount
()
-
1
)
{
//后面几项需要bottom
outRect
.
bottom
=
topBottom
;
}
else
if
(
surplusCount
!=
0
&&
childPosition
>
totalCount
-
surplusCount
-
1
)
{
outRect
.
bottom
=
topBottom
;
}
//被整除的需要右边
if
((
childPosition
+
1
-
headItemCount
)
%
layoutManager
.
getSpanCount
()
==
0
)
{
//加了右边后最后一列的图就非宽度少一个右边距
//outRect.right = leftRight;
}
outRect
.
top
=
topBottom
;
outRect
.
left
=
leftRight
/
2
;
outRect
.
right
=
leftRight
/
2
;
}
else
{
if
(
surplusCount
==
0
&&
childPosition
>
totalCount
-
layoutManager
.
getSpanCount
()
-
1
)
{
//后面几项需要右边
outRect
.
right
=
leftRight
;
}
else
if
(
surplusCount
!=
0
&&
childPosition
>
totalCount
-
surplusCount
-
1
)
{
outRect
.
right
=
leftRight
;
}
//被整除的需要下边
if
((
childPosition
+
1
)
%
layoutManager
.
getSpanCount
()
==
0
)
{
outRect
.
bottom
=
topBottom
;
}
outRect
.
top
=
topBottom
;
outRect
.
left
=
leftRight
;
}
}
/**
* 紧挨四条边的item 不设置边距
*
* @param outRect
* @param view
* @param parent
* @param state
*/
private
void
setGridlayoutSpaceItemDecorition2
(
Rect
outRect
,
View
view
,
RecyclerView
parent
,
RecyclerView
.
State
state
)
{
GridLayoutManager
layoutManager
=
(
GridLayoutManager
)
parent
.
getLayoutManager
();
//判断总的数量是否可以整除
int
totalCount
=
layoutManager
.
getItemCount
();
int
surplusCount
=
totalCount
%
layoutManager
.
getSpanCount
();
int
childPosition
=
parent
.
getChildAdapterPosition
(
view
);
if
(
childPosition
<
spanCount
)
{
//第一行
outRect
.
top
=
0
;
}
else
{
outRect
.
top
=
topBottom
/
2
;
}
if
(
childPosition
%
spanCount
==
0
)
{
//第一列
outRect
.
left
=
0
;
}
else
{
outRect
.
left
=
leftRight
/
2
;
}
if
((
childPosition
+
1
)
%
spanCount
==
0
)
{
//最后一列
outRect
.
right
=
0
;
}
else
{
outRect
.
right
=
leftRight
/
2
;
}
if
(
childPosition
>=
totalCount
-
surplusCount
)
{
//最后一行
outRect
.
bottom
=
0
;
}
else
{
outRect
.
bottom
=
topBottom
;
}
}
}
\ No newline at end of file
sobot_widget/src/main/res/drawable-night/sobot_normal_btn_bg.xml
0 → 100644
View file @
a64a3da5
<shape
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<solid
android:color=
"@color/sobot_common_gray7"
/>
<corners
android:radius=
"22dp"
/>
</shape>
\ No newline at end of file
sobot_widget/src/main/res/drawable-xhdpi/sobot_album_tag_video_white.png
0 → 100644
View file @
a64a3da5
173 Bytes
sobot_widget/src/main/res/drawable-xhdpi/sobot_icon_add.png
0 → 100644
View file @
a64a3da5
525 Bytes
sobot_widget/src/main/res/drawable-xhdpi/sobot_photo_selected.png
0 → 100644
View file @
a64a3da5
1.3 KB
sobot_widget/src/main/res/drawable-xhdpi/sobot_photo_unselected.png
0 → 100644
View file @
a64a3da5
2.02 KB
sobot_widget/src/main/res/drawable/sobot_bg_checkbox.xml
0 → 100644
View file @
a64a3da5
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<!-- checkbox 样式-->
<item
android:drawable=
"@drawable/sobot_photo_selected"
android:state_checked=
"true"
/>
<item
android:drawable=
"@drawable/sobot_photo_unselected"
/>
</selector>
\ No newline at end of file
sobot_widget/src/main/res/drawable/sobot_custom_scroll_style.xml
0 → 100644
View file @
a64a3da5
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<!--自定义滚动条样式-->
<gradient
android:angle=
"45"
android:centerColor=
"#E1E7F0"
android:endColor=
"#E1E7F0"
android:startColor=
"#E1E7F0"
/>
<corners
android:radius=
"2dp"
/>
<size
android:width=
"4dp"
/>
</shape>
\ No newline at end of file
sobot_widget/src/main/res/drawable/sobot_normal_btn_bg.xml
0 → 100644
View file @
a64a3da5
<shape
xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<solid
android:color=
"@color/sobot_color"
/>
<corners
android:radius=
"22dp"
/>
</shape>
\ No newline at end of file
sobot_widget/src/main/res/layout/sobot_activity_select_pic_and_video.xml
0 → 100644
View file @
a64a3da5
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:background=
"@color/sobot_common_gray6"
android:orientation=
"vertical"
>
<include
layout=
"@layout/sobot_common_layout_titlebar"
/>
<LinearLayout
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:background=
"@color/sobot_common_gray7"
android:orientation=
"horizontal"
android:padding=
"10dp"
>
<TextView
android:layout_width=
"0dp"
android:layout_height=
"wrap_content"
android:layout_weight=
"1"
android:text=
"@string/sobot_str_goto_setting_info"
android:textColor=
"@color/sobot_common_gray1"
android:textSize=
"12sp"
/>
<TextView
android:id=
"@+id/tv_go_to_settring"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginLeft=
"4dp"
android:text=
"@string/sobot_str_goto_setting_allow"
android:textColor=
"@color/sobot_color"
android:textSize=
"12sp"
/>
</LinearLayout>
<LinearLayout
android:layout_width=
"match_parent"
android:layout_height=
"0dp"
android:layout_weight=
"1"
android:orientation=
"vertical"
>
<androidx.recyclerview.widget.RecyclerView
android:id=
"@+id/sobot_rcy"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:layout_margin=
"3dp"
android:layout_weight=
"1"
android:horizontalSpacing=
"3dp"
android:scrollbarSize=
"10dp"
android:scrollbarThumbVertical=
"@drawable/sobot_custom_scroll_style"
android:verticalSpacing=
"3dp"
/>
</LinearLayout>
<LinearLayout
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:orientation=
"vertical"
>
<Button
android:id=
"@+id/sobot_btn_submit"
android:layout_width=
"match_parent"
android:layout_height=
"44dp"
android:layout_margin=
"20dp"
android:background=
"@drawable/sobot_normal_btn_bg"
android:gravity=
"center"
android:stateListAnimator=
"@null"
android:text=
"@string/sobot_button_send"
android:textAllCaps=
"false"
android:textColor=
"@color/sobot_common_wenzi_white_gray"
android:textSize=
"17sp"
/>
</LinearLayout>
</LinearLayout>
\ No newline at end of file
sobot_widget/src/main/res/layout/sobot_select_pic_and_video_item.xml
0 → 100644
View file @
a64a3da5
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
android:id=
"@+id/sobot_ll_content"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:background=
"@color/sobot_common_gray7"
>
<ImageView
android:id=
"@+id/sobot_iv_img"
android:layout_width=
"match_parent"
android:layout_height=
"90dp"
android:scaleType=
"centerCrop"
/>
<TextView
android:id=
"@+id/tv_duration"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"bottom"
android:layout_marginStart=
"6dp"
android:layout_marginLeft=
"6dp"
android:layout_marginBottom=
"6dp"
android:drawableStart=
"@drawable/sobot_album_tag_video_white"
android:drawableLeft=
"@drawable/sobot_album_tag_video_white"
android:drawablePadding=
"6dp"
android:ellipsize=
"end"
android:maxLines=
"1"
android:textColor=
"@color/sobot_common_wenzi_white_gray"
android:textSize=
"12sp"
android:visibility=
"gone"
/>
<View
android:id=
"@+id/view_masking_select"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:background=
"@color/sobot_half_transparent"
android:visibility=
"gone"
/>
<LinearLayout
android:id=
"@+id/ll_open_other"
android:layout_width=
"match_parent"
android:layout_height=
"90dp"
android:layout_gravity=
"center"
android:gravity=
"center"
android:orientation=
"vertical"
>
<ImageView
android:layout_width=
"26dp"
android:layout_height=
"26dp"
android:scaleType=
"centerCrop"
android:src=
"@drawable/sobot_icon_add"
/>
</LinearLayout>
<CheckBox
android:id=
"@+id/check_box"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_gravity=
"right"
android:layout_margin=
"3dp"
android:background=
"@drawable/sobot_bg_checkbox"
android:button=
"@null"
android:clickable=
"false"
android:enabled=
"false"
/>
</FrameLayout>
\ No newline at end of file
sobot_widget/src/main/res/values-en/strings.xml
View file @
a64a3da5
...
...
@@ -187,4 +187,9 @@
<string
name=
"sobot_srl_try_again"
>
Network error. Please check the network and try again
</string>
<string
name=
"sobot_srl_no_support_call"
>
The device does not support making calls
</string>
<string
name=
"sobot_str_select_pic_video"
>
Select photos and videos
</string>
<string
name=
"sobot_str_goto_setting_info"
>
Currently, only partial access to photos or videos is allowed
</string>
<string
name=
"sobot_str_goto_setting_allow"
>
Allow all>
</string>
<string
name=
"sobot_button_send"
>
Send
</string>
</resources>
sobot_widget/src/main/res/values-night/colors.xml
View file @
a64a3da5
...
...
@@ -40,11 +40,17 @@
<!--二级背景色-->
<color
name=
"sobot_common_gray7"
>
#262628
</color>
<!--透明-->
<color
name=
"sobot_transparent"
>
#00000000
</color>
<!--半透明-->
<color
name=
"sobot_half_transparent"
>
#73000000
</color>
<!-- 主题色 默认绿色 -->
<color
name=
"sobot_color"
>
@color/sobot_common_green
</color>
<!--文字颜色 绿色变白色-->
<color
name=
"sobot_common_wenzi_green_white"
>
@color/sobot_color
</color>
<!--文字颜色 绿色变白色-->
<color
name=
"sobot_common_wenzi_white_gray"
>
@color/sobot_common_gray3
</color>
<!--线条分割线颜色-->
<color
name=
"sobot_common_line_gray"
>
#272729
</color>
...
...
sobot_widget/src/main/res/values/colors.xml
View file @
a64a3da5
...
...
@@ -46,11 +46,17 @@
<!--二级背景色-->
<color
name=
"sobot_common_gray7"
>
#FFF2F5F7
</color>
<!--透明-->
<color
name=
"sobot_transparent"
>
#00000000
</color>
<!--半透明-->
<color
name=
"sobot_half_transparent"
>
#73000000
</color>
<!-- 主题色 默认绿色 -->
<color
name=
"sobot_color"
>
@color/sobot_common_green
</color>
<!--文字颜色 绿色变白色-->
<color
name=
"sobot_common_wenzi_green_white"
>
@color/sobot_color
</color>
<!--文字颜色 绿色变白色-->
<color
name=
"sobot_common_wenzi_white_gray"
>
#FFFFFF
</color>
<!--线条分割线颜色-->
<color
name=
"sobot_common_line_gray"
>
#EDEEF0
</color>
...
...
sobot_widget/src/main/res/values/strings.xml
View file @
a64a3da5
...
...
@@ -189,4 +189,9 @@
<string
name=
"sobot_srl_ctrl_v_success"
>
复制成功!
</string>
<string
name=
"sobot_srl_try_again"
>
网络错误,请检查网络后重试
</string>
<string
name=
"sobot_srl_no_support_call"
>
该设备不支持拨打电话
</string>
<string
name=
"sobot_str_select_pic_video"
>
选择照片和视频
</string>
<string
name=
"sobot_str_goto_setting_info"
>
当前仅允许访问部分照片或视频
</string>
<string
name=
"sobot_str_goto_setting_allow"
>
允许全部 >
</string>
<string
name=
"sobot_button_send"
>
发送
</string>
</resources>
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