Предотвращение захвата экрана на устройствах Android One

#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. Да, нам нужно остановить службу, как только приложение будет закрыто/приостановлено.