Android code sending command to Arduino Due to turn LED On/Off

It's the coding in Android side to send command to Arduino Due to control LED On/Off.


Modify AndroidManifest.xml to add <uses-feature> of "android.hardware.usb.accessory", <intent-filter> of "android.hardware.usb.action.USB_ACCESSORY_ATTACHED", and <meta-data> of resource="@xml/myfilter".
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.androidadkled"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
android:minSdkVersion="12"
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" >
<activity
android:name="com.example.androidadkled.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>


Create file /res/xml/myfilter.xml
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<usb-accessory
manufacturer="Arduino-er"
model="HelloADKLED"
version="0.1"/>
</resources>


Layout file, /res/layout/activity_main.xml
<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:text="Arduino LED Control" />
<TextView
android:id="@+id/textin"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<RadioGroup
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RadioButton
android:id="@+id/LedOn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="LED On" />
<RadioButton
android:id="@+id/LedOff"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="LED Off" />
</RadioGroup>

</LinearLayout>


Create a abstract class AbstractAdkActivity.java to extend Activity, implement the function of ADK; such that we can easy re-use it in furture and reduce the ADK related job in MainActivity.java.
/*
* abstract class for Activities have to read ADK
* for android:minSdkVersion="12"
*
*/

package com.example.androidadkled;

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

import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbAccessory;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;

public abstract class AbstractAdkActivity extends Activity {

private static int RQS_USB_PERMISSION = 0;
private static final String ACTION_USB_PERMISSION = "arduino-er.usb_permission";
private PendingIntent PendingIntent_UsbPermission;

private UsbManager myUsbManager;
private UsbAccessory myUsbAccessory;
private ParcelFileDescriptor myAdkParcelFileDescriptor;
private FileInputStream myAdkInputStream;
private FileOutputStream myAdkOutputStream;
boolean firstRqsPermission;

//do something in onCreate()
protected abstract void doOnCreate(Bundle savedInstanceState);
//do something after adk read
protected abstract void doAdkRead(String stringIn);

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);

myUsbManager = (UsbManager)getSystemService(Context.USB_SERVICE);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
registerReceiver(myUsbReceiver, intentFilter);

//Ask USB Permission from user
Intent intent_UsbPermission = new Intent(ACTION_USB_PERMISSION);
PendingIntent_UsbPermission = PendingIntent.getBroadcast(
this, //context
RQS_USB_PERMISSION, //request code
intent_UsbPermission, //intent
0); //flags
IntentFilter intentFilter_UsbPermission = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(myUsbPermissionReceiver, intentFilter_UsbPermission);

firstRqsPermission = true;
doOnCreate(savedInstanceState);
}

@Override
protected void onResume() {
super.onResume();

if(myAdkInputStream == null || myAdkOutputStream == null){

UsbAccessory[] usbAccessoryList = myUsbManager.getAccessoryList();
UsbAccessory usbAccessory = null;
if(usbAccessoryList != null){
usbAccessory = usbAccessoryList[0];

if(usbAccessory != null){
if(myUsbManager.hasPermission(usbAccessory)){
//already have permission
OpenUsbAccessory(usbAccessory);
}else{

if(firstRqsPermission){

firstRqsPermission = false;

synchronized(myUsbReceiver){
myUsbManager.requestPermission(usbAccessory,
PendingIntent_UsbPermission);
}
}

}
}
}
}
}

//Write String to Adk
void WriteAdk(String text){

byte[] buffer = text.getBytes();

if(myAdkOutputStream != null){

try {
myAdkOutputStream.write(buffer);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

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

@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(myUsbReceiver);
unregisterReceiver(myUsbPermissionReceiver);
}

Runnable runnableReadAdk = new Runnable(){

@Override
public void run() {
int numberOfByteRead = 0;
byte[] buffer = new byte[255];

while(numberOfByteRead >= 0){

try {
numberOfByteRead = myAdkInputStream.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() {
doAdkRead(stringBuilder.toString());
}});


} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
break;
}
}
}

};

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)){

UsbAccessory usbAccessory =
(UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);

if(usbAccessory!=null && usbAccessory.equals(myUsbAccessory)){
closeUsbAccessory();
}
}
}
};

private BroadcastReceiver myUsbPermissionReceiver = new BroadcastReceiver(){

@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action.equals(ACTION_USB_PERMISSION)){

synchronized(this){

UsbAccessory usbAccessory =
(UsbAccessory)intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);

if(intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)){
OpenUsbAccessory(usbAccessory);
}else{
finish();
}
}
}
}

};

private void OpenUsbAccessory(UsbAccessory acc){
myAdkParcelFileDescriptor = myUsbManager.openAccessory(acc);
if(myAdkParcelFileDescriptor != null){

myUsbAccessory = acc;
FileDescriptor fileDescriptor = myAdkParcelFileDescriptor.getFileDescriptor();
myAdkInputStream = new FileInputStream(fileDescriptor);
myAdkOutputStream = new FileOutputStream(fileDescriptor);

Thread thread = new Thread(runnableReadAdk);
thread.start();
}
}

private void closeUsbAccessory(){

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

myAdkParcelFileDescriptor = null;
myUsbAccessory = null;
}
}


Modify MainActivity.java to extend AbstractAdkActivity, and extend Activity in-turn. With AbstractAdkActivity handle most of the ADK related job, we only have to override the methods doOnCreate()(called in onCreate() method) and doAdkRead()(called after command read from ADK). To send command to ADK, call WriteAdk() method.
package com.example.androidadkled;

import android.os.Bundle;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.RadioButton;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AbstractAdkActivity {

TextView textIn;
RadioButton ledOn, ledOff;

@Override
protected void doOnCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
textIn = (TextView)findViewById(R.id.textin);
ledOn = (RadioButton)findViewById(R.id.LedOn);
ledOff = (RadioButton)findViewById(R.id.LedOff);

ledOn.setOnCheckedChangeListener(new OnCheckedChangeListener(){

@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if(isChecked){
WriteAdk("LEDON");
Toast.makeText(getApplicationContext(),
"LEDON", Toast.LENGTH_LONG).show();
}
}});

ledOff.setOnCheckedChangeListener(new OnCheckedChangeListener(){

@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if(isChecked){
WriteAdk("LEDOFF");
Toast.makeText(getApplicationContext(),
"LEDOFF", Toast.LENGTH_SHORT).show();
}
}});

}

@Override
protected void doAdkRead(String stringIn) {
textIn.setText(stringIn);
}

}


download filesDownload the files.

Refer the another post for the code in Arduino Due side.


Updated@2015-10-15Android control Arduino Due LED, using ADK (Accessory Development Kit)

Comments

Popular posts from this blog

Read analog input of Arduino Due board

Application Note of Cortex-M3 Embedded Software Development