Tuesday, September 16, 2014

Place groupIndicator of ExpandableListView on right side

To place groupIndicator of ExpandableListView on right side, we can call setIndicatorBounds() for Android devices before Jelly Bean, or call setIndicatorBoundsRelative() for devices of Jelly Bean or higher.

Run on Nexus 7 of Android 4.4.4:



On Nexus One running Android 2.3.6



Modify MainActivity.java of last example "Create groupIndicator for ExpandableListView example", override onWindowFocusChanged() method.

package com.example.androidexpandablelistview;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.support.v7.app.ActionBarActivity;
import android.annotation.TargetApi;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.widget.ExpandableListView;
import android.widget.Toast;

public class MainActivity extends ActionBarActivity {

 ExpandableListView expandableListView;
 MyExpandableListAdapter myExpandableListAdapter;
 List<String> groupList;
 HashMap<String, List<String>> childMap;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  init();
  expandableListView = (ExpandableListView) findViewById(R.id.mylist);
  myExpandableListAdapter = new MyExpandableListAdapter(this, groupList, childMap);
  expandableListView.setAdapter(myExpandableListAdapter);

 }

 @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
 @Override
 public void onWindowFocusChanged(boolean hasFocus) {
  super.onWindowFocusChanged(hasFocus);
  
  Drawable drawable_groupIndicator = 
   getResources().getDrawable(R.drawable.groupindicator);
  int drawable_width = drawable_groupIndicator.getMinimumWidth();
  
  if(android.os.Build.VERSION.SDK_INT < 
   android.os.Build.VERSION_CODES.JELLY_BEAN_MR2){
   expandableListView.setIndicatorBounds(
    expandableListView.getWidth()-drawable_width, 
    expandableListView.getWidth());
  }else{
   expandableListView.setIndicatorBoundsRelative(
    expandableListView.getWidth()-drawable_width, 
    expandableListView.getWidth());
  }
  
  Toast.makeText(MainActivity.this, 
   "drawable_width: " + drawable_width +"\n" +
   "expandableListView.getWidth()" + expandableListView.getWidth(), 
   Toast.LENGTH_LONG).show();
 }

 private void init() {
  groupList = new ArrayList<String>();
  childMap = new HashMap<String, List<String>>();

  List<String> groupList0 = new ArrayList<String>();
  groupList0.add("groupList0 - 1");
  groupList0.add("groupList0 - 2");
  groupList0.add("groupList0 - 3");
  
  List<String> groupList1 = new ArrayList<String>();
  groupList1.add("groupList1 - 1");
  groupList1.add("groupList1 - 2");
  groupList1.add("groupList1 - 3");

  List<String> groupList2 = new ArrayList<String>();
  groupList2.add("groupList2 - 1");
  groupList2.add("groupList2 - 2");
  groupList2.add("groupList2 - 3");

  List<String> groupList3 = new ArrayList<String>();
  groupList3.add("groupList3 - 1");
  groupList3.add("groupList3 - 2");
  groupList3.add("groupList3 - 3");

  groupList.add("Group List 0");
  groupList.add("Group List 1");
  groupList.add("Group List 2");
  groupList.add("Group List 3");

  childMap.put(groupList.get(0), groupList0);
  childMap.put(groupList.get(1), groupList1);
  childMap.put(groupList.get(2), groupList2);
  childMap.put(groupList.get(3), groupList3);
 }

}


"The import android.support.v7 cannot be resolved" and "ActionBarActivity cannot be resolved to a type"

It's a common error "The import android.support.v7 cannot be resolved" on import android.support.v7.app.ActionBarActivity; and "ActionBarActivity cannot be resolved to a type" on extends ActionBarActivity. It may be various reason to cause it. One of the reason is the auto-generated project appcompat_v7 closed.

Please check the video:

Monday, September 15, 2014

Create groupIndicator for ExpandableListView example

Modify from last exercise "ExpandableListView example", to create groupIndicator.


