无法在服务中调用蓝牙BroadcastReceiver方法

时间:2012-08-03 05:51:30

标签: android service bluetooth broadcastreceiver

我有这个服务类:

 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());
                }               
            }
        }
    };  
}

在我的Activity课程中,我有这个:

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);
    }
}

从不调用Service类中的BroadcastReceiver方法(bluetoothReceiver)。我不知道为什么。如果我在一个Activity中首先拥有IntentFilter和BroadcastReceiver代码,那么它可以工作 - 但不能在[单独的]服务中使用。我很难过。

我的AndroidManifest.xml是:

    <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>

我是Android的新手,所以我所做的可能不是最好的。希望有人可以帮助我。

1 个答案:

答案 0 :(得分:4)

可能你的接收器是静态的导致了这个问题。

BroadcastReceiver永远不应该是静态的。它可能会导致很多问题。

您的代码的其他非常糟糕的设计问题 - 保持对服务内部活动的引用,并使用它来修改视图是非常错误的事情。它可以很容易地记忆韭菜。 ServiceActivity之间进行通信的正确方法是实现android的Messanger,或通过BroadcastReceiver在它们之间发送广播。

如果您听取我的意见 - 您将无需使接收器静止(我猜您已将其设为静态,因为您正在使用内部的mActivity静态实例) 而且我很确定它会解决你的问题

您可以在此处阅读Messangerhttp://developer.android.com/reference/android/os/Messenger.html

确定你会在网上找到很多用法示例。

从服务广播活动更新的示例:

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);
}

}

这就是活动:

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
    }
};
}