Sunday, December 22, 2013

Implement Socket on Android to communicate with Raspberry Pi

There is a post "Java exercise - Implement client and server to communicate using Socket" in my another blog, Hello Raspberry Pi. In which, both host (implement ServerSocket and Socket) and client (implement Socket) are run on Raspberry Pi to setup communication between application via socket. Actually both the host and client can run on any PC with Java.

The client side in the post is ported to Android in this exercise, setup Socket in AsyncTask, to communicate with Raspberry Pi. The updated version of Host (run socket operation in background thread) run on Raspberry Pi or any other PC is here.

Implement Socket on Android to communicate with Raspberry Pi
Implement Socket on Android
MainActivity.java
package com.example.androidclient;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.UnknownHostException;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends Activity {
 
 TextView textResponse;
 EditText editTextAddress, editTextPort; 
 Button buttonConnect, buttonClear;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  editTextAddress = (EditText)findViewById(R.id.address);
  editTextPort = (EditText)findViewById(R.id.port);
  buttonConnect = (Button)findViewById(R.id.connect);
  buttonClear = (Button)findViewById(R.id.clear);
  textResponse = (TextView)findViewById(R.id.response);
  
  buttonConnect.setOnClickListener(buttonConnectOnClickListener);
  
  buttonClear.setOnClickListener(new OnClickListener(){

   @Override
   public void onClick(View v) {
    textResponse.setText("");
   }});
 }
 
 OnClickListener buttonConnectOnClickListener = 
   new OnClickListener(){

    @Override
    public void onClick(View arg0) {
     /*
      * You have to verify editTextAddress and
      * editTextPort are input as correct format.
      */
     
     MyClientTask myClientTask = new MyClientTask(
       editTextAddress.getText().toString(),
       Integer.parseInt(editTextPort.getText().toString()));
     myClientTask.execute();
    }};

 public class MyClientTask extends AsyncTask<Void, Void, Void> {
  
  String dstAddress;
  int dstPort;
  String response;
  
  MyClientTask(String addr, int port){
   dstAddress = addr;
   dstPort = port;
  }

  @Override
  protected Void doInBackground(Void... arg0) {
   
   try {
    Socket socket = new Socket(dstAddress, dstPort);
    InputStream inputStream = socket.getInputStream();
    ByteArrayOutputStream byteArrayOutputStream = 
                  new ByteArrayOutputStream(1024);
    byte[] buffer = new byte[1024];
    
    int bytesRead;
             while ((bytesRead = inputStream.read(buffer)) != -1){
                 byteArrayOutputStream.write(buffer, 0, bytesRead);
             }
             
             socket.close();
             response = byteArrayOutputStream.toString("UTF-8");
    
   } catch (UnknownHostException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   return null;
  }

  @Override
  protected void onPostExecute(Void result) {
   textResponse.setText(response);
   super.onPostExecute(result);
  }
  
 }

}


Layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:autoLink="web"
        android:text="http://android-er.blogspot.com/"
        android:textStyle="bold" />
    <EditText 
        android:id="@+id/address"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="dstAddress" />
    <EditText 
        android:id="@+id/port"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="dstPort" />
    <Button 
        android:id="@+id/connect"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Connect..."/>
    <Button 
        android:id="@+id/clear"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Clear"/>
    <TextView
        android:id="@+id/response"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>


AndroidManifest.xml have to be modified to add <uses-permission android:name="android.permission.INTERNET"/>



download filesDownload the files.

or Download and install the APK file.

Related:
Java Network exercise: client and server - client send something to server
Android client to send message to Java server on Raspberry Pi


Cross-post with Hello Raspberry Pi

2 comments:

Tushar Sahni said...

will this code work in simulator ??
I am trying on simulator.Nothing is happening.Neither app is crashing nor some log is coming.Do i need to run the app on device.Then it will work

Waiting for reply

Skype : tushar1271921
Email : tusharsahni50@gmail.com

Andr.oid Eric said...

Hello Tushar Sahni,

I haven't tried on emulator, sorry.