Copy drawables to /res/drawable/ folder. In my exercise, btn_check_buttonless_on.png and btn_check_buttonless_off.png copied from Android SDK folder: /Android/sdk/platforms/android-20/data/res/drawable-mdpi/

Create /res/drawable/groupindicator.xml, to define our groupIndicator.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/btn_check_buttonless_off"
       android:state_expanded="true" />
   <item android:drawable="@drawable/btn_check_buttonless_on"/>
</selector>

Modify /res/layout/activity_main.xml to specify android:groupIndicator of ExpandableListView.
<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:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.androidexpandablelistview.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" />

    <ExpandableListView
        android:id="@+id/mylist"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:groupIndicator="@drawable/groupindicator" />

</LinearLayout>



Next:
- Place groupIndicator of ExpandableListView on right side


Sunday, September 14, 2014

ExpandableListView example

Example of using ExpandableListView:


Create /res/layout/group_layout.xml, to define the layout of list group:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="#A0A0A0"
    android:orientation="horizontal" >
 
    <ImageView
        android:id="@+id/groupimg"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher" />
    <TextView
        android:id="@+id/group"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textColor="@android:color/white"
        android:textStyle="bold" />
 
</LinearLayout>

Create /res/layout/item_layout.xml to define layout of items:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="55dip"
    android:orientation="vertical" >
 
    <TextView
        android:id="@+id/item"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textStyle="italic" />
 
</LinearLayout>

/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:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.androidexpandablelistview.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" />

    <ExpandableListView
        android:id="@+id/mylist"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

Create MyExpandableListAdapter.java
package com.example.androidexpandablelistview;

import java.util.HashMap;
import java.util.List;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;

public class MyExpandableListAdapter extends BaseExpandableListAdapter {

 private Context context;
 private List<String> listGroup;
 private HashMap<String, List<String>> listChild;

 public MyExpandableListAdapter(Context context, List<String> listGroup,
   HashMap<String, List<String>> listChild) {
  this.context = context;
  this.listGroup = listGroup;
  this.listChild = listChild;
 }

 @Override
 public int getGroupCount() {
  return listGroup.size();
 }

 @Override
 public int getChildrenCount(int groupPosition) {
  return listChild.get(listGroup.get(groupPosition)).size();
 }

 @Override
 public Object getGroup(int groupPosition) {
  return listGroup.get(groupPosition);
 }

 @Override
 public Object getChild(int groupPosition, int childPosition) {
  return listChild.get(listGroup.get(groupPosition)).get(childPosition);
 }

 @Override
 public long getGroupId(int groupPosition) {
  return groupPosition;
 }

 @Override
 public long getChildId(int groupPosition, int childPosition) {
  return childPosition;
 }

 @Override
 public boolean hasStableIds() {
  return false;
 }

 @Override
 public View getGroupView(int groupPosition, boolean isExpanded,
   View convertView, ViewGroup parent) {
  if (convertView == null) {
   LayoutInflater infalInflater = (LayoutInflater) context
     .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
   convertView = infalInflater.inflate(R.layout.group_layout, null);
  }

  String textGroup = (String) getGroup(groupPosition);

  TextView textViewGroup = (TextView) convertView
    .findViewById(R.id.group);
  textViewGroup.setText(textGroup);

  return convertView;
 }

 @Override
 public View getChildView(int groupPosition, int childPosition,
   boolean isLastChild, View convertView, ViewGroup parent) {
  if (convertView == null) {
   LayoutInflater infalInflater = (LayoutInflater) context
     .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
   convertView = infalInflater.inflate(R.layout.item_layout, null);
  }

  TextView textViewItem = (TextView) convertView.findViewById(R.id.item);

  String text = (String) getChild(groupPosition, childPosition);

  textViewItem.setText(text);
  return convertView;
 }

 @Override
 public boolean isChildSelectable(int groupPosition, int childPosition) {
  // TODO Auto-generated method stub
  return false;
 }

}

MainActivity.java
package com.example.androidexpandablelistview;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.widget.ExpandableListView;

public class MainActivity extends ActionBarActivity {

