Monday, March 18, 2013

Improved Hello World ADK

If you try the "Hello World ADK in last article", you will note that the Permission Request Dialog will be opened twice. Because the call-back method onResume() will be called after dialog closed. To prevent the open of the second dialog, a flag firstRqsPermission is used.

Improved Hello World ADK


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

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.app.PendingIntent;
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;
 
 private static int RQS_USB_PERMISSION = 0;
 private static final String ACTION_USB_PERMISSION = "com.example.helloadk.usb_permission";
 private PendingIntent PendingIntent_UsbPermission;
 
 boolean firstRqsPermission;

 @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);
  
  //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);
  
  btnSend.setOnClickListener(new OnClickListener() {
   
   @Override
   public void onClick(View v) {
    
    String textToSend = textOut.getEditableText().toString();
    if(!textToSend.equals("")){
     sendText(textToSend);
    }
   }
  });
  
  firstRqsPermission = true;
  
 }

 @Override
 protected void onResume() {
  super.onResume();
  
  if(myFileInputStream == null || myFileOutputStream == 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;
       
       //request permission
       Toast.makeText(MainActivity.this, 
         "ask for permission", 
         Toast.LENGTH_LONG).show();
       
       synchronized(myUsbReceiver){
        myUsbManager.requestPermission(usbAccessory, 
          PendingIntent_UsbPermission);
       }
      }
      
     }
    }
   }
  }
 }
 
 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);
  unregisterReceiver(myUsbPermissionReceiver);
 }
 
 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 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 = UsbManager.getAccessory(intent);
     
     if(intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)){
      OpenUsbAccessory(usbAccessory);
      
      Toast.makeText(MainActivity.this, 
        "ACTION_USB_PERMISSION accepted", 
        Toast.LENGTH_LONG).show();
     }else{
      Toast.makeText(MainActivity.this, 
        "ACTION_USB_PERMISSION rejected", 
        Toast.LENGTH_LONG).show();
      finish();
     }
    }
   }
  }
  
 };

 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();
   } 
  }
 }

}

Modify /res/xml/myfilter.xml to update version number.
<?xml version="1.0" encoding="UTF-8"?>
<resources>
    <usb-accessory
        manufacturer="Arduino-er"
        model="HelloADK"
        version="0.3"/>
</resources>


download filesDownload the files.

Modify the code in Arduino side to update versionNumber and download url.

#include "variant.h"
#include <stdio.h>
#include <adk.h>
 
 
// Accessory descriptor. It's how Arduino identifies itself to Android.
char applicationName[] = "HelloADK"; // the app on your phone
char accessoryName[] = "Arduino Due"; // your Arduino board
char companyName[] = "Arduino-er";
 
// Make up anything you want for these
char versionNumber[] = "0.3";
char serialNumber[] = "1";
char url[] = "https://sites.google.com/site/arduinosite/exercise/helloadk/HelloADK_0.3.apk";
 
USBHost Usb;
ADK adk(&Usb, companyName, applicationName, accessoryName,versionNumber,url,serialNumber);
 
// Pin 13 has an LED connected on most Arduino boards.
int led = 13;
 
void setup() {
    Serial.begin(9600);
    cpu_irq_enable();
   
    pinMode(led, OUTPUT);
    //Indicate start of program
    digitalWrite(led, LOW);
    delay(2000);
    digitalWrite(led, HIGH);
    for(int i = 0; i <= 2; i++){
        digitalWrite(led, HIGH);
        delay(250);
        digitalWrite(led, LOW);
        delay(250);
    }
}
 
#define RCVSIZE 128
 
void loop() {
   
    char helloworld[] = "Hello World!\r\n";
   
    uint8_t buf[RCVSIZE];
    uint32_t nbread = 0;
   
    Usb.Task();
     
    if (adk.isReady()){
        digitalWrite(led, HIGH);
         
        adk.read(&nbread, RCVSIZE, buf);
        if (nbread > 0){
            adk.write(nbread, buf);
        }
         
    }else{
        digitalWrite(led, LOW);
    }
     
}


If you have installed APK of previous version, you have to un-install it before install this update version.

No comments:

Post a Comment