package com.ptrprograms.androidarduinoledcontrol;
import android.app.Fragment;
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;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* Created by Paul Trebilcox-Ruiz on 7/27/14.
*/
public class LEDControlFragment extends Fragment implements SeekBar.OnSeekBarChangeListener {
private static final String EXTRA_ACCESSORY = "extra_accessory";
private static final String ACTION_USB_PERMISSION = "com.ptrprograms.androidarduinoledcontrol.action.USB_PERMISSION";
private UsbManager mUsbManager;
private UsbAccessory mUsbAccessory;
private PendingIntent mPermissionIntent;
private boolean mPermissionRequestPending;
private ParcelFileDescriptor mFileDescriptor;
private FileOutputStream mOutputStream;
private TextView mRedLEDValueTV;
private TextView mGreenLEDValueTV;
private TextView mBlueLEDValueTV;
private SeekBar mRedLEDSeekBar;
private SeekBar mGreenLEDSeekBar;
private SeekBar mBlueLEDSeekBar;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mUsbManager = (UsbManager) getActivity().getSystemService( Context.USB_SERVICE );
mPermissionIntent = PendingIntent.getBroadcast( getActivity(), 0, new Intent( ACTION_USB_PERMISSION ), 0 );
IntentFilter filter = new IntentFilter( ACTION_USB_PERMISSION );
filter.addAction( UsbManager.ACTION_USB_ACCESSORY_DETACHED );
getActivity().registerReceiver( mUsbReceiver, filter );
if( savedInstanceState != null && savedInstanceState.containsKey( EXTRA_ACCESSORY ) ) {
mUsbAccessory = savedInstanceState.getParcelable( EXTRA_ACCESSORY );
openAccessory( mUsbAccessory );
}
setRetainInstance( true );
}
@Override
public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState ) {
View view = inflater.inflate( R.layout.fragment_main, container );
mRedLEDValueTV = (TextView) view.findViewById( R.id.red_led_value );
mRedLEDSeekBar = (SeekBar) view.findViewById( R.id.red_led_seek_bar );
mRedLEDSeekBar.setOnSeekBarChangeListener( this );
mGreenLEDValueTV = (TextView) view.findViewById( R.id.green_led_value );
mGreenLEDSeekBar = (SeekBar) view.findViewById( R.id.green_led_seek_bar );
mGreenLEDSeekBar.setOnSeekBarChangeListener( this );
mBlueLEDValueTV = (TextView) view.findViewById( R.id.blue_led_value );
mBlueLEDSeekBar = (SeekBar) view.findViewById( R.id.blue_led_seek_bar );
mBlueLEDSeekBar.setOnSeekBarChangeListener( this );
mRedLEDValueTV.setText( String.valueOf( mRedLEDSeekBar.getProgress() ) );
mGreenLEDValueTV.setText( String.valueOf( mGreenLEDSeekBar.getProgress() ) );
mBlueLEDValueTV.setText( String.valueOf( mBlueLEDSeekBar.getProgress() ) );
return view;
}
private void openAccessory(UsbAccessory accessory) {
if( accessory == null )
return;
mFileDescriptor = mUsbManager.openAccessory( accessory );
if (mFileDescriptor != null ) {
mUsbAccessory = accessory;
FileDescriptor fileDescriptor = mFileDescriptor.getFileDescriptor();
mOutputStream = new FileOutputStream( fileDescriptor );
}
}
@Override
public void onResume() {
super.onResume();
if( mOutputStream != null ) {
return;
}
UsbAccessory[] accessories = mUsbManager.getAccessoryList();
UsbAccessory accessory = ( accessories == null ? null : accessories[0] );
if( accessory != null ) {
if( mUsbManager.hasPermission( accessory ) ) {
openAccessory( accessory );
} else {
synchronized( mUsbReceiver ) {
if( !mPermissionRequestPending ) {
mUsbManager.requestPermission( accessory, mPermissionIntent );
mPermissionRequestPending = true;
}
}
}
}
}
@Override
public void onPause() {
super.onPause();
closeAccessory();
}
@Override
public void onDestroy() {
getActivity().unregisterReceiver( mUsbReceiver );
super.onDestroy();
}
private void closeAccessory() {
try {
if( mFileDescriptor != null ) {
mFileDescriptor.close();
}
} catch ( IOException e ) {
} finally {
mFileDescriptor = null;
mUsbAccessory = null;
}
}
@Override
public void onSaveInstanceState( Bundle outState ) {
super.onSaveInstanceState( outState );
outState.putParcelable( EXTRA_ACCESSORY, mUsbAccessory );
}
private void writeToArduin( byte LEDNum, int value ) {
byte[] buffer = new byte[2];
if( value > 255 ) {
value = 255;
} else if( value < 0 ) {
value = 0;
}
buffer[0] = LEDNum;
buffer[1] = (byte) value;
if( mOutputStream != null ) {
try {
mOutputStream.write( buffer );
} catch( IOException e ) {
Toast.makeText( getActivity(), "Something went wrong when writing to the Arduino", Toast.LENGTH_LONG ).show();
}
}
}
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
switch( seekBar.getId() ) {
case R.id.red_led_seek_bar: {
mRedLEDValueTV.setText( String.valueOf( seekBar.getProgress() ) );
writeToArduin( (byte) 0, seekBar.getProgress() );
break;
}
case R.id.green_led_seek_bar: {
mGreenLEDValueTV.setText( String.valueOf( seekBar.getProgress() ) );
writeToArduin( (byte) 1, seekBar.getProgress() );
break;
}
case R.id.blue_led_seek_bar: {
mBlueLEDValueTV.setText( String.valueOf( seekBar.getProgress() ) );
writeToArduin( (byte) 2, seekBar.getProgress() );
break;
}
}
}
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if( ACTION_USB_PERMISSION.equals( action ) ) {
UsbAccessory accessory = intent.getParcelableExtra( UsbManager.EXTRA_ACCESSORY );
if( intent.getBooleanExtra( UsbManager.EXTRA_PERMISSION_GRANTED, false ) ) {
openAccessory( accessory );
}
mPermissionRequestPending = false;
} else if( UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals( action ) ) {
UsbAccessory accessory = intent.getParcelableExtra( UsbManager.EXTRA_ACCESSORY );
if( accessory != null && accessory.equals( mUsbAccessory ) ) {
closeAccessory();
}
}
}
};
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
}