 ExpandableListView expandableListView;
 MyExpandableListAdapter myExpandableListAdapter;
 List<String> groupList;
 HashMap<String, List<String>> childMap;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  init();
  expandableListView = (ExpandableListView) findViewById(R.id.mylist);
  myExpandableListAdapter = new MyExpandableListAdapter(this, groupList, childMap);
  expandableListView.setAdapter(myExpandableListAdapter);
 }

 private void init() {
  groupList = new ArrayList<String>();
  childMap = new HashMap<String, List<String>>();

  List<String> groupList0 = new ArrayList<String>();
  groupList0.add("groupList0 - 1");
  groupList0.add("groupList0 - 2");
  groupList0.add("groupList0 - 3");
  
  List<String> groupList1 = new ArrayList<String>();
  groupList1.add("groupList1 - 1");
  groupList1.add("groupList1 - 2");
  groupList1.add("groupList1 - 3");

  List<String> groupList2 = new ArrayList<String>();
  groupList2.add("groupList2 - 1");
  groupList2.add("groupList2 - 2");
  groupList2.add("groupList2 - 3");

  List<String> groupList3 = new ArrayList<String>();
  groupList3.add("groupList3 - 1");
  groupList3.add("groupList3 - 2");
  groupList3.add("groupList3 - 3");
  
  groupList.add("Group List 0");
  groupList.add("Group List 1");
  groupList.add("Group List 2");
  groupList.add("Group List 3");

  childMap.put(groupList.get(0), groupList0);
  childMap.put(groupList.get(1), groupList1);
  childMap.put(groupList.get(2), groupList2);
  childMap.put(groupList.get(3), groupList3);
 }

}

download filesDownload the files.

Next:
- Create groupIndicator for ExpandableListView example
Place groupIndicator of ExpandableListView on right side

Monday, September 8, 2014

Android + Arduino Uno: display bits and ASCII char on LED Matrix

Add extra command of Displaying single ASCII char to previous example of "Android USB Host Mode control Arduino Uno + 8x8 LED Matrix".




Android Side:

Modify /res/layout/activity_main.xml to add Spinner for ASCII char selection.
<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:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.androidtouchview.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" />
    
    <TextView
        android:id="@+id/textstatus"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textStyle="bold"
        android:text="Status" />
    
    <Spinner
        android:id="@+id/asciispinner"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <GridLayout
        android:id="@+id/mygrid"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        android:columnCount="8"
        android:rowCount="8"
        android:layout_gravity="center"
        android:background="@android:color/background_light" >
    </GridLayout>

</LinearLayout>

MainActivity.java
package com.example.androidusbmatrix;

import java.util.HashMap;
import java.util.Iterator;

import com.example.androidusbmatrix.MyView.OnToggledListener;

import android.support.v7.app.ActionBarActivity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.GridLayout;
import android.widget.Spinner;
import android.widget.TextView;

