Can't call a Bluetooth BroadcastReceiver method in a Service

匿名 (未验证) 提交于 2019-12-03 02:29:01

问题:

I have this Service class:

 public class BluetoothService extends Service {      private static Activity mActivity;      @Override     public IBinder onBind(Intent intent) {         return null;     }      @Override     public void onCreate() {         IntentFilter intentFilter = new IntentFilter();         intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);         this.registerReceiver(bluetoothReceiver, intentFilter);          }      @Override     public void onDestroy() {         if (bluetoothReceiver != null) {             this.unregisterReceiver(bluetoothReceiver);         }            }      @Override     public void onStart(Intent intent, int startid) {            //     }      @Override     public int onStartCommand(Intent intent, int flags, int startId) {                 return START_STICKY;     }      public static BroadcastReceiver bluetoothReceiver = new BroadcastReceiver(){         @Override         public void onReceive(Context context, Intent intent) {             if (intent.getAction().equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {                 final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);                 TextView tvStatus = (TextView) mActivity.findViewById(R.id.tvtatus);                 Messaging.appendMessage(tvStatus, Bluetooth.getDeviceState(state));                 if (Bluetooth.isBluetoothEnabled()) {                     Messaging.appendMessage(tvStatus, Bluetooth.showMessage());                 }                            }         }     };   } 

And in my Activity class, I have this:

public class MainActivity extends Activity {      private TextView tvStatus;     private Intent intentBluetooth;      @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);         tvStatus = (TextView)findViewById(R.id.tvtatus);         intentBluetooth = new Intent(this, BluetoothService.class);        startService(intentBluetooth);     } } 

The BroadcastReceiver method (bluetoothReceiver) in the Service class is never called. I don't know why. If I have the IntentFilter and the BroadcastReceiver codes above all in an Activity, then it works - but not in a [separate] Service. I'm stumped.

My AndroidManifest.xml is:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"         package="com.onegoal.androidexample"         android:versionCode="1"         android:versionName="1.0.0"          android:installLocation="auto"         android:hardwareAccelerated="true">          <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="15" />          <uses-permission android:name="android.permission.BLUETOOTH" />         <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />         <uses-feature android:name="android.hardware.bluetooth" android:required="false" />           <application             android:icon="@drawable/ic_launcher"             android:label="@string/app_name"             android:theme="@style/AppTheme"              android:debuggable="true" >             <activity                 android:name=".MainActivity"                 android:label="@string/app_name"                 android:theme="@android:style/Theme.NoTitleBar" >                 <intent-filter>                     <action android:name="android.intent.action.MAIN" />                     <category android:name="android.intent.category.LAUNCHER" />                 </intent-filter>             </activity>             <service android:name=".BluetoothService">             </service>         </application>       </manifest> 

I'm new to Android so what I'm doing may not be the best. Hope someone can help me.

回答1:

maybe the fact that your receiver is static causing the problem.

BroadcastReceiver should never be static. it can cause lots of problems.

other really bad design problem with your code - holding reference to activity inside service, and using it to modify views is really wrong thing to do. it can cause easily to memory leek. the right why to communicate between Service and Activity is by implement android's Messanger, or sending broadcasts between them via BroadcastReceiver.

if you'll listen to my advice - you won't be have to make your receiver static (I guess you've made it static only because you are using the mActivity static instance inside) and I'm pretty sure it will solve your problem

you can read about Messanger here: http://developer.android.com/reference/android/os/Messenger.html

sure you'll find lots of usage examples in the net.

example of broadcasting updates to the activity from service:

public class MyService extends Service {  @Override public IBinder onBind(Intent arg0) {     // TODO Auto-generated method stub     return null; }  @Override public void onCreate() {     super.onCreate();      IntentFilter intentFilter = new IntentFilter();     intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);     this.registerReceiver(bluetoothReceiver, intentFilter); }  @Override public void onDestroy() {     if (bluetoothReceiver != null) {         this.unregisterReceiver(bluetoothReceiver);     }     super.onDestroy(); }  public BroadcastReceiver bluetoothReceiver = new BroadcastReceiver() {     @Override     public void onReceive(Context context, Intent intent) {         if (intent.getAction().equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {             final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);             updateUIWithNewState(state);         }     } };  protected void updateUIWithNewState(int state) {     Intent intent = new Intent("serviceUpdateReceivedAction");     intent.putExtra("state", state);     sendBroadcast(intent); }  } 

and that's the activity:

public class MyActivity extends Activity {  @Override protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);      Intent intent = new Intent(this, MyService.class);     startService(intent); }  @Override protected void onResume() {     super.onResume();      registerReceiver(mServiceUpdatesReceiver, new IntentFilter("serviceUpdateReceivedAction")); }  @Override protected void onPause() {     unregisterReceiver(mServiceUpdatesReceiver);     super.onPause(); }  private BroadcastReceiver mServiceUpdatesReceiver = new BroadcastReceiver() {      @Override     public void onReceive(Context context, Intent intent) {         int state = intent.getIntExtra("state", -1);         // do what ever you want in the UI according to the state     } }; } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!