2012-03-31 32 views
6

tôi bắt đầu một hoạt động từ BroadcastReceiver, được kích hoạt bởi một alaram (kiểu RTC_WAKEUP). in onTạo hoạt động đó tôi thêm các cờ nàyFLAG_TURN_SCREEN_ON không phải lúc nào cũng hoạt động

getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD | 
    WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | 
    WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | 
    WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON   
); 

vấn đề đôi khi (khoảng 10% trường hợp) màn hình không bật. báo động được kích hoạt chính xác (i ở đây âm thanh của một thông báo, cũng được kích hoạt trong bộ nhận onReceive() của người nhận, sau đó, nếu tôi nhấn nút nguồn của điện thoại, màn hình sẽ bật, hiển thị hoạt động của tôi và tắt ngay lập tức. rằng, nút nguồn làm việc tốt. điều này xảy ra trên android 2.3.7 và đây là onReceive() phương pháp

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

    Bundle extras = intent.getExtras(); 
    final int id = extras.getInt("timer_id"); 

    Intent activityIntent = new Intent(m_Context, MyActivity.class); 
    activityIntent.putExtra("timer_id", id); 
    activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP); 
    m_Context.startActivity(activityIntent); 

    // and now load the alarm sound and play it for the desired time 
    showFinishedNotification(); 
} 

tôi muốn tránh sử dụng PowerManager, vì nó cần một sự cho phép, và những lá cờ là ưa thích cách.

những gì có thể là một vấn đề? logcat không hiển thị bất kỳ vấn đề ...

+0

Bạn có quản lý để phá vỡ vấn đề? – Redwarp

+0

@Redwarp Giải pháp duy nhất là sử dụng quyền WAKE_LOCK và sử dụng khóa tĩnh. Có một 'WakefulBroadcastReceiver' mới trong thư viện hỗ trợ, xử lý khóa đánh thức một phần. Nó cần sự cho phép của cource. – shelll

Trả lời

3

vấn đề là đôi khi (khoảng 10% trường hợp) màn hình không bật

Nếu tôi phải đoán, thiết bị đang rơi vào giấc ngủ trước khi hoạt động khởi động. Khi trả tiền onReceive(), thiết bị có thể và sẽ rơi vào trạng thái ngủ và sẽ mất một khoảng thời gian sau khi onReceive() trả về trước khi hoạt động của bạn bắt đầu.

Kịch bản này giống nhau, nhưng thay thế startActivity() với startService(), là lý do tại sao tôi đã phải viết WakefulIntentService, trong đó sử dụng một WakeLock để đảm bảo rằng thiết bị vẫn tỉnh táo đủ lâu cho nó để làm công việc của mình, sau đó ra mắt WakeLock.

+0

thiết bị sẽ tỉnh táo vì âm thanh của thông báo đang phát. ... tôi có thể đặt người nhận ngủ với Thread.sleep (...) và thiết bị sẽ không rơi vào giấc ngủ? hoặc với một tin nhắn bị trì hoãn (mới xử lý()). postDelayed (...))? – shelll

+0

@shelll: "tôi có thể đặt người nhận ngủ với Thread.sleep (...) và thiết bị sẽ không rơi vào giấc ngủ?" - không. Đầu tiên, điều đó sẽ ngăn chặn hoạt động của bạn bắt đầu cho đến khi 'sleep()' hoàn thành, bởi vì 'onReceive()' được gọi trên luồng ứng dụng chính. Thứ hai, Android sẽ loại bỏ 'BroadcastReceiver' của bạn nếu bạn kết nối chuỗi ứng dụng chính quá lâu. "tôi có thể đặt người nhận ngủ với Thread.sleep (...) và thiết bị sẽ không ngủ được không?" - điều đó sẽ không ngăn thiết bị rơi vào giấc ngủ. Nó sẽ làm tăng tần suất của vấn đề này xảy ra một chút. – CommonsWare

+0

OK, do đó, không có giấc ngủ(), nhưng làm thế nào tôi có thể nghe thấy âm thanh thông báo (tôi lặp lại nó cho đến khi nó được hủy bỏ thủ công), nhưng màn hình không bật? – shelll

5

Tôi hơi muộn với bữa tiệc ở đây nhưng tôi đã chiến đấu trong một thời gian và cuối cùng đã tìm ra cách để màn hình mở khóa mọi lúc. Tôi thêm các cờ trong sự kiện onAttachToWindow(). Thông thường tôi làm điều này từ một WakefulBroadcastReceiver để màn hình chuyển tiếp thông suốt nhưng đó là trường hợp sử dụng phụ thuộc.

@Override 
public void onAttachedToWindow() { 
    super.onAttachedToWindow(); 
    //Screen On 
    getWindow().addFlags(
      WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED 
        | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD 
        | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON 
        | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); 
} 

private void clearFlags() { 
    //Don't forget to clear the flags at some point in time. 
    getWindow().clearFlags(
       WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED 
         | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD 
         | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON 
         | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); 
} 
5

Từ kinh nghiệm và nghiên cứu của tôi về chủ đề này:

  • Các FLAG_TURN_SCREEN_ON không thể được sử dụng để chuyển trên màn hình và OFF nhiều lần trong ứng dụng của bạn.

  • Các FLAG_TURN_SCREEN_ON chỉ có thể được sử dụng một lần để bật màn hình ON khi creating a new activity (tốt nhất là trong phương thức onCreate()) hoặc when re-creating a view.

Bây giờ, bạn có thể khắc phục hạn chế này bằng cách:

  • ra mắt một hoạt động mới và thiết lập các lá cờ ở đó, sau đó kết thúc hoạt động (bởi người dùng hoặc lập trình) để cho các lượt màn hình tắt.
  • Đặt các thông số params.screenBrightness thành as "dim" as possible, đôi khi màn hình "xuất hiện TẮT". Sau đó, bạn có thể tăng độ sáng để "BẬT" màn hình.Tuy nhiên, điều này thường không hoạt động vì màn hình vẫn mờ nhưng có thể nhìn thấy, điều này cũng không hoạt động nếu người dùng khóa điện thoại.
  • Sử dụng Power Manager Wakelock (điều này vẫn hoạt động nhưng Android không dùng chức năng này, vì vậy họ không khuyến khích sử dụng kỹ thuật này). Tuy nhiên, theo như tôi có thể nói đây là cách duy nhất tôi có thể nhận được ứng dụng của mình để BẬT/TẮT màn hình một cách đáng tin cậy.

Không có lý tưởng nào trong số này là lý tưởng (trên thực tế chúng cảm thấy như hack) nhưng chỉ sử dụng cái phù hợp hơn với nhu cầu ứng dụng của bạn.

Bạn có thể đọc thêm ở đây:

Các vấn đề liên quan