Android Open Source - BTSerialConsole Main Activity






From Project

Back to project page BTSerialConsole.

License

The source code is released under:

MIT License

If you think the Android project BTSerialConsole listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.neykov.bluetoothserialconsole;
//from  w w  w .j  a v  a  2s .  c o m
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;

import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;

import com.neykov.bluetoothserialconsole.connection.BluetoothDriver;
import com.neykov.bluetoothserialconsole.datalog.EEntryType;
import com.neykov.bluetoothserialconsole.dialogs.ConnectWaitDialogFragment;
import com.neykov.bluetoothserialconsole.fragments.DataLogFragment;
import com.neykov.bluetoothserialconsole.fragments.ConnectionFragment;
import com.neykov.bluetoothserialconsole.fragments.DataLogListFragment;
import com.neykov.bluetoothserialconsole.fragments.NoConnectionsFragment;
import com.neykov.bluetoothserialconsole.fragments.DataLogFragment.OnDataLogFragmentInteractionListener;
import com.neykov.bluetoothserialconsole.fragments.DataLogListFragment.DataLogListListener;
import com.neykov.bluetoothserialconsole.fragments.ConnectionFragment.ConnectionFragmentListener;
import com.neykov.bluetoothserialconsole.services.BluetoothSerialService;
import com.neykov.bluetoothserialconsole.services.SerialConnectionService;
import com.neykov.bluetoothserialconsole.services.SerialConnectionServiceBinder;

public class MainActivity extends Activity implements OnDataLogFragmentInteractionListener, ConnectionFragmentListener, DataLogListListener
{
  private static final String TAG = "MainActivity";

  public static final int CONNECT_TO_DEVICE_REQUEST = 1000;
  private static final int CONNECTION_PROGRESS_HIDE_DELAY = 1000;

  public static final String EXTRA_DEVICE_ADRESS = "device adress";
  public static final String EXTRA_HANDLER = "handler";
  public static final String ACTIVITY_ID = "activity_id";
  
  private static final String EXTRA_DATALOG_FRAGMENT_KEYS = "datalog fragments keys";
  
  private static final int FRAGMENT_CONTAINER_RESID = R.id.activity_main_fragment_container;
  private BluetoothSerialService mBtService;

  // Fragments.
  private FragmentManager fragmentManager;
  private NoConnectionsFragment mNoConnFragment;
  private HashMap<String, DataLogFragment> dataLogFragments;
  private Fragment displayedFragment;
  private DataLogListFragment dataLogListFragment;
  
  private ConnectionFragment mConnFragment;

  private ConnectWaitDialogFragment connStatusDialogFragment;
  
  private static final IntentFilter SERVICE_INTENT_FILTER = new IntentFilter()
  {
    {
      addAction(SerialConnectionService.ACTION_DEVICE_CONNECTION_STATE_CHANGED);
      addAction(SerialConnectionService.ACTION_BROADCAST_SERVICE_STATE);
      addAction(BluetoothSerialService.ACTION_INCOMING_ACCEPTED);
    }
  };
  private final BroadcastReceiver serviceIntentReceiver = new BroadcastReceiver()
  {
    @Override
    public void onReceive(Context context, Intent intent)
    {
      String action = intent.getAction();

      if (SerialConnectionService.ACTION_DEVICE_CONNECTION_STATE_CHANGED.equals(action))
      {
        //Get Extras.
        int connState = intent.getIntExtra(SerialConnectionService.EXTRA_DEVICE_CONNECTION_STATE, -1);
        String deviceName = intent.getStringExtra(SerialConnectionService.EXTRA_DEVICE_NAME);
        //BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothSerialService.EXTRA_BLUETOOTH_DEVICE);
        
        switch(connState)
        {
          case SerialConnectionService.CONNECTION_STATE_CONNECTED:
            onServiceConnectSuccess(deviceName);
            break;
          case SerialConnectionService.CONNECTION_STATE_DISCONNECTED:
            onServiceDisconnectSuccess(deviceName);
            break;
          case SerialConnectionService.CONNECTION_STATE_CONNECTING:
            onServiceConnect(deviceName);
            break;
          case SerialConnectionService.CONNECTION_STATE_CONNECT_FAILED:
            onServiceConnectFail(deviceName);
            break;
          case SerialConnectionService.CONNECTION_STATE_DISCONNECTING:
            onServiceDisconnect(deviceName);
          default:
            throw new IllegalArgumentException("The provided connection state extra was invalid or there was none.");
        }
      }
      else if(SerialConnectionService.ACTION_BROADCAST_SERVICE_STATE.equals(action))
      {
        onServiceStateReceived(intent.getExtras());
      }
      else if(BluetoothSerialService.ACTION_INCOMING_ACCEPTED.equals(action))
      {
        BluetoothDevice device = (BluetoothDevice) intent.getParcelableExtra(BluetoothSerialService.EXTRA_BLUETOOTH_DEVICE);
        onServiceIncomingAccepted(device);
      }
    }

    private void onServiceStateReceived(Bundle extras)
    {
      // TODO Auto-generated method stub
      
    }
  };

