Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
android_aiyuebao
Project
Project
Details
Activity
Releases
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
android
android_aiyuebao
Commits
e42dcad0
Commit
e42dcad0
authored
May 10, 2021
by
mengcuiguang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
代码优化
parent
4f306df4
Changes
25
Show whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
8 additions
and
2169 deletions
+8
-2169
build.gradle
app/build.gradle
+1
-4
AndroidManifest.xml
app/src/main/AndroidManifest.xml
+0
-23
ITelephony.aidl
.../main/aidl/com/android/internal/telephony/ITelephony.aidl
+0
-5
RingtoneHelper.java
...ava/com/wenshu/aiyuebao/call/business/RingtoneHelper.java
+0
-77
VideoDBHelper.java
...java/com/wenshu/aiyuebao/call/business/VideoDBHelper.java
+0
-77
CallCore.java
...main/java/com/wenshu/aiyuebao/call/callcore/CallCore.java
+0
-132
SystemCallCore.java
...ava/com/wenshu/aiyuebao/call/callcore/SystemCallCore.java
+0
-217
DetailApplyActivity.java
.../com/wenshu/aiyuebao/call/detail/DetailApplyActivity.java
+0
-91
PermissionActivity.java
...m/wenshu/aiyuebao/call/permission/PermissionActivity.java
+0
-85
PermissionManager.java
...om/wenshu/aiyuebao/call/permission/PermissionManager.java
+0
-201
PermissionUtil.java
...a/com/wenshu/aiyuebao/call/permission/PermissionUtil.java
+0
-157
PreferenceUtil.java
...a/com/wenshu/aiyuebao/call/preference/PreferenceUtil.java
+0
-10
CallProvider.java
.../java/com/wenshu/aiyuebao/call/provider/CallProvider.java
+0
-61
DataBaseHelper.java
...ava/com/wenshu/aiyuebao/call/provider/DataBaseHelper.java
+0
-32
PhoneListenService.java
.../com/wenshu/aiyuebao/call/service/PhoneListenService.java
+0
-129
DimensionUtil.java
...ain/java/com/wenshu/aiyuebao/call/util/DimensionUtil.java
+0
-31
CircleTextView.java
.../java/com/wenshu/aiyuebao/call/widget/CircleTextView.java
+0
-94
CustomVideoView.java
...java/com/wenshu/aiyuebao/call/widget/CustomVideoView.java
+0
-27
FloatingView.java
...in/java/com/wenshu/aiyuebao/call/widget/FloatingView.java
+0
-145
LockGuideView.java
...n/java/com/wenshu/aiyuebao/call/widget/LockGuideView.java
+0
-60
LockSlidingView.java
...java/com/wenshu/aiyuebao/call/widget/LockSlidingView.java
+0
-56
SlidingFinishView.java
...va/com/wenshu/aiyuebao/call/widget/SlidingFinishView.java
+0
-162
KylVideoActivity.kt
...java/com/wenshu/aiyuebao/ui/activitys/KylVideoActivity.kt
+0
-232
KuYinYuePageFragment.kt
...a/com/wenshu/aiyuebao/ui/fragment/KuYinYuePageFragment.kt
+7
-9
activity_kyl_video.xml
app/src/main/res/layout/activity_kyl_video.xml
+0
-52
No files found.
app/build.gradle
View file @
e42dcad0
...
...
@@ -64,8 +64,7 @@ android {
// 不显示Log
buildConfigField
"boolean"
,
"LOG_DEBUG"
,
"true"
buildConfigField
"String"
,
"AppKeyPre"
,
"\"abcd\""
// buildConfigField "String", "MainIp", DEBUG_URL
buildConfigField
"String"
,
"MainIp"
,
RELEASE_URL
buildConfigField
"String"
,
"MainIp"
,
DEBUG_URL
//混淆
minifyEnabled
false
...
...
@@ -250,6 +249,4 @@ dependencies {
implementation
(
name:
'tzsdk_reporter-3.0.0-20200807131516-release'
,
ext:
'aar'
)
// 快手
implementation
(
name:
'kssdk-ad-3.3.6-publishRelease'
,
ext:
'aar'
)
// 抖音滑动LayoutManager
implementation
(
name:
'LayoutManagerGroup'
,
ext:
'aar'
)
}
app/src/main/AndroidManifest.xml
View file @
e42dcad0
...
...
@@ -159,11 +159,6 @@
<activity
android:name=
"com.wenshu.aiyuebao.ui.activitys.XmlyAwardActivity"
/>
<activity
android:name=
"com.wenshu.aiyuebao.ui.activitys.XmlyPlayActivity"
/>
<activity
android:name=
"com.wenshu.aiyuebao.ui.activitys.TaskCpdActivity"
/>
<activity
android:name=
"com.wenshu.aiyuebao.ui.activitys.KylVideoActivity"
android:configChanges=
"orientation|screenSize|keyboardHidden"
/>
<activity
android:name=
"com.wenshu.aiyuebao.call.permission.PermissionActivity"
/>
<activity
android:name=
"com.wenshu.aiyuebao.call.detail.DetailApplyActivity"
/>
<service
android:name=
"com.wenshu.aiyuebao.service.UpdateService"
...
...
@@ -283,24 +278,6 @@
android:resource=
"@xml/wn_file_paths"
/>
</provider>
<!-- 来电秀 -->
<service
android:name=
"com.wenshu.aiyuebao.call.service.PhoneListenService"
android:enabled=
"true"
android:exported=
"false"
android:permission=
"android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
>
<intent-filter>
<action
android:name=
"android.intent.action.PHONE_STATE"
/>
<action
android:name=
"android.service.notification.NotificationListenerService"
/>
</intent-filter>
</service>
<provider
android:name=
"com.wenshu.aiyuebao.call.provider.CallProvider"
android:authorities=
"com.wenshu.aiyuebao.provider"
android:exported=
"true"
android:permission=
"com.wenshu.aiyuebao.permission"
/>
</application>
</manifest>
\ No newline at end of file
app/src/main/aidl/com/android/internal/telephony/ITelephony.aidl
deleted
100644 → 0
View file @
4f306df4
package
com
.
android
.
internal
.
telephony
;
interface
ITelephony
{
boolean
endCall
();
}
app/src/main/java/com/wenshu/aiyuebao/call/business/RingtoneHelper.java
deleted
100644 → 0
View file @
4f306df4
package
com
.
wenshu
.
aiyuebao
.
call
.
business
;
import
android.content.ContentValues
;
import
android.content.Context
;
import
android.database.Cursor
;
import
android.media.RingtoneManager
;
import
android.net.Uri
;
import
android.provider.MediaStore
;
import
android.text.TextUtils
;
import
android.widget.Toast
;
import
java.io.File
;
/**
* Ringtone设置来电秀
* 作者:孟崔广
*/
public
class
RingtoneHelper
{
/**
* 设置铃声为null
*
* @param context
*/
public
static
void
setNoRing
(
Context
context
)
{
if
(
context
==
null
)
{
return
;
}
RingtoneManager
.
setActualDefaultRingtoneUri
(
context
,
RingtoneManager
.
TYPE_RINGTONE
,
null
);
Toast
.
makeText
(
context
,
"已清除铃声!"
,
Toast
.
LENGTH_SHORT
).
show
();
}
/**
* 设置系统铃声
*
* @param context
* @param path
*/
public
static
void
setRing
(
Context
context
,
String
path
)
{
if
(
context
==
null
||
TextUtils
.
isEmpty
(
path
))
{
return
;
}
File
sdFile
=
new
File
(
path
);
ContentValues
values
=
new
ContentValues
();
values
.
put
(
MediaStore
.
MediaColumns
.
DATA
,
sdFile
.
getAbsolutePath
());
values
.
put
(
MediaStore
.
MediaColumns
.
TITLE
,
sdFile
.
getName
());
values
.
put
(
MediaStore
.
MediaColumns
.
MIME_TYPE
,
"audio/*"
);
values
.
put
(
MediaStore
.
Audio
.
Media
.
IS_RINGTONE
,
true
);
values
.
put
(
MediaStore
.
Audio
.
Media
.
IS_NOTIFICATION
,
false
);
values
.
put
(
MediaStore
.
Audio
.
Media
.
IS_ALARM
,
false
);
values
.
put
(
MediaStore
.
Audio
.
Media
.
IS_MUSIC
,
false
);
Uri
uri
=
MediaStore
.
Audio
.
Media
.
getContentUriForPath
(
sdFile
.
getAbsolutePath
());
if
(
uri
==
null
)
{
return
;
}
Uri
newUri
;
String
query
=
MediaStore
.
MediaColumns
.
DATA
+
"=\""
+
sdFile
.
getAbsolutePath
()
+
"\""
;
Cursor
cursor
=
context
.
getContentResolver
().
query
(
uri
,
null
,
query
,
null
,
null
);
if
(
cursor
!=
null
)
{
if
(
cursor
.
moveToFirst
())
{
String
id
=
cursor
.
getString
(
cursor
.
getColumnIndex
(
MediaStore
.
MediaColumns
.
_ID
));
newUri
=
Uri
.
parse
(
uri
.
toString
()
+
"/"
+
id
);
}
else
{
newUri
=
context
.
getContentResolver
().
insert
(
uri
,
values
);
}
cursor
.
close
();
}
else
{
newUri
=
context
.
getContentResolver
().
insert
(
uri
,
values
);
}
RingtoneManager
.
setActualDefaultRingtoneUri
(
context
,
RingtoneManager
.
TYPE_RINGTONE
,
newUri
);
// ToastUtil.show(context,"设置来电秀成功!");
}
}
app/src/main/java/com/wenshu/aiyuebao/call/business/VideoDBHelper.java
deleted
100644 → 0
View file @
4f306df4
package
com
.
wenshu
.
aiyuebao
.
call
.
business
;
import
android.content.ContentValues
;
import
android.content.Context
;
import
android.database.Cursor
;
import
android.net.Uri
;
import
android.text.TextUtils
;
import
android.util.Log
;
import
com.wenshu.aiyuebao.call.provider.CallProvider
;
import
com.wenshu.aiyuebao.common.Constant
;
import
java.util.regex.Matcher
;
import
java.util.regex.Pattern
;
/**
* 来电秀数据库操作
*
* 作者:孟崔广
*/
public
class
VideoDBHelper
{
public
static
final
String
UNKNOWN_NUMBER
=
"unknown"
;
private
static
final
String
AUTHORITY
=
"content://"
+
Constant
.
wenshu_PKG_NAME
+
".provider"
;
private
static
final
Uri
VIDEO_URI
=
Uri
.
parse
(
AUTHORITY
);
private
VideoDBHelper
()
{
}
private
static
class
SingleTon
{
private
static
VideoDBHelper
sInstance
=
new
VideoDBHelper
();
}
public
static
VideoDBHelper
getInstance
()
{
return
SingleTon
.
sInstance
;
}
public
void
setSelectVideo
(
Context
context
,
String
number
,
String
path
)
{
ContentValues
values
=
new
ContentValues
();
values
.
put
(
CallProvider
.
NUMBER
,
handleNumber
(
number
));
values
.
put
(
CallProvider
.
PATH
,
path
);
if
(!
TextUtils
.
isEmpty
(
queryVideo
(
context
,
number
)))
{
context
.
getContentResolver
().
delete
(
VIDEO_URI
,
CallProvider
.
NUMBER
+
"=\'"
+
number
+
"\'"
,
null
);
}
context
.
getContentResolver
().
insert
(
VIDEO_URI
,
values
);
}
public
String
getSelectVideo
(
Context
context
,
String
number
)
{
String
path
=
queryVideo
(
context
,
handleNumber
(
number
));
if
(
TextUtils
.
isEmpty
(
path
))
{
path
=
queryVideo
(
context
,
UNKNOWN_NUMBER
);
}
Log
.
d
(
"LLL"
,
"path = "
+
path
);
return
path
;
}
private
String
handleNumber
(
String
number
)
{
if
(
TextUtils
.
isEmpty
(
number
)
||
UNKNOWN_NUMBER
.
equals
(
number
))
{
return
number
;
}
String
regEx
=
"[^0-9]"
;
Pattern
p
=
Pattern
.
compile
(
regEx
);
Matcher
m
=
p
.
matcher
(
number
);
return
m
.
replaceAll
(
""
).
trim
();
}
private
String
queryVideo
(
Context
context
,
String
number
)
{
Cursor
cursor
=
context
.
getContentResolver
().
query
(
VIDEO_URI
,
null
,
CallProvider
.
NUMBER
+
"=\'"
+
number
+
"\'"
,
null
,
null
);
String
path
=
""
;
if
(
cursor
!=
null
&&
cursor
.
moveToFirst
())
{
path
=
cursor
.
getString
(
cursor
.
getColumnIndex
(
CallProvider
.
PATH
));
cursor
.
close
();
}
return
path
;
}
}
app/src/main/java/com/wenshu/aiyuebao/call/callcore/CallCore.java
deleted
100644 → 0
View file @
4f306df4
package
com
.
wenshu
.
aiyuebao
.
call
.
callcore
;
import
android.app.KeyguardManager
;
import
android.app.Notification
;
import
android.content.Context
;
import
android.text.TextUtils
;
import
com.wenshu.aiyuebao.call.widget.FloatingView
;
import
com.wenshu.aiyuebao.call.widget.LockGuideView
;
/**
* 来电秀核心设置
* 作者:孟崔广
*/
public
abstract
class
CallCore
{
protected
static
final
String
TAG
=
"CallCore"
;
public
static
final
String
SYSTEM_CALL_PKG
=
"system_call"
;
protected
static
final
int
STATUS_NONE
=
0
;
protected
static
final
int
STATUS_RINGING
=
1
;
protected
int
mStatus
=
STATUS_NONE
;
Context
mContext
;
FloatingView
mFloatingView
;
Notification
.
Action
[]
mActions
;
private
String
mPackage
;
private
boolean
mClicked
=
false
;
CallCore
(
Context
context
,
String
pkg
)
{
init
(
context
,
pkg
);
}
private
void
init
(
Context
context
,
String
pkg
)
{
if
(
context
==
null
)
{
return
;
}
mContext
=
context
;
mPackage
=
pkg
;
mFloatingView
=
new
FloatingView
(
context
);
mFloatingView
.
setListener
(
new
FloatingView
.
OnCallListener
()
{
@Override
public
void
onGet
()
{
mClicked
=
true
;
acceptCall
();
}
@Override
public
void
onEnd
()
{
mClicked
=
true
;
endCall
();
}
});
}
public
String
getPackage
()
{
return
mPackage
;
}
public
void
setPackage
(
String
aPackage
)
{
mPackage
=
aPackage
;
}
/**
* 有来电时:未接/挂断/通话结束
*/
void
showLockGuide
()
{
if
(!
mClicked
&&
isLocked
())
{
LockGuideView
guideView
=
new
LockGuideView
(
mContext
);
guideView
.
show
();
}
else
{
mClicked
=
false
;
}
}
/**
* 是否锁屏
* 有密码亮屏:isKeyguardLocked = false, isKeyguardSecure = true, isDeviceLocked = false, isDeviceSecure = true
* 无密码亮屏:isKeyguardLocked = false, isKeyguardSecure = false, isDeviceLocked = false, isDeviceSecure = false
* 有密码锁屏:isKeyguardLocked = true, isKeyguardSecure = true, isDeviceLocked = true, isDeviceSecure = true
* 无密码锁屏:isKeyguardLocked = true, isKeyguardSecure = false, isDeviceLocked = false, isDeviceSecure = false
*/
protected
boolean
isLocked
()
{
if
(
mContext
!=
null
)
{
KeyguardManager
manager
=
(
KeyguardManager
)
mContext
.
getSystemService
(
Context
.
KEYGUARD_SERVICE
);
return
manager
!=
null
&&
manager
.
isKeyguardLocked
();
}
return
false
;
}
protected
void
sendAction
(
int
position
)
{
if
(
mActions
!=
null
)
{
try
{
mActions
[
position
].
actionIntent
.
send
();
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
finally
{
mActions
=
null
;
}
}
}
protected
abstract
void
acceptCall
();
protected
abstract
void
endCall
();
public
abstract
void
onNotificationPosted
(
Notification
notification
);
public
abstract
void
onNotificationRemoved
(
Notification
notification
);
public
abstract
void
onDestroy
();
public
static
CallCore
createCallCore
(
Context
context
,
String
pkg
)
{
if
(
context
==
null
||
TextUtils
.
isEmpty
(
pkg
))
{
return
null
;
}
try
{
switch
(
pkg
)
{
case
SYSTEM_CALL_PKG:
return
new
SystemCallCore
(
context
,
pkg
);
default
:
return
null
;
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
return
null
;
}
}
app/src/main/java/com/wenshu/aiyuebao/call/callcore/SystemCallCore.java
deleted
100644 → 0
View file @
4f306df4
package
com
.
wenshu
.
aiyuebao
.
call
.
callcore
;
import
android.Manifest
;
import
android.app.Notification
;
import
android.content.BroadcastReceiver
;
import
android.content.ComponentName
;
import
android.content.Context
;
import
android.content.Intent
;
import
android.content.IntentFilter
;
import
android.content.pm.PackageManager
;
import
android.media.session.MediaController
;
import
android.media.session.MediaSessionManager
;
import
android.os.Build
;
import
android.os.Bundle
;
import
android.os.IBinder
;
import
android.os.SystemClock
;
import
android.service.notification.StatusBarNotification
;
import
android.telecom.TelecomManager
;
import
android.telephony.TelephonyManager
;
import
android.text.TextUtils
;
import
android.util.Log
;
import
android.view.InputDevice
;
import
android.view.KeyCharacterMap
;
import
android.view.KeyEvent
;
import
com.android.internal.telephony.ITelephony
;
import
com.wenshu.aiyuebao.call.service.PhoneListenService
;
import
java.lang.reflect.Method
;
import
java.util.ArrayList
;
import
java.util.List
;
/**
* 监听处理来电
* 作者:孟崔广
*/
public
class
SystemCallCore
extends
CallCore
{
private
static
final
List
<
String
>
mCallPkgs
=
new
ArrayList
<>();
private
TelecomManager
mTelManager
;
private
BroadcastReceiver
mPhoneStateReceiver
=
new
BroadcastReceiver
()
{
@Override
public
void
onReceive
(
Context
context
,
Intent
intent
)
{
String
action
=
intent
.
getAction
();
if
(
TextUtils
.
equals
(
action
,
"android.intent.action.PHONE_STATE"
))
{
if
(
mFloatingView
==
null
)
{
return
;
}
String
state
=
intent
.
getStringExtra
(
"state"
);
String
number
=
intent
.
getStringExtra
(
"incoming_number"
);
Log
.
d
(
TAG
,
this
+
" state = "
+
state
+
", number = "
+
number
);
if
(
TelephonyManager
.
EXTRA_STATE_RINGING
.
equalsIgnoreCase
(
state
))
{
if
(
isLocked
())
{
mStatus
=
STATUS_RINGING
;
}
mFloatingView
.
show
(
number
);
}
else
{
mFloatingView
.
hide
();
if
(
TelephonyManager
.
EXTRA_STATE_OFFHOOK
.
equalsIgnoreCase
(
state
)
&&
mStatus
==
STATUS_RINGING
)
{
mStatus
=
STATUS_NONE
;
showLockGuide
();
}
}
}
}
};
SystemCallCore
(
Context
context
,
String
pkg
)
{
super
(
context
,
pkg
);
init
(
context
);
}
private
void
init
(
Context
context
)
{
if
(
context
==
null
)
{
return
;
}
mTelManager
=
(
TelecomManager
)
context
.
getSystemService
(
Context
.
TELECOM_SERVICE
);
IntentFilter
filter
=
new
IntentFilter
();
filter
.
addAction
(
"android.intent.action.PHONE_STATE"
);
context
.
registerReceiver
(
mPhoneStateReceiver
,
filter
);
mCallPkgs
.
add
(
"com.google.android.dialer"
);
mCallPkgs
.
add
(
"com.android.incallui"
);
}
@Override
protected
void
acceptCall
()
{
if
(
mContext
==
null
)
{
return
;
}
if
(
mTelManager
!=
null
)
{
if
(
mContext
.
checkSelfPermission
(
Manifest
.
permission
.
READ_PHONE_STATE
)
!=
PackageManager
.
PERMISSION_GRANTED
)
{
return
;
}
mTelManager
.
showInCallScreen
(
false
);
}
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
O
)
{
if
(
mTelManager
!=
null
)
{
mTelManager
.
acceptRingingCall
();
}
}
else
{
sendHeadsetHook
(
true
);
}
}
@Override
protected
void
endCall
()
{
if
(
mContext
==
null
)
{
return
;
}
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
P
)
{
if
(
mTelManager
!=
null
)
{
mTelManager
.
endCall
();
}
}
else
{
sendHeadsetHook
(
false
);
try
{
Method
method
=
Class
.
forName
(
"android.os.ServiceManager"
).
getMethod
(
"getService"
,
String
.
class
);
IBinder
binder
=
(
IBinder
)
method
.
invoke
(
null
,
new
Object
[]{
Context
.
TELEPHONY_SERVICE
});
ITelephony
telephony
=
ITelephony
.
Stub
.
asInterface
(
binder
);
telephony
.
endCall
();
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
}
@Override
public
void
onNotificationPosted
(
Notification
notification
)
{
Log
.
d
(
TAG
,
"onNotificationPosted: "
+
notification
);
if
(
mContext
==
null
||
notification
==
null
)
{
return
;
}
if
(!
canReadContact
())
{
Bundle
bundle
=
notification
.
extras
;
if
(
bundle
!=
null
)
{
mFloatingView
.
setPerson
(
String
.
valueOf
(
bundle
.
getCharSequence
(
Notification
.
EXTRA_TITLE
)),
null
);
}
}
}
@Override
public
void
onNotificationRemoved
(
Notification
notification
)
{
Log
.
d
(
TAG
,
"onNotificationRemoved: "
+
notification
);
}
@Override
public
void
onDestroy
()
{
if
(
mContext
!=
null
)
{
mContext
.
unregisterReceiver
(
mPhoneStateReceiver
);
}
}
public
boolean
isCall
(
StatusBarNotification
sbn
)
{
return
sbn
!=
null
&&
sbn
.
getNotification
()
!=
null
&&
mCallPkgs
.
contains
(
sbn
.
getPackageName
())
&&
sbn
.
getNotification
().
actions
!=
null
;
}
private
boolean
canReadContact
()
{
return
mContext
!=
null
&&
mContext
.
checkSelfPermission
(
Manifest
.
permission
.
READ_CALL_LOG
)
==
PackageManager
.
PERMISSION_GRANTED
&&
mContext
.
checkSelfPermission
(
Manifest
.
permission
.
READ_CONTACTS
)
==
PackageManager
.
PERMISSION_GRANTED
;
}
/**
* 通过模拟耳机接听/挂断电话
*
* @param isAnswer: true, 接听; false: 挂断
*/
private
void
sendHeadsetHook
(
boolean
isAnswer
)
{
if
(
mContext
==
null
)
{
return
;
}
MediaSessionManager
sessionManager
=
(
MediaSessionManager
)
mContext
.
getSystemService
(
Context
.
MEDIA_SESSION_SERVICE
);
if
(
sessionManager
==
null
)
{
return
;
}
try
{
List
<
MediaController
>
controllers
=
sessionManager
.
getActiveSessions
(
new
ComponentName
(
mContext
,
PhoneListenService
.
class
));
for
(
MediaController
m
:
controllers
)
{
if
(
"com.android.server.telecom"
.
equals
(
m
.
getPackageName
()))
{
if
(
isAnswer
)
{
m
.
dispatchMediaButtonEvent
(
new
KeyEvent
(
KeyEvent
.
ACTION_DOWN
,
KeyEvent
.
KEYCODE_HEADSETHOOK
));
}
else
{
long
now
=
SystemClock
.
uptimeMillis
();
m
.
dispatchMediaButtonEvent
(
new
KeyEvent
(
now
,
now
,
KeyEvent
.
ACTION_DOWN
,
KeyEvent
.
KEYCODE_HEADSETHOOK
,
1
,
0
,
KeyCharacterMap
.
VIRTUAL_KEYBOARD
,
0
,
KeyEvent
.
FLAG_LONG_PRESS
,
InputDevice
.
SOURCE_KEYBOARD
));
}
m
.
dispatchMediaButtonEvent
(
new
KeyEvent
(
KeyEvent
.
ACTION_UP
,
KeyEvent
.
KEYCODE_HEADSETHOOK
));
Log
.
d
(
TAG
,
this
+
" headset sent to tel"
);
break
;
}
}
}
catch
(
Exception
e
)
{
Log
.
d
(
TAG
,
this
+
" Permission error, Access to notification not granted to the app."
);
}
}
}
app/src/main/java/com/wenshu/aiyuebao/call/detail/DetailApplyActivity.java
deleted
100644 → 0
View file @
4f306df4
package
com
.
wenshu
.
aiyuebao
.
call
.
detail
;
import
android.app.Activity
;
import
android.content.Context
;
import
android.content.Intent
;
import
android.os.Bundle
;
import
android.view.View
;
import
android.widget.TextView
;
import
androidx.annotation.Nullable
;
import
androidx.appcompat.app.AppCompatActivity
;
import
com.wenshu.aiyuebao.R
;
import
com.wenshu.aiyuebao.call.business.RingtoneHelper
;
import
com.wenshu.aiyuebao.call.permission.PermissionManager
;
import
com.wenshu.aiyuebao.ui.activitys.MainActivity
;
/**
* 设置成功
* 作者:孟崔广
*/
public
class
DetailApplyActivity
extends
AppCompatActivity
{
private
TextView
mRingtoneView
;
private
boolean
mSetRingtone
=
true
;
private
String
mVideoPath
;
public
static
final
String
KEY_VIDEO_PATH
=
"video_path"
;
public
static
final
String
KEY_SET_RINGTONE
=
"key_set_ringtone"
;
public
static
void
startSelf
(
Context
context
,
String
path
,
boolean
setRingtone
)
{
if
(
context
==
null
)
{
return
;
}
Intent
intent
=
new
Intent
(
context
,
DetailApplyActivity
.
class
);
intent
.
putExtra
(
DetailApplyActivity
.
KEY_VIDEO_PATH
,
path
);
intent
.
putExtra
(
DetailApplyActivity
.
KEY_SET_RINGTONE
,
setRingtone
);
if
(!(
context
instanceof
Activity
))
{
intent
.
addFlags
(
Intent
.
FLAG_ACTIVITY_NEW_TASK
);
}
context
.
startActivity
(
intent
);
}
@Override
protected
void
onCreate
(
@Nullable
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
setContentView
(
R
.
layout
.
activity_detail_apply
);
handleIntent
();
init
();
setRingtone
();
}
private
void
init
()
{
mRingtoneView
=
findViewById
(
R
.
id
.
ringtone_apply_tv
);
}
private
void
handleIntent
()
{
mSetRingtone
=
getIntent
().
getBooleanExtra
(
DetailApplyActivity
.
KEY_SET_RINGTONE
,
true
);
mVideoPath
=
getIntent
().
getStringExtra
(
DetailApplyActivity
.
KEY_VIDEO_PATH
);
}
private
void
setRingtone
()
{
if
(
PermissionManager
.
getInstance
().
isSettingsEnabled
(
this
))
{
if
(
mSetRingtone
)
{
RingtoneHelper
.
setRing
(
this
,
mVideoPath
);
mRingtoneView
.
setVisibility
(
View
.
VISIBLE
);
}
}
else
{
PermissionManager
.
getInstance
().
requestSettings
(
this
);
}
}
@Override
protected
void
onActivityResult
(
int
requestCode
,
int
resultCode
,
@Nullable
Intent
data
)
{
super
.
onActivityResult
(
requestCode
,
resultCode
,
data
);
PermissionManager
.
getInstance
().
onActivityResult
(
this
,
requestCode
);
if
(
PermissionManager
.
getInstance
().
isSettingsEnabled
(
this
))
{
if
(
mSetRingtone
)
{
RingtoneHelper
.
setRing
(
this
,
mVideoPath
);
mRingtoneView
.
setVisibility
(
View
.
VISIBLE
);
}
}
}
public
void
tvSucFinish
(
View
view
)
{
Intent
intent
=
new
Intent
(
this
,
MainActivity
.
class
);
startActivity
(
intent
);
finish
();
}
}
app/src/main/java/com/wenshu/aiyuebao/call/permission/PermissionActivity.java
deleted
100644 → 0
View file @
4f306df4
package
com
.
wenshu
.
aiyuebao
.
call
.
permission
;
import
android.app.Activity
;
import
android.content.Context
;
import
android.content.Intent
;
import
android.os.Bundle
;
import
android.view.View
;
import
android.widget.ImageView
;
import
androidx.annotation.NonNull
;
import
androidx.annotation.Nullable
;
import
androidx.appcompat.app.AppCompatActivity
;
import
com.wenshu.aiyuebao.R
;
/**
* 权限申请界面
* 作者:孟崔广
*/
public
class
PermissionActivity
extends
AppCompatActivity
{
private
ImageView
mSdcardIv
;
private
ImageView
mPhoneIv
;
private
ImageView
mFloatIv
;
private
ImageView
mNotificationIv
;
public
static
void
startSelf
(
Context
context
)
{
if
(
context
==
null
)
{
return
;
}
Intent
intent
=
new
Intent
(
context
,
PermissionActivity
.
class
);
if
(!(
context
instanceof
Activity
))
{
intent
.
addFlags
(
Intent
.
FLAG_ACTIVITY_NEW_TASK
);
}
context
.
startActivity
(
intent
);
}
@Override
protected
void
onCreate
(
@Nullable
Bundle
savedInstanceState
)
{
super
.
onCreate
(
savedInstanceState
);
setContentView
(
R
.
layout
.
activity_permission
);
init
();
updateUI
();
}
private
void
init
()
{
mSdcardIv
=
findViewById
(
R
.
id
.
sdcard_iv
);
mPhoneIv
=
findViewById
(
R
.
id
.
phone_iv
);
mFloatIv
=
findViewById
(
R
.
id
.
float_iv
);
mNotificationIv
=
findViewById
(
R
.
id
.
notification_iv
);
}
private
void
updateUI
()
{
mSdcardIv
.
setImageResource
(
PermissionManager
.
getInstance
().
isSdcardEnabled
(
this
)
?
R
.
mipmap
.
get_permission
:
R
.
mipmap
.
no_permission
);
mPhoneIv
.
setImageResource
(
PermissionManager
.
getInstance
().
isPhoneEnabled
(
this
)
?
R
.
mipmap
.
get_permission
:
R
.
mipmap
.
no_permission
);
mFloatIv
.
setImageResource
(
PermissionManager
.
getInstance
().
isFloatEnabled
(
this
)
?
R
.
mipmap
.
get_permission
:
R
.
mipmap
.
no_permission
);
mNotificationIv
.
setImageResource
(
PermissionManager
.
getInstance
().
isNotificationEnabled
(
this
)
?
R
.
mipmap
.
get_permission
:
R
.
mipmap
.
no_permission
);
if
(
PermissionManager
.
getInstance
().
checkEssential
(
this
))
{
finish
();
}
}
public
void
getPermission
(
View
view
)
{
PermissionManager
.
getInstance
().
requestEssential
(
this
);
}
@Override
protected
void
onActivityResult
(
int
requestCode
,
int
resultCode
,
@Nullable
Intent
data
)
{
super
.
onActivityResult
(
requestCode
,
resultCode
,
data
);
updateUI
();
PermissionManager
.
getInstance
().
onActivityResult
(
this
,
requestCode
);
}
@Override
public
void
onRequestPermissionsResult
(
int
requestCode
,
@NonNull
String
[]
permissions
,
@NonNull
int
[]
grantResults
)
{
super
.
onRequestPermissionsResult
(
requestCode
,
permissions
,
grantResults
);
updateUI
();
PermissionManager
.
getInstance
().
onRequestPermissionsResult
(
this
,
requestCode
,
permissions
,
grantResults
);
}
}
app/src/main/java/com/wenshu/aiyuebao/call/permission/PermissionManager.java
deleted
100644 → 0
View file @
4f306df4
package
com
.
wenshu
.
aiyuebao
.
call
.
permission
;
import
android.Manifest
;
import
android.app.Activity
;
import
android.content.Context
;
import
android.content.Intent
;
import
android.content.pm.PackageManager
;
import
android.net.Uri
;
import
android.os.Build
;
import
android.provider.Settings
;
import
androidx.core.app.ActivityCompat
;
import
androidx.core.app.NotificationManagerCompat
;
import
java.util.Set
;
public
class
PermissionManager
{
private
static
final
int
REQUEST_ID_PERMISSION
=
0
;
private
static
final
int
REQUEST_ID_NOTIFICATION
=
1
;
private
static
final
int
REQUEST_ID_POPUP
=
2
;
private
static
final
int
REQUEST_ID_CONTACT_PERMISSION
=
3
;
private
static
final
int
REQUEST_ID_SETTINGS_PERMISSION
=
4
;
/**
* 必需权限:读写sdcard,来电状态,接听/挂断电话,悬浮窗,通知栏
*/
private
String
[]
mEssentialPermissions
=
new
String
[]{
Manifest
.
permission
.
READ_PHONE_STATE
,
Manifest
.
permission
.
CALL_PHONE
,
Manifest
.
permission
.
WRITE_EXTERNAL_STORAGE
,
Manifest
.
permission
.
READ_EXTERNAL_STORAGE
,
""
,
};
/**
* 联系人权限
*/
private
String
[]
mContactPermissions
=
new
String
[]{
Manifest
.
permission
.
READ_CALL_LOG
,
Manifest
.
permission
.
READ_CONTACTS
,
Manifest
.
permission
.
WRITE_CONTACTS
,
};
private
PermissionManager
()
{
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
O
)
{
mEssentialPermissions
[
4
]
=
Manifest
.
permission
.
ANSWER_PHONE_CALLS
;
}
}
private
static
class
SingleTon
{
private
static
PermissionManager
sInstance
=
new
PermissionManager
();
}
public
static
PermissionManager
getInstance
()
{
return
SingleTon
.
sInstance
;
}
public
boolean
checkEssential
(
Context
context
)
{
if
(
context
==
null
)
{
return
false
;
}
for
(
String
permission
:
mEssentialPermissions
)
{
if
(
context
.
checkSelfPermission
(
permission
)
!=
PackageManager
.
PERMISSION_GRANTED
)
{
return
false
;
}
}
return
isNotificationEnabled
(
context
)
&&
isFloatEnabled
(
context
);
}
public
void
requestEssential
(
Activity
activity
)
{
if
(
activity
==
null
)
{
return
;
}
ActivityCompat
.
requestPermissions
(
activity
,
mEssentialPermissions
,
REQUEST_ID_PERMISSION
);
}
public
void
onRequestPermissionsResult
(
Activity
activity
,
int
requestCode
,
String
[]
permissions
,
int
[]
grantResults
)
{
if
(
activity
==
null
||
grantResults
==
null
)
{
return
;
}
if
(
requestCode
==
REQUEST_ID_PERMISSION
&&
grantResults
.
length
>
0
)
{
for
(
int
i
=
0
;
i
<
grantResults
.
length
;
i
++)
{
if
(
grantResults
[
i
]
==
PackageManager
.
PERMISSION_DENIED
)
{
if
(
ActivityCompat
.
shouldShowRequestPermissionRationale
(
activity
,
permissions
[
i
]))
{
ActivityCompat
.
requestPermissions
(
activity
,
mEssentialPermissions
,
REQUEST_ID_PERMISSION
);
}
else
{
PermissionUtil
.
jumpPermissionPage
(
activity
);
}
}
}
openFloatSettings
(
activity
);
openNotificationSettings
(
activity
);
}
}
public
void
onActivityResult
(
Activity
activity
,
int
requestCode
)
{
if
(
activity
==
null
)
{
return
;
}
}
public
boolean
isContactEnabled
(
Context
context
)
{
return
isPermissionsEnabled
(
context
,
mContactPermissions
);
}
public
void
requestSettings
(
Activity
activity
)
{
try
{
if
(
isSettingsEnabled
(
activity
))
{
return
;
}
Intent
intent
=
new
Intent
(
Settings
.
ACTION_MANAGE_WRITE_SETTINGS
);
intent
.
setData
(
Uri
.
parse
(
"package:"
+
activity
.
getPackageName
()));
activity
.
startActivityForResult
(
intent
,
REQUEST_ID_SETTINGS_PERMISSION
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
public
boolean
isSdcardEnabled
(
Context
context
)
{
String
[]
permissions
=
new
String
[]{
Manifest
.
permission
.
WRITE_EXTERNAL_STORAGE
,
Manifest
.
permission
.
READ_EXTERNAL_STORAGE
,
};
return
isPermissionsEnabled
(
context
,
permissions
);
}
public
boolean
isPhoneEnabled
(
Context
context
)
{
String
[]
permissions
=
new
String
[]{
Manifest
.
permission
.
READ_PHONE_STATE
,
Manifest
.
permission
.
CALL_PHONE
,
""
,
};
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
O
)
{
permissions
[
2
]
=
Manifest
.
permission
.
ANSWER_PHONE_CALLS
;
}
return
isPermissionsEnabled
(
context
,
permissions
);
}
public
boolean
isNotificationEnabled
(
Context
context
)
{
if
(
context
==
null
)
{
return
false
;
}
Set
<
String
>
packageNames
=
NotificationManagerCompat
.
getEnabledListenerPackages
(
context
);
return
packageNames
.
contains
(
context
.
getPackageName
());
}
public
boolean
isFloatEnabled
(
Context
context
)
{
if
(
context
==
null
)
{
return
false
;
}
return
Settings
.
canDrawOverlays
(
context
);
}
public
boolean
isSettingsEnabled
(
Context
context
)
{
if
(
context
==
null
)
{
return
false
;
}
return
Settings
.
System
.
canWrite
(
context
);
}
private
boolean
isPermissionsEnabled
(
Context
context
,
String
[]
permissions
)
{
if
(
context
==
null
||
permissions
==
null
)
{
return
false
;
}
for
(
String
permission
:
permissions
)
{
if
(
context
.
checkSelfPermission
(
permission
)
!=
PackageManager
.
PERMISSION_GRANTED
)
{
return
false
;
}
}
return
true
;
}
private
void
openNotificationSettings
(
Activity
activity
)
{
try
{
if
(
isNotificationEnabled
(
activity
))
{
return
;
}
Intent
intent
=
new
Intent
(
Settings
.
ACTION_NOTIFICATION_LISTENER_SETTINGS
);
activity
.
startActivityForResult
(
intent
,
REQUEST_ID_NOTIFICATION
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
private
void
openFloatSettings
(
Activity
activity
)
{
try
{
if
(
isFloatEnabled
(
activity
))
{
return
;
}
Intent
intent
=
new
Intent
(
Settings
.
ACTION_MANAGE_OVERLAY_PERMISSION
);
intent
.
setData
(
Uri
.
parse
(
"package:"
+
activity
.
getPackageName
()));
activity
.
startActivityForResult
(
intent
,
REQUEST_ID_POPUP
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
}
app/src/main/java/com/wenshu/aiyuebao/call/permission/PermissionUtil.java
deleted
100644 → 0
View file @
4f306df4
package
com
.
wenshu
.
aiyuebao
.
call
.
permission
;
import
android.content.ComponentName
;
import
android.content.Context
;
import
android.content.Intent
;
import
android.content.pm.PackageManager
;
import
android.net.Uri
;
import
android.os.Build
;
/**
* 手机厂商权限兼容
* 作者:孟崔广
*/
public
class
PermissionUtil
{
private
static
final
String
sManufacturer
=
Build
.
MANUFACTURER
.
toLowerCase
();
private
static
boolean
isIntentIllegal
(
Context
paramContext
,
Intent
paramIntent
)
{
return
paramContext
.
getPackageManager
().
queryIntentActivities
(
paramIntent
,
PackageManager
.
MATCH_DEFAULT_ONLY
).
size
()
>
0
;
}
private
static
Intent
getAll
(
Context
paramContext
)
{
Intent
intent
=
new
Intent
(
"android.settings.APPLICATION_DETAILS_SETTINGS"
);
intent
.
setData
(
Uri
.
fromParts
(
"package"
,
paramContext
.
getPackageName
(),
null
));
return
intent
;
}
private
static
Intent
getHuaWei
(
Context
paramContext
)
{
Intent
intent
=
new
Intent
();
intent
.
setComponent
(
new
ComponentName
(
"com.huawei.systemmanager"
,
"com.huawei.permissionmanager.ui.MainActivity"
));
if
(
isIntentIllegal
(
paramContext
,
intent
))
return
intent
;
intent
.
setComponent
(
new
ComponentName
(
"com.huawei.systemmanager"
,
"com.huawei.systemmanager.addviewmonitor.AddViewMonitorActivity"
));
if
(
isIntentIllegal
(
paramContext
,
intent
))
return
intent
;
intent
.
setComponent
(
new
ComponentName
(
"com.huawei.systemmanager"
,
"com.huawei.notificationmanager.ui.NotificationManagmentActivity"
));
return
intent
;
}
private
static
Intent
getXiaoMi
(
Context
paramContext
)
{
Intent
intent
=
new
Intent
(
"miui.intent.action.APP_PERM_EDITOR"
);
intent
.
putExtra
(
"extra_pkgname"
,
paramContext
.
getPackageName
());
if
(
isIntentIllegal
(
paramContext
,
intent
))
return
intent
;
intent
.
setPackage
(
"com.miui.securitycenter"
);
if
(
isIntentIllegal
(
paramContext
,
intent
))
return
intent
;
intent
.
setClassName
(
"com.miui.securitycenter"
,
"com.miui.permcenter.permissions.AppPermissionsEditorActivity"
);
return
intent
;
}
private
static
Intent
getOPPO
(
Context
paramContext
)
{
Intent
intent
=
new
Intent
();
intent
.
putExtra
(
"packageName"
,
paramContext
.
getPackageName
());
intent
.
setClassName
(
"com.color.safecenter"
,
"com.color.safecenter.permission.floatwindow.FloatWindowListActivity"
);
if
(
isIntentIllegal
(
paramContext
,
intent
))
return
intent
;
intent
.
setClassName
(
"com.coloros.safecenter"
,
"com.coloros.safecenter.sysfloatwindow.FloatWindowListActivity"
);
if
(
isIntentIllegal
(
paramContext
,
intent
))
return
intent
;
intent
.
setClassName
(
"com.oppo.safe"
,
"com.oppo.safe.permission.PermissionAppListActivity"
);
return
intent
;
}
private
static
Intent
getIqoo
(
Context
paramContext
)
{
Intent
intent
=
new
Intent
();
intent
.
setClassName
(
"com.iqoo.secure"
,
"com.iqoo.secure.ui.phoneoptimize.FloatWindowManager"
);
intent
.
putExtra
(
"packagename"
,
paramContext
.
getPackageName
());
if
(
isIntentIllegal
(
paramContext
,
intent
))
return
intent
;
intent
.
setComponent
(
new
ComponentName
(
"com.iqoo.secure"
,
"com.iqoo.secure.safeguard.SoftPermissionDetailActivity"
));
return
intent
;
}
private
static
Intent
getMeiZu
(
Context
paramContext
)
{
Intent
intent
=
new
Intent
(
"com.meizu.safe.security.SHOW_APPSEC"
);
intent
.
putExtra
(
"packageName"
,
paramContext
.
getPackageName
());
intent
.
setComponent
(
new
ComponentName
(
"com.meizu.safe"
,
"com.meizu.safe.security.AppSecActivity"
));
return
intent
;
}
public
static
void
jumpPermissionPage
(
Context
context
)
{
if
(
context
==
null
)
{
return
;
}
Intent
intent
;
if
(
sManufacturer
.
contains
(
"huawei"
))
{
intent
=
getHuaWei
(
context
);
}
else
if
(
sManufacturer
.
contains
(
"xiaomi"
))
{
intent
=
getXiaoMi
(
context
);
}
else
if
(
sManufacturer
.
contains
(
"oppo"
))
{
intent
=
getOPPO
(
context
);
}
else
if
(
sManufacturer
.
contains
(
"vivo"
))
{
intent
=
getIqoo
(
context
);
}
else
if
(
sManufacturer
.
contains
(
"meizu"
))
{
intent
=
getMeiZu
(
context
);
}
else
{
intent
=
getAll
(
context
);
}
try
{
intent
.
addFlags
(
Intent
.
FLAG_ACTIVITY_NEW_TASK
);
context
.
startActivity
(
intent
);
}
catch
(
Exception
exception
)
{
exception
.
printStackTrace
();
}
}
public
static
Intent
getAutoStartSettingIntent
(
Context
context
)
throws
Exception
{
ComponentName
componentName
=
null
;
String
brand
=
Build
.
MANUFACTURER
;
Intent
intent
=
new
Intent
();
intent
.
addFlags
(
Intent
.
FLAG_ACTIVITY_NEW_TASK
);
switch
(
brand
.
toLowerCase
())
{
case
"samsung"
:
//三星
componentName
=
new
ComponentName
(
"com.samsung.android.sm"
,
"com.samsung.android.sm.app.dashboard.SmartManagerDashBoardActivity"
);
break
;
case
"huawei"
:
//华为
componentName
=
ComponentName
.
unflattenFromString
(
"com.huawei.systemmanager/.startupmgr.ui.StartupNormalAppListActivity"
);
break
;
case
"xiaomi"
:
//小米
componentName
=
new
ComponentName
(
"com.miui.securitycenter"
,
"com.miui.permcenter.autostart.AutoStartManagementActivity"
);
break
;
case
"vivo"
:
//VIVO
componentName
=
new
ComponentName
(
"com.iqoo.secure"
,
"com.iqoo.secure.ui.phoneoptimize.AddWhiteListActivity"
);
break
;
case
"oppo"
:
//OPPO
// componentName = new ComponentName("com.oppo.safe", "com.oppo.safe.permission.startup.StartupAppListActivity");
componentName
=
new
ComponentName
(
"com.coloros.oppoguardelf"
,
"com.coloros.powermanager.fuelgaue.PowerUsageModelActivity"
);
break
;
case
"yulong"
:
case
"360"
:
//360
componentName
=
new
ComponentName
(
"com.yulong.android.coolsafe"
,
"com.yulong.android.coolsafe.ui.activity.autorun.AutoRunListActivity"
);
break
;
case
"meizu"
:
//魅族
componentName
=
new
ComponentName
(
"com.meizu.safe"
,
"com.meizu.safe.permission.SmartBGActivity"
);
break
;
case
"oneplus"
:
//一加
componentName
=
new
ComponentName
(
"com.oneplus.security"
,
"com.oneplus.security.chainlaunch.view.ChainLaunchAppListActivity"
);
break
;
case
"letv"
:
//乐视
intent
.
setAction
(
"com.letv.android.permissionautoboot"
);
default
:
//其他
intent
.
setAction
(
"android.settings.APPLICATION_DETAILS_SETTINGS"
);
intent
.
setData
(
Uri
.
fromParts
(
"package"
,
context
.
getPackageName
(),
null
));
break
;
}
intent
.
setComponent
(
componentName
);
return
intent
;
}
}
app/src/main/java/com/wenshu/aiyuebao/call/preference/PreferenceUtil.java
deleted
100644 → 0
View file @
4f306df4
package
com
.
wenshu
.
aiyuebao
.
call
.
preference
;
import
android.net.Uri
;
import
com.wenshu.aiyuebao.common.Constant
;
public
class
PreferenceUtil
{
public
static
final
String
AUTHORITY
=
Constant
.
wenshu_PKG_NAME
;
public
static
final
Uri
URI
=
Uri
.
parse
(
"content://"
+
AUTHORITY
);
}
app/src/main/java/com/wenshu/aiyuebao/call/provider/CallProvider.java
deleted
100644 → 0
View file @
4f306df4
package
com
.
wenshu
.
aiyuebao
.
call
.
provider
;
import
android.content.ContentProvider
;
import
android.content.ContentValues
;
import
android.database.Cursor
;
import
android.database.sqlite.SQLiteDatabase
;
import
android.net.Uri
;
import
android.util.Log
;
import
androidx.annotation.NonNull
;
import
androidx.annotation.Nullable
;
/**
* 初始化数据库
* 作者:孟崔广
*/
public
class
CallProvider
extends
ContentProvider
{
private
static
final
String
TAG
=
"LLL"
;
public
static
final
String
NUMBER
=
"number"
;
public
static
final
String
PATH
=
"path"
;
private
SQLiteDatabase
mDatabase
;
@Override
public
boolean
onCreate
()
{
mDatabase
=
new
DataBaseHelper
(
getContext
()).
getWritableDatabase
();
return
true
;
}
@Nullable
@Override
public
Cursor
query
(
@NonNull
Uri
uri
,
@Nullable
String
[]
projection
,
@Nullable
String
selection
,
@Nullable
String
[]
selectionArgs
,
@Nullable
String
sortOrder
)
{
return
mDatabase
.
query
(
DataBaseHelper
.
USER_TABLE_NAME
,
projection
,
selection
,
selectionArgs
,
sortOrder
,
null
,
null
);
}
@Nullable
@Override
public
String
getType
(
@NonNull
Uri
uri
)
{
return
null
;
}
@Nullable
@Override
public
Uri
insert
(
@NonNull
Uri
uri
,
@Nullable
ContentValues
values
)
{
Log
.
d
(
TAG
,
"values = "
+
values
);
mDatabase
.
insert
(
DataBaseHelper
.
USER_TABLE_NAME
,
null
,
values
);
return
uri
;
}
@Override
public
int
delete
(
@NonNull
Uri
uri
,
@Nullable
String
selection
,
@Nullable
String
[]
selectionArgs
)
{
return
mDatabase
.
delete
(
DataBaseHelper
.
USER_TABLE_NAME
,
selection
,
selectionArgs
);
}
@Override
public
int
update
(
@NonNull
Uri
uri
,
@Nullable
ContentValues
values
,
@Nullable
String
selection
,
@Nullable
String
[]
selectionArgs
)
{
return
0
;
}
}
app/src/main/java/com/wenshu/aiyuebao/call/provider/DataBaseHelper.java
deleted
100644 → 0
View file @
4f306df4
package
com
.
wenshu
.
aiyuebao
.
call
.
provider
;
import
android.content.Context
;
import
android.database.sqlite.SQLiteDatabase
;
import
android.database.sqlite.SQLiteOpenHelper
;
import
android.util.Log
;
public
class
DataBaseHelper
extends
SQLiteOpenHelper
{
private
static
final
String
DATABASE_NAME
=
"call.db"
;
public
static
final
String
USER_TABLE_NAME
=
"video"
;
private
static
final
int
DATABASE_VERSION
=
3
;
public
DataBaseHelper
(
Context
context
)
{
super
(
context
,
DATABASE_NAME
,
null
,
DATABASE_VERSION
);
}
@Override
public
void
onCreate
(
SQLiteDatabase
db
)
{
String
sql
=
"CREATE TABLE IF NOT EXISTS "
+
USER_TABLE_NAME
+
"(_id INTEGER PRIMARY KEY AUTOINCREMENT,"
+
" number TEXT, path TEXT)"
;
Log
.
d
(
"LLL"
,
"sql = "
+
sql
);
db
.
execSQL
(
sql
);
}
@Override
public
void
onUpgrade
(
SQLiteDatabase
db
,
int
oldVersion
,
int
newVersion
)
{
}
}
app/src/main/java/com/wenshu/aiyuebao/call/service/PhoneListenService.java
deleted
100644 → 0
View file @
4f306df4
package
com
.
wenshu
.
aiyuebao
.
call
.
service
;
import
android.app.Notification
;
import
android.app.NotificationChannel
;
import
android.app.NotificationManager
;
import
android.app.PendingIntent
;
import
android.content.Context
;
import
android.content.Intent
;
import
android.os.Build
;
import
android.service.notification.NotificationListenerService
;
import
android.service.notification.StatusBarNotification
;
import
android.util.Log
;
import
com.wenshu.aiyuebao.R
;
import
com.wenshu.aiyuebao.call.callcore.CallCore
;
import
com.wenshu.aiyuebao.call.callcore.SystemCallCore
;
import
com.wenshu.aiyuebao.ui.activitys.MainActivity
;
import
java.util.HashMap
;
import
java.util.Map
;
/**
* 通知核心
* 作者:孟崔广
*/
public
class
PhoneListenService
extends
NotificationListenerService
{
public
static
final
String
TAG
=
"PhoneListenService"
;
private
SystemCallCore
mSystemCallCore
;
private
Map
<
String
,
CallCore
>
mCallCores
=
new
HashMap
<>();
@Override
public
void
onCreate
()
{
super
.
onCreate
();
mSystemCallCore
=
(
SystemCallCore
)
CallCore
.
createCallCore
(
this
,
CallCore
.
SYSTEM_CALL_PKG
);
}
private
Notification
buildNotification
()
{
Intent
intent
=
new
Intent
(
this
,
MainActivity
.
class
);
intent
.
addFlags
(
Intent
.
FLAG_ACTIVITY_NEW_TASK
);
PendingIntent
contentIntent
=
PendingIntent
.
getActivity
(
this
,
0
,
intent
,
PendingIntent
.
FLAG_UPDATE_CURRENT
);
Notification
notification
;
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
O
)
{
NotificationManager
notificationManager
=
(
NotificationManager
)
getSystemService
(
Context
.
NOTIFICATION_SERVICE
);
if
(
notificationManager
==
null
)
{
return
null
;
}
String
channelId
=
getString
(
R
.
string
.
app_name
);
NotificationChannel
notificationChannel
=
new
NotificationChannel
(
channelId
,
channelId
,
NotificationManager
.
IMPORTANCE_DEFAULT
);
notificationChannel
.
setDescription
(
channelId
);
notificationChannel
.
setSound
(
null
,
null
);
notificationManager
.
createNotificationChannel
(
notificationChannel
);
notification
=
new
Notification
.
Builder
(
this
,
channelId
)
.
setContentTitle
(
getString
(
R
.
string
.
app_name
))
.
setContentText
(
"来电秀"
)
.
setSmallIcon
(
R
.
mipmap
.
ic_launcher_main
)
.
setContentIntent
(
contentIntent
)
.
build
();
}
else
{
notification
=
new
Notification
.
Builder
(
this
)
.
setContentTitle
(
getString
(
R
.
string
.
app_name
))
.
setContentText
(
"来电秀"
)
.
setSmallIcon
(
R
.
mipmap
.
ic_launcher_main
)
.
setContentIntent
(
contentIntent
)
.
build
();
}
return
notification
;
}
@Override
public
void
onNotificationPosted
(
StatusBarNotification
sbn
)
{
super
.
onNotificationPosted
(
sbn
);
if
(
sbn
==
null
)
{
return
;
}
if
(
mSystemCallCore
.
isCall
(
sbn
))
{
mSystemCallCore
.
onNotificationPosted
(
sbn
.
getNotification
());
}
CallCore
callCore
;
if
(
mCallCores
.
containsKey
(
sbn
.
getPackageName
()))
{
callCore
=
mCallCores
.
get
(
sbn
.
getPackageName
());
}
else
{
callCore
=
CallCore
.
createCallCore
(
this
,
sbn
.
getPackageName
());
if
(
callCore
!=
null
)
{
mCallCores
.
put
(
callCore
.
getPackage
(),
callCore
);
}
}
if
(
callCore
!=
null
)
{
callCore
.
onNotificationPosted
(
sbn
.
getNotification
());
}
}
@Override
public
void
onNotificationRemoved
(
StatusBarNotification
sbn
)
{
super
.
onNotificationRemoved
(
sbn
);
CallCore
callCore
=
mCallCores
.
get
(
sbn
.
getPackageName
());
if
(
callCore
!=
null
)
{
callCore
.
onNotificationRemoved
(
sbn
.
getNotification
());
}
}
@Override
public
void
onListenerConnected
()
{
Log
.
d
(
TAG
,
getClass
().
getSimpleName
()
+
": onListenerConnected"
);
super
.
onListenerConnected
();
}
@Override
public
void
onListenerDisconnected
()
{
Log
.
d
(
TAG
,
getClass
().
getSimpleName
()
+
": onListenerDisconnected"
);
super
.
onListenerDisconnected
();
}
@Override
public
void
onDestroy
()
{
Log
.
d
(
TAG
,
getClass
().
getSimpleName
()
+
": onDestroy"
);
mSystemCallCore
.
onDestroy
();
super
.
onDestroy
();
}
}
app/src/main/java/com/wenshu/aiyuebao/call/util/DimensionUtil.java
deleted
100644 → 0
View file @
4f306df4
package
com
.
wenshu
.
aiyuebao
.
call
.
util
;
import
android.content.Context
;
public
class
DimensionUtil
{
/**
* 根据手机的分辨率从 dp 的单位 转成为 px(像素)
*/
public
static
int
dip2px
(
Context
context
,
float
dpValue
)
{
final
float
scale
=
context
.
getResources
().
getDisplayMetrics
().
density
;
return
(
int
)
(
dpValue
*
scale
+
0.5f
);
}
/**
* 根据手机的分辨率从 px(像素) 的单位 转成为 dp
*/
public
static
int
px2dip
(
Context
context
,
float
pxValue
)
{
final
float
scale
=
context
.
getResources
().
getDisplayMetrics
().
density
;
return
(
int
)
(
pxValue
/
scale
+
0.5f
);
}
/**
* 根据手机的分辨率从 sp 的单位 转成为 px(像素)
*/
public
static
int
sp2px
(
Context
context
,
float
spValue
)
{
final
float
fontScale
=
context
.
getResources
().
getDisplayMetrics
().
scaledDensity
;
return
(
int
)
(
spValue
*
fontScale
+
0.5f
);
}
}
app/src/main/java/com/wenshu/aiyuebao/call/widget/CircleTextView.java
deleted
100644 → 0
View file @
4f306df4
package
com
.
wenshu
.
aiyuebao
.
call
.
widget
;
import
android.content.Context
;
import
android.content.res.TypedArray
;
import
android.graphics.Canvas
;
import
android.graphics.Color
;
import
android.graphics.Paint
;
import
android.text.TextPaint
;
import
android.util.AttributeSet
;
import
android.view.View
;
import
android.view.ViewGroup
;
import
com.wenshu.aiyuebao.R
;
import
com.wenshu.aiyuebao.call.util.DimensionUtil
;
public
class
CircleTextView
extends
View
{
private
String
mCustomText
;
private
int
mCustomColor
;
private
int
mCustomRadius
;
private
int
mFontSize
;
private
Paint
mCirclePaint
;
private
TextPaint
mTextPaint
;
public
CircleTextView
(
Context
context
)
{
this
(
context
,
null
);
}
public
CircleTextView
(
Context
context
,
AttributeSet
attrs
)
{
this
(
context
,
attrs
,
0
);
}
public
CircleTextView
(
Context
context
,
AttributeSet
attrs
,
int
defStyleAttr
)
{
super
(
context
,
attrs
,
defStyleAttr
);
initCustomAttrs
(
context
,
attrs
);
}
private
void
initCustomAttrs
(
Context
context
,
AttributeSet
attrs
)
{
TypedArray
ta
=
context
.
obtainStyledAttributes
(
attrs
,
R
.
styleable
.
CircleTextView
);
mFontSize
=
DimensionUtil
.
sp2px
(
context
,
ta
.
getInteger
(
R
.
styleable
.
CircleTextView_size
,
16
));
mCustomText
=
ta
.
getString
(
R
.
styleable
.
CircleTextView_text
);
mCustomColor
=
ta
.
getColor
(
R
.
styleable
.
CircleTextView_color
,
Color
.
BLUE
);
mCustomRadius
=
DimensionUtil
.
dip2px
(
context
,
ta
.
getInteger
(
R
.
styleable
.
CircleTextView_radius
,
30
));
ta
.
recycle
();
mCirclePaint
=
new
Paint
();
mCirclePaint
.
setColor
(
mCustomColor
);
mCirclePaint
.
setStyle
(
Paint
.
Style
.
STROKE
);
mCirclePaint
.
setStrokeWidth
(
2
);
mTextPaint
=
new
TextPaint
();
mTextPaint
.
setColor
(
mCustomColor
);
mTextPaint
.
setTextSize
(
mFontSize
);
}
@Override
protected
void
onMeasure
(
int
widthMeasureSpec
,
int
heightMeasureSpec
)
{
super
.
onMeasure
(
widthMeasureSpec
,
heightMeasureSpec
);
int
widthSpecSize
=
MeasureSpec
.
getSize
(
widthMeasureSpec
);
int
heightSpecSize
=
MeasureSpec
.
getSize
(
heightMeasureSpec
);
// 在wrap_content的情况下默认长度为200
int
minSize
=
100
;
// 当布局参数设置为wrap_content时,设置默认值
if
(
getLayoutParams
().
width
==
ViewGroup
.
LayoutParams
.
WRAP_CONTENT
&&
getLayoutParams
().
height
==
ViewGroup
.
LayoutParams
.
WRAP_CONTENT
)
{
setMeasuredDimension
(
minSize
,
minSize
);
// 宽 / 高任意一个布局参数为= wrap_content时,都设置默认值
}
else
if
(
getLayoutParams
().
width
==
ViewGroup
.
LayoutParams
.
WRAP_CONTENT
)
{
setMeasuredDimension
(
minSize
,
heightSpecSize
);
}
else
if
(
getLayoutParams
().
height
==
ViewGroup
.
LayoutParams
.
WRAP_CONTENT
)
{
setMeasuredDimension
(
widthSpecSize
,
minSize
);
}
}
@Override
protected
void
onDraw
(
Canvas
canvas
)
{
super
.
onDraw
(
canvas
);
// 处理padding属性
final
int
paddingLeft
=
getPaddingLeft
();
final
int
paddingTop
=
getPaddingTop
();
final
int
paddingRight
=
getPaddingRight
();
final
int
paddingBottom
=
getPaddingBottom
();
int
width
=
2
*
mCustomRadius
-
paddingLeft
-
paddingRight
;
int
height
=
2
*
mCustomRadius
-
paddingTop
-
paddingBottom
;
mCustomRadius
=
Math
.
min
(
width
,
height
)
/
2
;
canvas
.
drawCircle
(
width
/
2
,
height
/
2
,
mCustomRadius
,
mCirclePaint
);
// 将坐标原点移到控件中心
canvas
.
translate
(
width
/
2
f
,
height
/
2
f
);
float
textWidth
=
mTextPaint
.
measureText
(
mCustomText
);
// 文字baseline在y轴方向的位置
float
baseLineY
=
Math
.
abs
(
mTextPaint
.
ascent
()
+
mTextPaint
.
descent
())
/
2
;
canvas
.
drawText
(
mCustomText
,
-
textWidth
/
2
,
baseLineY
,
mTextPaint
);
}
}
app/src/main/java/com/wenshu/aiyuebao/call/widget/CustomVideoView.java
deleted
100644 → 0
View file @
4f306df4
package
com
.
wenshu
.
aiyuebao
.
call
.
widget
;
import
android.content.Context
;
import
android.util.AttributeSet
;
import
android.widget.VideoView
;
public
class
CustomVideoView
extends
VideoView
{
public
CustomVideoView
(
Context
context
)
{
super
(
context
);
}
public
CustomVideoView
(
Context
context
,
AttributeSet
attrs
)
{
super
(
context
,
attrs
);
}
public
CustomVideoView
(
Context
context
,
AttributeSet
attrs
,
int
defStyleAttr
)
{
super
(
context
,
attrs
,
defStyleAttr
);
}
@Override
protected
void
onMeasure
(
int
widthMeasureSpec
,
int
heightMeasureSpec
)
{
int
width
=
getDefaultSize
(
0
,
widthMeasureSpec
);
int
height
=
getDefaultSize
(
0
,
heightMeasureSpec
);
setMeasuredDimension
(
width
,
height
);
}
}
app/src/main/java/com/wenshu/aiyuebao/call/widget/FloatingView.java
deleted
100644 → 0
View file @
4f306df4
package
com
.
wenshu
.
aiyuebao
.
call
.
widget
;
import
android.content.Context
;
import
android.graphics.drawable.Drawable
;
import
android.os.Build
;
import
android.text.TextUtils
;
import
android.view.LayoutInflater
;
import
android.view.View
;
import
android.view.WindowManager
;
import
android.widget.FrameLayout
;
import
android.widget.ImageView
;
import
android.widget.TextView
;
import
android.widget.VideoView
;
import
com.wenshu.aiyuebao.R
;
import
com.wenshu.aiyuebao.call.business.VideoDBHelper
;
public
class
FloatingView
extends
FrameLayout
{
private
Context
mContext
;
private
WindowManager
mWindowManager
;
private
View
mView
;
private
VideoView
mVideoView
;
private
LockSlidingView
mAcceptView
;
private
LockSlidingView
mEndCallView
;
private
TextView
mNameView
;
private
TextView
mNumberView
;
private
ImageView
mHeadView
;
private
OnCallListener
mListener
;
private
boolean
mShown
=
false
;
public
FloatingView
(
Context
context
)
{
super
(
context
);
mContext
=
context
;
mView
=
LayoutInflater
.
from
(
context
).
inflate
(
R
.
layout
.
floating_view
,
null
);
mAcceptView
=
mView
.
findViewById
(
R
.
id
.
get_call
);
mEndCallView
=
mView
.
findViewById
(
R
.
id
.
end_call
);
mNameView
=
mView
.
findViewById
(
R
.
id
.
name_tv
);
mNumberView
=
mView
.
findViewById
(
R
.
id
.
number_tv
);
mHeadView
=
mView
.
findViewById
(
R
.
id
.
head_icon
);
mAcceptView
.
setListener
(()
->
{
hide
();
if
(
mListener
!=
null
)
{
mListener
.
onGet
();
}
});
mAcceptView
.
setOnSingleTapListener
(
e
->
{
hide
();
if
(
mListener
!=
null
)
{
mListener
.
onGet
();
}
});
mEndCallView
.
setListener
(()
->
{
hide
();
if
(
mListener
!=
null
)
{
mListener
.
onEnd
();
}
});
mEndCallView
.
setOnSingleTapListener
(
e
->
{
hide
();
if
(
mListener
!=
null
)
{
mListener
.
onEnd
();
}
});
mWindowManager
=
(
WindowManager
)
mContext
.
getSystemService
(
Context
.
WINDOW_SERVICE
);
mVideoView
=
mView
.
findViewById
(
R
.
id
.
video_view
);
mVideoView
.
setOnPreparedListener
(
mp
->
{
mp
.
start
();
mp
.
setLooping
(
true
);
});
}
public
void
setPerson
(
String
name
,
String
number
)
{
if
(!
TextUtils
.
isEmpty
(
name
))
{
mNameView
.
setText
(
name
);
}
if
(!
TextUtils
.
isEmpty
(
number
))
{
mNumberView
.
setText
(
number
);
}
}
public
void
setHead
(
Drawable
drawable
)
{
if
(
drawable
!=
null
)
{
mHeadView
.
setImageDrawable
(
drawable
);
}
}
public
void
setListener
(
OnCallListener
listener
)
{
this
.
mListener
=
listener
;
}
public
void
show
(
String
number
)
{
// if (!TextUtils.isEmpty(number)) {
// mNameView.setText(number);
// }
mVideoView
.
setVideoPath
(
VideoDBHelper
.
getInstance
().
getSelectVideo
(
mContext
,
number
));
mAcceptView
.
setVisible
();
mEndCallView
.
setVisible
();
WindowManager
.
LayoutParams
params
=
new
WindowManager
.
LayoutParams
();
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
O
)
{
params
.
type
=
WindowManager
.
LayoutParams
.
TYPE_APPLICATION_OVERLAY
;
}
else
{
params
.
type
=
WindowManager
.
LayoutParams
.
TYPE_SYSTEM_OVERLAY
;
}
params
.
flags
=
WindowManager
.
LayoutParams
.
FLAG_NOT_FOCUSABLE
|
WindowManager
.
LayoutParams
.
FLAG_LAYOUT_NO_LIMITS
|
WindowManager
.
LayoutParams
.
FLAG_LAYOUT_IN_SCREEN
|
WindowManager
.
LayoutParams
.
FLAG_NOT_TOUCH_MODAL
|
WindowManager
.
LayoutParams
.
FLAG_SHOW_WHEN_LOCKED
;
params
.
width
=
LayoutParams
.
MATCH_PARENT
;
params
.
height
=
LayoutParams
.
MATCH_PARENT
;
try
{
mWindowManager
.
addView
(
mView
,
params
);
}
catch
(
Exception
e
)
{
}
mShown
=
true
;
mVideoView
.
start
();
}
public
void
hide
()
{
if
(
mShown
)
{
try
{
mWindowManager
.
removeView
(
mView
);
mShown
=
false
;
mNameView
.
setText
(
""
);
mNumberView
.
setText
(
""
);
mHeadView
.
setImageDrawable
(
null
);
mVideoView
.
pause
();
}
catch
(
Exception
e
)
{
}
}
}
public
interface
OnCallListener
{
void
onGet
();
void
onEnd
();
}
}
app/src/main/java/com/wenshu/aiyuebao/call/widget/LockGuideView.java
deleted
100644 → 0
View file @
4f306df4
package
com
.
wenshu
.
aiyuebao
.
call
.
widget
;
import
android.content.Context
;
import
android.os.Build
;
import
android.view.LayoutInflater
;
import
android.view.View
;
import
android.view.WindowManager
;
import
com.wenshu.aiyuebao.R
;
import
com.wenshu.aiyuebao.call.permission.PermissionUtil
;
public
class
LockGuideView
{
private
View
mView
;
private
WindowManager
mWindowManager
;
private
boolean
mShown
=
false
;
public
LockGuideView
(
Context
context
)
{
mView
=
LayoutInflater
.
from
(
context
).
inflate
(
R
.
layout
.
float_lock_guide
,
null
);
mView
.
findViewById
(
R
.
id
.
close
).
setOnClickListener
(
v
->
hide
());
mView
.
findViewById
(
R
.
id
.
go_open
).
setOnClickListener
(
v
->
{
hide
();
PermissionUtil
.
jumpPermissionPage
(
context
);
});
mWindowManager
=
(
WindowManager
)
context
.
getSystemService
(
Context
.
WINDOW_SERVICE
);
}
public
void
show
()
{
WindowManager
.
LayoutParams
params
=
new
WindowManager
.
LayoutParams
();
if
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
O
)
{
params
.
type
=
WindowManager
.
LayoutParams
.
TYPE_APPLICATION_OVERLAY
;
}
else
{
params
.
type
=
WindowManager
.
LayoutParams
.
TYPE_SYSTEM_OVERLAY
;
}
params
.
flags
=
WindowManager
.
LayoutParams
.
FLAG_NOT_FOCUSABLE
|
WindowManager
.
LayoutParams
.
FLAG_LAYOUT_NO_LIMITS
|
WindowManager
.
LayoutParams
.
FLAG_LAYOUT_IN_SCREEN
|
WindowManager
.
LayoutParams
.
FLAG_NOT_TOUCH_MODAL
|
WindowManager
.
LayoutParams
.
FLAG_SHOW_WHEN_LOCKED
;
params
.
width
=
WindowManager
.
LayoutParams
.
WRAP_CONTENT
;
params
.
height
=
WindowManager
.
LayoutParams
.
WRAP_CONTENT
;
try
{
mWindowManager
.
addView
(
mView
,
params
);
mShown
=
true
;
}
catch
(
Exception
e
)
{
}
}
public
void
hide
()
{
if
(
mShown
)
{
try
{
mWindowManager
.
removeView
(
mView
);
mShown
=
false
;
}
catch
(
Exception
e
)
{
}
}
}
}
app/src/main/java/com/wenshu/aiyuebao/call/widget/LockSlidingView.java
deleted
100644 → 0
View file @
4f306df4
package
com
.
wenshu
.
aiyuebao
.
call
.
widget
;
import
android.content.Context
;
import
android.util.AttributeSet
;
import
android.util.Log
;
import
android.view.GestureDetector
;
import
android.view.MotionEvent
;
public
class
LockSlidingView
extends
SlidingFinishView
{
private
static
final
String
TAG
=
"LockSlidingView"
;
private
GestureDetector
mGestureDetector
;
private
OnSingleTapListener
mOnSingleTapListener
;
public
LockSlidingView
(
Context
context
)
{
super
(
context
);
}
public
LockSlidingView
(
Context
context
,
AttributeSet
attrs
)
{
super
(
context
,
attrs
);
}
public
LockSlidingView
(
Context
context
,
AttributeSet
attrs
,
int
defStyleAttr
)
{
super
(
context
,
attrs
,
defStyleAttr
);
}
protected
void
init
(
Context
context
)
{
super
.
init
(
context
);
mGestureDetector
=
new
GestureDetector
(
context
,
new
GestureDetector
.
SimpleOnGestureListener
()
{
@Override
public
boolean
onSingleTapConfirmed
(
MotionEvent
e
)
{
Log
.
d
(
TAG
,
"onSingleTapConfirmed()"
);
if
(
mOnSingleTapListener
!=
null
)
{
mOnSingleTapListener
.
onSingleTapConfirmed
(
e
);
return
true
;
}
return
false
;
}
});
}
@Override
public
boolean
onTouchEvent
(
MotionEvent
event
)
{
mGestureDetector
.
onTouchEvent
(
event
);
return
super
.
onTouchEvent
(
event
);
}
public
void
setOnSingleTapListener
(
OnSingleTapListener
onSingleTapListener
)
{
this
.
mOnSingleTapListener
=
onSingleTapListener
;
}
public
interface
OnSingleTapListener
{
void
onSingleTapConfirmed
(
MotionEvent
e
);
}
}
app/src/main/java/com/wenshu/aiyuebao/call/widget/SlidingFinishView.java
deleted
100644 → 0
View file @
4f306df4
package
com
.
wenshu
.
aiyuebao
.
call
.
widget
;
import
android.animation.Animator
;
import
android.animation.AnimatorListenerAdapter
;
import
android.animation.ObjectAnimator
;
import
android.content.Context
;
import
android.util.AttributeSet
;
import
android.util.DisplayMetrics
;
import
android.util.Log
;
import
android.view.MotionEvent
;
import
android.view.VelocityTracker
;
import
android.view.View
;
import
android.view.ViewConfiguration
;
import
android.widget.RelativeLayout
;
public
class
SlidingFinishView
extends
RelativeLayout
{
private
static
final
String
TAG
=
"SlidingFinishView"
;
private
VelocityTracker
mVelocityTracker
;
private
float
mDownY
;
private
static
final
int
MAX_VELOCITY_DP
=
150
;
private
static
final
int
MIN_FINISH_DIS_DP
=
80
;
private
View
mMoveView
;
private
int
mScreenHeight
;
private
Listener
mListener
;
private
boolean
mIsAnimation
;
private
float
mDensity
;
private
int
mMaxVelocityPx
;
private
int
mTouchSlop
;
public
SlidingFinishView
(
Context
context
)
{
super
(
context
);
init
(
context
);
}
public
SlidingFinishView
(
Context
context
,
AttributeSet
attrs
)
{
super
(
context
,
attrs
);
init
(
context
);
}
public
SlidingFinishView
(
Context
context
,
AttributeSet
attrs
,
int
defStyleAttr
)
{
super
(
context
,
attrs
,
defStyleAttr
);
init
(
context
);
}
protected
void
init
(
Context
context
)
{
DisplayMetrics
displayMetrics
=
context
.
getResources
().
getDisplayMetrics
();
mScreenHeight
=
displayMetrics
.
heightPixels
;
mDensity
=
displayMetrics
.
density
;
mMaxVelocityPx
=
(
int
)
(
MAX_VELOCITY_DP
*
mDensity
);
ViewConfiguration
viewConfiguration
=
ViewConfiguration
.
get
(
context
);
mTouchSlop
=
viewConfiguration
.
getScaledTouchSlop
();
}
public
void
setMoveView
(
View
moveView
)
{
mMoveView
=
moveView
;
}
public
void
setListener
(
Listener
listener
)
{
mListener
=
listener
;
}
@Override
public
boolean
onTouchEvent
(
MotionEvent
event
)
{
if
(
mIsAnimation
)
{
return
super
.
onTouchEvent
(
event
);
}
final
float
y
=
event
.
getRawY
();
switch
(
event
.
getAction
()
&
MotionEvent
.
ACTION_MASK
)
{
case
MotionEvent
.
ACTION_DOWN
:
if
(
mVelocityTracker
==
null
)
{
mVelocityTracker
=
VelocityTracker
.
obtain
();
}
else
{
mVelocityTracker
.
clear
();
}
mVelocityTracker
.
addMovement
(
event
);
mDownY
=
y
;
break
;
case
MotionEvent
.
ACTION_MOVE
:
if
(
mVelocityTracker
!=
null
)
{
mVelocityTracker
.
addMovement
(
event
);
}
handleMoveView
(
y
);
break
;
case
MotionEvent
.
ACTION_UP
:
final
VelocityTracker
velocityTracker
=
mVelocityTracker
;
velocityTracker
.
addMovement
(
event
);
velocityTracker
.
computeCurrentVelocity
(
1000
);
int
velocityY
=
(
int
)
velocityTracker
.
getYVelocity
();
velocityTracker
.
clear
();
doTriggerEvent
(
y
,
velocityY
);
break
;
}
return
true
;
}
private
void
handleMoveView
(
float
y
)
{
float
disY
=
y
-
mDownY
;
if
(
disY
>
0
)
{
disY
=
0
;
}
Log
.
d
(
TAG
,
"handleMoveView--disY="
+
disY
);
getMoveView
().
setTranslationY
(
disY
);
}
private
View
getMoveView
()
{
if
(
mMoveView
==
null
)
{
return
this
;
}
return
mMoveView
;
}
private
void
doTriggerEvent
(
float
y
,
int
velocityY
)
{
float
moveY
=
y
-
mDownY
;
//moveY小于0,表示向上滑动
Log
.
d
(
TAG
,
"doTriggerEvent--velocityY="
+
velocityY
+
"|moveY="
+
moveY
);
if
(
moveY
>=
0
||
Math
.
abs
(
moveY
)
<
mTouchSlop
)
{
Log
.
d
(
TAG
,
"doTriggerEvent--moveY >= 0 || Math.abs(moveY) < mTouchSlop"
);
return
;
}
if
(-
velocityY
>
mMaxVelocityPx
)
{
moveView
(
0
,
true
);
}
else
if
(-
moveY
>
MIN_FINISH_DIS_DP
*
mDensity
)
{
moveView
(
0
,
true
);
}
else
{
moveView
(
0
,
false
);
}
}
public
void
setVisible
()
{
getMoveView
().
setVisibility
(
VISIBLE
);
}
private
void
moveView
(
float
to
,
final
boolean
exit
)
{
mIsAnimation
=
true
;
if
(
exit
)
{
getMoveView
().
setVisibility
(
INVISIBLE
);
}
ObjectAnimator
animator
=
ObjectAnimator
.
ofFloat
(
getMoveView
(),
View
.
TRANSLATION_Y
,
to
);
int
duration
=
Math
.
min
((
int
)
Math
.
abs
(
getMoveView
().
getTranslationY
()
-
to
)
/
2
,
250
);
Log
.
d
(
TAG
,
"moveView--duration="
+
duration
);
animator
.
setDuration
(
duration
).
start
();
animator
.
addListener
(
new
AnimatorListenerAdapter
()
{
@Override
public
void
onAnimationEnd
(
Animator
animation
)
{
super
.
onAnimationEnd
(
animation
);
mIsAnimation
=
false
;
if
(
exit
)
{
if
(
mVelocityTracker
!=
null
)
{
mVelocityTracker
.
recycle
();
mVelocityTracker
=
null
;
}
if
(
mListener
!=
null
)
{
mListener
.
onSlidingOut
();
}
}
}
});
}
public
interface
Listener
{
void
onSlidingOut
();
}
}
app/src/main/java/com/wenshu/aiyuebao/ui/activitys/KylVideoActivity.kt
deleted
100644 → 0
View file @
4f306df4
package
com.wenshu.aiyuebao.ui.activitys
import
android.Manifest
import
android.media.MediaPlayer
import
android.os.Bundle
import
android.text.TextUtils
import
android.view.View
import
com.downloader.Error
import
com.downloader.OnDownloadListener
import
com.downloader.PRDownloader
import
com.wenshu.aiyuebao.R
import
com.wenshu.aiyuebao.ad.video.VideoAdingManager
import
com.wenshu.aiyuebao.call.business.VideoDBHelper
import
com.wenshu.aiyuebao.call.detail.DetailApplyActivity
import
com.wenshu.aiyuebao.call.permission.PermissionActivity
import
com.wenshu.aiyuebao.call.permission.PermissionManager
import
com.wenshu.aiyuebao.common.Constant
import
com.wenshu.aiyuebao.manager.UserManager
import
com.wenshu.aiyuebao.mvp.model.VideoAdingBean
import
com.wenshu.aiyuebao.mvp.presenters.KylVideoPresenter
import
com.wenshu.aiyuebao.mvp.views.KylVideoView
import
com.wenshu.aiyuebao.ui.activitys.base.BaseActivity
import
com.wenshu.aiyuebao.utils.MD5
import
com.tbruyelle.rxpermissions.RxPermissions
import
com.wenshu.aiyuebao.common.AppConfig
import
kotlinx.android.synthetic.main.activity_kyl_video.*
/**
* 描述:酷音乐视频
* 作者:孟崔广
* 时间:2021/1/4 15:09
*/
class
KylVideoActivity
:
BaseActivity
(),
View
.
OnClickListener
,
KylVideoView
{
companion
object
{
const
val
VIDEO_URL
=
"video_url"
const
val
VIDEO_ID
=
"video_id"
}
private
val
WEB_VEDIO_URL
=
"https://vring.kuyin123.com/friend/94aa83142f7f5c98?videoId="
private
lateinit
var
videoUrl
:
String
private
lateinit
var
videoId
:
String
private
val
kylVideoPresenter
by
lazy
{
KylVideoPresenter
()
}
private
lateinit
var
videoAdingManager
:
VideoAdingManager
private
var
loadVideoFailCount
=
0
private
var
downloadId
:
Int
=
-
1
//vedio下载id
private
var
downloadVedioSucFlag
=
false
// 下载视频成功
private
var
vedioPathName
=
""
override
fun
getContentViewLayoutID
()
=
R
.
layout
.
activity_kyl_video
override
fun
isApplyKitKatTranslucency
()
=
false
override
fun
getBundleExtras
(
extras
:
Bundle
?)
{
super
.
getBundleExtras
(
extras
)
extras
?.
let
{
videoUrl
=
it
.
getString
(
VIDEO_URL
,
""
)
videoId
=
it
.
getString
(
VIDEO_ID
,
""
)
}
}
override
fun
initViewsAndEvents
()
{
if
(
TextUtils
.
isEmpty
(
videoUrl
))
{
showToast
(
"加载失败,请稍后重试."
)
finish
()
return
}
videoAdingManager
=
VideoAdingManager
.
getInstance
(
this
)
initListener
()
loadVedio
(
videoUrl
)
}
private
fun
loadVedio
(
vedioUrl
:
String
)
{
cvvVedio
.
setOnPreparedListener
{
mp
:
MediaPlayer
->
mp
.
start
()
mp
.
isLooping
=
true
}
cvvVedio
?.
setVideoPath
(
vedioUrl
)
cvvVedio
?.
start
()
}
override
fun
onResume
()
{
super
.
onResume
()
cvvVedio
.
resume
()
}
override
fun
onPause
()
{
super
.
onPause
()
cvvVedio
.
pause
()
}
override
fun
onDestroy
()
{
super
.
onDestroy
()
if
(
downloadId
!=
-
1
)
{
PRDownloader
.
cancel
(
downloadId
)
}
videoAdingManager
.
setVideoAdingListener
(
null
)
videoAdingManager
.
onDestroy
()
kylVideoPresenter
.
detachView
()
}
override
fun
onClick
(
v
:
View
?)
{
when
(
v
?.
id
)
{
R
.
id
.
ivBack
->
finish
()
R
.
id
.
ivVedio
->
{
val
bundle
=
Bundle
()
bundle
.
putString
(
WebActivity
.
WEB_TITLE
,
"视频彩铃"
)
bundle
.
putString
(
WebActivity
.
WEB_URL
,
WEB_VEDIO_URL
+
videoId
)
readyGo
(
WebActivity
::
class
.
java
,
bundle
)
}
R
.
id
.
ivSetting
->
{
if
(
downloadVedioSucFlag
)
{
readyGo
()
return
}
RxPermissions
(
this
)
.
request
(
Manifest
.
permission
.
READ_EXTERNAL_STORAGE
,
Manifest
.
permission
.
WRITE_EXTERNAL_STORAGE
)
.
subscribe
{
granted
:
Boolean
->
if
(
granted
)
{
downloadVedioToCacheFile
()
awardVideo
()
}
else
{
showMissingPermissionDialog
(
"存储"
)
}
}
}
}
}
private
fun
downloadVedioToCacheFile
()
{
downloadVedioSucFlag
=
false
var
vedioPath
=
""
try
{
vedioPath
=
getExternalFilesDir
(
null
)
!!
.
absolutePath
+
"/video/"
}
catch
(
e
:
java
.
lang
.
Exception
)
{
vedioPath
=
filesDir
.
absolutePath
+
"/video/"
}
val
vedioName
=
MD5
.
GetMD5Code
(
System
.
currentTimeMillis
().
toString
()
+
UserManager
.
getInstance
().
userID
+
videoUrl
)
+
".mp4"
vedioPathName
=
vedioPath
+
vedioName
downloadId
=
PRDownloader
.
download
(
videoUrl
,
vedioPath
,
vedioName
)
.
build
()
.
start
(
object
:
OnDownloadListener
{
override
fun
onDownloadComplete
()
{
downloadVedioSucFlag
=
true
}
override
fun
onError
(
error
:
Error
)
{
}
})
}
private
fun
initListener
()
{
ivBack
.
setOnClickListener
(
this
)
ivSetting
.
setOnClickListener
(
this
)
ivVedio
.
setOnClickListener
(
this
)
}
/**
* 获取激励视频
*/
private
fun
awardVideo
()
{
if
(
AppConfig
.
isVideoSleep
)
{
showToast
(
"加载失败,请稍后重试。"
)
return
}
else
if
(
videoAdingManager
.
videoFinishFlag
)
{
showToast
(
"今日视频已看完,请明天再来吧"
)
return
}
loadVideoFailCount
=
0
showLoading
(
"加载中..."
)
val
bean
=
VideoAdingBean
()
bean
.
carrierType
=
Constant
.
CARRIER_KUYINYUE_VEDIO
loadVideo
(
videoAdingManager
,
bean
,
true
)
}
/**
* 加载激励视频
*/
private
fun
loadVideo
(
videoAdingManager
:
VideoAdingManager
,
bean
:
VideoAdingBean
,
isFirstLoad
:
Boolean
)
{
videoAdingManager
.
setVideoAdingListener
(
object
:
VideoAdingManager
.
VideoAdingListener
{
override
fun
videoAdingListenerError
(
adType
:
String
)
{
showToast
(
"加载超时,请休息一下"
)
hideLoading
()
}
override
fun
videoAdingListenerFail
(
adType
:
String
)
{
loadVideoFailCount
++
if
(
loadVideoFailCount
>=
3
)
{
hideLoading
()
showToast
(
"加载失败,请稍后重试!"
)
}
else
{
loadVideo
(
videoAdingManager
,
bean
,
false
)
}
}
override
fun
videoAdingListenerSuccess
(
adType
:
String
)
{
hideLoading
()
vedioAdingSuccess
(
adType
)
}
})
if
(
isFirstLoad
)
{
// 首页按权重加载
videoAdingManager
.
loadAding
(
this
,
bean
)
}
else
{
// 失败按优先级加载
videoAdingManager
.
loadFailAding
(
this
,
bean
)
}
}
private
fun
vedioAdingSuccess
(
adType
:
String
)
{
if
(!
downloadVedioSucFlag
||
TextUtils
.
isEmpty
(
vedioPathName
))
{
showToast
(
"视频处理中,请稍候"
)
return
}
readyGo
()
}
private
fun
readyGo
()
{
if
(
PermissionManager
.
getInstance
().
checkEssential
(
this
))
{
VideoDBHelper
.
getInstance
().
setSelectVideo
(
this
,
VideoDBHelper
.
UNKNOWN_NUMBER
,
vedioPathName
)
DetailApplyActivity
.
startSelf
(
this
,
vedioPathName
,
true
)
}
else
{
PermissionActivity
.
startSelf
(
this
)
}
}
}
app/src/main/java/com/wenshu/aiyuebao/ui/fragment/KuYinYuePageFragment.kt
View file @
e42dcad0
package
com.wenshu.aiyuebao.ui.fragment
import
android.os.Bundle
import
androidx.recyclerview.widget.GridLayoutManager
import
com.bytedance.sdk.openadsdk.*
import
com.scwang.smartrefresh.layout.api.RefreshLayout
import
com.scwang.smartrefresh.layout.listener.OnLoadMoreListener
import
com.scwang.smartrefresh.layout.listener.OnRefreshListener
import
com.wenshu.aiyuebao.R
import
com.wenshu.aiyuebao.manager.TtCsjAdManager
import
com.wenshu.aiyuebao.mvp.model.KylBean
import
com.wenshu.aiyuebao.mvp.presenters.KuYinYuePagePresenter
import
com.wenshu.aiyuebao.mvp.views.KuYinYuePageView
import
com.wenshu.aiyuebao.ui.activitys.KylVideoActivity
import
com.wenshu.aiyuebao.ui.adapter.KylPageAdapter
import
com.wenshu.aiyuebao.ui.fragment.base.LazyLoadBaseFragment
import
com.wenshu.aiyuebao.utils.LogUtil
import
com.scwang.smartrefresh.layout.api.RefreshLayout
import
com.scwang.smartrefresh.layout.listener.OnLoadMoreListener
import
com.scwang.smartrefresh.layout.listener.OnRefreshListener
import
kotlinx.android.synthetic.main.fragment_main_kyl_page.*
/**
...
...
@@ -63,10 +61,10 @@ class KuYinYuePageFragment(private val targetid: String) : LazyLoadBaseFragment(
override
fun
onItemClick
(
position
:
Int
)
{
if
(
kylData
!=
null
&&
kylData
.
size
>
0
)
{
val
bundle
=
Bundle
()
bundle
.
putString
(
KylVideoActivity
.
VIDEO_URL
,
kylData
[
position
].
url
)
bundle
.
putString
(
KylVideoActivity
.
VIDEO_ID
,
kylData
[
position
].
vedioId
)
readyGo
(
KylVideoActivity
::
class
.
java
,
bundle
)
//
val bundle = Bundle()
//
bundle.putString(KylVideoActivity.VIDEO_URL, kylData[position].url)
//
bundle.putString(KylVideoActivity.VIDEO_ID, kylData[position].vedioId)
//
readyGo(KylVideoActivity::class.java, bundle)
}
}
...
...
app/src/main/res/layout/activity_kyl_video.xml
deleted
100644 → 0
View file @
4f306df4
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:app=
"http://schemas.android.com/apk/res-auto"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:background=
"@color/black"
>
<com.wenshu.aiyuebao.call.widget.CustomVideoView
android:id=
"@+id/cvvVedio"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
/>
<ImageView
android:id=
"@+id/ivBack"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:layout_marginLeft=
"4dp"
android:layout_marginTop=
"14dp"
android:padding=
"20dp"
android:src=
"@mipmap/ic_left_arrow"
app:layout_constraintLeft_toLeftOf=
"parent"
app:layout_constraintTop_toTopOf=
"parent"
/>
<TextView
android:id=
"@+id/ivVedio"
android:layout_width=
"match_parent"
android:layout_height=
"40dp"
android:layout_alignParentBottom=
"true"
android:layout_marginLeft=
"50dp"
android:layout_marginRight=
"50dp"
android:background=
"@drawable/shape_tv_gold"
android:gravity=
"center"
android:text=
"设置视频彩铃"
android:layout_marginBottom=
"100dp"
app:layout_constraintBottom_toBottomOf=
"parent"
android:textColor=
"@color/white"
/>
<TextView
android:id=
"@+id/ivSetting"
android:layout_width=
"match_parent"
android:layout_height=
"40dp"
android:layout_alignParentBottom=
"true"
android:layout_marginLeft=
"50dp"
android:layout_marginRight=
"50dp"
android:background=
"@drawable/shape_tv_gold"
android:gravity=
"center"
android:text=
"看广告设置来电秀"
android:layout_marginBottom=
"40dp"
app:layout_constraintBottom_toBottomOf=
"parent"
android:textColor=
"@color/white"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
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