In this version, myUsbManager.requestPermission() will be called if have no permission for USB. And also implement BroadcastReceiver myUsbPermissionReceiver to handle user action. Such that another dialog will be open to ask user to allow accessing the USB accessory.
requestPermission() dialog |
The MainActivity.java code in Android side
/* * manufacturer="Arduino-er" * model="HelloADK" * version="0.2" */ 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; @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); } } }); } @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{ //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(); } } } }
Update version="0.2" in /res/xml/myfilter.xml.
<?xml version="1.0" encoding="UTF-8"?> <resources> <usb-accessory manufacturer="Arduino-er" model="HelloADK" version="0.2"/> </resources>
AndroidManifest.xml and the layout file keep no change as in the post "Hello World ADK: Android code".
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.2"; char serialNumber[] = "1"; char url[] = "https://sites.google.com/site/arduinosite/exercise/helloadk/HelloADK_0.2.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); } }
Next:
- Improved Hello World ADK
http://sites.google.com/site/arduinosite/exercise/helloadk-android-code/HelloADK_20130314a.zip
ReplyDelete