Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Android

วิธีป้องกันการถ่ายภาพหน้าจอ (Screenshot) เมื่อแอปไปอยู่ Background ใน Android

ภาพรวม

ในบางสถานการณ์ ต้องการป้องกันไม่ให้ถ่ายภาพหน้าจอ (Screenshot) หรือจับภาพหน้าจอได้ เมื่อแอปไปอยู่ Background หรือใน Recents screen ตัวอย่างนี้ใช้ FLAG_SECURE บน Window

ขั้นตอนที่ 1: สร้างโปรเจกต์ใหม่

สร้างโปรเจกต์ Android ใหม่ใน Android Studio

ขั้นตอนที่ 2: เพิ่ม Layout XML

ไฟล์ res/layout/activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:id="@+id/parent"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:gravity="center"
    android:orientation="vertical">
    <TextView
        android:id="@+id/openYoutube"
        android:text="Open youtube application"
        android:textSize="20sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

ขั้นตอนที่ 3: โค้ด Java - จุดสำคัญ

ไฟล์ src/MainActivity.java:

package com.example.andy.myapplication;

import android.os.Build;
import android.os.Bundle;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.view.WindowManager;

public class MainActivity extends AppCompatActivity {

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        // ⭐ จุดสำคัญ: ต้องเรียกก่อน setContentView()
        getWindow().setFlags(
            WindowManager.LayoutParams.FLAG_SECURE,
            WindowManager.LayoutParams.FLAG_SECURE
        );
        
        setContentView(R.layout.activity_main);
    }
}

🔑 โค้ดหลัก: FLAG_SECURE

getWindow().setFlags(
    WindowManager.LayoutParams.FLAG_SECURE,
    WindowManager.LayoutParams.FLAG_SECURE
);
  • ตั้งค่าก่อน setContentView() เพื่อให้มีผลกับ View ทั้งหมด
  • ป้องกัน: Screenshot, Screen recording, Remote display, App switcher preview
  • ทำงานบน API 1+ (รองรับเก่ามาก)

ผลลัพธ์ที่ได้

  • กด Power + Volume Down (Screenshot) → ได้ภาพสีดำ/ว่างเปล่า
  • Screen Recorder → บันทึกได้แต่เป็นหน้าจอสีดำ
  • Recent Apps (Overview) → แสดงเป็นหน้าจอสีดำ/บลัค
  • Cast/Mirroring → ไม่แสดงเนื้อหา

🎯 ใช้กับ Activity เฉพาะ vs ทั้งแอป

Activity เฉพาะ (ใน onCreate ของ Activity นั้น)

@Override
protected void onCreate(Bundle savedInstanceState) {
    getWindow().setFlags(FLAG_SECURE, FLAG_SECURE);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_sensitive);
}

ทั้งแอป (ใน BaseActivity หรือ Application subclass)

public class BaseActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        getWindow().setFlags(FLAG_SECURE, FLAG_SECURE);
        super.onCreate(savedInstanceState);
    }
}

// ทุก Activity extends BaseActivity จะได้รับการป้องกัน

เปิด/ปิดแบบ Dynamic (Runtime)

// เปิดป้องกัน
getWindow().setFlags(FLAG_SECURE, FLAG_SECURE);

// ปิดป้องกัน (ลบ Flag)
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);

⚠️ ข้อจำกัดและข้อควรระวัง

⚠️ ข้อจำกัด:
  • ไม่ป้องกันการถ่ายรูปด้วยกล้องถ่ายภาพภายนอก (Physical camera)
  • ไม่ป้องกัน Root/ADB screen capture (บางรุ่น)
  • บาง OEM อาจมี Bug ไม่บังคับ FLAG_SECURE ใน Recents
  • อาจส่งผลต่อ Accessibility Services (TalkBack, etc.)
  • Android 12+ มี Privacy Indicators แสดงสถานะการจับภาพ

กรณีใช้งานจริง (Use Cases)

  • แอปธนาคาร/การเงิน - หน้าจอข้อมูลบัญชี, OTP, บัตรเครดิต
  • แอปสุขภาพ - ข้อมูลผู้ป่วย, ผลตรวจ
  • แอป Enterprise - เอกสารความลับ, Trade secrets
  • DRM Content - วิดีโอ/เพลงที่มีลิขสิทธิ์
  • Authentication - หน้า Login, Biometric, PIN

วิธีทดสอบ

  1. รันแอปบนอุปกรณ์จริง
  2. กด Home → เปิด Recent Apps → จะเห็น Preview เป็นสีดำ
  3. ลอง Screenshot (Power + Vol Down) → ได้ภาพสีดำ
  4. ลอง Screen Record → วิดีโอเป็นสีดำ

🔧 ทดสอบด้วย ADB (สำหรับ Developer)

# Screenshot ผ่าน ADB (จะได้ภาพสีดำถ้า FLAG_SECURE ทำงาน)
adb exec-out screencap -p > screenshot.png

# Screen record
adb shell screenrecord /sdcard/test.mp4