简体   繁体   中英

How to pass message to Bluetooth Activity from another activity



I build an Android app that control RC car. This app have two activities, Bluetooth Activity and Direction Activity.

In Bluetooth activity I used list view to list all the devices and connect with one. I used the two class provided by Android "ConnectThread" and "ConnectedThread" . My main job is to only send character to the RC car to move. This character is generated by the Direction Activity which use Acceleration sensor to generate a character.

Problems:

1. how to send character from the Direction Activity to the Bluetooth activity?
2. After the Bluetooth Activity received the character how to send it over the Bluetooth connection?
3. Do I need the two classes "ConnectThread" and "ConnectedThread" to connect and send or just one of them?

PS. I am beginner and I have tried many things like intent, shared Preference, and Bundle. But every time I try an error occur.

Alright, let's make it simple for the moment.

As stated by @Zimano comments:

  1. You can use, like you tried, intents to share basic data (Strings, ints, floats, bytes) between your Activities, that is the most common way to do in Android. More details here: https://stackoverflow.com/a/19287072/3535408
  2. If you need to send data over the Bluetooth connexion, you have to have access to the ConnectedThread if you implemented Google's solution. But if you are the beginner you say you are (and it's not a problem or wrong) be aware that Android Activities have a life cycle . This basically means that at some point an Activity is created , starts , stops and finally ends up utterly destroyed . So if you started your Connection and Connected threads inside an Activity and you switch to another Activity, there is high and unvoidable risk that these threads will be killed as the Activity that started them is being destroyed for liberating resources (dearly important to the Android eco-system).

Two solutions. One easy but not recommandable, and one a bit complicated but part of the Android SDK and policy.

  1. Static Context or
  2. Services ;

In the first case, move all the code related to the Bluetooth outside your Activity into another class. Place it in a static context so that it can be used everywhere in the app (which is why it's a very poor design pattern but a working one...). Then you can access your Bluetooth threads everywhere and you can use the write method to send data ;

In the second case, move the same code into a service. Services are part of the Android SDK and are the way-to-go for what you want to achieve. But there are bind to an Activity. I did not handle a lot of Services in my experience so I am not sure if you can bind/unbind Android services at will whithout stopping the Bluetooth threads alonside as you switch between activities. More details here : http://developer.android.com/intl/es/guide/components/services.html

Anyway I hope I provided enough explaination so that you can work on your issue. If you have questions I will try to answer them.

@Mackovich Thank you very much and also the others who tried to help. For the sake of other people who is having same problem. this is my solution after searching for long time.

PS one thing I want to mention, I read about "Services" and it the right way. But I did it in other simple way.

I have two activities (1) Bluetooth search activity, and (2) Direction activity.

My problem was that I tried to do all the Bluetooth stuuf in activity (1) and just send command from activity (2) to (1) which will send it to the RC Car. And this is problem because as @Mackovich said the activity may be destroyed .

What did I do to solve is?

In activity (1) I used a ListView to display the Bluetooth devices broadcasting and to get these devices info. Then use an Intent to pass these info to the activity (2). Instated of connecting and trying to send in activity (1).

Note: In order to make a Bluetooth connection you need two important information:


1. UUID (which we aleard have).
2. MAC Address of the targeted Bluetooth device. (Which we get it form activity(1)).

So, first we need Bluetooth Adapter, Array Adapter (To holed the info of devices found) and Broadcast Receiver.

//Declare Bluetooth Stuff
    BluetoothAdapter mBluetoothAdapter; // Make instance of the Bluetooth
    ArrayAdapter mArrayAdapter; // Array where the devices will be stored
    private static final int ENABLE_BT_REQUEST_CODE = 1;
    private static final int DISCOVERABLE_BT_REQUEST_CODE = 2;
    private static final int DISCOVERABLE_DURATION = 300;
    public static String EXTRA_ADDRESS = "Device_MAC_Address";

    //In order for the bluetooth to discover the devices that broadcasting and obtain their info.
    BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            // Whenever a remote Bluetooth device is found
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                // Get the BluetoothDevice object from the Intent
                BluetoothDevice mBluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                // Add the name and address to an array adapter to show in a ListView
                mArrayAdapter.add(mBluetoothDevice.getName() + "\n" + mBluetoothDevice.getAddress());
            } else {
                Toast.makeText(getApplicationContext(), "No Paired Bluetooth Devices Found.", Toast.LENGTH_LONG).show();
            }
        }
    };

Then, after the user select one of the devices listed. We will obtain the device MAC address and send it to activity (2) to connect and send.

//Obtain the value of the item clicked as String value
                String itemValue = (String) DevicesList.getItemAtPosition(position);
                //Extract the MAC Address from the String value above
                String MAC = itemValue.substring(itemValue.length() - 17);
                // Make an intent to start next activity.
                Intent i = new Intent(BluetoothActivity.this, NavigationActivity.class);
                //Change the activity.
                i.putExtra(EXTRA_ADDRESS, MAC); //this will be received at  NavigationActivity(class) Activity
                startActivity(i);
            }
        });

Now, We solved the problem of passing data between activities. Because there is no need foe passing data.

This was for the Problem (1) in original post.

As for problem (2). The problem is if you used the code provided by Google. There is things you need to adjust. In the class ConnectThread insaid run method you need to define the object of the class ConnectedThread you created. By this way you will pass the BluetoothSocket variable used to connect to send data throw it.

And that also solves problem (3). And yes you need the two classes.

As I said in the Original Post I am beginner. So, I figured that what is the best way to explain to beginners is to think like one. Which in this case I am actually beginner.

I hope this is going to help someone else. And PLEASE if some find any thing in this is wrong. PLEASE tell me to correct it.

Thank you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM