#java #android #kotlin #screenshot
Вопрос:
Я хочу предотвратить захват скриншотов в телефонах Android. Я добавил строку
requireActivity().window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE)
Это нормально работает на обычных устройствах. Но когда я пробую на устройствах Android one, ( https://www.android.com/intl/en_in/one/ ), он все еще делает скриншоты.
Я пробовал другие приложения, такие как AmazonPrime, Hotstar и GooglePay, на устройствах Android one… В котором, хотя они и снимают скриншоты, контент полностью черный. Как этого добиться или предотвратить создание скриншота на устройствах Android One.
Ответ №1:
Мы можем прослушивать FileObserver
, чтобы определить, когда был сделан снимок экрана. Затем удалите захваченный файл скриншота из хранилища.
Вот пример кода для MediaListenerService
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Environment;
import android.os.FileObserver;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;
import androidx.documentfile.provider.DocumentFile;
import java.io.File;
public class MediaListenerService extends Service {
public static FileObserver observer;
private Context context;
public MediaListenerService() {
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
context = this;
startWatching();
}
private void startWatching() {
//The desired path to watch or monitor
String pathToWatch = Environment.getExternalStorageDirectory()
File.separator Environment.DIRECTORY_PICTURES
File.separator "Screenshots" File.separator;
Toast.makeText(this, "Service is Started and trying to watch " pathToWatch, Toast.LENGTH_LONG).show();
observer = new FileObserver(pathToWatch, FileObserver.ALL_EVENTS) { // set up a file observer to watch this directory
@Override
public void onEvent(int event, final String file) {
if (event == FileObserver.CREATE || event == FileObserver.CLOSE_WRITE || event == FileObserver.MODIFY || event == FileObserver.MOVED_TO amp;amp; !file.equals(".probe")) { // check that it's not equal to .probe because thats created every time camera is launched
String filePath = pathToWatch file;
Log.d("MediaListenerService", "File created [" filePath "]");
new Handler(Looper.getMainLooper()).postDelayed(() -> {
// Toast.makeText(getBaseContext(), file " was saved!", Toast.LENGTH_LONG).show();
File screenShotFile = new File(pathToWatch, file);
if (screenShotFile.exists()) {
try {
boolean isDeleted = screenShotFile.delete();
if (isDeleted) {
Toast.makeText(getBaseContext(), file " was deleted!", Toast.LENGTH_LONG).show();
Log.d("MediaListenerService", "File deleted [" filePath "]");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}, 200L);
}
}
};
observer.startWatching();
}
}
Добавить разрешение на файл в Manifest
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:requestLegacyExternalStorage="true"
Зарегистрируйте свою услугу в Manifest
разделе «Тег приложения».:
<service
android:name=".MediaListenerService"
android:enabled="true"
android:exported="false" />
И проверьте разрешение на хранение файлов и запустите службу в режиме основной активности в разделе onCreate
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
startService(Intent(baseContext, MediaListenerService::class.java))
} else {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
123
)
}
}
}
Комментарии:
1. Я согласен, что это работает для удаления файлов…. Но я хочу предотвратить это заранее, а не хранить и удалять позже… Кроме того, для этого мне также потребуется получить разрешение на доступ к хранилищу… что, я думаю, не лучшая идея только для предотвращения скриншотов. Кроме того, если я не остановлю службу должным образом, может возникнуть вероятность того, что скриншоты пользователя из приложения тоже будут удалены…
2. Да, нам нужно остановить службу, как только приложение будет закрыто/приостановлено.