  private final MyHandler mHandler = new MyHandler(this);
  private final ServiceConnection mConnection = new ServiceConnection()
  {
    @Override
    public void onServiceConnected(ComponentName className, IBinder binder)
    {
      SerialConnectionServiceBinder b = (SerialConnectionServiceBinder) binder;
      mBtService = (BluetoothSerialService) b.getService();
      mBtService.setDataReceiver(MainActivity.this.mHandler);
      mBtService.broadcastServiceState();
      Log.i(TAG, "Bound successfully to service: " + mBtService.toString());
    }

    @Override
    public void onServiceDisconnected(ComponentName className)
    {
      Log.i(TAG, "Unbound successfully from service: " + mBtService.toString());
      mBtService = null;
    }
  };
  
  /**
   * Lifecycle callback methods
   */

  @Override
  public boolean onCreateOptionsMenu(Menu menu)
  {
    // Inflate the menu items for use in the action bar
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.main, menu);
    return super.onCreateOptionsMenu(menu);
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item)
  {
    // Handle presses on the action bar items
    switch (item.getItemId())
    {
      case R.id.action_open_connect:
        showConnectionFragment();
        return true;
      case R.id.action_devices:
        showDataLogListFragment();
        return true;
      default:
        return super.onOptionsItemSelected(item);
    }
  }

  @Override
  protected void onStart()
  {
    super.onStart();
    Log.d(TAG, "Activity onStart() called: " + this.toString());

    // Start the service.
    Intent intent = new Intent(this, BluetoothSerialService.class);
    getApplicationContext().startService(intent);

    // Bind to again to service
    LocalBroadcastManager.getInstance(this).registerReceiver(serviceIntentReceiver, SERVICE_INTENT_FILTER);
    bindToBluetoothService();
  }

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

    // Instantiate fragments.
    dataLogFragments = new HashMap<String, DataLogFragment>();

    // Get the Fragment manager associated to this activity.
    fragmentManager = getFragmentManager();

    if (savedInstanceState == null)
    {
      showEmptyConnectionsFragmetns();
    }
  }

  @Override
  protected void onResume()
  {
    super.onResume();
    Log.d(TAG, "Activity onResume() called: " + this.toString());
  }

  @Override
  protected void onPause()
  {
    super.onPause();
    Log.d(TAG, "Activity onPause() called: " + this.toString());
  }

  @Override
  protected void onStop()
  {
    super.onStop();
    Log.d(TAG, "Activity onStop() called: " + this.toString());
  }

  @Override
  protected void onDestroy()
  {
    super.onDestroy();
    Log.d(TAG, "Activity onDestroy() called: " + this.toString());
    
    // Unbind from service.
    unbindService(mConnection);
    LocalBroadcastManager.getInstance(this).unregisterReceiver(serviceIntentReceiver);
  }

  @Override
  protected void onSaveInstanceState(Bundle outState)
  {
    super.onSaveInstanceState(outState);
    
    //Connection state dialog
    
    
    // Put ConnectionFragment if active.
    if(mConnFragment!=null && !mConnFragment.isDetached())
    fragmentManager.putFragment(outState, ConnectionFragment.TAG, mConnFragment);
    
    // Put DataLog fragments.
    ArrayList<String> fragmentKeys = new ArrayList<String>(10);
    Iterator<Entry<String, DataLogFragment>> it = dataLogFragments.entrySet().iterator();
    while (it.hasNext())
    {
      Entry<String, DataLogFragment> entry = it.next();
      DataLogFragment fragment = entry.getValue();
      String key = fragment.getDeviceName();
      fragmentManager.putFragment(outState, key, fragment);
      fragmentKeys.add(key);
    }
    String[] keys = fragmentKeys.toArray(new String[fragmentKeys.size()]);
    outState.putStringArray(EXTRA_DATALOG_FRAGMENT_KEYS, keys);
    
    //Put the ProgressDialog
    
  }

  @Override
  protected void onRestoreInstanceState(Bundle savedInstanceState)
  {
    super.onSaveInstanceState(savedInstanceState);
    
    // Get the ConnectionFragment.
    mConnFragment = (ConnectionFragment) fragmentManager.getFragment(savedInstanceState, ConnectionFragment.TAG);
    
    //Get the DataLog fragments.
    String[] fragmentkeys = savedInstanceState.getStringArray(EXTRA_DATALOG_FRAGMENT_KEYS);
    for(int index = 0; index<fragmentkeys.length; index++)
    {
      String key = fragmentkeys[index];
      DataLogFragment fragment = (DataLogFragment) fragmentManager.getFragment(savedInstanceState, key);
      dataLogFragments.put(fragmentkeys[index], fragment);
    }
  }

  public BluetoothSerialService getConnectionService()
  {
    return mBtService;
  }

  /**
   * Fragment transaction methods
   * @param tag TODO
   */
  // Action on action bar "Connect" button click.

  private void showFragment(Fragment fragment, boolean addToBackStack, String tag)
  {
    if(fragment == null)
    {
      throw new NullPointerException();
    }
    
    FragmentTransaction transaction = fragmentManager.beginTransaction();
    transaction.setCustomAnimations(R.animator.fade_in, R.animator.fade_out, R.animator.fade_in,
        R.animator.fade_out);
    if (addToBackStack)
    {
      transaction.addToBackStack(tag);
    }
    
    
    //If the currently displayed fragment is a DataLogFragment, just hide its views instead of destroying them.
    if(displayedFragment != null)
    {
      if (displayedFragment instanceof DataLogFragment)
      {
        transaction.hide(displayedFragment);
      }
      else
      {
        transaction.remove(displayedFragment);
      }
    }
      
    if(fragment instanceof DataLogFragment)
    {
      if(fragment.isDetached()) transaction.attach(fragment);
      transaction.show(fragment);
    }
    else
    {
      transaction.add(FRAGMENT_CONTAINER_RESID, fragment, tag);
    }
    transaction.commit();
    fragmentManager.executePendingTransactions();
    displayedFragment = fragment;
  }

  private void showEmptyConnectionsFragmetns()
  {
    if (mNoConnFragment == null)
    {
      mNoConnFragment = NoConnectionsFragment.newInstance();
    }
    showFragment(mNoConnFragment, false, NoConnectionsFragment.TAG);
  }

  private void showConnectionFragment()
  {
    if (mConnFragment == null)
    {
      mConnFragment = ConnectionFragment.newInstance();
    }
    showFragment(mConnFragment, false, null);
  }

  private void showDataLogFragment(DataLogFragment fragment)
  {
    if (fragment == null)
    {
      throw new NullPointerException();
    }
    showFragment(fragment, false, fragment.getTag());
  }

  private void showDataLogListFragment()
  {
    int fragmentCount = dataLogFragments.entrySet().size();
    BluetoothDevice[] fragmentDevices = new BluetoothDevice[fragmentCount];
    Iterator<Entry<String, DataLogFragment>> iter = dataLogFragments.entrySet().iterator();
    for(int i = 0;iter.hasNext(); i++)
    {
      fragmentDevices[i] = iter.next().getValue().getDevice();
    }
    
    if(dataLogListFragment == null)
    {
      dataLogListFragment = DataLogListFragment.newInstance(fragmentDevices);
    }
    else if(dataLogListFragment.isAdded())
    {
      dataLogListFragment.setListItems(fragmentDevices);
    }
    showFragment(dataLogListFragment, false, DataLogListFragment.TAG);
  }

  private void showConnWaitFragment(String initMessage)
  {
    if(connStatusDialogFragment==null || !connStatusDialogFragment.isVisible())
    {
      //Instantiate fragment.
      connStatusDialogFragment = ConnectWaitDialogFragment.newInstance(initMessage);
      connStatusDialogFragment.setRetainInstance(true);
      
      //Get a transaction and set it up.
      FragmentTransaction transaction = fragmentManager.beginTransaction();
      transaction.setCustomAnimations(R.animator.fade_in, R.animator.fade_out, R.animator.fade_in,
          R.animator.fade_out);
      transaction.addToBackStack(ConnectWaitDialogFragment.TAG);
      transaction.add(FRAGMENT_CONTAINER_RESID, connStatusDialogFragment, ConnectWaitDialogFragment.TAG);
      
      //Commit transaction and make sure it executes immediately.
      transaction.commit();
      fragmentManager.executePendingTransactions();
    }
  }
  
  private void dismissConnWaitFragment(String message, int delayMillis)
  {
    if(connStatusDialogFragment!=null && connStatusDialogFragment.isAdded())
    {
      //Set optional message to be displayed
      if(message != null)
      {
        connStatusDialogFragment.setMessage(message);
      }
      
      //Get a transaction and set it up.
      final FragmentTransaction transaction = fragmentManager.beginTransaction();
      transaction.setCustomAnimations(R.animator.fade_in, R.animator.fade_out, R.animator.fade_in,
          R.animator.fade_out);
      transaction.remove(connStatusDialogFragment);
      
      //Commit transaction and make sure it executes immediately.
      Handler handler = new Handler();
      handler.postDelayed(new Runnable()
      {
        public void run()
        {
          transaction.commit();
          fragmentManager.executePendingTransactions();
        }
      }, delayMillis);
      
      connStatusDialogFragment = null;
    }
  }
  
  
  private void bindToBluetoothService()
  {
    Intent intent = new Intent(this, BluetoothSerialService.class);
    intent.putExtra(EXTRA_HANDLER, new Messenger(mHandler));
    bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
  }

  private void onDataReceived(String data, String deviceName, EEntryType type)
  {
    DataLogFragment deviceFragment = getDataLogFragment(deviceName);
    deviceFragment.onDataReceive(data, type);
  }

  private DataLogFragment getDataLogFragment(String deviceName)
  {
    DataLogFragment fragment = dataLogFragments.get(deviceName);
    
    if(fragment==null)
    {
      fragment = createDataLogFragmentFor(deviceName);
    }
    
    return fragment;
  }
  
  private DataLogFragment createDataLogFragmentFor(String deviceName)
  {
    BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(deviceName);
    DataLogFragment fragment = DataLogFragment.newInstance(device);
    dataLogFragments.put(deviceName, fragment);
    FragmentTransaction transaction = fragmentManager.beginTransaction();
    transaction.add(FRAGMENT_CONTAINER_RESID, fragment, deviceName);
    transaction.commit();
    return fragment;
  }
  
   /**
   *****************************| Service Callback Methods |******************************* 
   */

  private void onServiceConnect(String deviceName)
  {
    Log.i(TAG, "Attempting connection to device: " + deviceName);
    showConnWaitFragment(this.getString(R.string.progress_dialog_connecting));
  }

  private void onServiceIncomingAccepted(BluetoothDevice device)
  {
    mConnFragment.onIncomingRequest(device);
  }
  
   private void onServiceConnectSuccess(String deviceName)
  {
    Log.i(TAG, "Connected successfully to device: " + deviceName);
    dismissConnWaitFragment(getString(R.string.progress_dialog_success), CONNECTION_PROGRESS_HIDE_DELAY);
    
    DataLogFragment deviceFragment = getDataLogFragment(deviceName);
    showDataLogFragment(deviceFragment);
    deviceFragment.onConnect();
  }

  private void onServiceConnectFail(String deviceName)
  {
    Log.i(TAG, "Failed connecting to device: " + deviceName);
    dismissConnWaitFragment(getString(R.string.progress_dialog_failed), CONNECTION_PROGRESS_HIDE_DELAY);
  }

  private void onServiceDisconnect(String stringExtra)
  {
  }

  private void onServiceDisconnectSuccess(String deviceName)
  {
    Log.w(TAG, "Disconnected from device: " + deviceName);
    DataLogFragment deviceFragment = dataLogFragments.get(deviceName);
    deviceFragment.onDisconnect();
  }


   /**
   ************************| ConnectionFragment Callback Methods |*************************** 
   */

  @Override
  public void onConnFragmentDeviceSelected(BluetoothDevice device, boolean incoming)
  {
    Toast.makeText(this, "Picked device " + device.getAddress(), Toast.LENGTH_SHORT).show();

    mBtService.stopListenForIncoming(BluetoothSerialService.CONNECT_INSECURE);
    
    
    if(incoming)
    {
      mBtService.connectToIncoming(device, BluetoothSerialService.CONNECT_INSECURE);
    }
    else
    {
      mBtService.connect(device, BluetoothSerialService.CONNECT_INSECURE);
    }
    
    mBtService.clearAcceptedIncoming();
    Log.d(TAG, "Service connect called: " + mBtService.toString());
  }

  @Override
  public void onConnFragmentRefresh()
  {
    mBtService.startListenForIncoming(BluetoothSerialService.CONNECT_INSECURE);
  }
  
  // Called when an active DataLogFragment wants to send data.
  @Override
  public void onFragmentDataSend(DataLogFragment sender, String data)
  {
    if (mBtService != null)
    {
      mBtService.writeTo(sender.getDeviceName(), data);
    }
  }

  @Override
  public void onDataLogListSelected(String deviceId)
  {
    this.showDataLogFragment(dataLogFragments.get(deviceId));
  }
  
  private static class MyHandler extends Handler
  {
    private final WeakReference<MainActivity> mActivity;

    public MyHandler(MainActivity activity)
    {
      super();
      mActivity = new WeakReference<MainActivity>(activity);
    }

    @Override
    public void handleMessage(Message msg)
    {
      
      Bundle data = msg.getData();
      BluetoothDevice device = data.getParcelable(BluetoothDriver.EXTRA_BLUETOOTH_DEVICE);
      boolean securityOption = data.getBoolean(BluetoothDriver.EXTRA_SECURITY_OPTION);
      String deviceName = device.getAddress();
      
      MainActivity activity = mActivity.get();
      if (activity == null)
      {
        return;
      }

      switch (msg.what)
      {
        case BluetoothDriver.MESSAGE_READ:
          activity.onDataReceived((String) msg.obj, deviceName, EEntryType.RECEIVE);
          break;
        case BluetoothDriver.MESSAGE_WRITE:
          activity.onDataReceived((String) msg.obj, deviceName, EEntryType.SEND);
          break;
      }
    }
  }

  
}




