1*90c8c64dSAndroid Build Coastguard Worker /* 2*90c8c64dSAndroid Build Coastguard Worker * Copyright (C) 2014 The Android Open Source Project 3*90c8c64dSAndroid Build Coastguard Worker * 4*90c8c64dSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*90c8c64dSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*90c8c64dSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*90c8c64dSAndroid Build Coastguard Worker * 8*90c8c64dSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*90c8c64dSAndroid Build Coastguard Worker * 10*90c8c64dSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*90c8c64dSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*90c8c64dSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*90c8c64dSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*90c8c64dSAndroid Build Coastguard Worker * limitations under the License. 15*90c8c64dSAndroid Build Coastguard Worker */ 16*90c8c64dSAndroid Build Coastguard Worker 17*90c8c64dSAndroid Build Coastguard Worker package com.example.android.bluetoothchat; 18*90c8c64dSAndroid Build Coastguard Worker 19*90c8c64dSAndroid Build Coastguard Worker import android.app.ActionBar; 20*90c8c64dSAndroid Build Coastguard Worker import android.app.Activity; 21*90c8c64dSAndroid Build Coastguard Worker import android.bluetooth.BluetoothAdapter; 22*90c8c64dSAndroid Build Coastguard Worker import android.bluetooth.BluetoothDevice; 23*90c8c64dSAndroid Build Coastguard Worker import android.content.Intent; 24*90c8c64dSAndroid Build Coastguard Worker import android.os.Bundle; 25*90c8c64dSAndroid Build Coastguard Worker import android.os.Handler; 26*90c8c64dSAndroid Build Coastguard Worker import android.os.Message; 27*90c8c64dSAndroid Build Coastguard Worker import android.support.annotation.Nullable; 28*90c8c64dSAndroid Build Coastguard Worker import android.support.v4.app.Fragment; 29*90c8c64dSAndroid Build Coastguard Worker import android.support.v4.app.FragmentActivity; 30*90c8c64dSAndroid Build Coastguard Worker import android.view.KeyEvent; 31*90c8c64dSAndroid Build Coastguard Worker import android.view.LayoutInflater; 32*90c8c64dSAndroid Build Coastguard Worker import android.view.Menu; 33*90c8c64dSAndroid Build Coastguard Worker import android.view.MenuInflater; 34*90c8c64dSAndroid Build Coastguard Worker import android.view.MenuItem; 35*90c8c64dSAndroid Build Coastguard Worker import android.view.View; 36*90c8c64dSAndroid Build Coastguard Worker import android.view.ViewGroup; 37*90c8c64dSAndroid Build Coastguard Worker import android.view.inputmethod.EditorInfo; 38*90c8c64dSAndroid Build Coastguard Worker import android.widget.ArrayAdapter; 39*90c8c64dSAndroid Build Coastguard Worker import android.widget.Button; 40*90c8c64dSAndroid Build Coastguard Worker import android.widget.EditText; 41*90c8c64dSAndroid Build Coastguard Worker import android.widget.ListView; 42*90c8c64dSAndroid Build Coastguard Worker import android.widget.TextView; 43*90c8c64dSAndroid Build Coastguard Worker import android.widget.Toast; 44*90c8c64dSAndroid Build Coastguard Worker 45*90c8c64dSAndroid Build Coastguard Worker import com.example.android.common.logger.Log; 46*90c8c64dSAndroid Build Coastguard Worker 47*90c8c64dSAndroid Build Coastguard Worker /** 48*90c8c64dSAndroid Build Coastguard Worker * This fragment controls Bluetooth to communicate with other devices. 49*90c8c64dSAndroid Build Coastguard Worker */ 50*90c8c64dSAndroid Build Coastguard Worker public class BluetoothChatFragment extends Fragment { 51*90c8c64dSAndroid Build Coastguard Worker 52*90c8c64dSAndroid Build Coastguard Worker private static final String TAG = "BluetoothChatFragment"; 53*90c8c64dSAndroid Build Coastguard Worker 54*90c8c64dSAndroid Build Coastguard Worker // Intent request codes 55*90c8c64dSAndroid Build Coastguard Worker private static final int REQUEST_CONNECT_DEVICE_SECURE = 1; 56*90c8c64dSAndroid Build Coastguard Worker private static final int REQUEST_CONNECT_DEVICE_INSECURE = 2; 57*90c8c64dSAndroid Build Coastguard Worker private static final int REQUEST_ENABLE_BT = 3; 58*90c8c64dSAndroid Build Coastguard Worker 59*90c8c64dSAndroid Build Coastguard Worker // Layout Views 60*90c8c64dSAndroid Build Coastguard Worker private ListView mConversationView; 61*90c8c64dSAndroid Build Coastguard Worker private EditText mOutEditText; 62*90c8c64dSAndroid Build Coastguard Worker private Button mSendButton; 63*90c8c64dSAndroid Build Coastguard Worker 64*90c8c64dSAndroid Build Coastguard Worker /** 65*90c8c64dSAndroid Build Coastguard Worker * Name of the connected device 66*90c8c64dSAndroid Build Coastguard Worker */ 67*90c8c64dSAndroid Build Coastguard Worker private String mConnectedDeviceName = null; 68*90c8c64dSAndroid Build Coastguard Worker 69*90c8c64dSAndroid Build Coastguard Worker /** 70*90c8c64dSAndroid Build Coastguard Worker * Array adapter for the conversation thread 71*90c8c64dSAndroid Build Coastguard Worker */ 72*90c8c64dSAndroid Build Coastguard Worker private ArrayAdapter<String> mConversationArrayAdapter; 73*90c8c64dSAndroid Build Coastguard Worker 74*90c8c64dSAndroid Build Coastguard Worker /** 75*90c8c64dSAndroid Build Coastguard Worker * String buffer for outgoing messages 76*90c8c64dSAndroid Build Coastguard Worker */ 77*90c8c64dSAndroid Build Coastguard Worker private StringBuffer mOutStringBuffer; 78*90c8c64dSAndroid Build Coastguard Worker 79*90c8c64dSAndroid Build Coastguard Worker /** 80*90c8c64dSAndroid Build Coastguard Worker * Local Bluetooth adapter 81*90c8c64dSAndroid Build Coastguard Worker */ 82*90c8c64dSAndroid Build Coastguard Worker private BluetoothAdapter mBluetoothAdapter = null; 83*90c8c64dSAndroid Build Coastguard Worker 84*90c8c64dSAndroid Build Coastguard Worker /** 85*90c8c64dSAndroid Build Coastguard Worker * Member object for the chat services 86*90c8c64dSAndroid Build Coastguard Worker */ 87*90c8c64dSAndroid Build Coastguard Worker private BluetoothChatService mChatService = null; 88*90c8c64dSAndroid Build Coastguard Worker 89*90c8c64dSAndroid Build Coastguard Worker @Override onCreate(Bundle savedInstanceState)90*90c8c64dSAndroid Build Coastguard Worker public void onCreate(Bundle savedInstanceState) { 91*90c8c64dSAndroid Build Coastguard Worker super.onCreate(savedInstanceState); 92*90c8c64dSAndroid Build Coastguard Worker setHasOptionsMenu(true); 93*90c8c64dSAndroid Build Coastguard Worker // Get local Bluetooth adapter 94*90c8c64dSAndroid Build Coastguard Worker mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 95*90c8c64dSAndroid Build Coastguard Worker 96*90c8c64dSAndroid Build Coastguard Worker // If the adapter is null, then Bluetooth is not supported 97*90c8c64dSAndroid Build Coastguard Worker if (mBluetoothAdapter == null) { 98*90c8c64dSAndroid Build Coastguard Worker FragmentActivity activity = getActivity(); 99*90c8c64dSAndroid Build Coastguard Worker Toast.makeText(activity, "Bluetooth is not available", Toast.LENGTH_LONG).show(); 100*90c8c64dSAndroid Build Coastguard Worker activity.finish(); 101*90c8c64dSAndroid Build Coastguard Worker } 102*90c8c64dSAndroid Build Coastguard Worker } 103*90c8c64dSAndroid Build Coastguard Worker 104*90c8c64dSAndroid Build Coastguard Worker 105*90c8c64dSAndroid Build Coastguard Worker @Override onStart()106*90c8c64dSAndroid Build Coastguard Worker public void onStart() { 107*90c8c64dSAndroid Build Coastguard Worker super.onStart(); 108*90c8c64dSAndroid Build Coastguard Worker // If BT is not on, request that it be enabled. 109*90c8c64dSAndroid Build Coastguard Worker // setupChat() will then be called during onActivityResult 110*90c8c64dSAndroid Build Coastguard Worker if (!mBluetoothAdapter.isEnabled()) { 111*90c8c64dSAndroid Build Coastguard Worker Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); 112*90c8c64dSAndroid Build Coastguard Worker startActivityForResult(enableIntent, REQUEST_ENABLE_BT); 113*90c8c64dSAndroid Build Coastguard Worker // Otherwise, setup the chat session 114*90c8c64dSAndroid Build Coastguard Worker } else if (mChatService == null) { 115*90c8c64dSAndroid Build Coastguard Worker setupChat(); 116*90c8c64dSAndroid Build Coastguard Worker } 117*90c8c64dSAndroid Build Coastguard Worker } 118*90c8c64dSAndroid Build Coastguard Worker 119*90c8c64dSAndroid Build Coastguard Worker @Override onDestroy()120*90c8c64dSAndroid Build Coastguard Worker public void onDestroy() { 121*90c8c64dSAndroid Build Coastguard Worker super.onDestroy(); 122*90c8c64dSAndroid Build Coastguard Worker if (mChatService != null) { 123*90c8c64dSAndroid Build Coastguard Worker mChatService.stop(); 124*90c8c64dSAndroid Build Coastguard Worker } 125*90c8c64dSAndroid Build Coastguard Worker } 126*90c8c64dSAndroid Build Coastguard Worker 127*90c8c64dSAndroid Build Coastguard Worker @Override onResume()128*90c8c64dSAndroid Build Coastguard Worker public void onResume() { 129*90c8c64dSAndroid Build Coastguard Worker super.onResume(); 130*90c8c64dSAndroid Build Coastguard Worker 131*90c8c64dSAndroid Build Coastguard Worker // Performing this check in onResume() covers the case in which BT was 132*90c8c64dSAndroid Build Coastguard Worker // not enabled during onStart(), so we were paused to enable it... 133*90c8c64dSAndroid Build Coastguard Worker // onResume() will be called when ACTION_REQUEST_ENABLE activity returns. 134*90c8c64dSAndroid Build Coastguard Worker if (mChatService != null) { 135*90c8c64dSAndroid Build Coastguard Worker // Only if the state is STATE_NONE, do we know that we haven't started already 136*90c8c64dSAndroid Build Coastguard Worker if (mChatService.getState() == BluetoothChatService.STATE_NONE) { 137*90c8c64dSAndroid Build Coastguard Worker // Start the Bluetooth chat services 138*90c8c64dSAndroid Build Coastguard Worker mChatService.start(); 139*90c8c64dSAndroid Build Coastguard Worker } 140*90c8c64dSAndroid Build Coastguard Worker } 141*90c8c64dSAndroid Build Coastguard Worker } 142*90c8c64dSAndroid Build Coastguard Worker 143*90c8c64dSAndroid Build Coastguard Worker @Override onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)144*90c8c64dSAndroid Build Coastguard Worker public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, 145*90c8c64dSAndroid Build Coastguard Worker @Nullable Bundle savedInstanceState) { 146*90c8c64dSAndroid Build Coastguard Worker return inflater.inflate(R.layout.fragment_bluetooth_chat, container, false); 147*90c8c64dSAndroid Build Coastguard Worker } 148*90c8c64dSAndroid Build Coastguard Worker 149*90c8c64dSAndroid Build Coastguard Worker @Override onViewCreated(View view, @Nullable Bundle savedInstanceState)150*90c8c64dSAndroid Build Coastguard Worker public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { 151*90c8c64dSAndroid Build Coastguard Worker mConversationView = (ListView) view.findViewById(R.id.in); 152*90c8c64dSAndroid Build Coastguard Worker mOutEditText = (EditText) view.findViewById(R.id.edit_text_out); 153*90c8c64dSAndroid Build Coastguard Worker mSendButton = (Button) view.findViewById(R.id.button_send); 154*90c8c64dSAndroid Build Coastguard Worker } 155*90c8c64dSAndroid Build Coastguard Worker 156*90c8c64dSAndroid Build Coastguard Worker /** 157*90c8c64dSAndroid Build Coastguard Worker * Set up the UI and background operations for chat. 158*90c8c64dSAndroid Build Coastguard Worker */ setupChat()159*90c8c64dSAndroid Build Coastguard Worker private void setupChat() { 160*90c8c64dSAndroid Build Coastguard Worker Log.d(TAG, "setupChat()"); 161*90c8c64dSAndroid Build Coastguard Worker 162*90c8c64dSAndroid Build Coastguard Worker // Initialize the array adapter for the conversation thread 163*90c8c64dSAndroid Build Coastguard Worker mConversationArrayAdapter = new ArrayAdapter<String>(getActivity(), R.layout.message); 164*90c8c64dSAndroid Build Coastguard Worker 165*90c8c64dSAndroid Build Coastguard Worker mConversationView.setAdapter(mConversationArrayAdapter); 166*90c8c64dSAndroid Build Coastguard Worker 167*90c8c64dSAndroid Build Coastguard Worker // Initialize the compose field with a listener for the return key 168*90c8c64dSAndroid Build Coastguard Worker mOutEditText.setOnEditorActionListener(mWriteListener); 169*90c8c64dSAndroid Build Coastguard Worker 170*90c8c64dSAndroid Build Coastguard Worker // Initialize the send button with a listener that for click events 171*90c8c64dSAndroid Build Coastguard Worker mSendButton.setOnClickListener(new View.OnClickListener() { 172*90c8c64dSAndroid Build Coastguard Worker public void onClick(View v) { 173*90c8c64dSAndroid Build Coastguard Worker // Send a message using content of the edit text widget 174*90c8c64dSAndroid Build Coastguard Worker View view = getView(); 175*90c8c64dSAndroid Build Coastguard Worker if (null != view) { 176*90c8c64dSAndroid Build Coastguard Worker TextView textView = (TextView) view.findViewById(R.id.edit_text_out); 177*90c8c64dSAndroid Build Coastguard Worker String message = textView.getText().toString(); 178*90c8c64dSAndroid Build Coastguard Worker sendMessage(message); 179*90c8c64dSAndroid Build Coastguard Worker } 180*90c8c64dSAndroid Build Coastguard Worker } 181*90c8c64dSAndroid Build Coastguard Worker }); 182*90c8c64dSAndroid Build Coastguard Worker 183*90c8c64dSAndroid Build Coastguard Worker // Initialize the BluetoothChatService to perform bluetooth connections 184*90c8c64dSAndroid Build Coastguard Worker mChatService = new BluetoothChatService(getActivity(), mHandler); 185*90c8c64dSAndroid Build Coastguard Worker 186*90c8c64dSAndroid Build Coastguard Worker // Initialize the buffer for outgoing messages 187*90c8c64dSAndroid Build Coastguard Worker mOutStringBuffer = new StringBuffer(""); 188*90c8c64dSAndroid Build Coastguard Worker } 189*90c8c64dSAndroid Build Coastguard Worker 190*90c8c64dSAndroid Build Coastguard Worker /** 191*90c8c64dSAndroid Build Coastguard Worker * Makes this device discoverable for 300 seconds (5 minutes). 192*90c8c64dSAndroid Build Coastguard Worker */ ensureDiscoverable()193*90c8c64dSAndroid Build Coastguard Worker private void ensureDiscoverable() { 194*90c8c64dSAndroid Build Coastguard Worker if (mBluetoothAdapter.getScanMode() != 195*90c8c64dSAndroid Build Coastguard Worker BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) { 196*90c8c64dSAndroid Build Coastguard Worker Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); 197*90c8c64dSAndroid Build Coastguard Worker discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); 198*90c8c64dSAndroid Build Coastguard Worker startActivity(discoverableIntent); 199*90c8c64dSAndroid Build Coastguard Worker } 200*90c8c64dSAndroid Build Coastguard Worker } 201*90c8c64dSAndroid Build Coastguard Worker 202*90c8c64dSAndroid Build Coastguard Worker /** 203*90c8c64dSAndroid Build Coastguard Worker * Sends a message. 204*90c8c64dSAndroid Build Coastguard Worker * 205*90c8c64dSAndroid Build Coastguard Worker * @param message A string of text to send. 206*90c8c64dSAndroid Build Coastguard Worker */ sendMessage(String message)207*90c8c64dSAndroid Build Coastguard Worker private void sendMessage(String message) { 208*90c8c64dSAndroid Build Coastguard Worker // Check that we're actually connected before trying anything 209*90c8c64dSAndroid Build Coastguard Worker if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) { 210*90c8c64dSAndroid Build Coastguard Worker Toast.makeText(getActivity(), R.string.not_connected, Toast.LENGTH_SHORT).show(); 211*90c8c64dSAndroid Build Coastguard Worker return; 212*90c8c64dSAndroid Build Coastguard Worker } 213*90c8c64dSAndroid Build Coastguard Worker 214*90c8c64dSAndroid Build Coastguard Worker // Check that there's actually something to send 215*90c8c64dSAndroid Build Coastguard Worker if (message.length() > 0) { 216*90c8c64dSAndroid Build Coastguard Worker // Get the message bytes and tell the BluetoothChatService to write 217*90c8c64dSAndroid Build Coastguard Worker byte[] send = message.getBytes(); 218*90c8c64dSAndroid Build Coastguard Worker mChatService.write(send); 219*90c8c64dSAndroid Build Coastguard Worker 220*90c8c64dSAndroid Build Coastguard Worker // Reset out string buffer to zero and clear the edit text field 221*90c8c64dSAndroid Build Coastguard Worker mOutStringBuffer.setLength(0); 222*90c8c64dSAndroid Build Coastguard Worker mOutEditText.setText(mOutStringBuffer); 223*90c8c64dSAndroid Build Coastguard Worker } 224*90c8c64dSAndroid Build Coastguard Worker } 225*90c8c64dSAndroid Build Coastguard Worker 226*90c8c64dSAndroid Build Coastguard Worker /** 227*90c8c64dSAndroid Build Coastguard Worker * The action listener for the EditText widget, to listen for the return key 228*90c8c64dSAndroid Build Coastguard Worker */ 229*90c8c64dSAndroid Build Coastguard Worker private TextView.OnEditorActionListener mWriteListener 230*90c8c64dSAndroid Build Coastguard Worker = new TextView.OnEditorActionListener() { 231*90c8c64dSAndroid Build Coastguard Worker public boolean onEditorAction(TextView view, int actionId, KeyEvent event) { 232*90c8c64dSAndroid Build Coastguard Worker // If the action is a key-up event on the return key, send the message 233*90c8c64dSAndroid Build Coastguard Worker if (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_UP) { 234*90c8c64dSAndroid Build Coastguard Worker String message = view.getText().toString(); 235*90c8c64dSAndroid Build Coastguard Worker sendMessage(message); 236*90c8c64dSAndroid Build Coastguard Worker } 237*90c8c64dSAndroid Build Coastguard Worker return true; 238*90c8c64dSAndroid Build Coastguard Worker } 239*90c8c64dSAndroid Build Coastguard Worker }; 240*90c8c64dSAndroid Build Coastguard Worker 241*90c8c64dSAndroid Build Coastguard Worker /** 242*90c8c64dSAndroid Build Coastguard Worker * Updates the status on the action bar. 243*90c8c64dSAndroid Build Coastguard Worker * 244*90c8c64dSAndroid Build Coastguard Worker * @param resId a string resource ID 245*90c8c64dSAndroid Build Coastguard Worker */ setStatus(int resId)246*90c8c64dSAndroid Build Coastguard Worker private void setStatus(int resId) { 247*90c8c64dSAndroid Build Coastguard Worker FragmentActivity activity = getActivity(); 248*90c8c64dSAndroid Build Coastguard Worker if (null == activity) { 249*90c8c64dSAndroid Build Coastguard Worker return; 250*90c8c64dSAndroid Build Coastguard Worker } 251*90c8c64dSAndroid Build Coastguard Worker final ActionBar actionBar = activity.getActionBar(); 252*90c8c64dSAndroid Build Coastguard Worker if (null == actionBar) { 253*90c8c64dSAndroid Build Coastguard Worker return; 254*90c8c64dSAndroid Build Coastguard Worker } 255*90c8c64dSAndroid Build Coastguard Worker actionBar.setSubtitle(resId); 256*90c8c64dSAndroid Build Coastguard Worker } 257*90c8c64dSAndroid Build Coastguard Worker 258*90c8c64dSAndroid Build Coastguard Worker /** 259*90c8c64dSAndroid Build Coastguard Worker * Updates the status on the action bar. 260*90c8c64dSAndroid Build Coastguard Worker * 261*90c8c64dSAndroid Build Coastguard Worker * @param subTitle status 262*90c8c64dSAndroid Build Coastguard Worker */ setStatus(CharSequence subTitle)263*90c8c64dSAndroid Build Coastguard Worker private void setStatus(CharSequence subTitle) { 264*90c8c64dSAndroid Build Coastguard Worker FragmentActivity activity = getActivity(); 265*90c8c64dSAndroid Build Coastguard Worker if (null == activity) { 266*90c8c64dSAndroid Build Coastguard Worker return; 267*90c8c64dSAndroid Build Coastguard Worker } 268*90c8c64dSAndroid Build Coastguard Worker final ActionBar actionBar = activity.getActionBar(); 269*90c8c64dSAndroid Build Coastguard Worker if (null == actionBar) { 270*90c8c64dSAndroid Build Coastguard Worker return; 271*90c8c64dSAndroid Build Coastguard Worker } 272*90c8c64dSAndroid Build Coastguard Worker actionBar.setSubtitle(subTitle); 273*90c8c64dSAndroid Build Coastguard Worker } 274*90c8c64dSAndroid Build Coastguard Worker 275*90c8c64dSAndroid Build Coastguard Worker /** 276*90c8c64dSAndroid Build Coastguard Worker * The Handler that gets information back from the BluetoothChatService 277*90c8c64dSAndroid Build Coastguard Worker */ 278*90c8c64dSAndroid Build Coastguard Worker private final Handler mHandler = new Handler() { 279*90c8c64dSAndroid Build Coastguard Worker @Override 280*90c8c64dSAndroid Build Coastguard Worker public void handleMessage(Message msg) { 281*90c8c64dSAndroid Build Coastguard Worker FragmentActivity activity = getActivity(); 282*90c8c64dSAndroid Build Coastguard Worker switch (msg.what) { 283*90c8c64dSAndroid Build Coastguard Worker case Constants.MESSAGE_STATE_CHANGE: 284*90c8c64dSAndroid Build Coastguard Worker switch (msg.arg1) { 285*90c8c64dSAndroid Build Coastguard Worker case BluetoothChatService.STATE_CONNECTED: 286*90c8c64dSAndroid Build Coastguard Worker setStatus(getString(R.string.title_connected_to, mConnectedDeviceName)); 287*90c8c64dSAndroid Build Coastguard Worker mConversationArrayAdapter.clear(); 288*90c8c64dSAndroid Build Coastguard Worker break; 289*90c8c64dSAndroid Build Coastguard Worker case BluetoothChatService.STATE_CONNECTING: 290*90c8c64dSAndroid Build Coastguard Worker setStatus(R.string.title_connecting); 291*90c8c64dSAndroid Build Coastguard Worker break; 292*90c8c64dSAndroid Build Coastguard Worker case BluetoothChatService.STATE_LISTEN: 293*90c8c64dSAndroid Build Coastguard Worker case BluetoothChatService.STATE_NONE: 294*90c8c64dSAndroid Build Coastguard Worker setStatus(R.string.title_not_connected); 295*90c8c64dSAndroid Build Coastguard Worker break; 296*90c8c64dSAndroid Build Coastguard Worker } 297*90c8c64dSAndroid Build Coastguard Worker break; 298*90c8c64dSAndroid Build Coastguard Worker case Constants.MESSAGE_WRITE: 299*90c8c64dSAndroid Build Coastguard Worker byte[] writeBuf = (byte[]) msg.obj; 300*90c8c64dSAndroid Build Coastguard Worker // construct a string from the buffer 301*90c8c64dSAndroid Build Coastguard Worker String writeMessage = new String(writeBuf); 302*90c8c64dSAndroid Build Coastguard Worker mConversationArrayAdapter.add("Me: " + writeMessage); 303*90c8c64dSAndroid Build Coastguard Worker break; 304*90c8c64dSAndroid Build Coastguard Worker case Constants.MESSAGE_READ: 305*90c8c64dSAndroid Build Coastguard Worker byte[] readBuf = (byte[]) msg.obj; 306*90c8c64dSAndroid Build Coastguard Worker // construct a string from the valid bytes in the buffer 307*90c8c64dSAndroid Build Coastguard Worker String readMessage = new String(readBuf, 0, msg.arg1); 308*90c8c64dSAndroid Build Coastguard Worker mConversationArrayAdapter.add(mConnectedDeviceName + ": " + readMessage); 309*90c8c64dSAndroid Build Coastguard Worker break; 310*90c8c64dSAndroid Build Coastguard Worker case Constants.MESSAGE_DEVICE_NAME: 311*90c8c64dSAndroid Build Coastguard Worker // save the connected device's name 312*90c8c64dSAndroid Build Coastguard Worker mConnectedDeviceName = msg.getData().getString(Constants.DEVICE_NAME); 313*90c8c64dSAndroid Build Coastguard Worker if (null != activity) { 314*90c8c64dSAndroid Build Coastguard Worker Toast.makeText(activity, "Connected to " 315*90c8c64dSAndroid Build Coastguard Worker + mConnectedDeviceName, Toast.LENGTH_SHORT).show(); 316*90c8c64dSAndroid Build Coastguard Worker } 317*90c8c64dSAndroid Build Coastguard Worker break; 318*90c8c64dSAndroid Build Coastguard Worker case Constants.MESSAGE_TOAST: 319*90c8c64dSAndroid Build Coastguard Worker if (null != activity) { 320*90c8c64dSAndroid Build Coastguard Worker Toast.makeText(activity, msg.getData().getString(Constants.TOAST), 321*90c8c64dSAndroid Build Coastguard Worker Toast.LENGTH_SHORT).show(); 322*90c8c64dSAndroid Build Coastguard Worker } 323*90c8c64dSAndroid Build Coastguard Worker break; 324*90c8c64dSAndroid Build Coastguard Worker } 325*90c8c64dSAndroid Build Coastguard Worker } 326*90c8c64dSAndroid Build Coastguard Worker }; 327*90c8c64dSAndroid Build Coastguard Worker onActivityResult(int requestCode, int resultCode, Intent data)328*90c8c64dSAndroid Build Coastguard Worker public void onActivityResult(int requestCode, int resultCode, Intent data) { 329*90c8c64dSAndroid Build Coastguard Worker switch (requestCode) { 330*90c8c64dSAndroid Build Coastguard Worker case REQUEST_CONNECT_DEVICE_SECURE: 331*90c8c64dSAndroid Build Coastguard Worker // When DeviceListActivity returns with a device to connect 332*90c8c64dSAndroid Build Coastguard Worker if (resultCode == Activity.RESULT_OK) { 333*90c8c64dSAndroid Build Coastguard Worker connectDevice(data, true); 334*90c8c64dSAndroid Build Coastguard Worker } 335*90c8c64dSAndroid Build Coastguard Worker break; 336*90c8c64dSAndroid Build Coastguard Worker case REQUEST_CONNECT_DEVICE_INSECURE: 337*90c8c64dSAndroid Build Coastguard Worker // When DeviceListActivity returns with a device to connect 338*90c8c64dSAndroid Build Coastguard Worker if (resultCode == Activity.RESULT_OK) { 339*90c8c64dSAndroid Build Coastguard Worker connectDevice(data, false); 340*90c8c64dSAndroid Build Coastguard Worker } 341*90c8c64dSAndroid Build Coastguard Worker break; 342*90c8c64dSAndroid Build Coastguard Worker case REQUEST_ENABLE_BT: 343*90c8c64dSAndroid Build Coastguard Worker // When the request to enable Bluetooth returns 344*90c8c64dSAndroid Build Coastguard Worker if (resultCode == Activity.RESULT_OK) { 345*90c8c64dSAndroid Build Coastguard Worker // Bluetooth is now enabled, so set up a chat session 346*90c8c64dSAndroid Build Coastguard Worker setupChat(); 347*90c8c64dSAndroid Build Coastguard Worker } else { 348*90c8c64dSAndroid Build Coastguard Worker // User did not enable Bluetooth or an error occurred 349*90c8c64dSAndroid Build Coastguard Worker Log.d(TAG, "BT not enabled"); 350*90c8c64dSAndroid Build Coastguard Worker Toast.makeText(getActivity(), R.string.bt_not_enabled_leaving, 351*90c8c64dSAndroid Build Coastguard Worker Toast.LENGTH_SHORT).show(); 352*90c8c64dSAndroid Build Coastguard Worker getActivity().finish(); 353*90c8c64dSAndroid Build Coastguard Worker } 354*90c8c64dSAndroid Build Coastguard Worker } 355*90c8c64dSAndroid Build Coastguard Worker } 356*90c8c64dSAndroid Build Coastguard Worker 357*90c8c64dSAndroid Build Coastguard Worker /** 358*90c8c64dSAndroid Build Coastguard Worker * Establish connection with other device 359*90c8c64dSAndroid Build Coastguard Worker * 360*90c8c64dSAndroid Build Coastguard Worker * @param data An {@link Intent} with {@link DeviceListActivity#EXTRA_DEVICE_ADDRESS} extra. 361*90c8c64dSAndroid Build Coastguard Worker * @param secure Socket Security type - Secure (true) , Insecure (false) 362*90c8c64dSAndroid Build Coastguard Worker */ connectDevice(Intent data, boolean secure)363*90c8c64dSAndroid Build Coastguard Worker private void connectDevice(Intent data, boolean secure) { 364*90c8c64dSAndroid Build Coastguard Worker // Get the device MAC address 365*90c8c64dSAndroid Build Coastguard Worker String address = data.getExtras() 366*90c8c64dSAndroid Build Coastguard Worker .getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS); 367*90c8c64dSAndroid Build Coastguard Worker // Get the BluetoothDevice object 368*90c8c64dSAndroid Build Coastguard Worker BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address); 369*90c8c64dSAndroid Build Coastguard Worker // Attempt to connect to the device 370*90c8c64dSAndroid Build Coastguard Worker mChatService.connect(device, secure); 371*90c8c64dSAndroid Build Coastguard Worker } 372*90c8c64dSAndroid Build Coastguard Worker 373*90c8c64dSAndroid Build Coastguard Worker @Override onCreateOptionsMenu(Menu menu, MenuInflater inflater)374*90c8c64dSAndroid Build Coastguard Worker public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 375*90c8c64dSAndroid Build Coastguard Worker inflater.inflate(R.menu.bluetooth_chat, menu); 376*90c8c64dSAndroid Build Coastguard Worker } 377*90c8c64dSAndroid Build Coastguard Worker 378*90c8c64dSAndroid Build Coastguard Worker @Override onOptionsItemSelected(MenuItem item)379*90c8c64dSAndroid Build Coastguard Worker public boolean onOptionsItemSelected(MenuItem item) { 380*90c8c64dSAndroid Build Coastguard Worker switch (item.getItemId()) { 381*90c8c64dSAndroid Build Coastguard Worker case R.id.secure_connect_scan: { 382*90c8c64dSAndroid Build Coastguard Worker // Launch the DeviceListActivity to see devices and do scan 383*90c8c64dSAndroid Build Coastguard Worker Intent serverIntent = new Intent(getActivity(), DeviceListActivity.class); 384*90c8c64dSAndroid Build Coastguard Worker startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_SECURE); 385*90c8c64dSAndroid Build Coastguard Worker return true; 386*90c8c64dSAndroid Build Coastguard Worker } 387*90c8c64dSAndroid Build Coastguard Worker case R.id.insecure_connect_scan: { 388*90c8c64dSAndroid Build Coastguard Worker // Launch the DeviceListActivity to see devices and do scan 389*90c8c64dSAndroid Build Coastguard Worker Intent serverIntent = new Intent(getActivity(), DeviceListActivity.class); 390*90c8c64dSAndroid Build Coastguard Worker startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_INSECURE); 391*90c8c64dSAndroid Build Coastguard Worker return true; 392*90c8c64dSAndroid Build Coastguard Worker } 393*90c8c64dSAndroid Build Coastguard Worker case R.id.discoverable: { 394*90c8c64dSAndroid Build Coastguard Worker // Ensure this device is discoverable by others 395*90c8c64dSAndroid Build Coastguard Worker ensureDiscoverable(); 396*90c8c64dSAndroid Build Coastguard Worker return true; 397*90c8c64dSAndroid Build Coastguard Worker } 398*90c8c64dSAndroid Build Coastguard Worker } 399*90c8c64dSAndroid Build Coastguard Worker return false; 400*90c8c64dSAndroid Build Coastguard Worker } 401*90c8c64dSAndroid Build Coastguard Worker 402*90c8c64dSAndroid Build Coastguard Worker } 403