diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 66fa088..82e83c1 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -24,37 +24,44 @@
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
- android:icon="@mipmap/ic_launcher"
+ android:icon="@mipmap/logo"
android:label="@string/app_name"
- android:roundIcon="@mipmap/ic_launcher_round"
+ android:roundIcon="@mipmap/logo"
android:supportsRtl="true"
android:theme="@style/Theme.RecordScreen"
tools:targetApi="31">
-
-
-
+ android:exported="true" >
+
+
+
+
+
+
+ android:exported="false">
@@ -66,11 +73,19 @@
+ android:screenOrientation="portrait"
+ android:taskAffinity=""
+ android:theme="@style/Theme.Transparent" />
+
(), ConnectionListener,F
private fun bingVp() {
val tabIcons =
- intArrayOf(R.drawable.tab1_selector, R.drawable.tab2_selector, R.drawable.tab3_selector)
+ intArrayOf(R.drawable.tab1_selector, R.drawable.tab2_selector)
binding.run {
viewPager2.isUserInputEnabled = false
viewPager2.adapter = ViewPager2Adapter(this@MainActivity1)
@@ -155,11 +155,8 @@ class MainActivity1 : BaseActivity(), ConnectionListener,F
override fun onTabReselected(tab: TabLayout.Tab?) {
}
-
})
-
}
-
}
private fun showPermissionDialog() {
@@ -213,28 +210,18 @@ class MainActivity1 : BaseActivity(), ConnectionListener,F
this@MainActivity1.moveTaskToBack(true)
}
-
- override fun onServiceConnected() {
- viewModel.updateServiceConnectStatus(true)
- FloatingWindowBridge.registerCallback(this)
-// updateFloatingBtnStatus()
-
- //新开进程的时候检测当前悬浮窗状态,刷新当前各ImageView状态
- FloatingWindowBridge.sendCommand(FloatingWindowBridge.COMMEND_sync_view_status)
-
- }
- /**
- * 新开进程的时候检测当前悬浮窗状态,刷新当前各ImageView状态
- */
- private fun updateFloatingBtnStatus(){
- FloatingWindowBridge.sendCommand(FloatingWindowBridge.COMMEND_sync_view_status)
- }
-
override fun onResume() {
super.onResume()
//初始进程中,在桌面回到Activity的时候更新当前录制状态
FloatingWindowBridge.sendCommand(FloatingWindowBridge.COMMEND_sync_recording_status)
}
+ override fun onServiceConnected() {
+ viewModel.updateServiceConnectStatus(true)
+ FloatingWindowBridge.registerCallback(this)
+ //新开进程的时候检测当前悬浮窗状态,刷新当前各ImageView状态
+ FloatingWindowBridge.sendCommand(FloatingWindowBridge.COMMEND_sync_view_status)
+ FloatingWindowBridge.sendCommand(FloatingWindowBridge.COMMEND_sync_recording_status)
+ }
override fun onRefreshViewShow(
webCamShow: Boolean,
diff --git a/app/src/main/java/com/audio/record/screen/test/activity/ScreenshotAnimActivity.kt b/app/src/main/java/com/audio/record/screen/test/activity/ScreenshotAnimActivity.kt
new file mode 100644
index 0000000..0e33e81
--- /dev/null
+++ b/app/src/main/java/com/audio/record/screen/test/activity/ScreenshotAnimActivity.kt
@@ -0,0 +1,110 @@
+package com.audio.record.screen.test.activity
+
+import android.animation.Animator
+import android.animation.AnimatorSet
+import android.animation.ObjectAnimator
+import android.content.Context
+import android.content.Intent
+import android.graphics.Bitmap
+import android.media.projection.MediaProjectionManager
+import android.os.Bundle
+import android.os.Handler
+import android.os.Looper
+import android.os.PersistableBundle
+import android.view.animation.DecelerateInterpolator
+import android.widget.ImageView
+import android.widget.TextView
+import androidx.activity.result.ActivityResultLauncher
+import androidx.activity.result.contract.ActivityResultContracts
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.view.isVisible
+import com.audio.record.screen.test.R
+import com.audio.record.screen.test.base.BaseActivity
+import com.audio.record.screen.test.databinding.ActivityPlayBinding
+import com.audio.record.screen.test.service.FloatingCallback
+import com.audio.record.screen.test.service.FloatingWindowBridge
+import com.audio.record.screen.test.service.ScreenshotAnimExecutor
+import com.audio.record.screen.test.tool.Common
+import com.audio.record.screen.test.tool.ScreenCaptureHelper
+
+
+/**
+ * Service悬浮窗中请求权限的透明Activity
+ */
+class ScreenshotAnimActivity : AppCompatActivity(), FloatingCallback {
+
+
+ private lateinit var imageView: ImageView
+ private lateinit var tv: TextView
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ Common.setStatusBarTextColor(this, true)
+ setContentView(R.layout.floating_screenshot_anim)
+ Common.showLog("---ScreenshotAnimActivity--onCreate")
+ FloatingWindowBridge.registerCallback(this)
+ imageView = findViewById(R.id.image)
+ tv = findViewById(R.id.tv_content)
+ }
+
+
+ override fun onRefreshBitmap(bitmap: Bitmap) {
+ super.onRefreshBitmap(bitmap)
+ Common.showLog("---ScreenshotAnimActivity--onRefreshBitmap")
+ tv.isVisible = false
+ imageView.setImageBitmap(bitmap)
+
+ val fullScreenSize = Common.getFullScreenSize(this)
+ val screenWidth = fullScreenSize.first
+ val screenHeight = fullScreenSize.second
+
+ val scale = 0.25f
+ val targetX = (screenWidth - screenWidth * scale - 12).toFloat()
+ val targetY = (screenHeight - screenHeight * scale - 14).toFloat()
+
+ // 设置初始位置在中心
+ imageView.translationX = 0f
+ imageView.translationY = 0f
+ imageView.scaleX = 1f
+ imageView.scaleY = 1f
+
+ // 缩放动画
+ val scaleX = ObjectAnimator.ofFloat(imageView, "scaleX", 1f, scale)
+ val scaleY = ObjectAnimator.ofFloat(imageView, "scaleY", 1f, scale)
+
+ // 位移动画(目标点是右下角)
+ val translateX = ObjectAnimator.ofFloat(imageView, "translationX", 0f, targetX - screenWidth / 2f)
+ val translateY = ObjectAnimator.ofFloat(imageView, "translationY", 0f, targetY - screenHeight / 2f)
+
+ val animatorSet = AnimatorSet().apply {
+ playTogether(scaleX, scaleY, translateX, translateY)
+ duration = 600L
+ interpolator = DecelerateInterpolator()
+ addListener(object : Animator.AnimatorListener {
+ override fun onAnimationStart(animation: Animator) {
+ Common.showLog("-----动画开始")
+ }
+
+ override fun onAnimationEnd(animation: Animator) {
+ Common.showLog("-----动画结束")
+ Handler(Looper.getMainLooper()).postDelayed({
+ finish()
+ }, 2000)
+ }
+
+ override fun onAnimationCancel(animation: Animator) {}
+ override fun onAnimationRepeat(animation: Animator) {}
+ })
+ }
+ animatorSet.start()
+
+
+
+ }
+
+ override fun onResume() {
+ super.onResume()
+ Common.showLog("--ScreenshotAnimActivity---onResume")
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/audio/record/screen/test/activity/WelcomeActivity.kt b/app/src/main/java/com/audio/record/screen/test/activity/WelcomeActivity.kt
new file mode 100644
index 0000000..6c59bad
--- /dev/null
+++ b/app/src/main/java/com/audio/record/screen/test/activity/WelcomeActivity.kt
@@ -0,0 +1,48 @@
+package com.audio.record.screen.test.activity
+
+import android.content.Intent
+import androidx.appcompat.app.AppCompatActivity
+import android.os.Bundle
+import android.os.CountDownTimer
+import com.audio.record.screen.test.R
+import com.audio.record.screen.test.base.BaseActivity
+import com.audio.record.screen.test.databinding.ActivityWelcomeBinding
+
+class WelcomeActivity : BaseActivity() {
+ private val total = 2000L
+ private var countDownTimer:CountDownTimer? = null
+ override fun initBinding(): ActivityWelcomeBinding =
+ ActivityWelcomeBinding.inflate(layoutInflater)
+
+ override fun getFullColor(): Boolean = true
+
+ override fun onCreateInit() {
+ countDownTimer =object :CountDownTimer(total, 1000){
+ override fun onTick(millisUntilFinished: Long) {
+
+ }
+
+ override fun onFinish() {
+ toMain()
+ }
+
+ }
+ countDownTimer?.start()
+
+ }
+
+ private fun toMain(){
+ startActivity(Intent(this,MainActivity1::class.java))
+ finish()
+ }
+
+ override fun onInitPadding(): Boolean = false
+
+
+ override fun onDestroy() {
+ super.onDestroy()
+ countDownTimer?.cancel()
+ countDownTimer = null
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/audio/record/screen/test/adapter/ImageGroupAdapter.kt b/app/src/main/java/com/audio/record/screen/test/adapter/ImageGroupAdapter.kt
index 7e85423..2f13a00 100644
--- a/app/src/main/java/com/audio/record/screen/test/adapter/ImageGroupAdapter.kt
+++ b/app/src/main/java/com/audio/record/screen/test/adapter/ImageGroupAdapter.kt
@@ -32,9 +32,18 @@ class ImageGroupAdapter(context: Context, private var click: (cropRatio: String)
adapter = ImageInfoAdapter(mContext, position == 0) {}.apply {
updateData(item.images)
}
- layoutManager = GridLayoutManager(mContext, 3)
+ if (this.layoutManager == null) {
+ layoutManager = GridLayoutManager(mContext, 3)
+ }
isNestedScrollingEnabled = false
- addItemDecoration(GridSpacingItemDecoration(3, 5.dpToPx(mContext), true))
+ setHasFixedSize(false)
+ if (this.itemDecorationCount <= 0) {
+ val gridSpacingItemDecoration =
+ GridSpacingItemDecoration(3, 5.dpToPx(mContext), true)
+ addItemDecoration(gridSpacingItemDecoration)
+ }
+
+
}
}
}
diff --git a/app/src/main/java/com/audio/record/screen/test/adapter/VideoGroupAdapter.kt b/app/src/main/java/com/audio/record/screen/test/adapter/VideoGroupAdapter.kt
index 2c9abb1..0d7527e 100644
--- a/app/src/main/java/com/audio/record/screen/test/adapter/VideoGroupAdapter.kt
+++ b/app/src/main/java/com/audio/record/screen/test/adapter/VideoGroupAdapter.kt
@@ -7,24 +7,27 @@ import androidx.recyclerview.widget.RecyclerView
import com.audio.record.screen.test.base.BaseAdapter
import com.audio.record.screen.test.data.VideoGroup
import com.audio.record.screen.test.databinding.AdapterVideoDateBinding
+import com.audio.record.screen.test.tool.Common
import com.audio.record.screen.test.tool.NoScrollLinearLayoutManager
-class VideoGroupAdapter(context: Context, private var click: (cropRatio:String) -> Unit) :
+class VideoGroupAdapter(context: Context, private var click: (cropRatio: String) -> Unit) :
BaseAdapter(context) {
override fun getViewBinding(parent: ViewGroup?): AdapterVideoDateBinding {
return AdapterVideoDateBinding.inflate(LayoutInflater.from(parent!!.context), parent, false)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
- val itemHolder: VHolder = holder as VHolder
+ val itemHolder: VHolder =
+ holder as VHolder
val item = data[position]
itemHolder.vb.run {
- tvDate.text = item.date
+ tvDate.text = item.date
videoInfoRecycler.run {
- adapter = VideoInfoAdapter(mContext){}.apply {
+ setHasFixedSize(false)
+ adapter = VideoInfoAdapter(mContext, position == data.size - 1) {}.apply {
updateData(item.videos)
}
layoutManager = NoScrollLinearLayoutManager(mContext)
@@ -33,7 +36,6 @@ class VideoGroupAdapter(context: Context, private var click: (cropRatio:String)
}
-
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/audio/record/screen/test/adapter/VideoInfoAdapter.kt b/app/src/main/java/com/audio/record/screen/test/adapter/VideoInfoAdapter.kt
index f55b64d..06471c2 100644
--- a/app/src/main/java/com/audio/record/screen/test/adapter/VideoInfoAdapter.kt
+++ b/app/src/main/java/com/audio/record/screen/test/adapter/VideoInfoAdapter.kt
@@ -4,6 +4,7 @@ import android.content.Context
import android.content.Intent
import android.view.LayoutInflater
import android.view.ViewGroup
+import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import com.audio.record.screen.test.activity.PlayActivity
import com.audio.record.screen.test.base.BaseAdapter
@@ -11,7 +12,11 @@ import com.audio.record.screen.test.data.VideoInfo
import com.audio.record.screen.test.databinding.AdapterVideoInfoBinding
import com.audio.record.screen.test.tool.Common
-class VideoInfoAdapter(context: Context, private var click: (cropRatio: String) -> Unit) :
+class VideoInfoAdapter(
+ context: Context,
+ var isLast: Boolean,
+ private var click: (cropRatio: String) -> Unit
+) :
BaseAdapter(context) {
override fun getViewBinding(parent: ViewGroup?): AdapterVideoInfoBinding {
return AdapterVideoInfoBinding.inflate(LayoutInflater.from(parent!!.context), parent, false)
@@ -22,15 +27,17 @@ class VideoInfoAdapter(context: Context, private var click: (cropRatio: String)
holder as VHolder
val item = data[position]
+
itemHolder.vb.run {
+ space.isVisible = position == data.size - 1 && isLast
image.setImageBitmap(item.thumbnail)
tvName.text = item.displayName
tvTime.text = Common.formatDuration(item.duration)
tvSize.text = Common.formatFileSize(item.size)
root.setOnClickListener {
- mContext.startActivity(Intent(mContext,PlayActivity::class.java).apply {
+ mContext.startActivity(Intent(mContext, PlayActivity::class.java).apply {
putExtra(PlayActivity.KEY_URI, item.uri)
- putExtra(PlayActivity.KEY_name,item.displayName)
+ putExtra(PlayActivity.KEY_name, item.displayName)
})
}
}
diff --git a/app/src/main/java/com/audio/record/screen/test/adapter/ViewPager2Adapter.kt b/app/src/main/java/com/audio/record/screen/test/adapter/ViewPager2Adapter.kt
index e48fa28..15aaa16 100644
--- a/app/src/main/java/com/audio/record/screen/test/adapter/ViewPager2Adapter.kt
+++ b/app/src/main/java/com/audio/record/screen/test/adapter/ViewPager2Adapter.kt
@@ -11,8 +11,7 @@ class ViewPager2Adapter(fragmentActivity: FragmentActivity) :
FragmentStateAdapter(fragmentActivity) {
private val fragments: List = arrayListOf(
MainFragment.newInstance(),
- RecordMainFragment.newInstance(),
- MainFragment.newInstance()
+ RecordMainFragment.newInstance()
)
override fun getItemCount(): Int = fragments.size
diff --git a/app/src/main/java/com/audio/record/screen/test/dialog/DialogPermission.kt b/app/src/main/java/com/audio/record/screen/test/dialog/DialogPermission.kt
index d5992d2..d8f230c 100644
--- a/app/src/main/java/com/audio/record/screen/test/dialog/DialogPermission.kt
+++ b/app/src/main/java/com/audio/record/screen/test/dialog/DialogPermission.kt
@@ -27,7 +27,7 @@ class DialogPermission(private var mClickType: (type: Int) -> Unit) : BottomShee
super.onStart()
val dialog = dialog
if (dialog != null) {
- dialog.setCanceledOnTouchOutside(true)
+ dialog.setCanceledOnTouchOutside(false)
val window = dialog.window
if (window != null) {
window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
diff --git a/app/src/main/java/com/audio/record/screen/test/fragment/child/ImageFragment.kt b/app/src/main/java/com/audio/record/screen/test/fragment/child/ImageFragment.kt
index 421140f..8d92280 100644
--- a/app/src/main/java/com/audio/record/screen/test/fragment/child/ImageFragment.kt
+++ b/app/src/main/java/com/audio/record/screen/test/fragment/child/ImageFragment.kt
@@ -8,12 +8,14 @@ import androidx.core.view.isVisible
import androidx.recyclerview.widget.LinearLayoutManager
import com.audio.record.screen.test.adapter.ImageGroupAdapter
import com.audio.record.screen.test.base.BaseFragment
+import com.audio.record.screen.test.data.ImageGroup
import com.audio.record.screen.test.databinding.FragmentImageBinding
import com.audio.record.screen.test.tool.Common
import com.audio.record.screen.test.tool.VideoFileHelper
class ImageFragment : BaseFragment() {
+ private lateinit var imageGroupAdapter:ImageGroupAdapter
companion object {
@JvmStatic
@@ -30,6 +32,27 @@ class ImageFragment : BaseFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
+
+ imageGroupAdapter = ImageGroupAdapter(requireContext()) {
+ }
+
+ binding.videoRecycler.run {
+ adapter = imageGroupAdapter
+ layoutManager = LinearLayoutManager(requireContext())
+ }
+
+
+ }
+
+ override fun onResume() {
+ super.onResume()
+ getInfo()?.let {
+ imageGroupAdapter.updateData(it)
+ }
+
+ }
+
+ private fun getInfo():List?{
val queryVideoInfoListInFolder =
VideoFileHelper.queryGroupedImagesByDay(requireContext(),Common.imagesFolderDir)
@@ -38,23 +61,13 @@ class ImageFragment : BaseFragment() {
layoutEmpty.isVisible = true
}
Common.showLog("IMag isEmpty()")
- return
+ return null
} else {
binding.run {
layoutEmpty.isVisible = false
}
}
- val imageGroupAdapter = ImageGroupAdapter(requireContext()) {
- }
-
- binding.videoRecycler.run {
- adapter = imageGroupAdapter.apply {
- updateData(queryVideoInfoListInFolder)
- }
- layoutManager = LinearLayoutManager(requireContext())
- }
-
-
+ return queryVideoInfoListInFolder
}
diff --git a/app/src/main/java/com/audio/record/screen/test/fragment/child/VideoFragment.kt b/app/src/main/java/com/audio/record/screen/test/fragment/child/VideoFragment.kt
index 4337444..513fcf6 100644
--- a/app/src/main/java/com/audio/record/screen/test/fragment/child/VideoFragment.kt
+++ b/app/src/main/java/com/audio/record/screen/test/fragment/child/VideoFragment.kt
@@ -17,6 +17,7 @@ import com.audio.record.screen.test.tool.Common
import com.audio.record.screen.test.tool.VideoFileHelper
class VideoFragment : BaseFragment() {
+ private lateinit var videoGroupAdapter:VideoGroupAdapter
companion object {
@JvmStatic
@@ -33,7 +34,24 @@ class VideoFragment : BaseFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
+ videoGroupAdapter = VideoGroupAdapter(requireContext()) {
+ }
+ binding.videoRecycler.run {
+ adapter = videoGroupAdapter
+ layoutManager = LinearLayoutManager(requireContext())
+ }
+ }
+ override fun onResume() {
+ super.onResume()
+ getInfo()?.let {
+ videoGroupAdapter.updateData(it)
+ }
+
+ }
+
+
+ private fun getInfo():MutableList?{
val queryVideoInfoListInFolder =
VideoFileHelper.queryVideoInfoListInFolder(requireContext(),Common.videosFolderDir)
@@ -43,7 +61,7 @@ class VideoFragment : BaseFragment() {
layoutRecent.isVisible = false
}
Common.showLog("queryVideoInfoListInFolder.isEmpty()")
- return
+ return null
} else {
binding.run {
layoutEmpty.isVisible = false
@@ -62,21 +80,9 @@ class VideoFragment : BaseFragment() {
val removeRecent = removeRecent(listOf)
if (removeRecent.isEmpty()||removeRecent[0].videos.isEmpty()) {
Common.showLog("removeRecent.isEmpty()")
- return
+ return null
}
-
-
- val videoGroupAdapter = VideoGroupAdapter(requireContext()) {
- }
-
- binding.videoRecycler.run {
- adapter = videoGroupAdapter.apply {
- updateData(removeRecent)
- }
- layoutManager = LinearLayoutManager(requireContext())
- }
-
-
+ return removeRecent
}
diff --git a/app/src/main/java/com/audio/record/screen/test/service/FloatingCallback.kt b/app/src/main/java/com/audio/record/screen/test/service/FloatingCallback.kt
index 634414e..c9f606b 100644
--- a/app/src/main/java/com/audio/record/screen/test/service/FloatingCallback.kt
+++ b/app/src/main/java/com/audio/record/screen/test/service/FloatingCallback.kt
@@ -1,5 +1,6 @@
package com.audio.record.screen.test.service
+import android.graphics.Bitmap
import androidx.camera.core.processing.SurfaceProcessorNode.In
interface FloatingCallback {
@@ -17,6 +18,6 @@ interface FloatingCallback {
fun onRefreshRecordingStatus(status:Int){}
-
+ fun onRefreshBitmap(bitmap:Bitmap){}
}
diff --git a/app/src/main/java/com/audio/record/screen/test/service/FloatingWindowBridge.kt b/app/src/main/java/com/audio/record/screen/test/service/FloatingWindowBridge.kt
index de2f6a3..bc6d193 100644
--- a/app/src/main/java/com/audio/record/screen/test/service/FloatingWindowBridge.kt
+++ b/app/src/main/java/com/audio/record/screen/test/service/FloatingWindowBridge.kt
@@ -130,8 +130,8 @@ object FloatingWindowBridge {
if (isBound) {
Common.showLog("Service-=======unbindService 1111")
context.unbindService(connection)
- service = null
- mBinder = null
+// service = null
+// mBinder = null
isBound = false
}
}
diff --git a/app/src/main/java/com/audio/record/screen/test/service/RecordState.kt b/app/src/main/java/com/audio/record/screen/test/service/RecordState.kt
deleted file mode 100644
index b61f47b..0000000
--- a/app/src/main/java/com/audio/record/screen/test/service/RecordState.kt
+++ /dev/null
@@ -1,7 +0,0 @@
-package com.audio.record.screen.test.service
-
-
-enum class RecordState {
- DEFAULT,
- RECORDING,
- PAUSE }
\ No newline at end of file
diff --git a/app/src/main/java/com/audio/record/screen/test/service/ScreenRecordService.kt b/app/src/main/java/com/audio/record/screen/test/service/ScreenRecordService.kt
index 2ffe7b4..16d2af2 100644
--- a/app/src/main/java/com/audio/record/screen/test/service/ScreenRecordService.kt
+++ b/app/src/main/java/com/audio/record/screen/test/service/ScreenRecordService.kt
@@ -40,8 +40,10 @@ import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import com.audio.record.screen.test.R
+import com.audio.record.screen.test.activity.MainActivity1
import com.audio.record.screen.test.activity.PlayActivity
import com.audio.record.screen.test.activity.ScreenPermissionActivity
+import com.audio.record.screen.test.activity.ScreenshotAnimActivity
import com.audio.record.screen.test.tool.Common
import com.audio.record.screen.test.tool.ConstValue
import com.audio.record.screen.test.tool.DraggableViewHelper
@@ -78,7 +80,7 @@ class ScreenRecordService : Service() {
private var imRecord: ImageView? = null
private var tvRecordTime: TextView? = null
private var imNoAudioRecord: ImageView? = null
- private var imScreenshot:ImageView? = null
+ private var imScreenshot: ImageView? = null
//截屏View
private var screenshotView: View? = null
@@ -161,10 +163,7 @@ class ScreenRecordService : Service() {
inner class FloatingBinder : Binder() {
fun getService() = this@ScreenRecordService
- fun setCallback(cb: FloatingCallback) {
- callbackRef = cb
- }
fun registerCallback(callback: FloatingCallback) {
// 避免重复添加
@@ -215,13 +214,14 @@ class ScreenRecordService : Service() {
}
ConstValue.type_record_audio -> {
+ Common.showLog("Service--- 录制带音频的视频")
isWithAudio = true
val arrayOf = arrayOf("3", "2", "1")
showCountDownView(arrayOf)
}
ConstValue.type_screenshot -> {
- startScreenshot()
+ startScreenshot(isScreenshotViewAdded)
}
}
ballType = null
@@ -262,11 +262,12 @@ class ScreenRecordService : Service() {
}
return NotificationCompat.Builder(this, channelId)
- .setContentTitle("屏幕录制中")
- .setContentText("正在录制屏幕...")
+ .setContentTitle("")
+ .setContentText("")
+ .setPriority(NotificationCompat.PRIORITY_HIGH)
.setCustomContentView(remoteViews)
.setCustomBigContentView(remoteViews)
- .setSmallIcon(R.drawable.test)
+ .setSmallIcon(R.mipmap.logo)
.build()
}
@@ -274,18 +275,26 @@ class ScreenRecordService : Service() {
/**
* 开始截屏
*/
- private fun startScreenshot(){
+ private fun startScreenshot(showView: Boolean) {
// TODO: 开始截屏
- mIntent?.let { intent->
- mediaProjectionManager.getMediaProjection(mCode, intent)?.let { mediaProjection->
+ mIntent?.let { intent ->
+ mediaProjectionManager.getMediaProjection(mCode, intent)?.let { mediaProjection ->
hideScreenshot()
- ScreenCaptureHelper.startScreenCapture(this, mediaProjection) {
+ val intent = Intent(this, ScreenshotAnimActivity::class.java)
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ startActivity(intent)
+ ScreenCaptureHelper.startScreenCapture(this, mediaProjection) { bit ->
+ callbacks.forEach {
+ it.get()?.onRefreshBitmap(bit)
+ }
//截屏完成
- showScreenshot()
+ if (showView)
+ showScreenshot()
}
}
}
}
+
@SuppressLint("ClickableViewAccessibility")
fun showCameraView() {
if (frontCameraView == null) {
@@ -375,7 +384,7 @@ class ScreenRecordService : Service() {
}
Common.showLog("-------layoutParamsBall.x=${layoutParamsBall.x} layoutParamsBall.y=${layoutParamsBall.y}")
}
- if (!isBallViewAdded) {
+ if (!isBallViewAdded&&!isBallExpandViewAdded) {
windowManager.addView(ballView, layoutParamsBall)
isBallViewAdded = true
}
@@ -391,6 +400,17 @@ class ScreenRecordService : Service() {
tvRecordTime = ballViewExpand!!.findViewById(R.id.tv_record_time)
imNoAudioRecord = ballViewExpand!!.findViewById(R.id.ic_without_audio)
imScreenshot = ballViewExpand!!.findViewById(R.id.ic_screenshot)
+ ballViewExpand!!.findViewById(R.id.ic_home).setOnClickListener {
+
+
+ val launchIntent = packageManager.getLaunchIntentForPackage(packageName)
+ launchIntent?.apply {
+ addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ startActivity(this)
+ }
+
+
+ }
imRecord?.setOnClickListener {
it.isSelected.let { select ->
@@ -454,7 +474,7 @@ class ScreenRecordService : Service() {
aX = aX.coerceIn(0, screenWidth - aWidthPx)
aY = aY.coerceIn(0, screenHeight - aHeightPx)
- if (aX >= screenWidth/2) {
+ if (aX >= screenWidth / 2) {
layoutParamsBallExpand.x = aX - 10.dpToPx(this)
} else {
@@ -509,7 +529,7 @@ class ScreenRecordService : Service() {
windowManager,
true
) {
- startScreenshot()
+ startScreenshot(true)
}
}
if (!isScreenshotViewAdded) {
@@ -633,12 +653,14 @@ class ScreenRecordService : Service() {
}
if (countdownView?.windowToken == null) {
+ Common.showLog("Service--- 录制带音频的视频 addView")
windowManager.addView(countdownView, layoutParamsCountDown)
val tvCountdown = countdownView!!.findViewById(R.id.tv_countdown)
index = 0
countDownHandler = Handler(Looper.getMainLooper())
animateNext(countdownValues, tvCountdown) {
//倒计时结束后,开启录制
+ Common.showLog("Service--- 倒计时结束")
hideCountDown()
mIntent?.let { intent ->
mediaProjectionManager.getMediaProjection(mCode, intent)
@@ -898,17 +920,18 @@ class ScreenRecordService : Service() {
}
- fun getViewStatus(){
+ fun getViewStatus() {
callbacks.forEach {
- it.get()?.onRefreshViewShow(isWebcamViewAdded,isScreenshotViewAdded,isBallViewAdded)
+ it.get()?.onRefreshViewShow(isWebcamViewAdded, isScreenshotViewAdded, isBallViewAdded||isBallExpandViewAdded)
}
}
- fun getRecordingStatus(){
+ fun getRecordingStatus() {
callbacks.forEach {
it.get()?.onRefreshRecordingStatus(mRecordingStatus)
}
}
+
fun stopRecording() {
// TODO: 录屏完成
mRecordingStatus = ConstValue.status_complete
diff --git a/app/src/main/java/com/audio/record/screen/test/service/ScreenshotAnimExecutor.kt b/app/src/main/java/com/audio/record/screen/test/service/ScreenshotAnimExecutor.kt
new file mode 100644
index 0000000..36d4602
--- /dev/null
+++ b/app/src/main/java/com/audio/record/screen/test/service/ScreenshotAnimExecutor.kt
@@ -0,0 +1,21 @@
+package com.audio.record.screen.test.service
+
+import android.content.Context
+import android.content.Intent
+import android.graphics.Bitmap
+import com.audio.record.screen.test.activity.ScreenPermissionActivity
+import com.audio.record.screen.test.activity.ScreenshotAnimActivity
+import com.audio.record.screen.test.tool.Common
+
+object ScreenshotAnimExecutor {
+ var latestBitmap: Bitmap? = null
+
+
+ fun show(context: Context, bitmap: Bitmap) {
+ latestBitmap = bitmap
+ Common.showLog("-----show-------------")
+ val intent = Intent(context, ScreenshotAnimActivity::class.java)
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ context.startActivity(intent)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/audio/record/screen/test/tool/ScreenCaptureHelper.kt b/app/src/main/java/com/audio/record/screen/test/tool/ScreenCaptureHelper.kt
index 1ccf91d..9ab7626 100644
--- a/app/src/main/java/com/audio/record/screen/test/tool/ScreenCaptureHelper.kt
+++ b/app/src/main/java/com/audio/record/screen/test/tool/ScreenCaptureHelper.kt
@@ -1,5 +1,8 @@
package com.audio.record.screen.test.tool
+import android.animation.Animator
+import android.animation.AnimatorSet
+import android.animation.ObjectAnimator
import android.content.ContentValues
import android.content.Context
import android.content.Intent
@@ -23,6 +26,7 @@ import android.view.WindowManager
import android.view.animation.DecelerateInterpolator
import android.widget.ImageView
import com.audio.record.screen.test.R
+import com.audio.record.screen.test.service.ScreenshotAnimExecutor
import java.io.File
import java.io.FileOutputStream
@@ -37,7 +41,7 @@ object ScreenCaptureHelper {
context: Context,
mediaProjection: MediaProjection,
folderName: String = Common.imagesFolderDir,
- isOK:()->Unit
+ isOK:(bitmap:Bitmap)->Unit
) {
val metrics = Resources.getSystem().displayMetrics
val full = Common.getFullScreenSize(context)
@@ -45,11 +49,11 @@ object ScreenCaptureHelper {
val height = full.second
val density = metrics.densityDpi
- Common.showLog("startScreenCapture width=${width}, height=${height} density=${density} Thread=${Thread.currentThread().name}")
+// Common.showLog("startScreenCapture width=${width}, height=${height} density=${density} Thread=${Thread.currentThread().name}")
val imageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 2)
mediaProjection.registerCallback(object : MediaProjection.Callback() {
override fun onStop() {
- Common.showLog("startScreenCapture MediaProjection 被系统或用户停止")
+// Common.showLog("startScreenCapture MediaProjection 被系统或用户停止")
// 这里应该释放 MediaRecorder 和 VirtualDisplay 等
virtualDisplay?.release()
mediaProjection.stop()
@@ -67,9 +71,9 @@ object ScreenCaptureHelper {
val image = imageReader.acquireLatestImage()
if (image != null) {
val bitmap = imageToBitmap(image)
+ isOK.invoke(bitmap)
saveBitmap(context, bitmap, folderName)
- showScreenshotPreviewAnimation(context, bitmap,width,height)
- isOK.invoke()
+
image.close()
}
imageReader.close()
@@ -165,14 +169,7 @@ object ScreenCaptureHelper {
).apply {
gravity = Gravity.TOP or Gravity.START
}
- imageView.post {
- Common.showLog("实际宽高 width=${imageView.width}, height=${imageView.height}")
-
- }
- Common.showLog("layoutParams layoutParams x=${layoutParams.x}, y=${layoutParams.y}")
windowManager.addView(inflate, layoutParams)
-
-
val scale = 0.3f
val targetWidth = (screenWidth * scale).toInt()
val targetHeight = (screenHeight * scale).toInt()
@@ -180,19 +177,28 @@ object ScreenCaptureHelper {
val targetX = screenWidth - targetWidth - 20
val navigationBarHeight = Common.getNavigationBarHeight(context)
val statusBarHeight = Common.getStatusBarHeight(context)
- Common.showLog("navigationBarHeight=${navigationBarHeight}, statusBarHeight=${statusBarHeight} ")
+// Common.showLog("navigationBarHeight=${navigationBarHeight}, statusBarHeight=${statusBarHeight} ")
val targetY = screenHeight - targetHeight - navigationBarHeight - statusBarHeight - 20
- Common.showLog("宽高 targetWidth=${targetWidth}, targetHeight=${targetHeight} targetX = ${targetX} targetY = ${targetY}")
+// Common.showLog("宽高 targetWidth=${targetWidth}, targetHeight=${targetHeight} targetX = ${targetX} targetY = ${targetY}")
- inflate.animate()
- .scaleX(scale)
- .scaleY(scale)
- .setDuration(600)
- .setInterpolator(DecelerateInterpolator())
- .withEndAction {
+
+ val scaleX = ObjectAnimator.ofFloat(inflate, "scaleX", 1f, scale)
+ val scaleY = ObjectAnimator.ofFloat(inflate, "scaleY", 1f, scale)
+ val animatorSet = AnimatorSet()
+ animatorSet.playTogether(scaleX, scaleY)
+ animatorSet.duration = 50
+ animatorSet.interpolator = DecelerateInterpolator()
+ animatorSet.addListener(object : Animator.AnimatorListener {
+ override fun onAnimationStart(animation: Animator) {
+ Common.showLog("-----动画开始")
+ }
+
+ override fun onAnimationEnd(animation: Animator) {
+ // 更新 layoutParams 和结束逻辑...
+ Common.showLog("-----动画结束")
// 清除动画偏移
inflate.scaleX = 1f
inflate.scaleY = 1f
@@ -217,8 +223,11 @@ object ScreenCaptureHelper {
}
}, 3000)
}
- .start()
+ override fun onAnimationCancel(animation: Animator) {}
+ override fun onAnimationRepeat(animation: Animator) {}
+ })
+ animatorSet.start()
inflate.setOnClickListener {
Common.showLog("-----点击小截图")
}
@@ -226,4 +235,87 @@ object ScreenCaptureHelper {
}
+
+ fun showScreenshotPreviewAnimationNew(context: Context, screenshotBitmap: Bitmap, screenWidth: Int, screenHeight: Int) {
+ val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
+ val inflate = LayoutInflater.from(context).inflate(R.layout.floating_screenshot_anim, null)
+ val imageView = inflate.findViewById(R.id.image)
+ imageView.setImageBitmap(screenshotBitmap)
+
+ // 初始全屏展示
+ val layoutParams = WindowManager.LayoutParams(
+ screenWidth,
+ screenHeight,
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
+ WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
+ else
+ WindowManager.LayoutParams.TYPE_PHONE,
+ WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
+ WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or
+ WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
+ PixelFormat.TRANSLUCENT
+ ).apply {
+ gravity = Gravity.TOP or Gravity.START
+ x = 0
+ y = 0
+ }
+
+ windowManager.addView(inflate, layoutParams)
+
+ // 动画目标位置与缩放比例
+ val scale = 0.25f
+ val targetWidth = (screenWidth * scale).toInt()
+ val targetHeight = (screenHeight * scale).toInt()
+ val targetX = screenWidth - targetWidth - 32 // 留点边距
+ val targetY = screenHeight - targetHeight - Common.getNavigationBarHeight(context) - 32
+
+ // 设置原始位置(居中)
+ inflate.pivotX = 0f
+ inflate.pivotY = 0f
+ inflate.translationX = 0f
+ inflate.translationY = 0f
+ inflate.scaleX = 1f
+ inflate.scaleY = 1f
+
+ // 执行缩放+位移动画
+ inflate.animate()
+ .scaleX(scale)
+ .scaleY(scale)
+ .translationX(targetX.toFloat())
+ .translationY(targetY.toFloat())
+ .setDuration(500)
+ .setInterpolator(DecelerateInterpolator())
+ .withStartAction {
+ Common.showLog("📸 截图动画开始")
+ }
+ .withEndAction {
+ Common.showLog("✅ 截图动画结束:变成小图")
+ // 动画后清除 scale/translation 状态并更新窗口布局为小图位置
+ inflate.scaleX = 1f
+ inflate.scaleY = 1f
+ inflate.translationX = 0f
+ inflate.translationY = 0f
+
+ layoutParams.width = targetWidth
+ layoutParams.height = targetHeight
+ layoutParams.x = targetX
+ layoutParams.y = targetY
+ windowManager.updateViewLayout(inflate, layoutParams)
+
+ // 延时关闭
+ inflate.postDelayed({
+ try {
+ windowManager.removeView(inflate)
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }, 3000)
+ }
+ .start()
+
+ inflate.setOnClickListener {
+ Common.showLog("🖼️ 点击了截图缩略图")
+ }
+ }
+
}
diff --git a/app/src/main/res/drawable/bg_welcome.png b/app/src/main/res/drawable/bg_welcome.png
new file mode 100644
index 0000000..8aa0609
Binary files /dev/null and b/app/src/main/res/drawable/bg_welcome.png differ
diff --git a/app/src/main/res/drawable/bg_welcome_icon.png b/app/src/main/res/drawable/bg_welcome_icon.png
new file mode 100644
index 0000000..0faa931
Binary files /dev/null and b/app/src/main/res/drawable/bg_welcome_icon.png differ
diff --git a/app/src/main/res/layout/activity_welcome.xml b/app/src/main/res/layout/activity_welcome.xml
new file mode 100644
index 0000000..888bd8c
--- /dev/null
+++ b/app/src/main/res/layout/activity_welcome.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/adapter_video_date.xml b/app/src/main/res/layout/adapter_video_date.xml
index c99e836..1479862 100644
--- a/app/src/main/res/layout/adapter_video_date.xml
+++ b/app/src/main/res/layout/adapter_video_date.xml
@@ -2,7 +2,7 @@
+ android:layout_height="wrap_content">
@@ -61,6 +61,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:text="@string/app_name"
+ android:visibility="gone"
android:textColor="@color/color_8D8D8D"
android:textSize="11sp" />
@@ -69,9 +70,15 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"
+ android:layout_marginTop="6dp"
android:textColor="@color/color_8D8D8D"
android:textSize="11sp" />
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/custom_notification.xml b/app/src/main/res/layout/custom_notification.xml
index 2dccf2b..1fb8d40 100644
--- a/app/src/main/res/layout/custom_notification.xml
+++ b/app/src/main/res/layout/custom_notification.xml
@@ -10,98 +10,105 @@
-
+
+
+
+
+
+
-
+
+
+
+
-
-
+
+
+
+
+
-
+
+
+
+
+
+
-
+
+
+
+
-
-
+
+
+
+
+
-
+
+
+
+
+
+
-
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
-
-
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/floating_screenshot_anim.xml b/app/src/main/res/layout/floating_screenshot_anim.xml
index cdcb6f7..e56fba5 100644
--- a/app/src/main/res/layout/floating_screenshot_anim.xml
+++ b/app/src/main/res/layout/floating_screenshot_anim.xml
@@ -1,12 +1,21 @@
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+
+ android:layout_gravity="center"
+ android:text="@string/Screenshot_please_wait"
+ android:textColor="@color/black"
+ android:textSize="21sp" />
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_main.xml b/app/src/main/res/layout/fragment_main.xml
index adc933b..a6ba405 100644
--- a/app/src/main/res/layout/fragment_main.xml
+++ b/app/src/main/res/layout/fragment_main.xml
@@ -10,7 +10,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="31dp"
- android:text="@string/Collection"
+ android:text="@string/app_name"
android:textColor="@color/black"
android:textSize="39sp"
app:layout_constraintLeft_toLeftOf="parent"
diff --git a/app/src/main/res/layout/fragment_record_normal.xml b/app/src/main/res/layout/fragment_record_normal.xml
index fe1a610..a7169bc 100644
--- a/app/src/main/res/layout/fragment_record_normal.xml
+++ b/app/src/main/res/layout/fragment_record_normal.xml
@@ -11,7 +11,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="31dp"
- android:text="@string/Collection"
+ android:text="@string/app_name"
android:textColor="@color/black"
android:textSize="39sp"
app:layout_constraintLeft_toLeftOf="parent"
diff --git a/app/src/main/res/layout/fragment_recording.xml b/app/src/main/res/layout/fragment_recording.xml
index c547b65..0c06faa 100644
--- a/app/src/main/res/layout/fragment_recording.xml
+++ b/app/src/main/res/layout/fragment_recording.xml
@@ -15,6 +15,7 @@
android:text="@string/app_name"
android:textColor="@color/title_color"
android:textSize="28sp"
+ android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
diff --git a/app/src/main/res/layout/fragment_video.xml b/app/src/main/res/layout/fragment_video.xml
index 4cee54a..f08938b 100644
--- a/app/src/main/res/layout/fragment_video.xml
+++ b/app/src/main/res/layout/fragment_video.xml
@@ -76,7 +76,7 @@
diff --git a/app/src/main/res/mipmap-xxxhdpi/logo.png b/app/src/main/res/mipmap-xxxhdpi/logo.png
new file mode 100644
index 0000000..9364e6c
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/logo.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/test.jpg b/app/src/main/res/mipmap-xxxhdpi/test.jpg
deleted file mode 100644
index 9429440..0000000
Binary files a/app/src/main/res/mipmap-xxxhdpi/test.jpg and /dev/null differ
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index c311892..9f80fd6 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -19,6 +19,8 @@ through the notification panel
There\'s nothing here.
Recent
New
+ Running...
+ Screenshot, please wait...
- -100
- 100