Вопрос по service, broadcastreceiver, bluetooth, android – Не удается вызвать метод Bluetooth BroadcastReceiver в службе

0

У меня есть этот класс обслуживания:

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

И в моем классе деятельности у меня есть это:

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

Метод BroadcastReceiver (bluetoothReceiver) в классе Service никогда не вызывается. Я не знаю почему. Если у меня есть коды 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, поэтому то, что я делаю, может быть не самым лучшим. Надеюсь, кто-нибудь может мне помочь.

Вы дали разрешение Bluetooth в AndroidManifest.xml? Lucifer
Вы зарегистрировали Receiver в Манифесте и, как сказал @Lucifer, вы взяли Разрешение ?? Даже я не думаю, что вы можете сделать TextView tvStatus = (TextView) mActivity.findViewById (R.id.tvtatus); в твоем приемнике ..? AAnkit
Да, у меня есть эти разрешения в AndroidManifest.xml: & lt; использует-разрешение android: name = & quot; android.permission.BLUETOOTH & quot; / & GT; & lt; использует разрешение Android: имя = & quot; android.permission.BLUETOOTH_ADMIN & quot; / & GT; ChuongPham

Ваш Ответ

1   ответ
4

может быть тот факт, чтоyour receiver is static вызывая проблему.

BroadcastReceiver никогда не должно быть статичным. это может вызвать много проблем.

Другая действительно плохая проблема дизайна с вашим кодом - хранение ссылки на активность внутри сервиса и использование ее для изменения представлений - это действительно неправильная вещь. это может легко вызвать лук-порей. право зачем общаться междуService а такжеActivity является реализацией AndroidMessangerили отправка трансляций между ними черезBroadcastReceiver.

если вы прислушиваетесь к моему совету - вам не придется делать ваш приемник статичным (я полагаю, вы сделали его статичным только потому, что вы используете статический экземпляр mActivity внутри) и я уверен, что это решит вашу проблему

Вы можете прочитать оMessanger Вот:http://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
    }
};
}
@ Чуонг: я не хочу начинать спорить о том, возможно это или нет. если все, что делает ваш приемник, это настройки текста в textView, зачем вам нужен сервис? это классическая причина для реализации получателя внутри действия
@ Чуонг: подождите секунду, я напишу вам в качестве примера из моего собственного проекта, который я использую Messanger
Я не спорю с тобой. Я просто говорю, что пока не могу найти способ использовать класс Messenger (потому что я не знаю, как). Вот и все. Надеюсь, это прояснит любое недоразумение ChuongPham
@ Чуонг: знаете что? - Думаю, вам лучше вместо этого использовать трансляции. вам нужно зарегистрировать свою активность на какой-то трансляции, которую отправит ваша служба. это второй вариант, который я предложил в своем ответе. тебе нужен пример как это сделать? в любом случае - это хороший пример, который я нашел:websmithing.com/2011/02/01/…
Делать приемник нестатичным не имеет значения. Я видел класс Messenger ранее, но не могу найти способ, чтобы этот класс мог отправлять прогрессивно обновленные сообщения, полученные от BroadcastReceiver, для такого намерения, как BluetoothAdapter.EXTRA_STATE. ChuongPham

Похожие вопросы