Tôi xử lý việc này bằng cách sử dụng AlarmManager để lên lịch và hủy hành động hết thời gian chờ.
Sau đó, trong sự kiện onPause() của tất cả các hoạt động của tôi, tôi lên lịch báo thức. Trong sự kiện onResume() của tất cả các hoạt động của tôi, tôi kiểm tra xem báo thức có tắt hay không. Nếu báo thức tắt, tôi tắt ứng dụng của mình. Nếu báo thức vẫn chưa tắt, tôi sẽ hủy báo thức.
Tôi đã tạo Timeout.java để quản lý báo thức của mình. Khi báo thức tắt mục đích được kích hoạt:
public class Timeout {
private static final int REQUEST_ID = 0;
private static final long DEFAULT_TIMEOUT = 5 * 60 * 1000; // 5 minutes
private static PendingIntent buildIntent(Context ctx) {
Intent intent = new Intent(Intents.TIMEOUT);
PendingIntent sender = PendingIntent.getBroadcast(ctx, REQUEST_ID, intent, PendingIntent.FLAG_CANCEL_CURRENT);
return sender;
}
public static void start(Context ctx) {
ctx.startService(new Intent(ctx, TimeoutService.class));
long triggerTime = System.currentTimeMillis() + DEFAULT_TIMEOUT;
AlarmManager am = (AlarmManager) ctx.getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.RTC, triggerTime, buildIntent(ctx));
}
public static void cancel(Context ctx) {
AlarmManager am = (AlarmManager) ctx.getSystemService(Context.ALARM_SERVICE);
am.cancel(buildIntent(ctx));
ctx.startService(new Intent(ctx, TimeoutService.class));
}
}
Sau đó, tôi đã tạo một dịch vụ để nắm bắt ý định được tạo bởi báo thức. Nó đặt ra một số trạng thái toàn cầu trong trường hợp của tôi về lớp ứng dụng để chỉ ra rằng ứng dụng nên khóa:
public class TimeoutService extends Service {
private BroadcastReceiver mIntentReceiver;
@Override
public void onCreate() {
super.onCreate();
mIntentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(Intents.TIMEOUT)) {
timeout(context);
}
}
};
IntentFilter filter = new IntentFilter();
filter.addAction(Intents.TIMEOUT);
registerReceiver(mIntentReceiver, filter);
}
private void timeout(Context context) {
App.setShutdown();
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nm.cancelAll();
}
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(mIntentReceiver);
}
public class TimeoutBinder extends Binder {
public TimeoutService getService() {
return TimeoutService.this;
}
}
private final IBinder mBinder = new TimeoutBinder();
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}
Cuối cùng, tôi đã tạo ra một lớp con của Hoạt động rằng tất cả các hoạt động ứng dụng của tôi lớp con từ để quản lý khóa và mở khóa:
public class LockingActivity extends Activity {
@Override
protected void onPause() {
super.onPause();
Timeout.start(this);
}
@Override
protected void onResume() {
super.onResume();
Timeout.cancel(this);
checkShutdown();
}
private void checkShutdown() {
if (App.isShutdown()) {
finish();
}
}
}
Sử dụng onPause and onResume để bắt đầu và ngừng thời gian chờ mang lại cho tôi các ngữ nghĩa sau đây. Miễn là một trong các hoạt động của ứng dụng của tôi đang hoạt động, đồng hồ hết giờ không hoạt động. Vì tôi đã sử dụng loại AlarmManager.RTC, bất cứ khi nào điện thoại chuyển sang chế độ ngủ, đồng hồ hết giờ sẽ chạy. Nếu thời gian chờ xảy ra trong khi điện thoại đang ngủ thì dịch vụ của tôi sẽ nhận hết thời gian chờ ngay khi điện thoại thức dậy. Ngoài ra, đồng hồ chạy khi bất kỳ hoạt động nào khác đang mở.
Đối với một phiên bản chi tiết hơn trong số này, bạn có thể thấy tôi thực sự thực hiện chúng trong ứng dụng của tôi https://github.com/bpellin/keepassdroid
bạn có thể làm rõ những gì diễn ra trong tệp kê khai không? – yanokwa
mã của bạn không bao giờ sử dụng lớp TimeoutService. Bạn có thể cho biết cách thức và nơi bạn đang sử dụng? – Peanut
Tôi đã sử dụng để khởi động dịch vụ bất cứ khi nào ứng dụng bắt đầu và dừng lại bất cứ khi nào ứng dụng kết thúc. Điều này tạo ra rất nhiều email có liên quan, bởi vì mọi người nhìn thấy dịch vụ đang chạy và giả sử nó đang sử dụng các tài nguyên quá mức. Vì vậy, tôi đã thêm mã trong các phương thức bắt đầu và dừng của Timeout để bắt đầu và ngừng dịch vụ. Tôi đã chỉnh sửa câu trả lời của mình để phản ánh điều này. –