Menjaga perangkat tetap aktif

Tetap teratur dengan koleksi Simpan dan kategorikan konten berdasarkan preferensi Anda.

Agar baterai tidak habis, perangkat Android yang tidak ada aktivitas selama beberapa saat akan beralih ke mode tidur. Namun, ada kalanya aplikasi perlu mengaktifkan layar atau CPU dan menjaganya agar tetap aktif guna menyelesaikan beberapa pekerjaan.

Pendekatan yang diambil bergantung pada kebutuhan aplikasi. Namun, panduan praktisnya adalah Anda harus menggunakan pendekatan yang paling ringan untuk aplikasi, guna meminimalkan dampak aplikasi terhadap resource sistem. Bagian berikut menjelaskan cara menangani kasus saat perilaku tidur default perangkat tidak kompatibel dengan persyaratan aplikasi Anda.

Cara alternatif untuk menggunakan fitur penguncian layar saat aktif

Sebelum menambahkan dukungan fitur penguncian layar saat aktif ke aplikasi, pertimbangkan apakah kasus penggunaan aplikasi Anda mendukung salah satu solusi alternatif berikut:

  • Jika aplikasi Anda melakukan download HTTP yang dapat berjalan lama, pertimbangkan untuk menggunakan DownloadManager.
  • Jika aplikasi Anda menyinkronkan data dari server eksternal, pertimbangkan untuk membuat adaptor sinkronisasi.
  • Jika aplikasi Anda bergantung pada layanan latar belakang, pertimbangkan untuk menggunakan JobScheduler atau Firebase Cloud Messaging untuk memicu layanan ini pada interval tertentu.

Menjaga layar agar tetap aktif

Aplikasi tertentu harus menjaga layar agar tetap aktif, seperti aplikasi film atau game. Cara terbaik untuk melakukannya adalah dengan menggunakan FLAG_KEEP_SCREEN_ON di aktivitas Anda (dan hanya dalam aktivitas, tidak dalam layanan atau komponen aplikasi lainnya). Contoh:

Kotlin

    class MainActivity : Activity() {

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
        }
    }
    

Java

    public class MainActivity extends Activity {
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
      }
    }
    

Tidak seperti fitur penguncian layar saat aktif (dibahas dalam Menjaga Agar CPU Tetap Aktif), keuntungan menggunakan pendekatan ini adalah pendekatan ini tidak memerlukan izin khusus, dan platform dengan benar mengelola pengguna yang berpindah antar-aplikasi, dan aplikasi tidak perlu mengkhawatirkan pelepasan resource yang tidak digunakan.

Cara lain untuk menerapkannya adalah dalam file XML tata letak aplikasi Anda, dengan menggunakan atribut android:keepScreenOn:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:keepScreenOn="true">
        ...
    </RelativeLayout>

Menggunakan android:keepScreenOn="true" sama saja dengan menggunakan FLAG_KEEP_SCREEN_ON. Anda dapat menggunakan pendekatan mana pun yang terbaik untuk aplikasi Anda. Keuntungan menyetel flag secara terprogram dalam aktivitas adalah Anda nantinya diberikan opsi menghapus flag secara terprogram, sehingga memungkinkan layar dinonaktifkan.

Catatan: Anda tidak perlu menghapus flag FLAG_KEEP_SCREEN_ON kecuali Anda tidak lagi menginginkan layar agar tetap aktif di aplikasi yang sedang berjalan (misalnya, jika Anda ingin agar layar menetapkan waktu habis setelah tidak aktif selama beberapa saat). Pengelola jendela akan memastikan bahwa hal yang tepat terjadi saat aplikasi beralih ke latar belakang atau kembali ke latar depan. Namun, jika Anda ingin menghapus flag secara eksplisit dan memungkinkan layar untuk dinonaktifkan lagi, gunakan clearFlags(): getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON).

Menjaga CPU agar tetap aktif

Jika Anda perlu menjaga CPU agar tetap berjalan guna menyelesaikan beberapa pekerjaan sebelum perangkat beralih ke mode tidur, Anda dapat menggunakan fitur layanan sistem PowerManager yang disebut penguncian layar saat aktif. Fitur penguncian layar saat aktif memungkinkan aplikasi mengontrol status daya perangkat host.

Membuat dan menyimpan fitur penguncian layar saat aktif dapat memiliki dampak yang besar terhadap masa pakai baterai perangkat host. Oleh karena itu, sebaiknya gunakan fitur penguncian layar saat aktif hanya ketika benar-benar diperlukan dan simpan fitur ini dalam jangka waktu sesingkat mungkin. Misalnya, Anda tidak perlu menggunakan fitur penguncian layar saat aktif dalam aktivitas. Seperti yang dijelaskan di atas, jika Anda ingin agar layar tetap aktif dalam aktivitas, gunakan FLAG_KEEP_SCREEN_ON.

Salah satu kasus yang tepat untuk menggunakan fitur penguncian layar saat aktif yaitu pada layanan latar belakang yang perlu menggunakan fitur penguncian layar saat aktif agar CPU tetap berjalan guna melakukan pekerjaan saat layar nonaktif. Namun sekali lagi, praktik ini harus diminimalkan karena dampaknya terhadap masa pakai baterai.

