2013-05-07 28 views
11

Tôi có một bộ thu phát sóng đang được kích hoạt ngay khi nó được đăng ký (và sau đó được kích hoạt lại bằng onPause/onResume), chắc chắn đây là hành vi sai? Tôi đã bỏ lỡ một cái gì đó ở đây?BroadcastReceiver onReceive được kích hoạt khi đăng ký

class FooActivity extends Activity {  

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     broadcastReceiver = new FooBroadcastReceiver(); 
     intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     registerReceiver(connectivityReceiver, intentFilter);   
    } 

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


class MyBroadcastReceiver extends BroadcastReceiver { 

    @Override 
    public void onReceive(Context context, Intent intent) {  
     if (connectivityAction(intent)) { 
      Log.d("footag", "onReceive"); 
     } 
    } 

    private boolean connectivityAction(Intent intent) { 
     return ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction()); 
    } 

} 
+0

không có gì sai trong đó. Có một loo k tại tài liệu: 'http: // developer.android.com/training/monitoring-device-state/connection-monitoring.html' –

+0

@Adam' MyBroadcastReceiver' là tĩnh trong ví dụ của bạn đúng không? – Blundell

+0

Ngoài ra, bạn có thể thực hiện điều này 'NetworkInfo networkInfo = intent.getParcelableExtra (ConnectivityManager.EXTRA_NETWORK_INFO);' để thu thập thêm thông tin về lý do BroadcastReciever của bạn được gọi là – Blundell

Trả lời

10

Cảm ơn câu trả lời! Giải pháp của tôi là kết quả của tất cả chúng, bằng cách chuyển sang bộ nhận khai báo kê khai và bật/tắt thành phần bộ thu trong onResume/onPause đã dừng tính chất dính của người nhận. Và bằng cách cho phép/vô hiệu hóa các thành phần tôi có thể có phần của tâm trí rằng tôi là một công dân hạng hai.

@Override 
protected void onResume() { 
    super.onResume(); 
    setReceiverState(PackageManager.COMPONENT_ENABLED_STATE_ENABLED); 
} 

@Override 
protected void onPause() { 
    super.onPause(); 
    setReceiverState(PackageManager.COMPONENT_ENABLED_STATE_DISABLED); 
} 


private void setReceiverState(int receiverState) { 
    ComponentName receiver = new ComponentName(this, FooBroadcastReceiver.class); 
    PackageManager pm = this.getPackageManager(); 
    pm.setComponentEnabledSetting(receiver, receiverState,  
    PackageManager.DONT_KILL_APP); 
} 

AndroidManifest.xml

<receiver android:name="com.example.receiver.FooBroadcastReceiver"> 
    <intent-filter> 
    <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> 
    </intent-filter> 
</receiver> 
+1

Có nghĩa là bạn không thể tạo một cái bình và sẽ phải là Thư viện Android :-) – Blundell

+1

trong trường hợp thư viện, khách hàng sẽ thêm người nhận vào bản kê khai và nó vẫn có thể là .jar. Mặc dù quá trình hợp nhất lib và manifest sẽ đẹp hơn: ( –

+1

BroadcastReceivers như thế này, không còn được kích hoạt khi nhắm mục tiêu API cấp 23 trở lên. Bạn phải đăng ký/hủy đăng ký chúng trong onResume()/onPause() – Ridcully

-2

xóa hai dòng sau chúng sẽ không được kích hoạt ở chế độ bật và bật!

registerReceiver(connectivityReceiver, intentFilter); 
unregisterReceiver(connectivityReceiver); 
+0

tại sao chúng không được áp dụng? – tipu

+5

Tư vấn tốt. Gỡ cài đặt ứng dụng của bạn và sẽ không có bất kỳ thông báo nào: D –

15

Phát sóng CONNECTIVITY_ACTION có vẻ dính trên một số thiết bị (mặc dù tài liệu ngụ ý rằng nó không được). Điều này có nghĩa là khi bạn đăng ký người nhận, nó sẽ ngay lập tức gọi onReceive() với chương trình phát sóng được gửi gần đây nhất. Vì bạn đang đăng ký và hủy đăng ký trong onPause()onResume() bạn sẽ nhận được rất nhiều cuộc gọi đến onReceive(). Bạn có thể muốn làm điều này theo một cách khác.

+0

i m phải đối mặt với cùng một vấn đề ..m đăng ký trên onStartCommand dịch vụ: IntentFilter filter = new IntentFilter ( ConnectivityManager.CONNECTIVITY_ACTION); registerReceiver (networkStateReceiver, filter); – KOTIOS

+0

@DIVA Khi OP cho biết, hãy sử dụng trình thu thập khai báo kê khai và không đăng ký người nhận bằng mã. –

+0

m phải đối mặt với vấn đề lạ ở đây: u có thể tham khảo http://pastie.org/pastes/9503426/text này khi tôi sử dụng hành động khác ngoài wifi và chạy mã nó sẽ không in "Trong phương pháp onreceive" nhưng khi tôi sử dụng bộ lọc IntentFilter = new IntentFilter ( Khả năng kết nốiManager.CONNECTIVITY_ACTION); nó in mà biết nếu wifi là tắt hoặc trên ..whats lý do – KOTIOS

1

Đây là một giải pháp mà làm việc cho tôi:

class FooActivity extends Activity {  

    private Intent mReceiverRegisteringIntent; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     broadcastReceiver = new FooBroadcastReceiver(); 
     intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     mReceiverRegisteringIntent = registerReceiver(connectivityReceiver, intentFilter);   
    } 

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


    private class MyBroadcastReceiver extends BroadcastReceiver { 

     @Override 
     public void onReceive(Context context, Intent intent) {  
      if (connectivityAction(intent)) { 
       Log.d("footag", "onReceive"); 
       //if mReceiverRegisteringIntent is not null, then this is the sticky 
       //broadcast received when registering the receiver for the first time 
       if (mReceiverRegisteringIntent != null) { 
        //set it to null for future broadcasts 
        mReceiverRegisteringIntent = null; 
        return; //do nothing 
       } 

       //logic for future broadcasts 
       ... 
      } 
     } 

     private boolean connectivityAction(Intent intent) { 
      return ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction()); 
     } 
    } 

} 

Tôi giả định rằng MyBroadcastReceiver là một lớp bên trong cho FooActivity để nó có thể truy cập vào mReceiverRegisteringIntent

+0

Cảm ơn rất nhiều! là giải pháp đúng. –

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