2012-06-04 18 views
54

Tôi cần một số trợ giúp để hiểu khi nào tôi có thể mong đợi máy thu phát của tôi sẽ hoạt động khi vừa đăng ký trong tệp kê khai so với phải đăng ký từ hoạt động hoặc dịch vụ đang chạy.Broadcast Receiver Đăng ký trong Manifest vs. Activity

Vì vậy, ví dụ nếu tôi đăng ký một độc lập nhận với bộ lọc ý định sau nó hoạt động mà không cần phải là một tài liệu tham khảo dịch vụ/hoạt động với nó:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.blk_burn.standalonereceiver" 
    android:versionCode="1" 
    android:versionName="1.0" > 

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

    <application 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" > 

     <receiver android:name="TestReceiver"> 
      <intent-filter> 
       <action android:name="android.media.AUDIO_BECOMING_NOISY"/> 
      </intent-filter> 
     </receiver> 

    </application> 

</manifest> 

Tuy nhiên nếu tôi thay android.media.AUDIO_BECOMING_NOISY với android.intent.action.HEADSET_PLUG người nhận không được kích hoạt (Android Documentation)

Từ những gì tôi tìm thấy trên trang này, bạn phải đăng ký người nhận này từ một hoạt động hoặc dịch vụ đã hoạt động để nó hoạt động (Post).

  • Bất cứ ai có cho tôi biết tại sao điều này không hoạt động khi chỉ điều chỉnh bộ lọc ý định của bạn trong biểu hiện và tại sao bạn cần phải có một dịch vụ đang chạy ở chế độ nền mà tài liệu tham khảo/đăng ký người nhận?

  • Có công việc xung quanh để tôi chỉ có thể đăng ký người nhận trong tệp kê khai của ứng dụng bằng bộ lọc ý định với android.intent.action.HEADSET_PLUG không?

  • Làm cách nào để xác định hành động phát sóng nào từ android documentation cần phải có dịch vụ hoặc hoạt động đăng ký chúng so với chỉ có bộ lọc phù hợp trong tệp kê khai?

Trả lời

78

Nếu người nhận của bạn được đăng ký trong tệp kê khai và ứng dụng của bạn không chạy, quy trình mới sẽ được tạo để xử lý chương trình phát sóng. Nếu bạn đăng ký nó trong mã, nó gắn liền với cuộc sống của hoạt động/dịch vụ mà bạn đã đăng ký. Đối với một số chương trình phát sóng, việc tạo một quy trình ứng dụng mới nếu nó không tồn tại, hoặc có một số an ninh, hiệu suất, vv tác động, và do đó bạn chỉ có thể đăng ký người nhận trong mã.

Đối với phát sóng HEADSET_PLUG, có vẻ như ý tưởng của bạn là ứng dụng đã chạy có thể thực hiện điều này để thực hiện điều chỉnh ứng dụng cụ thể cho giao diện người dùng, khối lượng, v.v. Nếu ứng dụng của bạn không chạy, bạn không nên quan tâm tai nghe bị tháo ra.

AFAIK, không có nơi duy nhất mà thông tin này được tóm tắt cho tất cả các chương trình phát sóng, nhưng mỗi Intent phải có chú thích trong JavaDoc về cách đăng ký và sử dụng nó, nhưng dường như nó thiếu ở những nơi. Bạn sẽ có thể biên dịch một danh sách nếu bạn grep cây nguồn Android cho Intent.FLAG_RECEIVER_REGISTERED_ONLY.

+1

intent.Flag .. và tìm mã trong mã nguồn có ý nghĩa. thanks –

+1

Đối với đoạn đầu tiên .. Tắt tắt :) –

+1

Bạn có bất kỳ tài liệu chính thức nào để hỗ trợ tuyên bố của mình không (** Nếu người nhận của bạn được đăng ký trong tệp kê khai và ứng dụng của bạn không chạy, quy trình mới sẽ được tạo để xử lý phát sóng. **)? –

8

