Sending Peer Intents

Binding to QPair Service

The main feature of the LG QPair SDK is sending Peer Intents to the peer device to make it do something. To do this, applications need to bind to the QPair service first of all.

 

The following code is an example for binding to the QPair service.

 

Intent intent = new Intent(QPairConstants.ACTION_SERVICE);
bindService(intent.setPackage(QPairConstants.PACKAGE_NAME), new QPairServiceConnection(), 0);

 

In QPair SDK revision 1, use QPairConstants.ACTION_QPAIR_SERVICE instead of QPairConstants.ACTION_SERVICE and remove setPackage().

Implementing ServiceConnection

Binding services in Android are asynchronous. You are only told whether the request was successfully received by the service when you request binding. You are notified of the actual result, i.e. whether the service was started and connected to the application successfully, afterward through a ServiceConnection interface.

 

Developers have to implement a ServiceConnection to monitor the service in order to do something that depends on the connection status. In this paragraph, 'connection' means the connection between an application and the QPair service. It is not a QPair connection.

 

For details on service binding, please refer to Bound Services on the Android developer website.

 

In the above code, QPairServiceConnection is a class that implements ServiceConnection. It has two callback methods: onServiceConnected() andonServiceDisconnected().Developers can add codes for their jobs in those callbacks.

 

An example for QPairServiceConnection is shown below.

 

public class QPairServiceConnection implements ServiceConnection {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        // Do something when the service is connected.
        ...
        unbindService(this);
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
       // Do something when the connection is lost.
       ...
    }
}

 

It is recommended that you unbind from the service when all the jobs are done. See the 6th line of the code block above.

 

Working with a Peer Intent

Specifically, the QPair service provides a Remote Process Call(RPC). Once the service is connected, the remote service object will be passed as an argument by means ofServiceConnection. You can cast it to an object that can be handled by QPair using the stub, and create a Peer Intent from it.

 

The following codes show how to get the remote service object and create a Peer Intent.

 

@Override
public void onServiceConnected(ComponentName name, IBinder service) {
    // get the remote service object as IPeerContext
    IPeerContext iPeerContext = IPeerContext.Stub.asInterface(service);

    IPeerIntent peerIntent = null;
    try {
        // create a Peer Intent
        peerIntent = iPeerContext.newPeerIntent();
    } catch (RemoteException e) {
        e.printStackTrace();
    }
}

 

With the above code, you are ready to send a Peer Intent to the peer device. Developers do not need to know what the peer device is or how it communicates.

To send the Peer Intent, developers set the information for the Peer Intent as they would for an Android Intent and then ask the peer device to do something by calling a QPair API with the Peer Intent.

 

The following codes are an example to show how to ask the peer device to start a particular service.

 
try {
    // set the package name of the service on the peer device
    IPeerIntent peerIntent = iPeerContext.newPeerIntent();
    peerIntent.setPackage("com.lge.p2pclients.sample.PeerSideService");

    // create callback to get the error messages
    IPeerIntent callback = iPeerContext.newPeerIntent();
    callback.setAction("com.lge.p2pclients.sample.ACTION_CALLBACK");

    // start service on the peer device 
    iPeerContext.startServiceOnPeer(peerIntent, callback, callback);
} catch (RemoteException e) {
    e.printStackTrace();
}

 

For more examples, such as starting an Activity, refer to Samples with the sample source code included in the SDK package.

 

Getting Results

In the above code block, you can see a Peer Intent callback. This is used for getting results. The QPair service will broadcast an intent with a given action name incallback when the API like startActivityOnPeer() is performed on the peer device. In the example above, the given action name iscom.lge.p2pclients.sample.ACTION_CALLBACK. To get results, you need to register a broadcast receiver for the given action

If you use the same variable as both of second and third arguments of startActivityOnPeer() as the above code block, the callback intent will be received when the API succeeds or fails. Of course, you can define success callback and failure callback separately. See Start Custom Activity on Peer.

 

In QPair SDK revision 1, startActivityOnPeer(), startServiceOnPeer(), sendBroadcastOnPeer(), startServiceOnPeerWithFile() only have failure callback as a parameter. See API Reference.

 

Error messages are attached to a failure callback if errors occur during communication with the peer device. You can retrieve error messages as follows:

 

 
BroadcastReceiver callbackReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        // retrieve the error cause
        String errorMessage = 
                         intent.getStringExtra(QPairConstants.EXTRA_CAUSE);
    }
};

...

//Register callback receiver for call back intent 
registerReceiver(callbackReceiver,
              new IntentFilter("com.lge.p2pclients.sample.ACTION_CALLBACK"));

 

All available error causes are described in the following table, and they are defined in the QPairConstants class.

 

Table 1. Error Messages

Error Message

Description

QPair is off

QPair is off on the local device.

QPair have internal error

An internal error has occurred.

Connection is not available

QPair is not available. Check whether Bluetooth is on.

Connection is not established

There is no QPair connection. The peer device may not be close enough to the local device.

Connection is not stable

The QPair connection is too unstable for communicate with the peer device.

Connection spit error

An error has occurred in the Android framework. A detailed error message is attached to the intent as an extra field with the name ‘QPairConstants.EXTRA_CAUSE’.

There is no destination on peer

The intent is not resolvable on the peer device. This error cannot occur through sendBroadcastOnPeer().

Exception is thrown on peer

The peer device throws an exception on casting. A detailed error message is attached to the intent as an extra with the name ‘QPairConstants.EXTRA_CAUSE’.

Checksum is not matched

File checksum is not matched between sender and receiver.

Sending Files

The QPair SDK provides a special API for sending files through the QPair connection: startServiceOnPeerWithFile(). A Peer Intent is also required, and the Peer Intent needs to contain the path and MIME type of the source file. See the following codes:

 

 
// gets source’s full path
String path = android.os.Environment.getExternalStorageDirectory().
                                                            getAbsolutePath()+ "/";
String filename = "mydir/myimage.jpg";
String imagePath = path + filename;

IPeerContext peerContext = IPeerContext.Stub.asInterface(service);
try {
    IPeerIntent peerIntent = peerContext.newPeerIntent();

    // set path and type of the source file
    peerIntent.setDataAndType(imagePath, "image/*");
    // set service to be started on peer
    peerIntent.setPackage("com.lge.p2pclients.sample.PeerSideService");
    // call APIs to send the file and Peer Intent
    peerContext.startServiceOnPeerWithFile(peerIntent, "myimage.jpg", 
null, null);
} catch (RemoteException e) {
    ...
}

 

The file myimage.jpg in the external storage directory mydir will be sent to the peer device. The file path on the peer device will be ‘myimage.jpg’ in the default storage. The PeerSideService service will be started if the file is sent successfully.

You must set success callback and failure callback in startServiceOnPeerWithFile().

QPair uses Bluetooth 2.0 because the minimum SDK for target devices is Android API level 16 and it only supports Bluetooth 2.0.
In addition, file transmission over QPair has low priority. The transmission might be delayed if there is any urgent QPair data. In conclusion, file transmission speed over QPair may not be same to the theoretical speed of Bluetooth 2.0. If you want to send files faster, open your own Bluetooth socket with the ‘bluetooth_address’ property and use it for file transmission.

In QPair SDK revision 1, startServiceOnPeerWithFile() only has failure callback as a parameter. See API References.

 

Navigation