Airplane Mode trong Android OS có thể xem như chủ đề dành cho những lập trình viên Android mới làm quen với lập trình hệ thống. Trong bài tập số 2, buổi 7, môn Android 1, lớp BKAD08L có yêu cầu xây dựng một activity cho phép bật tắt chế độ airplane. Bài viết này sẽ hướng dẫn các bạn từng bước giải quyết bài tập đó, ngoài ra phần cuối sẽ bổ sung một số thông tin điều chỉnh từ Google trong các phiên bản mới.
Chú ý: bài đọc này yêu cầu bạn biết lập trình Android cơ bản.
Thiết lập quyền
Để có thể điều khiển airplane mode, ứng dụng cần quyền truy cập settings hệ thống, vì thế ta thêm dòng lệnh sau vào AndroidManifest.xml (thiếu dòng này ứng dụng sẽ bị force close khi chạy)
1 | <uses-permission android:name="android.permission.WRITE_SETTINGS"/> |
Tạo giao diện cho ứng dụng
Bạn có nhiều lựa chọn giao diện phù hợp với đầu bài, trường hợp đơn giản nhất là sử dụng điều khiển Switch, ngoài ra có thể dùng ToggleButton hoặc các một kiểu nào đó mà bạn thích.
Trong ví dụ này tôi sử dụng Switch, chú ý rằng Switch chỉ có từ API 14 (Android 4.0) trở lên, vì thế nếu muốn thử ứng dụng với các máy có Android OS thấp hơn hãy chuyển sang sử dụng các điều khiển khác, tôi lựa chọn Switch hoàn toàn vì sở thích. Hình bên thể hiện giao diện của ứng dụng khi bật và tắt airplane mode, chúng ta có thể thấy kí hiệu máy bay trên phần thanh trạng thái của Android OS hoàn toàn khớp với trạng thái của Switch.
Đoạn XML dưới đây thể hiện các thuộc tính của Switch khi đặt trên activity chính của ứng dụng, như vậy ta sẽ triển khai phương thức btnSwitch để xử lý khi người sử dụng chuyển trạng thái của Switch.
1 2 3 4 5 6 7 8 9 | <Switch android:id="@+id/switch1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:checked="false" android:onClick="btnSwitch" android:text="Airplane Mode:" /> |
Viết mã cho activity
Toàn bộ mã phần xử lý activity, để hiểu rõ hãy đọc những dòng ghi chú giải thích ngay trong đoạn mã.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | package mobipro.bai72; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.provider.Settings; import android.view.View; import android.widget.Switch; public class MainActivity extends Activity { Switch sw; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // lưu lại switch để sử dụng trong các phương thức khác sw = (Switch) findViewById(R.id.switch1); // cập nhật trạng thái switch cho khớp với thiết bị updateState(); } public void btnSwitch(View v) { // xử lý trường hợp bật airplane mode if (sw.isChecked()) { // ghi giá trị ON vào system settings Settings.System.putInt(getContentResolver(),Settings.System.AIRPLANE_MODE_ON, 1); // gửi broadcast cập nhật trạng thái ON Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); intent.putExtra("state", true); sendBroadcast(intent); } // xử lý trường hợp tắt airplane mode else { // ghi giá trị OFF vào system settings Settings.System.putInt(getContentResolver(),Settings.System.AIRPLANE_MODE_ON, 0); // gửi broadcast cập nhật trạng thái OFF Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); intent.putExtra("state", false); sendBroadcast(intent); } // cập nhật lại trạng thái (đề phòng việc setting thất bại) updateState(); } // đọc trạng thái airplane mode và cập nhật trạng thái của switch phù hợp void updateState() { int mode = Settings.System.getInt(this.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0); sw.setChecked(mode != 0); } } |
Airplane Mode và những thay đổi từ Android 4.2.2
Từ phiên bản 4.2.2, Google thay đổi chính sách bảo mật, trong đó chỉ những ứng dụng thuộc loại system mới có thể thay đổi giá trị thuộc settings (các ứng dụng loại thường vẫn có thể đọc những giá trị này), nếu bạn dịch đoạn mã trên với API 17 trở lên sẽ có thông báo hằng Settings.System.AIRPLANE_MODE_ON bị deprecated, hằng số này được thay bằng Settings.Global.AIRPLANE_MODE_ON. Bạn có thể tham khảo thêm về class mới tại Reference of Settings.Global
Vậy vẫn muốn thay đổi airplane mode thì sẽ làm thế nào? Có một vài phương án sau bạn có thể lựa chọn:
- Cài đặt ứng dụng của bạn như là system app. Trường hợp này thiết bị cần phải được root, apk sẽ được cài vào /system/app và bạn cần thêm quyền android.permission.WRITE_SECURE_SETTINGS vào AndroidManifest.xml
- Sử dụng reflection để gọi trực tiếp api của Android. Cách này rủi ro vì có thể api bị thay đổi trong các phiên bản sau, ta cũng không biết rõ thực sự api này thực hiện những gì và như vậy đã thực hiện đủ các công việc cần thiết hay chưa
- Thay vì trực tiếp thay đổi, gọi setting activity mặc định của hệ thống để người dùng tự thay đổi. Đoạn mã dưới đây sẽ giúp gọi activity mặc định:Đây là giải pháp an toàn nhất, ngoài ra bạn không cần bất kì quyền gì đặc biệt (kể cả quyền android.permission.WRITE_SETTINGS được đề cập ở phần đầu). Chú ý rằng một số phiên bản được tùy biến bởi nhà sản xuất có thể không có activity này1startActivityForResult(new Intent(android.provider.Settings.ACTION_AIRPLANE_MODE_SETTINGS), CODE);
Bình luận mới