3

I have a method where I register broadcast receivers using intent filters to discover bluetooth devices.

// global variable
 String xpto = "empty";

Here is the void method:

IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);

            BroadcastReceiver mReceiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {

                     App appState = ((App)getApplicationContext());
                     appState.setTeste("OLAAAAA");

                    String action = intent.getAction();

                    elementos = new Vector<String>();

                    String delimiter = "_";
                    String[] temp = null;

                    xpto = "OLA";

                    // When discovery finds a device
                    if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                        // Get the BluetoothDevice object from the Intent
                        BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);


                        // SO VAI VERIFICAR DO QUE ESTAO PRESENTES (DISCOVERABLE) OS QUE ESTAO PAIRED
                        if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
                            Log.v("TAG","PAIRED AND PRESENT="+device.getName());
                            temp = device.getName().split(delimiter);
                        }

                        int aux = 0;

                        if(temp != null)
                        {
                            for(int i =0; i < temp.length ; i++)
                            {
                                if(temp[aux].equals("SapoFit"))
                                {
                                    elementos.add(temp[aux]+"_"+temp[aux+1]);
                                    Log.v("TAG","Seleccionado="+temp[aux]+"_"+temp[aux+1]);
                                }
                                aux++;
                            }

                            elSelecionado = temp[0]+"_"+temp[0+1];

                        }

                    } 

                }
            };

            this.registerReceiver(mReceiver, filter);

            Log.v("TAG","HERE COMES empty="+xpto.toString());

My problem is: because the code in that method is executed sequentially, by the time I try to use (in that method in the sequence) some global variables I allocate in Broadcast Receiver, they are still null or empty.

I've though in some "solutions" like moving my "main code" from place to broadcast receiver, or having some other global variable alocated to 1 when B.R is finished (and a while x =! 1 in main code to wait) but this is not good programming, I'm sure there is a correct way to do that.

I've found PendingResult but is API Level 11, too high for me. Any suggestions?

Tiago
  • 1,116
  • 5
  • 25
  • 39

2 Answers2

1

If it is used by multiple components and is truly "global" to your application, you may extend the Application object and use it there. This means the it will be allocated before either of your components starts and it is accessible to all of your components. It is also "safe" and recommended by many as "global" variables are outside of the Lifecycle as is the Application object. As long as both Components are not either reading and writing at the SAME instant, you should be fine. If you foresee an issue there, you can make the code thread-safe by synchronizing it, as well.

A word of warning on extending the Application. This should not be used for everything that requires multiple objects to access it. This should only be used for data that needs to remain outside of the Lifecycle out of necessity.

Please let me know if you need clarification on how to extend an Application and access the new data.

Hope this helps, FuzzicalLogic

Fuzzical Logic
  • 12,947
  • 2
  • 30
  • 58
  • I'm put this code http://pastebin.com/mXG6iyW6 the class App in another file and added that in the manifest, but I'm still getting nulls. What am I not understanding? – Tiago Jan 05 '12 at 15:12
  • I'll take a look. Null is just one of those things that we have to deal with. :) – Fuzzical Logic Jan 05 '12 at 21:57
  • After looking at your code, 1) In your Activity, don't use getApplicationContext(). Use getApplication(). Activities have access to both. Both are similar, but have access to different information. 2) You might be running into a situation where the processsing is too efficient and the Application might be dying. Making the state (and its getter and setter) static may resolve this and this is a safe place to do this (even recommended by Google for when you need to persist outside the Android Lifecycle of objects). – Fuzzical Logic Jan 05 '12 at 22:22
  • Also, if you make the Application object a Singleton (which it essentially is anyway), it will also keep its data. Just don't store any references to a Lifecycle manage object in it and you will be fine. – Fuzzical Logic Jan 05 '12 at 22:24
1

Maybe you can use wait() and notify().. Take care to do it synchronyzed:

NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

synchronized (nm) {
            try {
                // Esperar a que finalice la descarga
                nm.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

Refer to Threading in Java: How to lock an object? and also how to fire notification from BroadcastReceiver?

Community
  • 1
  • 1
Miquel
  • 8,339
  • 11
  • 59
  • 82