public class MainActivity extends ActionBarActivity 
 implements OnToggledListener{

 TextView textStatus;
 MyView[] myViews;
 GridLayout myGridLayout;
 
 private static final int targetVendorID = 9025; //Arduino Uno
 private static final int targetProductID = 67; //Arduino Uno, not 0067
 private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
 PendingIntent mPermissionIntent;
 UsbDevice deviceFound = null;
 UsbInterface usbInterfaceFound = null;
 UsbInterface usbInterface;
 UsbDeviceConnection usbDeviceConnection;
 UsbEndpoint endpointIn = null;
 UsbEndpoint endpointOut = null;
 
 Spinner spAscii;
 AsciiCode Asciis[];
 ArrayAdapter<AsciiCode> asciiArrayAdapter;
 
 final byte SYNC_WORD   = (byte) 0xff;
 final byte CMD_01_Bits    = 0x01;
 final byte CMD_02_SingleChar  = 0x02;

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

  textStatus = (TextView) findViewById(R.id.textstatus);
  myGridLayout = (GridLayout) findViewById(R.id.mygrid);

  int numOfCol = myGridLayout.getColumnCount();
  int numOfRow = myGridLayout.getRowCount();
  myViews = new MyView[numOfCol * numOfRow];
  for (int yPos = 0; yPos < numOfRow; yPos++) {
   for (int xPos = 0; xPos < numOfCol; xPos++) {
    MyView tView = new MyView(this, xPos, yPos);
    tView.setOnToggledListener(this);
    myViews[yPos * numOfCol + xPos] = tView;
    myGridLayout.addView(tView);
   }
  }

  myGridLayout.getViewTreeObserver().addOnGlobalLayoutListener(
    new OnGlobalLayoutListener() {

     @Override
     public void onGlobalLayout() {

      int pLength;
      final int MARGIN = 5;

      int pWidth = myGridLayout.getWidth();
      int pHeight = myGridLayout.getHeight();
      int numOfCol = myGridLayout.getColumnCount();
      int numOfRow = myGridLayout.getRowCount();

      // Set myGridLayout equal width and height
      if (pWidth >= pHeight) {
       pLength = pHeight;
      } else {
       pLength = pWidth;
      }
      ViewGroup.LayoutParams pParams = myGridLayout
        .getLayoutParams();
      pParams.width = pLength;
      pParams.height = pLength;
      myGridLayout.setLayoutParams(pParams);

      int w = pLength / numOfCol; // pWidth/numOfCol;
      int h = pLength / numOfRow; // pHeight/numOfRow;

      for (int yPos = 0; yPos < numOfRow; yPos++) {
       for (int xPos = 0; xPos < numOfCol; xPos++) {
        GridLayout.LayoutParams params = (GridLayout.LayoutParams) myViews[yPos
          * numOfCol + xPos].getLayoutParams();
        params.width = w - 2 * MARGIN;
        params.height = h - 2 * MARGIN;
        params.setMargins(MARGIN, MARGIN, MARGIN,
          MARGIN);
        myViews[yPos * numOfCol + xPos]
          .setLayoutParams(params);
       }
      }

      // deprecated in API level 16
      myGridLayout.getViewTreeObserver()
        .removeGlobalOnLayoutListener(this);
      // for API Level >= 16
      // myGridLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
     }
    });
  
  // register the broadcast receiver
  mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(
   ACTION_USB_PERMISSION), 0);
  IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
  registerReceiver(mUsbReceiver, filter);

  registerReceiver(mUsbDeviceReceiver, new IntentFilter(
   UsbManager.ACTION_USB_DEVICE_ATTACHED));
  registerReceiver(mUsbDeviceReceiver, new IntentFilter(
   UsbManager.ACTION_USB_DEVICE_DETACHED));

  connectUsb();
  
  spAscii = (Spinner)findViewById(R.id.asciispinner);
  initAsciis();
  asciiArrayAdapter = new ArrayAdapter<AsciiCode>(this,
    android.R.layout.simple_list_item_1, 
    android.R.id.text1, 
    Asciis);
  asciiArrayAdapter.setDropDownViewResource(
    android.R.layout.simple_spinner_dropdown_item);
  spAscii.setAdapter(asciiArrayAdapter);
  spAscii.setOnItemSelectedListener(new OnItemSelectedListener(){

   @Override
   public void onItemSelected(AdapterView<?> parent, View view,
     int position, long id) {
    AsciiCode item = (AsciiCode) parent.getItemAtPosition(position);
    
    if(deviceFound != null){
     byte[] bytesSend = new byte[3];
     
     bytesSend[0] = SYNC_WORD;
     bytesSend[1] = CMD_02_SingleChar; //CMD
     bytesSend[2] = (byte) item.charAscii;
     
     usbDeviceConnection.bulkTransfer(endpointOut,
       bytesSend, bytesSend.length, 0);
    }
   }

   @Override
   public void onNothingSelected(AdapterView<?> arg0) {
    // TODO Auto-generated method stub
    
   }});
  
 }

 @Override
 public void OnToggled(MyView v, boolean touchOn) {
  if(deviceFound != null){
   byte[] bytesSend = setupCmd();

   usbDeviceConnection.bulkTransfer(endpointOut,
     bytesSend, bytesSend.length, 0);
  }
 }
 
 private byte[] setupCmd(){
  byte[] bytes = new byte[18];
  
  bytes[0] = SYNC_WORD;
  bytes[1] = CMD_01_Bits; //CMD
  
  int i = 2;
  int numOfRow = 8;
  int numOfCol = 8;
  int numOfHalfCol = 4;

  for (int yPos = 0; yPos < numOfRow; yPos++) {
   byte b = 0x00;
   byte mask = 0x01;

   for (int xPos = 0; xPos < numOfHalfCol; xPos++) {
    
    if(myViews[yPos * numOfCol + xPos].touchOn){
     b = (byte) (b | mask);
    }
    
    mask = (byte) (mask << 1);
   }
   bytes[i] = b;
   
   i++;
   b = 0x00;
   mask = 0x10;
   for (int xPos = numOfHalfCol; xPos < numOfCol; xPos++) {
    
    if(myViews[yPos * numOfCol + xPos].touchOn){
     b = (byte) (b | mask);
    }
    
    mask = (byte) (mask << 1);
   }
   bytes[i] = b;
   
   i++;
  }

  return bytes;
 }
 
 //usb related
 private boolean setupUsbComm() {

  // for more info, search SET_LINE_CODING and
  // SET_CONTROL_LINE_STATE in the document:
  // "Universal Serial Bus Class Definitions for Communication Devices"
  // at http://adf.ly/dppFt
  final int RQSID_SET_LINE_CODING = 0x20;
  final int RQSID_SET_CONTROL_LINE_STATE = 0x22;

  boolean success = false;

  UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
  Boolean permitToRead = manager.hasPermission(deviceFound);

  if (permitToRead) {
   usbDeviceConnection = manager.openDevice(deviceFound);
   if (usbDeviceConnection != null) {
    usbDeviceConnection.claimInterface(usbInterfaceFound, true);

    usbDeviceConnection.controlTransfer(0x21, // requestType
      RQSID_SET_CONTROL_LINE_STATE, // SET_CONTROL_LINE_STATE
      0, // value
      0, // index
      null, // buffer
      0, // length
      0); // timeout

    // baud rate = 9600
    // 8 data bit
    // 1 stop bit
    byte[] encodingSetting = new byte[] { (byte) 0x80, 0x25, 0x00,
      0x00, 0x00, 0x00, 0x08 };
    usbDeviceConnection.controlTransfer(0x21, // requestType
      RQSID_SET_LINE_CODING, // SET_LINE_CODING
      0, // value
      0, // index
      encodingSetting, // buffer
      7, // length
      0); // timeout
   }

  } else {
   manager.requestPermission(deviceFound, mPermissionIntent);
   textStatus.setText("Permission: " + permitToRead);
  }

  return success;
 }
 
 private void connectUsb() {

  textStatus.setText("connectUsb()");

  searchEndPoint();

  if (usbInterfaceFound != null) {
   setupUsbComm();
  }

 }
 
 private void releaseUsb() {

  textStatus.setText("releaseUsb()");

  if (usbDeviceConnection != null) {
   if (usbInterface != null) {
    usbDeviceConnection.releaseInterface(usbInterface);
    usbInterface = null;
   }
   usbDeviceConnection.close();
   usbDeviceConnection = null;
  }

  deviceFound = null;
  usbInterfaceFound = null;
  endpointIn = null;
  endpointOut = null;
 }

 private void searchEndPoint() {

  usbInterfaceFound = null;
  endpointOut = null;
  endpointIn = null;

  // Search device for targetVendorID and targetProductID
  if (deviceFound == null) {
   UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
   HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
   Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();

   while (deviceIterator.hasNext()) {
    UsbDevice device = deviceIterator.next();

    if (device.getVendorId() == targetVendorID) {
     if (device.getProductId() == targetProductID) {
      deviceFound = device;
     }
    }
   }
  }

  if (deviceFound == null) {
   textStatus.setText("device not found");
  } else {

   // Search for UsbInterface with Endpoint of USB_ENDPOINT_XFER_BULK,
   // and direction USB_DIR_OUT and USB_DIR_IN

   for (int i = 0; i < deviceFound.getInterfaceCount(); i++) {
    UsbInterface usbif = deviceFound.getInterface(i);

    UsbEndpoint tOut = null;
    UsbEndpoint tIn = null;

    int tEndpointCnt = usbif.getEndpointCount();
    if (tEndpointCnt >= 2) {
     for (int j = 0; j < tEndpointCnt; j++) {
      if (usbif.getEndpoint(j).getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
       if (usbif.getEndpoint(j).getDirection() == UsbConstants.USB_DIR_OUT) {
        tOut = usbif.getEndpoint(j);
       } else if (usbif.getEndpoint(j).getDirection() == UsbConstants.USB_DIR_IN) {
        tIn = usbif.getEndpoint(j);
       }
      }
     }

     if (tOut != null && tIn != null) {
      // This interface have both USB_DIR_OUT
      // and USB_DIR_IN of USB_ENDPOINT_XFER_BULK
      usbInterfaceFound = usbif;
      endpointOut = tOut;
      endpointIn = tIn;
     }
    }

   }

  }
 }
 
 private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {

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

    textStatus.setText("ACTION_USB_PERMISSION");

    synchronized (this) {
     UsbDevice device = (UsbDevice) intent
       .getParcelableExtra(UsbManager.EXTRA_DEVICE);

     if (intent.getBooleanExtra(
       UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
      if (device != null) {
       connectUsb();
      }
     } else {
      textStatus.setText("permission denied for device ");
     }
    }
   }
  }
 };

 private final BroadcastReceiver mUsbDeviceReceiver = new BroadcastReceiver() {

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

    deviceFound = (UsbDevice) intent
      .getParcelableExtra(UsbManager.EXTRA_DEVICE);

    textStatus.setText("ACTION_USB_DEVICE_ATTACHED");

    connectUsb();

   } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {

    UsbDevice device = (UsbDevice) intent
      .getParcelableExtra(UsbManager.EXTRA_DEVICE);

    textStatus.setText("ACTION_USB_DEVICE_DETACHED");

    if (device != null) {
     if (device == deviceFound) {
      releaseUsb();
     }
    }
    
   }
  }

 };
 
 public void initAsciis() {
  Asciis = new AsciiCode[128];
  for (int i = 0; i < 128; i++) {
   Asciis[i] = new AsciiCode(i);
  }
 }
 
 class AsciiCode{
  int id;
  char charAscii;
  
  AsciiCode(int id){
   this.id = id;
   charAscii = (char)id;
  }
  
  public String toString(){
   return 
    String.format("%03d", id)
    + " /(hex) 0x" + String.format("%02x", id).toUpperCase()
    + " : " + charAscii;
  }

 }

}