Untuk menggunakan fitur penguncian layar saat aktif, langkah pertama adalah menambahkan izin WAKE_LOCK ke file manifes aplikasi Anda:

<uses-permission android:name="android.permission.WAKE_LOCK" />

Jika aplikasi Anda menyertakan penerima siaran yang menggunakan layanan untuk melakukan beberapa pekerjaan, Anda dapat mengelola fitur penguncian layar saat aktif melalui WakefulBroadcastReceiver, seperti yang dijelaskan dalam Menggunakan penerima siaran yang menjaga agar perangkat tetap aktif. Ini adalah pendekatan pilihan. Jika aplikasi Anda tidak mengikuti pola tersebut, berikut cara menyetel fitur penguncian layar saat aktif secara langsung:

Kotlin

    val wakeLock: PowerManager.WakeLock =
            (getSystemService(Context.POWER_SERVICE) as PowerManager).run {
                newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyApp::MyWakelockTag").apply {
                    acquire()
                }
            }
    

Java

    PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
    WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
            "MyApp::MyWakelockTag");
    wakeLock.acquire();
    

Untuk melepaskan penguncian layar saat aktif, panggil wakelock.release(). Tindakan ini akan melepaskan klaim Anda terhadap CPU. Penting untuk melepaskan fitur penguncian layar saat aktif segera setelah aplikasi selesai menggunakannya agar baterai tidak habis.

Menggunakan penerima siaran yang menjaga agar perangkat tetap aktif

Menggunakan penerima siaran bersamaan dengan layanan memungkinkan Anda mengelola siklus proses tugas latar belakang.

WakefulBroadcastReceiver adalah jenis penerima siaran khusus yang menangani pembuatan dan pengelolaan PARTIAL_WAKE_LOCK untuk aplikasi Anda. WakefulBroadcastReceiver meneruskan pekerjaan ke Service (biasanya IntentService), sambil memastikan bahwa perangkat tidak beralih kembali ke mode tidur selama proses pengalihan. Jika Anda tidak mengaktifkan fitur penguncian layar saat aktif ketika mengalihkan pekerjaan ke layanan, Anda secara efektif mengizinkan perangkat kembali ke mode tidur sebelum pekerjaan selesai. Hasil akhirnya adalah aplikasi mungkin belum selesai melakukan pekerjaan hingga beberapa titik arbitrer di masa mendatang, sehingga menjadi hasil yang tidak Anda inginkan.

Langkah pertama dalam menggunakan WakefulBroadcastReceiver adalah dengan menambahkannya ke manifes Anda, seperti pada penerima siaran lainnya:

<receiver android:name=".MyWakefulReceiver"></receiver>

Kode berikut memulai MyIntentService dengan metode startWakefulService(). Metode ini sebanding dengan startService(), tetapi perbedaannya adalah WakefulBroadcastReceiver menyimpan fitur penguncian layar saat aktif saat layanan dimulai. Intent yang diteruskan dengan startWakefulService() akan menyimpan identifikasi tambahan penguncian layar saat aktif:

Kotlin

    class MyWakefulReceiver : WakefulBroadcastReceiver() {

        override fun onReceive(context: Context, intent: Intent) {

            // Start the service, keeping the device awake while the service is
            // launching. This is the Intent to deliver to the service.
            Intent(context, MyIntentService::class.java).also { service ->
                WakefulBroadcastReceiver.startWakefulService(context, service)
            }
        }
    }
    

Java

    public class MyWakefulReceiver extends WakefulBroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {

            // Start the service, keeping the device awake while the service is
            // launching. This is the Intent to deliver to the service.
            Intent service = new Intent(context, MyIntentService.class);
            startWakefulService(context, service);
        }
    }
    

Setelah selesai, layanan akan memanggil MyWakefulReceiver.completeWakefulIntent() untuk melepaskan penguncian layar saat aktif. Dalam metode completeWakefulIntent(), parameternya berisi intent sama yang diteruskan dari WakefulBroadcastReceiver:

Kotlin

    const val NOTIFICATION_ID = 1

    class MyIntentService : IntentService("MyIntentService") {

        private val notificationManager: NotificationManager? = null
        internal var builder: NotificationCompat.Builder? = null

        override fun onHandleIntent(intent: Intent) {
            val extras: Bundle = intent.extras
            // Do the work that requires your app to keep the CPU running.
            // ...
            // Release the wake lock provided by the WakefulBroadcastReceiver.
            MyWakefulReceiver.completeWakefulIntent(intent)
        }
    }
    

Java

    public class MyIntentService extends IntentService {
        public static final int NOTIFICATION_ID = 1;
        private NotificationManager notificationManager;
        NotificationCompat.Builder builder;
        public MyIntentService() {
            super("MyIntentService");
        }
        @Override
        protected void onHandleIntent(Intent intent) {
            Bundle extras = intent.getExtras();
            // Do the work that requires your app to keep the CPU running.
            // ...
            // Release the wake lock provided by the WakefulBroadcastReceiver.
            MyWakefulReceiver.completeWakefulIntent(intent);
        }
    }