Autore Topic: Chiarire Funzionamento BroadcastReceiver  (Letto 1125 volte)

Offline dr4gone

  • Utente junior
  • **
  • Post: 66
  • Respect: +1
    • Mostra profilo
Chiarire Funzionamento BroadcastReceiver
« il: 02 Febbraio 2013, 12:33:35 CET »
0
Ciao a tutti , sto cercando di capire il funzionamento di questo importante strumento. ma ho delle difficoltà:

1 - Gestire correttamente il register e l'unregister del Broadcast receiver
2 - Passare dati dal broadcastreceiver all'activity in ricezione.

La cosa che vorrei fare come esempio è usare un BR (broadcastreceiver) per sentire i cambiamenti di stato del modulo bluetooth, e ritornare in una textview sull'activity principale lo stato in cui si trova al momento il bluetooth.
Non dovrebbe essere una cosa complicatissima per iniziare.
Ma ho  dei problemi durante l'implementazione, cioè riesco a farlo funzionare legegndo lo stato sul DDMS, ma non riesco a passare lo stato alla textview nell' activity principale... (mi sfugge qualcosa)... Credo  che questo
Codice (Java): [Seleziona]
 stato=myIntent.getStringExtra("stato"); sia il mio problema. (sotto ho messo il codice completo).

Altro problema fastidioso si verifica quando chiudo l'applicazione  mi ritorna un eccezione e il logcat mi dice: Unable to destroy activity {com.example.broadcasttest/com.example.broadcasttest.MainActivity}: java.lang.IllegalArgumentException: Receiver not registered: null

Ora suppongo che io non registri correttamente il Receiver.. e quindi ovviamente se non è registrato non posso cancellarlo.. Ma come devo fare??

Android manifest.xml
Ecco il codice che ho scritto:
Codice (XML): [Seleziona]
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.example.broadcasttest"
   android:versionCode="1"
   android:versionName="1.0" >

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

    <application
     
       android:label="@string/app_name" >
           <activity
           android:name=".MainActivity"
           android:label="test" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
       
        <receiver android:name="MyBluetoothReceiver" >
            <intent-filter>
                <action android:name="android.bluetooth.adapter.action.STATE_CHANGED" >
                </action>
            </intent-filter>
        </receiver>
    </application>

MyBluetoothReceiver
Codice (Java): [Seleziona]
package com.example.broadcasttest;

import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class MyBluetoothReceiver extends BroadcastReceiver {
        public static  String status = "null";
  @Override
  public void onReceive(Context context, Intent intent) {
      final String action = intent.getAction();
     

      if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
          final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
                                               BluetoothAdapter.ERROR);
         
          switch (state) {
          case BluetoothAdapter.STATE_OFF:
                  setStatus("BT_off");
              break;
          case BluetoothAdapter.STATE_TURNING_OFF:
                  setStatus("TurningBT_off...");
              break;
          case BluetoothAdapter.STATE_ON:
                  setStatus("BT_on");
              break;
          case BluetoothAdapter.STATE_TURNING_ON:
                  setStatus("TurningBT_on...");
              break;
          }
          Intent myIntent = new Intent(context, MainActivity.class);
          myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
          myIntent.putExtra("stato",status);
          context.startActivity(myIntent);  
         
          Log.i("BTstatus", getStatus());
      }
  }
/**
 * @return the status
 */

public static String getStatus() {
        return status;
}
/**
 * @param status the status to set
 */

 public void setStatus(String status) {
        this.status = status;
}
 
 
}

E activity Principale
Codice (Java): [Seleziona]
package com.example.broadcasttest;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

public class MainActivity extends Activity {
         
        BroadcastReceiver mBtReceiver;
        public String stato = "";
        TextView textView;
               
public void onCreate(Bundle savedInstanceState) {
                    super.onCreate(savedInstanceState);
                    setContentView(R.layout.activity_main);
                   
                   
                    // Registro il broadcasts BluetoothAdapter state change
                    IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
                    this.registerReceiver(mBtReceiver, filter);
                   
                    // Richiamiamo i valori dello stato del Bluetooth
                    Intent myIntent=getIntent();
                stato=myIntent.getStringExtra("stato");
               // Log.i("Status in Activity", stato);
                   
                    if (stato!=null){
                        textView = new TextView(getApplicationContext());
                textView.setText(stato);
                textView.setTextSize(20);
                textView.setLines(1);
                    }
                    else{
                       
                        textView = new TextView(getApplicationContext());
                textView.setText("null");
                textView.setTextSize(20);
                textView.setLines(1);
                    }
                   
                   
                   
                   
                   
                }

                @Override
                public void onDestroy() {
                    super.onDestroy();

                        // Cancello il  broadcast listener
                    unregisterReceiver(mBtReceiver);
                }
        }
Qualcuno mi sa spiegare cosa sbaglio ?
O indirizzarmi a capire i due errori?

Grazie

Offline GabMarioPower

  • Moderatore globale
  • Utente senior
  • *****
  • Post: 606
  • Respect: +153
    • Github
    • Google+
    • gabrielemariotti
    • GabMarioPower
    • Mostra profilo
  • Play Store ID:
    GAB+MARIO+DEV
  • Sistema operativo:
    Ubuntu 14.04 , Win 10
Re:Chiarire Funzionamento BroadcastReceiver
« Risposta #1 il: 02 Febbraio 2013, 13:55:50 CET »
+1
Ci sono alcune cose su cui devi porre l'attenzione.

Senza entrare troppo nel dettaglio (meriterebbe un tutorial)  il BroadcastReceiver può essere registrato nel Manifest o tramite codice.
Le due cose non sono equivalenti e dipende da cosa si vuole realizzare.
Se è registrato a codice tramite il register e unregister il BroadcastReceiver vive nel contesto in cui è stato creato.
Tu lo hai registrato sia nel manifest sia attraverso un  register.... attenzione! Prova ad andare in debug e vedere quale parte.

Seconda cosa è dove hai posizionato il register e l'unregister.
Buona norma è metterli nel
Codice (Java): [Seleziona]
onResume() e nel
Codice (Java): [Seleziona]
onPause() .

Altro dettaglio è questo:
Codice (Java): [Seleziona]
myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);Se leggi la documentazione trovi che:
When using this flag, if a task is already running for the activity you are now starting, then a new activity will not be started; instead, the current task will simply be brought to the front of the screen with the state it was last in

Questo è legato al concetto sopra di register e unregister. Anche qui prova ad andare in debug per capire cosa succede.

Ultima cosa molto importante.
Se un BroadcastReceiver è registrato tramite il register dentro una Activity, viene eseguito nella main Thread UI. Questo implica che l'elaborazione che metti nel onReceiver() blocca la UI e può essere lunga altrimenti l'applicazione viene forzata e chiusa con un messaggio di errore.



Offline dr4gone

  • Utente junior
  • **
  • Post: 66
  • Respect: +1
    • Mostra profilo
Re:Chiarire Funzionamento BroadcastReceiver
« Risposta #2 il: 02 Febbraio 2013, 18:50:07 CET »
0
Grazie dei chiarimenti.
Proverò tutto quello che hai suggerito.  ;-)