スクリーンショットを検知したら通知をする
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- これを追加 -->
<uses-permission android:name="android.permission.DETECT_SCREEN_CAPTURE" />
<application
MainActivity.kt
package com.example.detectscreencapture
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.example.detectscreencapture.ui.theme.DetectScreenCaptureTheme
class MainActivity : ComponentActivity() {
private val screenCaptureCallback = ScreenCaptureCallback {
Log.d("ScreenCapture", "Detect Screen captured")
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
DetectScreenCaptureTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
Greeting(
name = "Android",
modifier = Modifier.padding(innerPadding)
)
}
}
}
}
override fun onStart() {
super.onStart()
registerScreenCaptureCallback(mainExecutor, screenCaptureCallback)
}
override fun onStop() {
super.onStop()
try {
unregisterScreenCaptureCallback(screenCaptureCallback)
} catch (e: IllegalArgumentException) {
e.printStackTrace()
}
}
}
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Text(
text = "Hello $name!",
modifier = modifier
)
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
DetectScreenCaptureTheme {
Greeting("Android")
}
}
スクリーンショットすると検知・通知されますが画像自体は問題なくスクリーンショットされています。
次にスクリーンショットした画面自体真っ黒にしたい場合は下記コードを組むだけで実現できます。
package com.example.detectscreencapture
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.detectscreencapture.ui.theme.DetectScreenCaptureTheme
class MainActivity : ComponentActivity() {
private val screenCaptureCallback = ScreenCaptureCallback {
Log.d("ScreenCapture", "Detect Screen captured")
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
/** ------ ここのコードを追加する ------ */
window?.setFlags(
android.view.WindowManager.LayoutParams.FLAG_SECURE,
android.view.WindowManager.LayoutParams.FLAG_SECURE
)
/** ------ ここまで ------ */
enableEdgeToEdge()
setContent {
DetectScreenCaptureTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
Greeting(
name = "Android",
modifier = Modifier.padding(innerPadding)
)
}
}
}
}
override fun onStart() {
super.onStart()
registerScreenCaptureCallback(mainExecutor, screenCaptureCallback)
}
override fun onStop() {
super.onStop()
try {
unregisterScreenCaptureCallback(screenCaptureCallback)
} catch (e: IllegalArgumentException) {
e.printStackTrace()
}
}
}
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
Box(
modifier = Modifier
.fillMaxSize()
.padding(8.dp),
contentAlignment = Alignment.Center
) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(4.dp),
verticalArrangement = Arrangement.Top,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "Hello $name!",
modifier = modifier
)
Text(
text = "スクショ画像は真っ暗です"
)
}
}
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
DetectScreenCaptureTheme {
Greeting("Android")
}
}
このようにスクリーンショットした画面は真っ黒となります。NetflixやAmazon Prime, マッチングアプリではこのような技術がネイティブアプリにあるのかなと感じました。



