Handling binary responses in native Android using Java adapters
Nathan Hazout May 01, 2016
MobileFirst_Platform Binary Java Adapters AndroidOverview
In this example, I will show a native Android application that can convert a string to a QR code. The user will input a string (for example a URL), submit it to the Java Adapter, which will in turn send an image representing the QR code. The Android application will handle the binary data and display the image.Adapter code
This section is the same as the iOS version. I've created a MobileFirst project calledBinaryResponse
. In it I've added a Java Adapter called QR
.
To make the QR generation easier, I am using the ZXing library. I've copied core-3.2.0.jar and javase-3.2.0.jar into the lib
folder of my adapter.
I left QRApplication.java
as-is and wrote my code in QRResource.java
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Path("/")
public class QRResource {
//Define logger (Standard java.util.Logger)
static Logger logger = Logger.getLogger(QRResource.class.getName());
//Define the server api to be able to perform server operations
WLServerAPI api = WLServerAPIProvider.getWLServerAPI();
@GET
@Path("/{itemId}")
@Produces("image/png")
public Response getQR(@PathParam(value="itemId") String id) throws WriterException, IOException{
QRCodeWriter writter = new QRCodeWriter();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
BitMatrix bitMatrix = writter.encode(id, BarcodeFormat.QR_CODE, 200, 200);
MatrixToImageWriter.writeToStream(bitMatrix, "png", stream);
return Response.ok(stream.toByteArray(), "image/png").build();
}
}
@Path("/")
at line 1 to define that the URL path for my resource should just be /adapters/adapterName.
The adapter resource file contains only one method, getQR
, which can be accessed via HTTP GET
using the path @Path("/{itemId}")
at line 11, where itemId
is the string provided by the user.
The method uses @Produces("image/png")
and automatically adds the image/png
Content-Type in the response.
The implementation details of this method are out of scope and can be understood from the ZXing documentation. All I did was use QRCodeWriter
to encode the string to a 200 by 200 bar code. The resulting stream is returned in the response.
Android Studio Project
I've created a new Android project namedBinaryResponse
and configured it to use MobileFirst Platform.
The UI simply shows an EditText
to enter the string, a Button
to trigger the request and a ImageView
to display the generated QRCode.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WLClient client = WLClient.createInstance(this);
buttonInvoke = (Button)findViewById(R.id.generate);
codeInput = (EditText)findViewById(R.id.code);
imageView = (ImageView)findViewById(R.id.imageView);
final MainActivity activity = this;
buttonInvoke.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
Editable input = codeInput.getText();
String code = URLEncoder.encode(input.toString(), "utf-8");
URI adapterPath = new URI("/adapters/QR/" + code);
WLResourceRequest request = new WLResourceRequest(adapterPath,WLResourceRequest.GET);
request.send(new MyInvokeListener(activity));
} catch (URISyntaxException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
});
}
Clicking on the Generate button creates a WLResourceRequest
that points to the adapter URL, with the user provided string appended.
I used send(WLHttpResponseListener)
and created a new class called MyInvokeListener
to handle the response.
MyInvokeListener
implements WLHttpResponseListener
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public MyInvokeListener(MainActivity activity) {
Log.v(TAG, "MyInvokeListener constructor");
this.activity = activity;
}
@Override
public void onFailure(HttpResponse httpResponse, Exception e) {
Log.v(TAG, "onFailure");
}
@Override
public void onSuccess(HttpResponse httpResponse) {
Log.v(TAG, "onSuccess");
HttpEntity entity = httpResponse.getEntity();
try {
InputStream content = entity.getContent();
activity.setImage(content);
} catch (IOException e) {
e.printStackTrace();
}
}
The onSuccess
method receives a raw HttpResponse
object. The content is extracted as an InputStream
.
Back in the MainActivity
there is a method to take that InputStream
and use it to display the image.
1
2
3
4
5
6
7
8
9
10
11
12
13
public void setImage(final InputStream input){
runOnUiThread(new Runnable() {
@Override
public void run() {
imageView.setImageBitmap(BitmapFactory.decodeStream(input));
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
Sample
You can find the code for this example on GitHub.
For best results, make sure you use MobileFirst with the latest iFix available by checking for updates in Eclipse, or IBM Fix Central if you have installed a Studio version from there.

Inclusive terminology note: The Mobile First Platform team is making changes to support the IBM® initiative to replace racially biased and other discriminatory language in our code and content with more inclusive language. While IBM values the use of inclusive language, terms that are outside of IBM's direct influence are sometimes required for the sake of maintaining user understanding. As other industry leaders join IBM in embracing the use of inclusive language, IBM will continue to update the documentation to reflect those changes.
Last modified on May 01, 2016