Other files, AndroidManifest.xml, device_filter.xml and MyView.java, refer to last post.

download filesDownload the files.


Arduino side:

UnoUsbMatrix.ino
/*
 *  Modify from Row-Column Scanning an 8x8 LED matrix tutorial
 *  http://android-er.blogspot.com
 *  http://arduino-er.blogspot.com/
 */

byte font[128][8] = {
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0000 (nul)
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0001
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0002
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0003
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0004
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0005
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0006
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0007
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0008
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0009
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+000A
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+000B
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+000C
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+000D
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+000E
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+000F
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0010
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0011
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0012
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0013
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0014
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0015
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0016
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0017
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0018
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0019
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+001A
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+001B
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+001C
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+001D
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+001E
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+001F
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0020 (space)
    { 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00},   // U+0021 (!)
    { 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0022 (")
    { 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00},   // U+0023 (#)
    { 0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00},   // U+0024 ($)
    { 0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00},   // U+0025 (%)
    { 0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00},   // U+0026 (&)
    { 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0027 (')
    { 0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00},   // U+0028 (()
    { 0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00},   // U+0029 ())
    { 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00},   // U+002A (*)
    { 0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00},   // U+002B (+)
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06},   // U+002C (,)
    { 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00},   // U+002D (-)
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00},   // U+002E (.)
    { 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00},   // U+002F (/)
    { 0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00},   // U+0030 (0)
    { 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00},   // U+0031 (1)
    { 0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00},   // U+0032 (2)
    { 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00},   // U+0033 (3)
    { 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00},   // U+0034 (4)
    { 0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00},   // U+0035 (5)
    { 0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00},   // U+0036 (6)
    { 0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00},   // U+0037 (7)
    { 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00},   // U+0038 (8)
    { 0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00},   // U+0039 (9)
    { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00},   // U+003A (:)
    { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06},   // U+003B (//)
    { 0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00},   // U+003C (<)
    { 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00},   // U+003D (=)
    { 0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00},   // U+003E (>)
    { 0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00},   // U+003F (?)
    { 0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00},   // U+0040 (@)
    { 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00},   // U+0041 (A)
    { 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00},   // U+0042 (B)
    { 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00},   // U+0043 (C)
    { 0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00},   // U+0044 (D)
    { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00},   // U+0045 (E)
    { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00},   // U+0046 (F)
    { 0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00},   // U+0047 (G)
    { 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00},   // U+0048 (H)
    { 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},   // U+0049 (I)
    { 0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00},   // U+004A (J)
    { 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00},   // U+004B (K)
    { 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00},   // U+004C (L)
    { 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00},   // U+004D (M)
    { 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00},   // U+004E (N)
    { 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00},   // U+004F (O)
    { 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00},   // U+0050 (P)
    { 0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00},   // U+0051 (Q)
    { 0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00},   // U+0052 (R)
    { 0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00},   // U+0053 (S)
    { 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},   // U+0054 (T)
    { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00},   // U+0055 (U)
    { 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00},   // U+0056 (V)
    { 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00},   // U+0057 (W)
    { 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00},   // U+0058 (X)
    { 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00},   // U+0059 (Y)
    { 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00},   // U+005A (Z)
    { 0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00},   // U+005B ([)
    { 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00},   // U+005C (\)
    { 0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00},   // U+005D (])
    { 0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00},   // U+005E (^)
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF},   // U+005F (_)
    { 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0060 (`)
    { 0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00},   // U+0061 (a)
    { 0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00},   // U+0062 (b)
    { 0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00},   // U+0063 (c)
    { 0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00},   // U+0064 (d)
    { 0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00},   // U+0065 (e)
    { 0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00},   // U+0066 (f)
    { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F},   // U+0067 (g)
    { 0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00},   // U+0068 (h)
    { 0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},   // U+0069 (i)
    { 0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E},   // U+006A (j)
    { 0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00},   // U+006B (k)
    { 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},   // U+006C (l)
    { 0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00},   // U+006D (m)
    { 0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00},   // U+006E (n)
    { 0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00},   // U+006F (o)
    { 0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F},   // U+0070 (p)
    { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78},   // U+0071 (q)
    { 0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00},   // U+0072 (r)
    { 0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00},   // U+0073 (s)
    { 0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00},   // U+0074 (t)
    { 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00},   // U+0075 (u)
    { 0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00},   // U+0076 (v)
    { 0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00},   // U+0077 (w)
    { 0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00},   // U+0078 (x)
    { 0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F},   // U+0079 (y)
    { 0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00},   // U+007A (z)
    { 0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00},   // U+007B ({)
    { 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00},   // U+007C (|)
    { 0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00},   // U+007D (})
    { 0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+007E (~)
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}    // U+007F
};

// 2-dimensional array of row pin numbers:
const int row[8] = {
  2, 7, 19, 5, 13, 18, 12, 16
};

// 2-dimensional array of column pin numbers:
const int col[8] = {
  6, 11, 10, 3, 17, 4, 8, 9
};

// 2-dimensional array of pixels:
int pixels[8][8];

const int ST_0 = 0;       //waiting Sync word
const int ST_1_CMD = 1;   //Waiting CMD
const int ST_2_DATA= 2;  //Receiving Data for CMD_01_Bits
const int ST_3_CHAR= 3;  //Receiving Single Char for CMD_02_SingleChar
const int DATA_LENGTH = 16;  //length of data = 16
const byte SYNC_WORD = 0xFF;
const byte CMD_01_Bits = 0x01;        //Send as 8x8 bit map
const byte CMD_02_SingleChar = 0x02;  //single char
int cmdState;
int dataIndex;

byte data[DATA_LENGTH];

void setup() {
  
  Serial.begin(9600);

  // initialize the I/O pins as outputs
  // iterate over the pins:
  for (int thisPin = 0; thisPin < 8; thisPin++) {
    // initialize the output pins:
    pinMode(col[thisPin], OUTPUT);
    pinMode(row[thisPin], OUTPUT);
    // take the col pins (i.e. the cathodes) high to ensure that
    // the LEDS are off:
    digitalWrite(col[thisPin], HIGH);
  }
  
  for(int y=0; y<8; y++){
    for(int x=0; x<8; x++){
      pixels[x][y] = HIGH;
    }
  }
  
  cmdState = ST_0;
}

void loop() {
  refreshScreen();
  
  if(Serial.available()){
    cmdHandle(Serial.read());
  }

}

void cmdHandle(int incomingByte){
  
  //prevent from lost-sync
  if(incomingByte == SYNC_WORD){
    cmdState = ST_1_CMD;
    return;
  }
  
  switch(cmdState){
    case ST_0:
        if(incomingByte == SYNC_WORD){
          cmdState = ST_1_CMD;
        }
        break;
    case ST_1_CMD:{
          switch(incomingByte){
            case CMD_01_Bits:
                cmdState = ST_2_DATA;
                dataIndex = 0;
                break;
            case CMD_02_SingleChar:
                cmdState = ST_3_CHAR;
                break;
            default:
                cmdState = ST_0;
          }
        }
        break;
    case ST_2_DATA:{
          data[dataIndex] = incomingByte;
          dataIndex++;
        
          int iData = 0;
          if(dataIndex==DATA_LENGTH){
            cmdState = ST_0;
            for(int i=0; i<8; i++){
              byte mask = 0x01;
            
              for(int j=0; j<4; j++){
                  if (data[iData] & mask){
                    pixels[i][j] = LOW;
                  }else{
                    pixels[i][j] = HIGH;
                  }
                  mask = mask << 1;
              }
            
              iData++;
              for(int j=4; j<8; j++){
                  if (data[iData] & mask){
                    pixels[i][j] = LOW;
                  }else{
                    pixels[i][j] = HIGH;
                  }
                  mask = mask << 1;
              }
            
              iData++;
            }
          }
        }
        break;
      
      case ST_3_CHAR:
        
        
        setupChar((char)incomingByte);
        cmdState = ST_0;
        break;
        
  }
  
}

void setupChar(char c){

  for (int x = 0; x < 8; x++) {
    byte bitMask = 0x01;
    byte f = font[c][x];
    for (int y = 0; y < 8; y++) {
      if (f & bitMask){
        pixels[x][y] = LOW;
      }else{
        pixels[x][y] = HIGH;
      }
      bitMask = bitMask << 1;
    }
  }

}

void refreshScreen() {
  // iterate over the rows (anodes):
  for (int thisRow = 0; thisRow < 8; thisRow++) {
    // take the row pin (anode) high:
    digitalWrite(row[thisRow], HIGH);
    // iterate over the cols (cathodes):
    for (int thisCol = 0; thisCol < 8; thisCol++) {
      // get the state of the current pixel;
      int thisPixel = pixels[thisRow][thisCol];
      // when the row is HIGH and the col is LOW,
      // the LED where they meet turns on:
      digitalWrite(col[thisCol], thisPixel);
      // turn the pixel off:
      if (thisPixel == LOW) {
        digitalWrite(col[thisCol], HIGH);
      }
    }
    // take the row pin low to turn off the whole row:
    digitalWrite(row[thisRow], LOW);
  }
}


download filesDownload UnoUsbMatrix.ino for Arduino Uno.