Monday, March 11, 2013

Hello World ADK: Android code

Last post demonstrate my Hello World ADK, with sample code in Arduino Due side. Here is the sample code in Android side.

Hello World ADK: Communication between Arduino Due and Android device
Check last post to view demo video and sample code in Arduino Due side



- Modify AndroidManifest.xml to <uses-festure>, <uses-library>, <intent-filter>, and <meta-data>.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.helloadk"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="10"
        android:targetSdkVersion="17" />
    
    <uses-feature android:name="android.hardware.usb.accessory"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <uses-library android:name="com.android.future.usb.accessory"/>
        <activity
            android:name="com.example.helloadk.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
            </intent-filter>
            <meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
                android:resource="@xml/myfilter"/>
        </activity>
    </application>

</manifest>


- Craete /res/xml/myfilter.xml to to define resource of usb-accessory (update version="0.1" to match latest versionNumber in HelloADK Arduino code).

<?xml version="1.0" encoding="UTF-8"?>
<resources>
    <usb-accessory
        manufacturer="Arduino-er"
        model="HelloADK"
        version="0.1"/>
</resources>


Main Java code, MainActivity.java.

/*
 * manufacturer="Arduino-er"
 * model="HelloADK"
 * version="0.1"
 */

package com.example.helloadk;

import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import com.android.future.usb.UsbAccessory;
import com.android.future.usb.UsbManager;

import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
 
 EditText textOut;
 TextView textIn;
 Button btnSend;
 
 private UsbManager myUsbManager;
 private UsbAccessory myUsbAccessory;
 private ParcelFileDescriptor myParcelFileDescriptor;
 private FileInputStream myFileInputStream;
 private FileOutputStream myFileOutputStream;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  textOut = (EditText)findViewById(R.id.textout);
  textIn = (TextView)findViewById(R.id.textin);
  btnSend = (Button)findViewById(R.id.btnsend);
  
  myUsbManager = UsbManager.getInstance(this);
  IntentFilter intentFilter = new IntentFilter();
  intentFilter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
  registerReceiver(myUsbReceiver, intentFilter);
  
  btnSend.setOnClickListener(new OnClickListener() {
   
   @Override
   public void onClick(View v) {
    
    String textToSend = textOut.getEditableText().toString();
    if(!textToSend.equals("")){
     sendText(textToSend);
    }
   }
  });
  
 }

 @Override
 protected void onResume() {
  super.onResume();
  
  if(myFileInputStream == null || myFileOutputStream == null){
   
   UsbAccessory[] usbAccessoryList = myUsbManager.getAccessoryList();
   UsbAccessory usbAccessory = null;
   if(usbAccessoryList != null){
    usbAccessory = usbAccessoryList[0];
    OpenUsbAccessory(usbAccessory);
   }
  }
 }
 
 Runnable myRunnable = new Runnable(){

  @Override
  public void run() {
   int numberOfByteRead = 0;
   byte[] buffer = new byte[255];
   
   while(numberOfByteRead >= 0){
    
    try {
     numberOfByteRead = myFileInputStream.read(buffer, 0, buffer.length);
     final StringBuilder stringBuilder = new StringBuilder();
     for(int i=0; i<numberOfByteRead; i++){
      stringBuilder.append((char)buffer[i]);
     }
     
     runOnUiThread(new Runnable(){

      @Override
      public void run() {
       textIn.setText(stringBuilder.toString());
      }});
     
     
    } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
     break;
    }
   }
  }
  
 };
 
 private void OpenUsbAccessory(UsbAccessory acc){
  myParcelFileDescriptor = myUsbManager.openAccessory(acc);
  if(myParcelFileDescriptor != null){
   
   myUsbAccessory = acc;
   FileDescriptor fileDescriptor = myParcelFileDescriptor.getFileDescriptor();
   myFileInputStream = new FileInputStream(fileDescriptor);
   myFileOutputStream = new FileOutputStream(fileDescriptor);
   
   Thread thread = new Thread(myRunnable);
   thread.start();
  }
 }
 
 private void closeUsbAccessory(){
  
  if(myParcelFileDescriptor != null){
   try {
    myParcelFileDescriptor.close();
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
  
  myParcelFileDescriptor = null;
  myUsbAccessory = null;
 }

 @Override
 protected void onPause() {
  super.onPause();
  closeUsbAccessory();
 }

 @Override
 protected void onDestroy() {
  super.onDestroy();
  unregisterReceiver(myUsbReceiver);
 }
 
 private BroadcastReceiver myUsbReceiver = new BroadcastReceiver(){
  
  @Override
  public void onReceive(Context context, Intent intent) {

   String action = intent.getAction();
   if(action.equals(UsbManager.ACTION_USB_ACCESSORY_DETACHED)){
    
    Toast.makeText(MainActivity.this, "onReceive: ACTION_USB_ACCESSORY_DETACHED", Toast.LENGTH_LONG).show();
    
    UsbAccessory usbAccessory = UsbManager.getAccessory(intent);
    
    if(usbAccessory!=null && usbAccessory.equals(myUsbAccessory)){
     closeUsbAccessory();
    }
   }
  }
 };

 private void sendText(String text){

  byte[] buffer = text.getBytes();

  if(myFileOutputStream != null){
   
   try {
    myFileOutputStream.write(buffer);
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   } 
  }
 }

}


<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" >

    <EditText
        android:id="@+id/textout"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>
    <Button
        android:id="@+id/btnsend"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Send"/>
    <TextView
        android:id="@+id/textin"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>


Please notice that this example have no permission obtained to communicating with the USB device in Java code, but include <intent-filter> of "android.hardware.usb.action.USB_DEVICE_ATTACHED" in AndroidManifest.xml. The result is: When the Android device plus in Arduino Due board, and user click OK to start this App in confirm dialog, it work as expected. If user click Cancel, and then start this app manually, it will be stopped. Permission obtaining feature will be improved in next post, "Request Permission to access USB accessory".



No comments:

Post a Comment