Java Source Code List

com.neykov.bluetoothserialconsole.MainActivity.java
com.neykov.bluetoothserialconsole.connection.BluetoothDriver.java
com.neykov.bluetoothserialconsole.connection.ConnectionParameters.java
com.neykov.bluetoothserialconsole.connection.DeviceDriver.java
com.neykov.bluetoothserialconsole.connection.IDeviceDriverCallback.java
com.neykov.bluetoothserialconsole.connection.IDeviceDriver.java
com.neykov.bluetoothserialconsole.connection.enums.EBaudRate.java
com.neykov.bluetoothserialconsole.connection.enums.EDataBits.java
com.neykov.bluetoothserialconsole.connection.enums.EFlowControl.java
com.neykov.bluetoothserialconsole.connection.enums.EParity.java
com.neykov.bluetoothserialconsole.connection.enums.EStopBits.java
com.neykov.bluetoothserialconsole.data.DataClientManager.java
com.neykov.bluetoothserialconsole.data.DataClient.java
com.neykov.bluetoothserialconsole.data.DataConsumer.java
com.neykov.bluetoothserialconsole.data.DataProducer.java
com.neykov.bluetoothserialconsole.data.ICommandReader.java
com.neykov.bluetoothserialconsole.data.IDataWriter.java
com.neykov.bluetoothserialconsole.datalog.EEntryType.java
com.neykov.bluetoothserialconsole.dialogs.ConnectWaitDialogFragment.java
com.neykov.bluetoothserialconsole.fragments.ConnectionFragment.java
com.neykov.bluetoothserialconsole.fragments.DataLogFragment.java
com.neykov.bluetoothserialconsole.fragments.DataLogListFragment.java
com.neykov.bluetoothserialconsole.fragments.DeviceListAdapter.java
com.neykov.bluetoothserialconsole.fragments.NoConnectionsFragment.java
com.neykov.bluetoothserialconsole.services.BluetoothIncomingCallback.java
com.neykov.bluetoothserialconsole.services.BluetoothSerialService.java
com.neykov.bluetoothserialconsole.services.ConnectionLimitReachedException.java
com.neykov.bluetoothserialconsole.services.SerialConnectionServiceBinder.java
com.neykov.bluetoothserialconsole.services.SerialConnectionService.java