Như người nhận phát sóng thông thường có thể được định cấu hình trong tệp kê khaiAndroidManifest.xml. BroadcastReceiver được cấu hình theo cách này được gọi là đăng ký tĩnh.

Bạn có thể đăng ký nhận của bạn trong file manifest bằng cách sử dụng các yếu tố:

<receiver 
    android:name=".ConnectivityChangeReceiver"> 
    <intent-filter> 
     <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> 
    </intent-filter> 
</receiver> 

Yếu tố lồng nhau được dùng để xác định trường hợp người nhận phải phản ứng.

Dyanmic Broadcast Recievers

Là một thay thế, bạn có thể đăng ký thi BroadcastReceiver của bạn tự động trong mã của bạn. Bạn chỉ cần gọi phương thức registerReceiver() trên đối tượng Context của bạn.

Phương pháp registerReceiver() có hai tham số:

Những lập luận của phương pháp registerReceiver()

  • nhận: Các BroadcastReceiver bạn muốn đăng ký
  • lọc: Các IntentFilter đối tượng xác định sự kiện mà người nhận của bạn nên nghe.

Khi bạn đăng ký người nhận theo cách này, nó sẽ sống miễn là thành phần này còn Android sẽ gửi sự kiện đến người nhận này cho đến khi tự tạo thành phần.

Nhiệm vụ của bạn là xử lý vòng đời chính xác. Do đó khi bạn thêm một máy thu động, hãy cẩn thận để hủy đăng ký cùng một bộ thu trong phương thức onPause() của Hoạt động của bạn!

Tôi đề nghị đăng ký nhận trong phương thức onResume() của hoạt động của bạn và để unregister nó trong) phương pháp của bạn onPause (:

@Override 
protected void onPause() { 
    unregisterReceiver(mReceiver); 
    super.onPause(); 
} 

@Override 
protected void onResume() { 
    this.mReceiver = new ConnectivityChangeReceiver(); 
    registerReceiver(
     this.mReceiver, 
     new IntentFilter(
       ConnectivityManager.CONNECTIVITY_ACTION)); 
    super.onResume(); 
} 

Khi sử dụng phương pháp nào để đăng ký

Những phương pháp để sử dụng cho việc đăng ký BroadcastReceiver của bạn phụ thuộc vào những gì ứng dụng của bạn thực hiện với sự kiện hệ thống. Tôi nghĩ rằng về cơ bản có hai lý do tại sao ứng dụng của bạn muốn biết về các sự kiện toàn hệ thống:

  • Ứng dụng của bạn cung cấp một số loại dịch vụ xung quanh những sự kiện
  • ứng dụng của bạn muốn phản ứng ân cần đến nhà nước thay đổi

Ví dụ cho danh mục đầu tiên là những ứng dụng cần phải hoạt động ngay khi thiết bị được khởi động hoặc phải bắt đầu một số loại công việc bất cứ khi nào ứng dụng được cài đặt. Battery Widget Pro hoặc App2SD là các ví dụ hay cho các loại ứng dụng này. Đối với loại này, bạn phải đăng ký BroadcastReceiver trong tệp kê khai.

Ví dụ về danh mục thứ hai là sự kiện báo hiệu thay đổi đối với trường hợp mà ứng dụng của bạn có thể dựa vào. Giả sử ứng dụng của bạn phụ thuộc vào kết nối Bluetooth được thiết lập. Bạn phải phản ứng với thay đổi trạng thái - nhưng chỉ khi ứng dụng của bạn hoạt động. Trong trường hợp này, không cần phải có bộ thu phát sóng đã đăng ký tĩnh. Một đăng ký động sẽ hợp lý hơn.

Ngoài ra còn có một số sự kiện mà bạn thậm chí không được phép đăng ký tĩnh. Một ví dụ cho sự kiện này là sự kiện Intent.ACTION_TIME_TICK được phát mỗi phút. Đó là một quyết định khôn ngoan bởi vì một máy thu tĩnh sẽ không cần thiết tiêu hao pin.