|
@@ -0,0 +1,1394 @@
|
|
|
+package kr.co.icontrols.iotplatform;
|
|
|
+
|
|
|
+import android.Manifest;
|
|
|
+import android.app.Activity;
|
|
|
+import android.bluetooth.BluetoothAdapter;
|
|
|
+import android.bluetooth.BluetoothDevice;
|
|
|
+import android.bluetooth.BluetoothGatt;
|
|
|
+import android.bluetooth.BluetoothGattCallback;
|
|
|
+import android.bluetooth.BluetoothGattCharacteristic;
|
|
|
+import android.bluetooth.BluetoothGattDescriptor;
|
|
|
+import android.bluetooth.BluetoothGattService;
|
|
|
+import android.bluetooth.BluetoothManager;
|
|
|
+import android.bluetooth.BluetoothProfile;
|
|
|
+import android.content.Context;
|
|
|
+import android.content.Intent;
|
|
|
+import android.os.Build;
|
|
|
+import android.os.Bundle;
|
|
|
+import android.os.Handler;
|
|
|
+import android.os.Looper;
|
|
|
+import android.os.Message;
|
|
|
+import android.util.Log;
|
|
|
+import android.view.LayoutInflater;
|
|
|
+import android.view.View;
|
|
|
+import android.view.ViewGroup;
|
|
|
+import android.widget.AbsListView;
|
|
|
+import android.widget.AdapterView;
|
|
|
+import android.widget.BaseAdapter;
|
|
|
+import android.widget.ImageView;
|
|
|
+import android.widget.LinearLayout;
|
|
|
+import android.widget.ListView;
|
|
|
+import android.widget.TextView;
|
|
|
+import android.widget.Toast;
|
|
|
+
|
|
|
+import androidx.appcompat.app.AppCompatActivity;
|
|
|
+
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Locale;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+import kr.co.icontrols.iotplatform.AWS.AmazonBLEinfo;
|
|
|
+import kr.co.icontrols.iotplatform.Protocol.bleProtocol;
|
|
|
+import kr.co.icontrols.iotplatform.Protocol.bleProtocolState;
|
|
|
+import kr.co.icontrols.iotplatform.utils.hdcUUID;
|
|
|
+
|
|
|
+import static android.bluetooth.BluetoothDevice.TRANSPORT_LE;
|
|
|
+import static kr.co.icontrols.iotplatform.Protocol.bleProtocolState.RSP_BLINK_PROTOCOL_TIMEOUT;
|
|
|
+import static kr.co.icontrols.iotplatform.Protocol.bleProtocolState.RSP_BUZZER_PROTOCOL_TIMEOUT;
|
|
|
+import static kr.co.icontrols.iotplatform.Protocol.bleProtocolState.RSP_GROUP_LIGHT_TIMEOUT;
|
|
|
+import static kr.co.icontrols.iotplatform.Protocol.bleProtocolState.RSP_GROUP_SWITCH_TIMEOUT;
|
|
|
+import static kr.co.icontrols.iotplatform.Protocol.bleProtocolState.RSP_INIT_GROUP_LIGHT_TIMEOUT;
|
|
|
+import static kr.co.icontrols.iotplatform.Protocol.bleProtocolState.RSP_INIT_GROUP_SWITCH_TIMEOUT;
|
|
|
+import static kr.co.icontrols.iotplatform.Protocol.bleProtocolState.SCAN_RESULT_PROTOCOL_FAIL;
|
|
|
+import static kr.co.icontrols.iotplatform.utils.CommonUtils.DebugLogOutput;
|
|
|
+import static kr.co.icontrols.iotplatform.utils.CommonUtils.DismissConnectDialog;
|
|
|
+import static kr.co.icontrols.iotplatform.utils.CommonUtils.IsRunningProgress;
|
|
|
+import static kr.co.icontrols.iotplatform.utils.CommonUtils.appendByteArray;
|
|
|
+import static kr.co.icontrols.iotplatform.utils.CommonUtils.byteArrayToHex;
|
|
|
+import static kr.co.icontrols.iotplatform.utils.CommonUtils.displayProgress;
|
|
|
+import static kr.co.icontrols.iotplatform.utils.CommonUtils.getProgressDialog;
|
|
|
+import static kr.co.icontrols.iotplatform.utils.CommonUtils.isBlueToothEnable;
|
|
|
+import static kr.co.icontrols.iotplatform.utils.CommonUtils.isPasswordValid;
|
|
|
+import static kr.co.icontrols.iotplatform.utils.CommonUtils.showNotiMsg;
|
|
|
+import static kr.co.icontrols.iotplatform.utils.Constants.RESULT_ENABLE_BT_MAIN;
|
|
|
+import static kr.co.icontrols.iotplatform.utils.Constants.RESULT_LIGHT_BLINK_SUCCESS;
|
|
|
+import static kr.co.icontrols.iotplatform.utils.Constants.RESULT_RETRY_BUT_NO_DEVICE;
|
|
|
+import static kr.co.icontrols.iotplatform.utils.Constants.RESULT_RETRY_SCAN_DEVICE;
|
|
|
+import static kr.co.icontrols.iotplatform.utils.Constants.RESULT_SWITCH_MAPPER_BUZZER_SUCCESS;
|
|
|
+
|
|
|
+public class SwitchMapperRegisterActivity extends AppCompatActivity implements View.OnClickListener {
|
|
|
+
|
|
|
+ private final String TAG = "SwitchMapperRegister";
|
|
|
+
|
|
|
+ private final int SCAN_TYPE_NOTHING = -1;
|
|
|
+ private final int SCAN_TYPE_SWITCH = 0;
|
|
|
+ private final int SCAN_TYPE_LIGHT = 1;
|
|
|
+ private int scanType = SCAN_TYPE_SWITCH;
|
|
|
+
|
|
|
+ // Switch scan ui
|
|
|
+ private LinearLayout layoutSwitchList;
|
|
|
+ private TextView txtSwitch;
|
|
|
+ private ListView listViewSwitch;
|
|
|
+ private DeviceArrayAdapter switchArrayAdapter;
|
|
|
+ private List<AmazonBLEinfo> swithList = new ArrayList<>();
|
|
|
+
|
|
|
+
|
|
|
+ // Light scan ui
|
|
|
+ private LinearLayout layoutLightList;
|
|
|
+ private TextView txtLight;
|
|
|
+ private ListView listViewLight;
|
|
|
+ private DeviceArrayAdapter lightArrayAdapter;
|
|
|
+ private List<AmazonBLEinfo> lightList = new ArrayList<>();
|
|
|
+ private List<String> lightListSelected = new ArrayList<>();
|
|
|
+ private List<String> lightScanList = new ArrayList<>();
|
|
|
+
|
|
|
+ // completed ui
|
|
|
+ private LinearLayout layoutCompleted;
|
|
|
+ private TextView txtCompleted;
|
|
|
+
|
|
|
+ // Bluetooth
|
|
|
+ private static final int REQUEST_ENABLE_BT = 1;
|
|
|
+ private static final int PERMISSION_REQUEST_FINE_LOCATION = 1;
|
|
|
+
|
|
|
+ // ble
|
|
|
+ private Handler handler;
|
|
|
+ //private BluetoothGatt bluetoothGatt;
|
|
|
+ private BluetoothAdapter bluetoothAdapter;
|
|
|
+ private BluetoothGattCharacteristic bluetoothGattCharacteristic;
|
|
|
+ private Map<String, BluetoothGatt> connectedDeviceMap;
|
|
|
+
|
|
|
+ //status
|
|
|
+ private final int UI_STATUS_LOADING = 0;
|
|
|
+ private final int UI_STATUS_SHOW_SWITCH_LIST = 1;
|
|
|
+ private final int UI_STATUS_SHOW_LIGHT_LIST = 3;
|
|
|
+ private final int UI_STATUS_SHOW_FAIL = 4;
|
|
|
+ private final int UI_STATUS_SHOW_COMPLETED = 5;
|
|
|
+ private final int UI_STATUS_SHOW_ETC = 6;
|
|
|
+
|
|
|
+ private final int PROCESS_STATUS_NOTHING = 0;
|
|
|
+ private final int PROCESS_STATUS_BUZZER = 1;
|
|
|
+ private final int PROCESS_STATUS_BLINK = 2;
|
|
|
+ private final int PROCESS_STATUS_SCAN_LIGHT = 3;
|
|
|
+ private final int PROCESS_STATUS_GROUPING_SWITCH = 4;
|
|
|
+ private final int PROCESS_STATUS_GROUPING_LIGHT = 5;
|
|
|
+ private final int PROCESS_STATUS_INIT_SWITCH = 6;
|
|
|
+ private final int PROCESS_STATUS_INIT_LIGHT = 7;
|
|
|
+
|
|
|
+ //retry to scan device
|
|
|
+ private boolean isRetry = false;
|
|
|
+
|
|
|
+ private int status_process = PROCESS_STATUS_NOTHING;
|
|
|
+ private int selectedSwitchPosition = 0;
|
|
|
+ private int selectedLightPosition = 0;
|
|
|
+ private int sendIndexLight = 0;
|
|
|
+ private String selectedSwitchMac = "";
|
|
|
+ private String selectedLightMac = "";
|
|
|
+ private Handler switchRegisterHandler;
|
|
|
+ private static final long SCAN_PERIOD = 5000;
|
|
|
+ private int FIRST_SCAN_PERIOD = 500;
|
|
|
+ private int SCAN_COUNT = 3;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void onCreate(Bundle savedInstanceState) {
|
|
|
+ super.onCreate(savedInstanceState);
|
|
|
+ setContentView(R.layout.activity_switch_mapper_register);
|
|
|
+
|
|
|
+ Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
|
|
|
+ startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
|
|
|
+ requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_REQUEST_FINE_LOCATION);
|
|
|
+
|
|
|
+ final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
|
|
|
+ if (bluetoothManager != null) {
|
|
|
+ bluetoothAdapter = bluetoothManager.getAdapter();
|
|
|
+ }
|
|
|
+
|
|
|
+ setUI();
|
|
|
+
|
|
|
+ // Switch Device Selected & alarm buzzer
|
|
|
+ listViewSwitch.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
|
|
+ @Override
|
|
|
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
|
|
+ final AmazonBLEinfo item = (AmazonBLEinfo) parent.getItemAtPosition(position);
|
|
|
+ selectedSwitchMac = item.getMacAddr();
|
|
|
+ selectedSwitchPosition = position;
|
|
|
+ startSwitchBuzzer();
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ listViewLight.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
|
|
+ @Override
|
|
|
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
|
|
+ final AmazonBLEinfo item = (AmazonBLEinfo) parent.getItemAtPosition(position);
|
|
|
+ selectedLightMac = item.getMacAddr();
|
|
|
+ selectedLightPosition = position;
|
|
|
+
|
|
|
+ if(lightListSelected.contains(selectedLightMac)) {
|
|
|
+ lightListSelected.remove(selectedLightMac);
|
|
|
+ lightArrayAdapter.notifyDataSetChanged();
|
|
|
+ selectedLightPosition = -1;
|
|
|
+ } else {
|
|
|
+ startBlinkLight();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ switchRegisterHandler = new Handler(Looper.getMainLooper()) {
|
|
|
+ @Override
|
|
|
+ public void handleMessage(Message msg) {
|
|
|
+ DebugLogOutput(TAG, "[handleMessage what] : " + msg.what);
|
|
|
+ switch (msg.what) {
|
|
|
+ case bleProtocolState.BLUETOOTH_CONNECTED:
|
|
|
+ //Toast.makeText(SwitchMapperRegisterActivity.this, "BLE Connected", Toast.LENGTH_SHORT).show();
|
|
|
+ DebugLogOutput(TAG, "[Switch Register Protocol] Switch Device Connect");
|
|
|
+ break;
|
|
|
+
|
|
|
+ case bleProtocolState.BLUETOOTH_DISCONNECTED:
|
|
|
+ //Toast.makeText(SwitchMapperRegisterActivity.this, "Switch Device Disconnect", Toast.LENGTH_SHORT).show();
|
|
|
+ DebugLogOutput(TAG, "[Buzzer Protocol] Switch Device Disconnect");
|
|
|
+ break;
|
|
|
+
|
|
|
+ case bleProtocolState.BLUETOOTH_NOT_CONNECTED:
|
|
|
+ //Toast.makeText(SwitchMapperRegisterActivity.this, "BLE Connect Fail", Toast.LENGTH_SHORT).show();
|
|
|
+ showNotiMsg(SwitchMapperRegisterActivity.this,"블루투스 연결을 실패하였습니다.");
|
|
|
+ DebugLogOutput(TAG, "[Switch Register Protocol] BLE Connect Fail");
|
|
|
+ if(layoutLightList.getVisibility() != View.VISIBLE) {
|
|
|
+ retryScanDevice();
|
|
|
+ } else {
|
|
|
+ if(IsRunningProgress()){
|
|
|
+ DismissConnectDialog();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case bleProtocolState.BLUETOOTH_GET_NOTIFICATION:
|
|
|
+ switchRegisterHandler.removeMessages(bleProtocolState.BLUETOOTH_GET_NOTIFICATION_FAIL);
|
|
|
+ //Toast.makeText(SwitchMapperRegisterActivity.this, "Mac : " + msg.obj, Toast.LENGTH_SHORT).show();
|
|
|
+ DebugLogOutput(TAG, "[Switch Register Protocol] Get MAC Success");
|
|
|
+ bleDisconnect(selectedSwitchMac);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case bleProtocolState.BLUETOOTH_GET_NOTIFICATION_FAIL:
|
|
|
+ //Toast.makeText(SwitchMapperRegisterActivity.this, "Time Over 5' Sec", Toast.LENGTH_SHORT).show();
|
|
|
+ DebugLogOutput(TAG, "[Switch Register Protocol] BLUETOOTH_GET_NOTIFICATION_FAIL");
|
|
|
+ bleDisconnect(selectedSwitchMac);
|
|
|
+ break;
|
|
|
+ case bleProtocolState.RSP_BUZZER_PROTOCOL_SUCCESS:{
|
|
|
+ switchRegisterHandler.removeMessages(RSP_BUZZER_PROTOCOL_TIMEOUT);
|
|
|
+ //bleDisconnect(selectedSwitchMac);
|
|
|
+ changeUI(UI_STATUS_SHOW_SWITCH_LIST);
|
|
|
+ Intent intent = new Intent(SwitchMapperRegisterActivity.this, PopupActivity.class);
|
|
|
+ intent.putExtra(PopupActivity.POPUP_MODE, PopupActivity.MODE_YESNO);
|
|
|
+ intent.putExtra(PopupActivity.POPUP_TITLE_TEXT, getString(R.string.popup_confirm_register_switch_mapper_title));
|
|
|
+ intent.putExtra(PopupActivity.POPUP_BODY_TEXT, getString(R.string.popup_confirm_register_switch_mapper_description));
|
|
|
+ intent.putExtra(PopupActivity.POPUP_OK_BUTTON_TEXT, getString(R.string.yes));
|
|
|
+ intent.putExtra(PopupActivity.POPUP_CANCEL_BUTTON_TEXT, getString(R.string.re_select));
|
|
|
+ startActivityForResult(intent, RESULT_SWITCH_MAPPER_BUZZER_SUCCESS);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case bleProtocolState.RSP_BUZZER_PROTOCOL_FAIL:
|
|
|
+ switchRegisterHandler.removeMessages(RSP_BUZZER_PROTOCOL_TIMEOUT);
|
|
|
+ //bleDisconnect(selectedSwitchMac);
|
|
|
+ changeUI(UI_STATUS_SHOW_SWITCH_LIST,"스마트 스위치 연결음 송신에 실패하였습니다.");
|
|
|
+ break;
|
|
|
+ case RSP_BUZZER_PROTOCOL_TIMEOUT:
|
|
|
+ //bleDisconnect(selectedSwitchMac);
|
|
|
+ changeUI(UI_STATUS_SHOW_SWITCH_LIST,"스마트 스위치 연결시간이 초과되었습니다.");
|
|
|
+ break;
|
|
|
+ case bleProtocolState.RSP_BLINK_PROTOCOL_SUCCESS:{
|
|
|
+ switchRegisterHandler.removeMessages(RSP_BLINK_PROTOCOL_TIMEOUT);
|
|
|
+ changeUI(UI_STATUS_SHOW_LIGHT_LIST);
|
|
|
+ Intent intent = new Intent(SwitchMapperRegisterActivity.this, PopupActivity.class);
|
|
|
+ intent.putExtra(PopupActivity.POPUP_MODE, PopupActivity.MODE_YESNO);
|
|
|
+ intent.putExtra(PopupActivity.POPUP_TITLE_TEXT, getString(R.string.popup_confirm_register_light_title));
|
|
|
+ intent.putExtra(PopupActivity.POPUP_BODY_TEXT, getString(R.string.popup_confirm_register_light_description));
|
|
|
+ intent.putExtra(PopupActivity.POPUP_OK_BUTTON_TEXT, getString(R.string.yes));
|
|
|
+ intent.putExtra(PopupActivity.POPUP_CANCEL_BUTTON_TEXT, getString(R.string.re_select));
|
|
|
+ startActivityForResult(intent, RESULT_LIGHT_BLINK_SUCCESS);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case bleProtocolState.RSP_BLINK_PROTOCOL_FAIL:
|
|
|
+ switchRegisterHandler.removeMessages(RSP_BLINK_PROTOCOL_TIMEOUT);
|
|
|
+ changeUI(UI_STATUS_SHOW_LIGHT_LIST,"스마트 조명 깜빡임 요청 중에 오류가 발생하였습니다.");
|
|
|
+ //TODO 스마트 조명 깜빡임 실패시 로직 구현해야함.
|
|
|
+ break;
|
|
|
+ case RSP_BLINK_PROTOCOL_TIMEOUT:
|
|
|
+ changeUI(UI_STATUS_SHOW_LIGHT_LIST,"스마트 조명 깜빡임 요청시간을 초과되었습니다.");
|
|
|
+ //TODO 스마트 조명 깜빡임 Timeout 로직 구현해야함.
|
|
|
+ break;
|
|
|
+ case bleProtocolState.SCAN_RESULT_PROTOCOL_SUCCESS:
|
|
|
+ changeUI(UI_STATUS_SHOW_LIGHT_LIST,"등록하실 스마트 조명를 선택해 주세요\n선택하신 스마트 조명이 깜빡입니다.");
|
|
|
+ switchRegisterHandler.removeMessages(bleProtocolState.SCAN_RESULT_PROTOCOL_FAIL);
|
|
|
+ //TODO - 현재 스마트 스위치에서 스캔된 모듈 정보와 단말기에서 스캔한 모듈 정보 둘 다 존재할 경우로 작업했음.(차후 스마트 스위치에서 스캔된 모듈로 표시해야 될수도 있음)
|
|
|
+ for(int i = 0 ; i < lightList.size() ; i++) {
|
|
|
+ boolean isExist = false;
|
|
|
+ for(String s : lightScanList) {
|
|
|
+ if(lightList.get(i).getMacAddr().equals(s)){
|
|
|
+ isExist = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(!isExist) {
|
|
|
+ lightList.remove(i--);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ lightArrayAdapter.notifyDataSetChanged();
|
|
|
+ break;
|
|
|
+ case bleProtocolState.SCAN_RESULT_PROTOCOL_FAIL:
|
|
|
+ changeUI(UI_STATUS_SHOW_SWITCH_LIST,"스마트 스위치의 검색 요청이 실패하였습니다.");
|
|
|
+ //TODO 스마트 스위치에서 스마트 조명 스캔 실패시.
|
|
|
+ break;
|
|
|
+ case bleProtocolState.RSP_GROUP_SWITCH_SUCCESS:
|
|
|
+ switchRegisterHandler.removeMessages(bleProtocolState.RSP_GROUP_SWITCH_TIMEOUT);
|
|
|
+ sendIndexLight = 0;
|
|
|
+ startGroupForLight(sendIndexLight++);
|
|
|
+ //initGroupDataForLight(sendIndexLight++); //스마트 조명 그루핑 초기화 과정 제외.
|
|
|
+ break;
|
|
|
+ case bleProtocolState.RSP_GROUP_SWITCH_FAIL:
|
|
|
+ switchRegisterHandler.removeMessages(bleProtocolState.RSP_GROUP_SWITCH_TIMEOUT);
|
|
|
+ changeUI(UI_STATUS_SHOW_LIGHT_LIST,"스마트 스위치의 그룹 요청이 실패하였습니다.");
|
|
|
+ break;
|
|
|
+ case bleProtocolState.RSP_GROUP_SWITCH_TIMEOUT:
|
|
|
+ changeUI(UI_STATUS_SHOW_LIGHT_LIST,"스마트 스위치의 그룹 요청시간을 초과하였습니다.");
|
|
|
+ break;
|
|
|
+ case bleProtocolState.RSP_GROUP_LIGHT_SUCCESS:
|
|
|
+ switchRegisterHandler.removeMessages(bleProtocolState.RSP_GROUP_LIGHT_TIMEOUT);
|
|
|
+ if(lightListSelected.size() > sendIndexLight) {
|
|
|
+ startGroupForLight(sendIndexLight++);
|
|
|
+ } else {
|
|
|
+ RequestHandlerSendMessage(bleProtocolState.RSP_GROUP_END, null);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case bleProtocolState.RSP_GROUP_LIGHT_FAIL:
|
|
|
+ switchRegisterHandler.removeMessages(bleProtocolState.RSP_GROUP_LIGHT_TIMEOUT);
|
|
|
+ changeUI(UI_STATUS_SHOW_LIGHT_LIST,"스마트 조명 그룹 요청이 실패하였습니다.");
|
|
|
+ break;
|
|
|
+ case bleProtocolState.RSP_GROUP_LIGHT_TIMEOUT:
|
|
|
+ changeUI(UI_STATUS_SHOW_LIGHT_LIST,"스마트 조명 그룹 요청시간을 초과하였습니다.");
|
|
|
+ break;
|
|
|
+ case bleProtocolState.RSP_GROUP_END:
|
|
|
+ changeUI(UI_STATUS_SHOW_COMPLETED,"스마트 스위치 등록이 완료되었습니다.");
|
|
|
+ for(String key : connectedDeviceMap.keySet()){
|
|
|
+ DebugLogOutput(TAG, "onSuccessed] connectedDeviceMap bluetoothGatt disconnect / MAC :"+key);
|
|
|
+ connectedDeviceMap.get(key).disconnect();
|
|
|
+ connectedDeviceMap.get(key).close();
|
|
|
+ }
|
|
|
+ connectedDeviceMap.clear();
|
|
|
+ break;
|
|
|
+ case bleProtocolState.RSP_INIT_GROUP_SWITCH_SUCCES:
|
|
|
+ switchRegisterHandler.removeMessages(bleProtocolState.RSP_INIT_GROUP_SWITCH_TIMEOUT);
|
|
|
+ startGroupForSwitch();
|
|
|
+ break;
|
|
|
+ case bleProtocolState.RSP_INIT_GROUP_SWITCH_FAIL:
|
|
|
+ switchRegisterHandler.removeMessages(bleProtocolState.RSP_INIT_GROUP_SWITCH_TIMEOUT);
|
|
|
+ changeUI(UI_STATUS_SHOW_LIGHT_LIST,"스마트 스위치 그룹 초기화 요청이 실패하였습니다.");
|
|
|
+ break;
|
|
|
+ case bleProtocolState.RSP_INIT_GROUP_SWITCH_FAIL_OVER_LIGHT:
|
|
|
+ switchRegisterHandler.removeMessages(bleProtocolState.RSP_INIT_GROUP_SWITCH_TIMEOUT);
|
|
|
+ changeUI(UI_STATUS_SHOW_LIGHT_LIST,"스마트 스위치 초기화 버튼(독서버튼 5초)을 눌러 초기화 하세요.");
|
|
|
+ break;
|
|
|
+ case RSP_INIT_GROUP_SWITCH_TIMEOUT:
|
|
|
+ changeUI(UI_STATUS_SHOW_LIGHT_LIST,"스마트 스위치 그룹 초기화 시간을 초과하였습니다.");
|
|
|
+ break;
|
|
|
+ case bleProtocolState.RSP_INIT_GROUP_LIGHT_SUCCES:
|
|
|
+ switchRegisterHandler.removeMessages(bleProtocolState.RSP_INIT_GROUP_LIGHT_TIMEOUT);
|
|
|
+ if(lightListSelected.size() > sendIndexLight) {
|
|
|
+ initGroupDataForLight(sendIndexLight++);
|
|
|
+ } else {
|
|
|
+ sendIndexLight = 0;
|
|
|
+ startGroupForLight(sendIndexLight++);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case bleProtocolState.RSP_INIT_GROUP_LIGHT_FAIL:
|
|
|
+ switchRegisterHandler.removeMessages(bleProtocolState.RSP_INIT_GROUP_LIGHT_TIMEOUT);
|
|
|
+ changeUI(UI_STATUS_SHOW_LIGHT_LIST,"스마트 조명 그룹 초기화 요청이 실패하였습니다.");
|
|
|
+ break;
|
|
|
+ case RSP_INIT_GROUP_LIGHT_TIMEOUT:
|
|
|
+ changeUI(UI_STATUS_SHOW_LIGHT_LIST,"스마트 조명 그룹 초기화 시간을 초과하였습니다.");
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ throw new IllegalStateException("Unexpected value: " + msg.what);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ checkEnableBluetooth();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void startSwitchBuzzer() {
|
|
|
+ changeUI(UI_STATUS_LOADING,"스마트 스위치로 연결음 요청 중입니다...");
|
|
|
+ status_process = PROCESS_STATUS_BUZZER;
|
|
|
+ if (!connectedDeviceMap.containsKey(selectedSwitchMac)) {
|
|
|
+ DebugLogOutput(TAG, "onClick: bluetoothGatt is null");
|
|
|
+ BluetoothDevice bluetoothDevice = bluetoothAdapter.getRemoteDevice(selectedSwitchMac);
|
|
|
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
|
+ connectedDeviceMap.put(selectedSwitchMac, bluetoothDevice.connectGatt(SwitchMapperRegisterActivity.this, false, swithGattCallback, TRANSPORT_LE));
|
|
|
+ } else {
|
|
|
+ connectedDeviceMap.put(selectedSwitchMac, bluetoothDevice.connectGatt(SwitchMapperRegisterActivity.this, false, swithGattCallback));
|
|
|
+ }
|
|
|
+ } else if (connectedDeviceMap.containsKey(selectedSwitchMac)) {
|
|
|
+ RequestHandlerSendMessage(RSP_BUZZER_PROTOCOL_TIMEOUT,null);
|
|
|
+ switchBLEGattWriteRequestCommand(selectedSwitchMac,bleProtocol.buzzerSwitchProtocol);
|
|
|
+ DebugLogOutput(TAG, "buzzerSwitchProtocol : " + byteArrayToHex(bleProtocol.buzzerSwitchProtocol));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void startSwitchScanLight() {
|
|
|
+ changeUI(UI_STATUS_LOADING,"스마트 스위치의 검색 범위 내 스마트 조명을 찾고 있습니다...");
|
|
|
+ status_process = PROCESS_STATUS_SCAN_LIGHT;
|
|
|
+ lightScanList.clear();
|
|
|
+ if (!connectedDeviceMap.containsKey(selectedSwitchMac)) {
|
|
|
+ DebugLogOutput(TAG, "onClick: bluetoothGatt is null");
|
|
|
+ BluetoothDevice bluetoothDevice = bluetoothAdapter.getRemoteDevice(selectedSwitchMac);
|
|
|
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
|
+ connectedDeviceMap.put(selectedSwitchMac, bluetoothDevice.connectGatt(SwitchMapperRegisterActivity.this, false, swithGattCallback, TRANSPORT_LE));
|
|
|
+ } else {
|
|
|
+ connectedDeviceMap.put(selectedSwitchMac, bluetoothDevice.connectGatt(SwitchMapperRegisterActivity.this, false, swithGattCallback));
|
|
|
+ }
|
|
|
+ } else if (connectedDeviceMap.containsKey(selectedSwitchMac)) {
|
|
|
+ RequestHandlerSendMessage(SCAN_RESULT_PROTOCOL_FAIL,null);
|
|
|
+ DebugLogOutput(TAG, String.format("Before scanRequestSwitchProtocol : %s", byteArrayToHex(bleProtocol.scanRequestSwitchProtocol)));
|
|
|
+ bleProtocol.scanRequestSwitchProtocol[3] = (byte) (SCAN_COUNT & 0xff);
|
|
|
+ DebugLogOutput(TAG, String.format("After scanRequestSwitchProtocol : %s", byteArrayToHex(bleProtocol.scanRequestSwitchProtocol)));
|
|
|
+ switchBLEGattWriteRequestCommand(selectedSwitchMac,bleProtocol.scanRequestSwitchProtocol);
|
|
|
+ DebugLogOutput(TAG, "scanRequestSwitchProtocol : " + byteArrayToHex(bleProtocol.scanRequestSwitchProtocol));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void startBlinkLight() {
|
|
|
+ changeUI(UI_STATUS_LOADING,"선택된 스마트 조명에 깜빡임을 요청중입니다...");
|
|
|
+ status_process = PROCESS_STATUS_BLINK;
|
|
|
+ if (!connectedDeviceMap.containsKey(selectedLightMac)) {
|
|
|
+ DebugLogOutput(TAG, "onClick: bluetoothGatt is null");
|
|
|
+ BluetoothDevice bluetoothDevice = bluetoothAdapter.getRemoteDevice(selectedLightMac);
|
|
|
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
|
+ connectedDeviceMap.put(selectedLightMac, bluetoothDevice.connectGatt(SwitchMapperRegisterActivity.this, false, lightGattCallback, TRANSPORT_LE));
|
|
|
+ } else {
|
|
|
+ connectedDeviceMap.put(selectedLightMac, bluetoothDevice.connectGatt(SwitchMapperRegisterActivity.this, false, lightGattCallback));
|
|
|
+ }
|
|
|
+ } else if (connectedDeviceMap.containsKey(selectedLightMac)) {
|
|
|
+ RequestHandlerSendMessage(RSP_BLINK_PROTOCOL_TIMEOUT, null);
|
|
|
+ lightBLEGattWriteRequestCommand(selectedLightMac,bleProtocol.blinkLightProtocol);
|
|
|
+ DebugLogOutput(TAG, "blinkLightProtocol : " + byteArrayToHex(bleProtocol.blinkLightProtocol));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void initGroupDataForSwitch() {
|
|
|
+ changeUI(UI_STATUS_LOADING,"스마트 스위치 그룹 초기화 요청 중입니다.");
|
|
|
+ status_process = PROCESS_STATUS_INIT_SWITCH;
|
|
|
+ if (!connectedDeviceMap.containsKey(selectedSwitchMac)) {
|
|
|
+ DebugLogOutput(TAG, "onClick: bluetoothGatt is null");
|
|
|
+ BluetoothDevice bluetoothDevice = bluetoothAdapter.getRemoteDevice(selectedSwitchMac);
|
|
|
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
|
+ connectedDeviceMap.put(selectedSwitchMac, bluetoothDevice.connectGatt(SwitchMapperRegisterActivity.this, false, swithGattCallback, TRANSPORT_LE));
|
|
|
+ } else {
|
|
|
+ connectedDeviceMap.put(selectedSwitchMac, bluetoothDevice.connectGatt(SwitchMapperRegisterActivity.this, false, swithGattCallback));
|
|
|
+ }
|
|
|
+ } else if (connectedDeviceMap.containsKey(selectedSwitchMac)) {
|
|
|
+ RequestHandlerSendMessage(bleProtocolState.RSP_INIT_GROUP_SWITCH_TIMEOUT, null);
|
|
|
+ switchBLEGattWriteRequestCommand(selectedSwitchMac,bleProtocol.initGroupDateSwitchProtocol);
|
|
|
+ DebugLogOutput(TAG, "initGroupDateSwitchProtocol : " + byteArrayToHex(bleProtocol.initGroupDateSwitchProtocol));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void initGroupDataForLight(final int index) {
|
|
|
+ changeUI(UI_STATUS_LOADING,"스마트 조명 그룹 초기화 요청 중입니다.");
|
|
|
+ status_process = PROCESS_STATUS_INIT_LIGHT;
|
|
|
+ final String mac = lightListSelected.get(index);
|
|
|
+ if (!connectedDeviceMap.containsKey(mac)) {
|
|
|
+ DebugLogOutput(TAG, "onClick: bluetoothGatt is null");
|
|
|
+ BluetoothDevice bluetoothDevice = bluetoothAdapter.getRemoteDevice(mac);
|
|
|
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
|
+ connectedDeviceMap.put(mac, bluetoothDevice.connectGatt(SwitchMapperRegisterActivity.this, false, lightGattCallback, TRANSPORT_LE));
|
|
|
+ } else {
|
|
|
+ connectedDeviceMap.put(mac, bluetoothDevice.connectGatt(SwitchMapperRegisterActivity.this, false, lightGattCallback));
|
|
|
+ }
|
|
|
+ } else if (connectedDeviceMap.containsKey(mac)) {
|
|
|
+ RequestHandlerSendMessage(bleProtocolState.RSP_INIT_GROUP_LIGHT_TIMEOUT, null);
|
|
|
+ lightBLEGattWriteRequestCommand(mac,bleProtocol.initGroupDateLightProtocol);
|
|
|
+ DebugLogOutput(TAG, "initGroupDateLightProtocol : " + byteArrayToHex(bleProtocol.initGroupDateLightProtocol));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void startGroupForSwitch() {
|
|
|
+ changeUI(UI_STATUS_LOADING,"스마트 스위치 그룹 요청 중입니다.");
|
|
|
+ status_process = PROCESS_STATUS_GROUPING_SWITCH;
|
|
|
+ if (!connectedDeviceMap.containsKey(selectedSwitchMac)) {
|
|
|
+ DebugLogOutput(TAG, "onClick: bluetoothGatt is null");
|
|
|
+ BluetoothDevice bluetoothDevice = bluetoothAdapter.getRemoteDevice(selectedSwitchMac);
|
|
|
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
|
+ connectedDeviceMap.put(selectedSwitchMac, bluetoothDevice.connectGatt(SwitchMapperRegisterActivity.this, false, swithGattCallback, TRANSPORT_LE));
|
|
|
+ } else {
|
|
|
+ connectedDeviceMap.put(selectedSwitchMac, bluetoothDevice.connectGatt(SwitchMapperRegisterActivity.this, false, swithGattCallback));
|
|
|
+ }
|
|
|
+ } else if (connectedDeviceMap.containsKey(selectedSwitchMac)) {
|
|
|
+ RequestHandlerSendMessage(bleProtocolState.RSP_GROUP_SWITCH_TIMEOUT, null);
|
|
|
+ switchBLEGattWriteRequestCommand(selectedSwitchMac,getGroupProtocolForSwitch());
|
|
|
+ DebugLogOutput(TAG, "groupSwitchProtocol : " + byteArrayToHex(getGroupProtocolForSwitch()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void startGroupForLight(final int index) {
|
|
|
+ status_process = PROCESS_STATUS_GROUPING_LIGHT;
|
|
|
+ final String mac = lightListSelected.get(index);
|
|
|
+ changeUI(UI_STATUS_LOADING,"스마트 조명 그룹 요청 중입니다.("+index+"/"+lightListSelected.size()+")");
|
|
|
+ if (!connectedDeviceMap.containsKey(mac)) {
|
|
|
+ DebugLogOutput(TAG, "onClick: bluetoothGatt is null");
|
|
|
+ BluetoothDevice bluetoothDevice = bluetoothAdapter.getRemoteDevice(mac);
|
|
|
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
|
+ connectedDeviceMap.put(mac, bluetoothDevice.connectGatt(SwitchMapperRegisterActivity.this, false, lightGattCallback, TRANSPORT_LE));
|
|
|
+ } else {
|
|
|
+ connectedDeviceMap.put(mac, bluetoothDevice.connectGatt(SwitchMapperRegisterActivity.this, false, lightGattCallback));
|
|
|
+ }
|
|
|
+ } else if (connectedDeviceMap.containsKey(mac)) {
|
|
|
+ RequestHandlerSendMessage(bleProtocolState.RSP_GROUP_LIGHT_TIMEOUT, null);
|
|
|
+ lightBLEGattWriteRequestCommand(mac,getGroupProtocolForLight());
|
|
|
+ DebugLogOutput(TAG, "groupLightProtocol : " + byteArrayToHex(getGroupProtocolForLight()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private byte[] getGroupProtocolForSwitch() {
|
|
|
+ int switchSize = (lightListSelected.size() * 6) + 4;
|
|
|
+ byte[] switchProtocol = new byte[switchSize];
|
|
|
+ switchProtocol[0] = (byte) (0xF2 & 0xff);
|
|
|
+ switchProtocol[1] = (byte) (0x62 & 0xff);
|
|
|
+ switchProtocol[2] = (byte) (((lightListSelected.size() * 6) + 1) & 0xff);
|
|
|
+ switchProtocol[3] = (byte) (lightListSelected.size() & 0xff);
|
|
|
+ for (int i = 0; i < lightListSelected.size(); i++) {
|
|
|
+ String lightMac = lightListSelected.get(i);
|
|
|
+ String[] lightMacParts = lightMac.split(":");
|
|
|
+ byte[] toMacPartsAddress = new byte[6];
|
|
|
+ for (int b = 0; b < 6; b++) {
|
|
|
+ Integer hex = Integer.parseInt(lightMacParts[b], 16);
|
|
|
+ toMacPartsAddress[b] = hex.byteValue();
|
|
|
+ }
|
|
|
+ switchProtocol = appendByteArray(switchProtocol, toMacPartsAddress, 4 + (i * 6));
|
|
|
+ }
|
|
|
+ return switchProtocol;
|
|
|
+ }
|
|
|
+
|
|
|
+ private byte[] getGroupProtocolForLight() {
|
|
|
+ int switchCount = 1;
|
|
|
+ int lightSize = (switchCount * 6) + 4;
|
|
|
+ byte[] lightProtocol = new byte[lightSize];
|
|
|
+
|
|
|
+ lightProtocol[0] = (byte) (0xF2 & 0xff);
|
|
|
+ lightProtocol[1] = (byte) (0x60 & 0xff);
|
|
|
+ lightProtocol[2] = (byte) (((switchCount * 6) + 1) & 0xff); //Length(Header, Command, Length 는 제외)
|
|
|
+ lightProtocol[3] = (byte) (0x01 & 0xff); //그루핑 스마트 조명 스위치 개수.
|
|
|
+
|
|
|
+ for (int i = 0; i < switchCount; i++) {
|
|
|
+ String lightMac = selectedSwitchMac;
|
|
|
+ String[] lightMacParts = lightMac.split(":");
|
|
|
+ byte[] toMacPartsAddress = new byte[6];
|
|
|
+ for (int b = 0; b < 6; b++) {
|
|
|
+ Integer hex = Integer.parseInt(lightMacParts[b], 16);
|
|
|
+ toMacPartsAddress[b] = hex.byteValue();
|
|
|
+ }
|
|
|
+ lightProtocol = appendByteArray(lightProtocol, toMacPartsAddress, 4 + (i * 6));
|
|
|
+ }
|
|
|
+ return lightProtocol;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void onStart() {
|
|
|
+ super.onStart();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void onResume() {
|
|
|
+ super.onResume();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onClick(View v) {
|
|
|
+ /*
|
|
|
+ final View fv = v;
|
|
|
+ fv.setEnabled(false);
|
|
|
+ Timer buttonTimer = new Timer();
|
|
|
+ buttonTimer.schedule(new TimerTask() {
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ runOnUiThread(new Runnable() {
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ try {
|
|
|
+ fv.setEnabled(true);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ } finally {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }, 500);
|
|
|
+ */
|
|
|
+
|
|
|
+ switch (v.getId()) {
|
|
|
+ case R.id.btnBack:
|
|
|
+ onBackPressed();
|
|
|
+ break;
|
|
|
+ case R.id.btnGroup:
|
|
|
+ if(lightListSelected.size() == 0) {
|
|
|
+ showNotiMsg(SwitchMapperRegisterActivity.this,"스마트 조명을 하나 이상 선택해주세요.");
|
|
|
+ } else {
|
|
|
+ startGroupForSwitch();
|
|
|
+ //initGroupDataForSwitch();
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case R.id.btnCompleted:
|
|
|
+ actvityExit();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
|
+ super.onActivityResult(requestCode, resultCode, data);
|
|
|
+ switch (requestCode) {
|
|
|
+ case RESULT_ENABLE_BT_MAIN:
|
|
|
+ checkEnableBluetooth2();
|
|
|
+ break;
|
|
|
+ case RESULT_RETRY_BUT_NO_DEVICE:
|
|
|
+ finish();
|
|
|
+ break;
|
|
|
+ case RESULT_RETRY_SCAN_DEVICE:
|
|
|
+ if (resultCode == Activity.RESULT_OK) {
|
|
|
+ isRetry= true;
|
|
|
+ startScanningDevice();
|
|
|
+ } else {
|
|
|
+ finish();
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case RESULT_SWITCH_MAPPER_BUZZER_SUCCESS:
|
|
|
+ if (resultCode == Activity.RESULT_OK) {
|
|
|
+ startSwitchScanLight();
|
|
|
+ } else {
|
|
|
+ selectedSwitchPosition = -1;
|
|
|
+ changeUI(UI_STATUS_SHOW_SWITCH_LIST);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case RESULT_LIGHT_BLINK_SUCCESS:
|
|
|
+ if (resultCode == Activity.RESULT_OK) {
|
|
|
+ if(!lightListSelected.contains(selectedLightMac)) {
|
|
|
+ lightListSelected.add(selectedLightMac);
|
|
|
+ lightArrayAdapter.notifyDataSetChanged();
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ selectedLightPosition = -1;
|
|
|
+ changeUI(UI_STATUS_SHOW_LIGHT_LIST);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ protected void onDestroy() {
|
|
|
+ super.onDestroy();
|
|
|
+
|
|
|
+ DebugLogOutput(TAG, "bleDisconnect: Call");
|
|
|
+ for(String key : connectedDeviceMap.keySet()){
|
|
|
+ DebugLogOutput(TAG, "onDestroy] connectedDeviceMap bluetoothGatt disconnect / MAC :"+key);
|
|
|
+ connectedDeviceMap.get(key).disconnect();
|
|
|
+ connectedDeviceMap.get(key).close();
|
|
|
+ }
|
|
|
+ connectedDeviceMap.clear();
|
|
|
+
|
|
|
+ if(swithList != null) {
|
|
|
+ swithList.clear();
|
|
|
+ }
|
|
|
+
|
|
|
+ if(lightList != null) {
|
|
|
+ lightList.clear();
|
|
|
+ }
|
|
|
+
|
|
|
+ if(lightListSelected != null) {
|
|
|
+ lightListSelected.clear();
|
|
|
+ }
|
|
|
+
|
|
|
+ if(lightScanList != null) {
|
|
|
+ lightScanList.clear();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void activityExit() {
|
|
|
+ Intent intent = new Intent(getApplicationContext(), MainActivity.class);
|
|
|
+ intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK
|
|
|
+ | Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
|
+ startActivity(intent);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void setUI() {
|
|
|
+
|
|
|
+ connectedDeviceMap = new HashMap<String, BluetoothGatt>();
|
|
|
+
|
|
|
+ // Scan Device
|
|
|
+ listViewSwitch = findViewById(R.id.listViewSwitch);
|
|
|
+ switchArrayAdapter = new DeviceArrayAdapter(swithList,SCAN_TYPE_SWITCH);
|
|
|
+ listViewSwitch.setAdapter(switchArrayAdapter);
|
|
|
+ listViewSwitch.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);
|
|
|
+
|
|
|
+ // Scan Wifi
|
|
|
+ listViewLight = findViewById(R.id.listViewLight);
|
|
|
+ lightArrayAdapter = new DeviceArrayAdapter(lightList,SCAN_TYPE_LIGHT);
|
|
|
+ listViewLight.setAdapter(lightArrayAdapter);
|
|
|
+ listViewLight.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
|
|
|
+
|
|
|
+ // ui
|
|
|
+ layoutSwitchList = findViewById(R.id.layoutSwitchList);
|
|
|
+ layoutLightList = findViewById(R.id.layoutLightList);
|
|
|
+ layoutCompleted = findViewById(R.id.layoutCompleted);
|
|
|
+ txtSwitch = findViewById(R.id.txtSwitch);
|
|
|
+ txtLight = findViewById(R.id.txtLight);
|
|
|
+ txtCompleted = findViewById(R.id.txtCompleted);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void changeUI(final int status) {
|
|
|
+ changeUI(status, null, -1);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void changeUI(final int status,final String msg) {
|
|
|
+ changeUI(status, msg, -1);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void changeUI(final int status,final String msg, final long hideTime) {
|
|
|
+ runOnUiThread(new Runnable() {
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ switch (status) {
|
|
|
+ case UI_STATUS_LOADING:
|
|
|
+ if(IsRunningProgress()){
|
|
|
+ getProgressDialog().showTitle(msg);
|
|
|
+ } else {
|
|
|
+ if(hideTime > 0) {
|
|
|
+ displayProgress(SwitchMapperRegisterActivity.this, msg, null, hideTime);
|
|
|
+ } else {
|
|
|
+ displayProgress(SwitchMapperRegisterActivity.this, msg, null, 10000);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case UI_STATUS_SHOW_SWITCH_LIST:
|
|
|
+ layoutSwitchList.setVisibility(View.VISIBLE);
|
|
|
+ layoutLightList.setVisibility(View.GONE);
|
|
|
+ layoutCompleted.setVisibility(View.GONE);
|
|
|
+ if(msg!=null) {
|
|
|
+ txtSwitch.setText(msg);
|
|
|
+ }
|
|
|
+ if(IsRunningProgress()) {
|
|
|
+ DismissConnectDialog();
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case UI_STATUS_SHOW_LIGHT_LIST:
|
|
|
+ layoutSwitchList.setVisibility(View.GONE);
|
|
|
+ layoutLightList.setVisibility(View.VISIBLE);
|
|
|
+ layoutCompleted.setVisibility(View.GONE);
|
|
|
+ if(msg!=null) {
|
|
|
+ txtLight.setText(msg);
|
|
|
+ }
|
|
|
+ if(IsRunningProgress()) {
|
|
|
+ DismissConnectDialog();
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case UI_STATUS_SHOW_COMPLETED:
|
|
|
+ findViewById(R.id.btnBack).setVisibility(View.INVISIBLE);
|
|
|
+ layoutSwitchList.setVisibility(View.GONE);
|
|
|
+ layoutLightList.setVisibility(View.GONE);
|
|
|
+ layoutCompleted.setVisibility(View.VISIBLE);
|
|
|
+ if(msg!=null) {
|
|
|
+ txtCompleted.setText(msg);
|
|
|
+ }
|
|
|
+ if(IsRunningProgress()) {
|
|
|
+ DismissConnectDialog();
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case UI_STATUS_SHOW_FAIL:
|
|
|
+ showNotiMsg(SwitchMapperRegisterActivity.this,msg);
|
|
|
+ new Handler().postDelayed(new Runnable() {
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ actvityExit();
|
|
|
+ }
|
|
|
+ },3000);
|
|
|
+ if(IsRunningProgress()) {
|
|
|
+ DismissConnectDialog();
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ private void actvityExit() {
|
|
|
+ Intent intent = new Intent(getApplicationContext(), ProfileActivity.class);
|
|
|
+ intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK
|
|
|
+ | Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
|
+ startActivity(intent);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void bleDisconnect(String mac) {
|
|
|
+ if(connectedDeviceMap.containsKey(mac)) {
|
|
|
+ if(connectedDeviceMap.get(mac) !=null) {
|
|
|
+ connectedDeviceMap.get(mac).disconnect();
|
|
|
+ connectedDeviceMap.get(mac).close();
|
|
|
+ }
|
|
|
+ connectedDeviceMap.remove(mac);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Ble 검색
|
|
|
+ */
|
|
|
+ private void startScanningDevice() {
|
|
|
+ changeUI(UI_STATUS_LOADING,"등록할 스마트 조명을 찾고 있습니다.");
|
|
|
+ scanLeDevice(true);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void scanLeDevice(final boolean enable) {
|
|
|
+ handler = new Handler();
|
|
|
+ if (enable) {
|
|
|
+ swithList.clear();
|
|
|
+ lightList.clear();
|
|
|
+ lightListSelected.clear();
|
|
|
+ // Stops scanning after a pre-defined scan period.
|
|
|
+ handler.postDelayed(new Runnable() {
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ bluetoothAdapter.stopLeScan(leScanCallback);
|
|
|
+
|
|
|
+ if(switchArrayAdapter == null || lightArrayAdapter == null || (switchArrayAdapter.getCount() == 0) || (lightArrayAdapter.getCount() == 0)) {
|
|
|
+ changeUI(UI_STATUS_SHOW_SWITCH_LIST,"검색된 장치가 없습니다.");
|
|
|
+ retryScanDevice();
|
|
|
+ } else {
|
|
|
+ switchArrayAdapter.notifyDataSetChanged();
|
|
|
+ lightArrayAdapter.notifyDataSetChanged();
|
|
|
+ changeUI(UI_STATUS_SHOW_SWITCH_LIST,"등록하실 스마트 스위치를 \n" +
|
|
|
+ "선택해 주세요.\n" +
|
|
|
+ "선택하신 스마트 스위치의 \n" +
|
|
|
+ "진동(소리)이 울립니다.\n");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }, SCAN_PERIOD);
|
|
|
+ bluetoothAdapter.startLeScan(leScanCallback);
|
|
|
+ } else {
|
|
|
+ bluetoothAdapter.stopLeScan(leScanCallback);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private final BluetoothAdapter.LeScanCallback leScanCallback =
|
|
|
+ new BluetoothAdapter.LeScanCallback() {
|
|
|
+ @Override
|
|
|
+ public void onLeScan(final BluetoothDevice device, int rssi,
|
|
|
+ final byte[] scanRecord) {
|
|
|
+ runOnUiThread(new Runnable() {
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ if (device.getName() != null && device.getName().toUpperCase().contains("ICON_LS")) {
|
|
|
+ DebugLogOutput(TAG, "Scan Switch Register Record :" + byteArrayToHex(scanRecord));
|
|
|
+ AmazonBLEinfo thisDevice = new AmazonBLEinfo(device.getName(),
|
|
|
+ device.getAddress(), device);
|
|
|
+ if (!swithList.contains(thisDevice)) {
|
|
|
+ swithList.add(thisDevice);
|
|
|
+ }
|
|
|
+ } else if (device.getName() != null && device.getName().toUpperCase().contains("ICON_LM")) {
|
|
|
+ DebugLogOutput(TAG, "Scan Light Register Record :" + byteArrayToHex(scanRecord));
|
|
|
+ AmazonBLEinfo thisDevice = new AmazonBLEinfo(device.getName(),
|
|
|
+ device.getAddress(), device);
|
|
|
+ if (!lightList.contains(thisDevice)) {
|
|
|
+ lightList.add(thisDevice);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ private final BluetoothGattCallback swithGattCallback = new BluetoothGattCallback() {
|
|
|
+ @Override
|
|
|
+ public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
|
|
|
+ super.onConnectionStateChange(gatt, status, newState);
|
|
|
+
|
|
|
+ if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothProfile.STATE_CONNECTED) {
|
|
|
+ DebugLogOutput(TAG, String.format(Locale.getDefault(),
|
|
|
+ "BluetoothGatt.STATE_CONNECTED State from %s (%s) - status %d - state %d",
|
|
|
+ gatt.getDevice().getName(),
|
|
|
+ gatt.getDevice().getAddress(),
|
|
|
+ status,
|
|
|
+ newState
|
|
|
+ ));
|
|
|
+
|
|
|
+ RequestHandlerSendMessage(bleProtocolState.BLUETOOTH_CONNECTED, null);
|
|
|
+
|
|
|
+ gatt.discoverServices();
|
|
|
+
|
|
|
+ } else if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothProfile.STATE_DISCONNECTED) {
|
|
|
+ DebugLogOutput(TAG, String.format(Locale.getDefault(),
|
|
|
+ "bluetoothGatt.STATE_DISCONNECTED State from %s (%s) - status %d - state %d",
|
|
|
+ gatt.getDevice().getName(),
|
|
|
+ gatt.getDevice().getAddress(),
|
|
|
+ status,
|
|
|
+ newState
|
|
|
+ ));
|
|
|
+
|
|
|
+ RequestHandlerSendMessage(bleProtocolState.BLUETOOTH_DISCONNECTED, null);
|
|
|
+
|
|
|
+ } else if (status != BluetoothGatt.GATT_SUCCESS) {
|
|
|
+ DebugLogOutput(TAG, String.format(Locale.getDefault(),
|
|
|
+ "bluetoothGatt.GATT_FAIL from %s (%s) - status %d - state %d",
|
|
|
+ gatt.getDevice().getName(),
|
|
|
+ gatt.getDevice().getAddress(),
|
|
|
+ status,
|
|
|
+ newState
|
|
|
+ ));
|
|
|
+ bleDisconnect(gatt.getDevice().getAddress());
|
|
|
+ RequestHandlerSendMessage(bleProtocolState.BLUETOOTH_NOT_CONNECTED, null);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onServicesDiscovered(BluetoothGatt gatt, int status) {
|
|
|
+ super.onServicesDiscovered(gatt, status);
|
|
|
+
|
|
|
+ DebugLogOutput(TAG, String.format(Locale.getDefault(),
|
|
|
+ "onServicesDiscovered State from %s (%s) - status %d",
|
|
|
+ gatt.getDevice().getName(),
|
|
|
+ gatt.getDevice().getAddress(),
|
|
|
+ status
|
|
|
+ ));
|
|
|
+
|
|
|
+ BluetoothGattService deviceGattService = gatt.getService(hdcUUID.SWITCH_GATT_SERVICE_UUID);
|
|
|
+ if (deviceGattService == null) {
|
|
|
+ DebugLogOutput(TAG, "Switch # device No Gatt Service !!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ bluetoothGattCharacteristic = deviceGattService.getCharacteristic(hdcUUID.SWITCH_NOTIFICATION_CHARACTERISTIC_UUID);
|
|
|
+ if (bluetoothGattCharacteristic == null) {
|
|
|
+ DebugLogOutput(TAG, "Switch # device No Gatt Notification Service !!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ DebugLogOutput(TAG, "Switch/Set on Notification");
|
|
|
+ gatt.setCharacteristicNotification(bluetoothGattCharacteristic, true);
|
|
|
+
|
|
|
+ if (hdcUUID.SWITCH_NOTIFICATION_CHARACTERISTIC_UUID.equals(bluetoothGattCharacteristic.getUuid())) {
|
|
|
+ DebugLogOutput(TAG, "Switch/Write Descriptor");
|
|
|
+ BluetoothGattDescriptor descriptor = bluetoothGattCharacteristic.getDescriptor(hdcUUID.SWITCH_GATT_DESCRIPTORS_UUID);
|
|
|
+ descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
|
|
|
+ gatt.writeDescriptor(descriptor);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
|
|
|
+ super.onCharacteristicWrite(gatt, characteristic, status);
|
|
|
+ byte[] data = characteristic.getValue();
|
|
|
+
|
|
|
+ DebugLogOutput(TAG, String.format(Locale.getDefault(),
|
|
|
+ "onCharacteristicWrite State from %s (%s) - status %d - data %s",
|
|
|
+ gatt.getDevice().getName(),
|
|
|
+ gatt.getDevice().getAddress(),
|
|
|
+ status,
|
|
|
+ byteArrayToHex(data)
|
|
|
+ ));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
|
|
|
+ super.onCharacteristicChanged(gatt, characteristic);
|
|
|
+ byte[] data = characteristic.getValue();
|
|
|
+
|
|
|
+ // non use notification
|
|
|
+ DebugLogOutput(TAG, String.format(Locale.getDefault(),
|
|
|
+ "onCharacteristicChanged State from %s (%s) - data %s",
|
|
|
+ gatt.getDevice().getName(),
|
|
|
+ gatt.getDevice().getAddress(),
|
|
|
+ byteArrayToHex(data)
|
|
|
+ ));
|
|
|
+
|
|
|
+ if (data[0] == (byte) (bleProtocol.BLE_HEADER) && data[1] == (byte) (bleProtocol.BLE_COMMAND_STOA_MAC_ADDR_RSP_TO_APP)) {
|
|
|
+ DebugLogOutput(TAG, "SWITCH # get Notification");
|
|
|
+
|
|
|
+ try {
|
|
|
+ String mac = "";
|
|
|
+ mac = String.format("%02x", data[3] & 0xff).toUpperCase() + ":" +
|
|
|
+ String.format("%02x", data[4] & 0xff).toUpperCase() + ":" +
|
|
|
+ String.format("%02x", data[5] & 0xff).toUpperCase() + ":" +
|
|
|
+ String.format("%02x", data[6] & 0xff).toUpperCase() + ":" +
|
|
|
+ String.format("%02x", data[7] & 0xff).toUpperCase() + ":" +
|
|
|
+ String.format("%02x", data[8] & 0xff).toUpperCase();
|
|
|
+
|
|
|
+ DebugLogOutput(TAG, "onCharacteristicChanged: MAC : " + mac);
|
|
|
+
|
|
|
+ RequestHandlerSendMessage(bleProtocolState.BLUETOOTH_GET_NOTIFICATION, mac);
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ } else if (data[0] == (byte) (bleProtocol.BLE_HEADER) && data[1] == (byte) (bleProtocol.BLE_COMMAND_STOA_BUZZER_PLAY_RSP_TO_APP)) {
|
|
|
+ if(data[3] == (byte)0x01) {
|
|
|
+ DebugLogOutput(TAG, "get RSP_BUZZER_PROTOCOL_SUCCESS");
|
|
|
+ RequestHandlerSendMessage(bleProtocolState.RSP_BUZZER_PROTOCOL_SUCCESS, null);
|
|
|
+ } else {
|
|
|
+ DebugLogOutput(TAG, "get RSP_BUZZER_PROTOCOL_FAIL");
|
|
|
+ RequestHandlerSendMessage(bleProtocolState.RSP_BUZZER_PROTOCOL_FAIL, null);
|
|
|
+ }
|
|
|
+ } else if (data[0] == bleProtocol.BLE_HEADER && data[1] == bleProtocol.BLE_COMMAND_STOA_SWITCH_SCANRSP_TO_APP) {
|
|
|
+ int num = data[3];
|
|
|
+ int len = num * 8;
|
|
|
+ for (int i = 4; i < len; i += 8) {
|
|
|
+ String scanResultInfo = String.format("ICON_LM_%02X%02X%02X", data[i + 3], data[i + 4], data[i + 5]);
|
|
|
+ DebugLogOutput(TAG, "scanResultInfo[" + scanResultInfo + "]");
|
|
|
+ lightScanList.add(String.format("%02X:%02X:%02X:%02X:%02X:%02X", data[i], data[i + 1], data[i + 2], data[i + 3], data[i + 4], data[i + 5]));
|
|
|
+ }
|
|
|
+ RequestHandlerSendMessage(bleProtocolState.SCAN_RESULT_PROTOCOL_SUCCESS,null);
|
|
|
+ } else if (data[0] == bleProtocol.BLE_HEADER && data[1] == bleProtocol.BLE_COMMAND_STOA_SWITCH_GROUPING_RSP_TO_APP) {
|
|
|
+ DebugLogOutput(TAG, "Switch/Write Protocol(GROUP) : " + byteArrayToHex(characteristic.getValue()));
|
|
|
+ if(data[4] == (byte)0x01) {
|
|
|
+ DebugLogOutput(TAG, "get RSP_GROUP_SWITCH_SUCCESS");
|
|
|
+ RequestHandlerSendMessage(bleProtocolState.RSP_GROUP_SWITCH_SUCCESS, null);
|
|
|
+ } else {
|
|
|
+ DebugLogOutput(TAG, "get RSP_GROUP_SWITCH_FAIL");
|
|
|
+ RequestHandlerSendMessage(bleProtocolState.RSP_GROUP_SWITCH_FAIL, null);
|
|
|
+ }
|
|
|
+ } else if (data[0] == bleProtocol.BLE_HEADER && data[1] == bleProtocol.BLE_COMMAND_STOA_INIT_SWITCH_GROUPING_RSP_TO_APP) {
|
|
|
+ if(data[3] == (byte)0x01) {
|
|
|
+ DebugLogOutput(TAG, "get RSP_INIT_GROUP_SWITCH_SUCCES");
|
|
|
+ RequestHandlerSendMessage(bleProtocolState.RSP_INIT_GROUP_SWITCH_SUCCES, null);
|
|
|
+ } else if(data[3] == (byte)0x03) {
|
|
|
+ DebugLogOutput(TAG, "get RSP_INIT_GROUP_SWITCH_FAIL_OVER_LIGHT");
|
|
|
+ RequestHandlerSendMessage(bleProtocolState.RSP_INIT_GROUP_SWITCH_FAIL_OVER_LIGHT, null);
|
|
|
+ } else {
|
|
|
+ DebugLogOutput(TAG, "get RSP_INIT_GROUP_SWITCH_FAIL");
|
|
|
+ RequestHandlerSendMessage(bleProtocolState.RSP_INIT_GROUP_SWITCH_FAIL, null);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
|
|
|
+ super.onDescriptorWrite(gatt, descriptor, status);
|
|
|
+ byte[] data = descriptor.getValue();
|
|
|
+
|
|
|
+ DebugLogOutput(TAG, String.format(Locale.getDefault(),
|
|
|
+ "onDescriptorWrite State from %s (%s) - status %d - data %s",
|
|
|
+ gatt.getDevice().getName(),
|
|
|
+ gatt.getDevice().getAddress(),
|
|
|
+ status,
|
|
|
+ byteArrayToHex(data)
|
|
|
+ ));
|
|
|
+ if(status_process == PROCESS_STATUS_BUZZER) {
|
|
|
+ DebugLogOutput(TAG, "스마트 스위치 소리 요청\nonDescriptorWrite: status_process = " + status_process);
|
|
|
+ RequestHandlerSendMessage(RSP_BUZZER_PROTOCOL_TIMEOUT, null);
|
|
|
+ switchBLEGattWriteRequestCommand(gatt.getDevice().getAddress(), bleProtocol.buzzerSwitchProtocol);
|
|
|
+ } else if(status_process == PROCESS_STATUS_SCAN_LIGHT) {
|
|
|
+ DebugLogOutput(TAG, String.format("Before scanRequestSwitchProtocol : %s", byteArrayToHex(bleProtocol.scanRequestSwitchProtocol)));
|
|
|
+ bleProtocol.scanRequestSwitchProtocol[3] = (byte) (SCAN_COUNT & 0xff);
|
|
|
+ DebugLogOutput(TAG, String.format("After scanRequestSwitchProtocol : %s", byteArrayToHex(bleProtocol.scanRequestSwitchProtocol)));
|
|
|
+ switchBLEGattWriteRequestCommand(gatt.getDevice().getAddress(),bleProtocol.scanRequestSwitchProtocol);
|
|
|
+ RequestHandlerSendMessage(SCAN_RESULT_PROTOCOL_FAIL,null);
|
|
|
+ } else if(status_process == PROCESS_STATUS_GROUPING_SWITCH) {
|
|
|
+ DebugLogOutput(TAG, "스마트 스위치 그룹 요청\nonDescriptorWrite: status_process = " + status_process);
|
|
|
+ RequestHandlerSendMessage(bleProtocolState.RSP_GROUP_SWITCH_TIMEOUT, null);
|
|
|
+ switchBLEGattWriteRequestCommand(selectedSwitchMac,getGroupProtocolForSwitch());
|
|
|
+ } else if(status_process == PROCESS_STATUS_INIT_SWITCH) {
|
|
|
+ DebugLogOutput(TAG, "스마트 스위치 그룹 정보 초기화\nonDescriptorWrite: status_process = " + status_process);
|
|
|
+ RequestHandlerSendMessage(bleProtocolState.RSP_INIT_GROUP_SWITCH_TIMEOUT, null);
|
|
|
+ switchBLEGattWriteRequestCommand(selectedSwitchMac,bleProtocol.initGroupDateSwitchProtocol);
|
|
|
+ } else {
|
|
|
+ RequestHandlerSendMessage(bleProtocolState.BLUETOOTH_GET_NOTIFICATION_FAIL, null);
|
|
|
+ switchBLEGattWriteRequestCommand(gatt.getDevice().getAddress(), bleProtocol.getMacSwitchProtocol);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ private final BluetoothGattCallback lightGattCallback = new BluetoothGattCallback() {
|
|
|
+ @Override
|
|
|
+ public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
|
|
|
+ super.onConnectionStateChange(gatt, status, newState);
|
|
|
+
|
|
|
+ if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothProfile.STATE_CONNECTED) {
|
|
|
+ DebugLogOutput(TAG, String.format(Locale.getDefault(),
|
|
|
+ "BluetoothGatt.STATE_CONNECTED State from %s (%s) - status %d - state %d",
|
|
|
+ gatt.getDevice().getName(),
|
|
|
+ gatt.getDevice().getAddress(),
|
|
|
+ status,
|
|
|
+ newState
|
|
|
+ ));
|
|
|
+
|
|
|
+ RequestHandlerSendMessage(bleProtocolState.BLUETOOTH_CONNECTED, null);
|
|
|
+
|
|
|
+ gatt.discoverServices();
|
|
|
+
|
|
|
+ } else if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothProfile.STATE_DISCONNECTED) {
|
|
|
+ DebugLogOutput(TAG, String.format(Locale.getDefault(),
|
|
|
+ "bluetoothGatt.STATE_DISCONNECTED State from %s (%s) - status %d - state %d",
|
|
|
+ gatt.getDevice().getName(),
|
|
|
+ gatt.getDevice().getAddress(),
|
|
|
+ status,
|
|
|
+ newState
|
|
|
+ ));
|
|
|
+
|
|
|
+ RequestHandlerSendMessage(bleProtocolState.BLUETOOTH_DISCONNECTED, null);
|
|
|
+
|
|
|
+ } else if (status != BluetoothGatt.GATT_SUCCESS) {
|
|
|
+ DebugLogOutput(TAG, String.format(Locale.getDefault(),
|
|
|
+ "bluetoothGatt.GATT_FAIL from %s (%s) - status %d - state %d",
|
|
|
+ gatt.getDevice().getName(),
|
|
|
+ gatt.getDevice().getAddress(),
|
|
|
+ status,
|
|
|
+ newState
|
|
|
+ ));
|
|
|
+ bleDisconnect(gatt.getDevice().getAddress());
|
|
|
+ RequestHandlerSendMessage(bleProtocolState.BLUETOOTH_NOT_CONNECTED, null);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onServicesDiscovered(BluetoothGatt gatt, int status) {
|
|
|
+ super.onServicesDiscovered(gatt, status);
|
|
|
+
|
|
|
+ DebugLogOutput(TAG, String.format(Locale.getDefault(),
|
|
|
+ "onServicesDiscovered State from %s (%s) - status %d",
|
|
|
+ gatt.getDevice().getName(),
|
|
|
+ gatt.getDevice().getAddress(),
|
|
|
+ status
|
|
|
+ ));
|
|
|
+
|
|
|
+ BluetoothGattService deviceGattService = gatt.getService(hdcUUID.LIGHT_GATT_SERVICE_UUID);
|
|
|
+ if (deviceGattService == null) {
|
|
|
+ DebugLogOutput(TAG, "Light # device No Gatt Service !!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ bluetoothGattCharacteristic = deviceGattService.getCharacteristic(hdcUUID.LIGHT_GATT_NOTIFICATION_CHARACTERISTIC_UUID);
|
|
|
+ if (bluetoothGattCharacteristic == null) {
|
|
|
+ DebugLogOutput(TAG, "Light # device No Gatt Notification Service !!");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ DebugLogOutput(TAG, "Light/Set on Notification");
|
|
|
+ gatt.setCharacteristicNotification(bluetoothGattCharacteristic, true);
|
|
|
+
|
|
|
+ if (hdcUUID.LIGHT_GATT_NOTIFICATION_CHARACTERISTIC_UUID.equals(bluetoothGattCharacteristic.getUuid())) {
|
|
|
+ DebugLogOutput(TAG, "Light/Write Descriptor");
|
|
|
+ BluetoothGattDescriptor descriptor = bluetoothGattCharacteristic.getDescriptor(hdcUUID.LIGHT_GATT_DESCRIPTORS_UUID);
|
|
|
+ descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
|
|
|
+ gatt.writeDescriptor(descriptor);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
|
|
|
+ super.onCharacteristicWrite(gatt, characteristic, status);
|
|
|
+ byte[] data = characteristic.getValue();
|
|
|
+
|
|
|
+ DebugLogOutput(TAG, String.format(Locale.getDefault(),
|
|
|
+ "onCharacteristicWrite State from %s (%s) - status %d - data %s",
|
|
|
+ gatt.getDevice().getName(),
|
|
|
+ gatt.getDevice().getAddress(),
|
|
|
+ status,
|
|
|
+ byteArrayToHex(data)
|
|
|
+ ));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
|
|
|
+ super.onCharacteristicChanged(gatt, characteristic);
|
|
|
+ byte[] data = characteristic.getValue();
|
|
|
+
|
|
|
+ // non use notification
|
|
|
+ DebugLogOutput(TAG, String.format(Locale.getDefault(),
|
|
|
+ "onCharacteristicChanged State from %s (%s) - data %s",
|
|
|
+ gatt.getDevice().getName(),
|
|
|
+ gatt.getDevice().getAddress(),
|
|
|
+ byteArrayToHex(data)
|
|
|
+ ));
|
|
|
+
|
|
|
+ if (data[0] == bleProtocol.BLE_HEADER && data[1] == bleProtocol.BLE_COMMAND_LTOA_BLINK_LIGHT_RSP_TO_APP && data[2] == (byte)0x01) {
|
|
|
+ if (data[3] == (byte) 0x01) {
|
|
|
+ DebugLogOutput(TAG, "get RSP_BLINK_PROTOCOL_SUCCESS");
|
|
|
+ RequestHandlerSendMessage(bleProtocolState.RSP_BLINK_PROTOCOL_SUCCESS, null);
|
|
|
+ } else if (data[3] == (byte) 0x02) {
|
|
|
+ DebugLogOutput(TAG, "get RSP_BLINK_PROTOCOL_FAIL");
|
|
|
+ RequestHandlerSendMessage(bleProtocolState.RSP_BLINK_PROTOCOL_FAIL, null);
|
|
|
+ }
|
|
|
+ } else if (data[0] == bleProtocol.BLE_HEADER && data[1] == bleProtocol.BLE_COMMAND_LTOA_LIGHT_GROUPING_RSP_TO_APP && data[2] == (byte)0x03) {
|
|
|
+ DebugLogOutput(TAG, "Light/Write Protocol(GROUP) : " + byteArrayToHex(characteristic.getValue()));
|
|
|
+ /*
|
|
|
+ Error Code
|
|
|
+ 0x01: Success, 1 번째 그룹스위치 설정 (최종 1 개)
|
|
|
+ 0x02: Success, 2 번째 그룹스위치 설정 (최종 2 개)
|
|
|
+ 0x03: Error, 3 번째 그룹스위치 설정 설정 (이미 2 개 설정되어 있음)
|
|
|
+ 0x0A: Sucess, 이미 등록된 그룹스위치 설정 (재설정됨)
|
|
|
+ */
|
|
|
+ if(data[4] == (byte)0x01 || data[4] == (byte)0x02 || data[4] == (byte)0x0A) {
|
|
|
+ DebugLogOutput(TAG, "get RSP_GROUP_LIGHT_SUCCESS");
|
|
|
+ RequestHandlerSendMessage(bleProtocolState.RSP_GROUP_LIGHT_SUCCESS, null);
|
|
|
+ } else {
|
|
|
+ DebugLogOutput(TAG, "get RSP_GROUP_LIGHT_FAIL");
|
|
|
+ RequestHandlerSendMessage(bleProtocolState.RSP_GROUP_LIGHT_FAIL, null);
|
|
|
+ }
|
|
|
+ } else if (data[0] == bleProtocol.BLE_HEADER && data[1] == bleProtocol.BLE_COMMAND_LTOA_INIT_LIGHT_GROUPING_RSP_TO_APP) {
|
|
|
+ if(data[3] == (byte)0x01) {
|
|
|
+ DebugLogOutput(TAG, "get RSP_BUZZER_PROTOCOL_SUCCESS");
|
|
|
+ RequestHandlerSendMessage(bleProtocolState.RSP_INIT_GROUP_LIGHT_SUCCES, null);
|
|
|
+ } else {
|
|
|
+ DebugLogOutput(TAG, "get RSP_BUZZER_PROTOCOL_FAIL");
|
|
|
+ RequestHandlerSendMessage(bleProtocolState.RSP_INIT_GROUP_LIGHT_FAIL, null);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
|
|
|
+ super.onDescriptorWrite(gatt, descriptor, status);
|
|
|
+ byte[] data = descriptor.getValue();
|
|
|
+
|
|
|
+ DebugLogOutput(TAG, String.format(Locale.getDefault(),
|
|
|
+ "onDescriptorWrite State from %s (%s) - status %d - data %s",
|
|
|
+ gatt.getDevice().getName(),
|
|
|
+ gatt.getDevice().getAddress(),
|
|
|
+ status,
|
|
|
+ byteArrayToHex(data)
|
|
|
+ ));
|
|
|
+ if(status_process == PROCESS_STATUS_BLINK) {
|
|
|
+ DebugLogOutput(TAG, "조명 깜빡임 요청\nonDescriptorWrite: status_process = " + status_process);
|
|
|
+ RequestHandlerSendMessage(RSP_BLINK_PROTOCOL_TIMEOUT, null);
|
|
|
+ lightBLEGattWriteRequestCommand(gatt.getDevice().getAddress(), bleProtocol.blinkLightProtocol);
|
|
|
+ } else if(status_process == PROCESS_STATUS_GROUPING_LIGHT) {
|
|
|
+ DebugLogOutput(TAG, "조명 그룹 요청\nonDescriptorWrite: status_process = " + status_process);
|
|
|
+ RequestHandlerSendMessage(bleProtocolState.RSP_GROUP_LIGHT_TIMEOUT, null);
|
|
|
+ lightBLEGattWriteRequestCommand(gatt.getDevice().getAddress(),getGroupProtocolForLight());
|
|
|
+ DebugLogOutput(TAG, "groupLightProtocol : " + byteArrayToHex(getGroupProtocolForLight()));
|
|
|
+ } else if(status_process == PROCESS_STATUS_INIT_LIGHT) {
|
|
|
+ DebugLogOutput(TAG, "조명 그룹 초기화 요청\nonDescriptorWrite: status_process = " + status_process);
|
|
|
+ RequestHandlerSendMessage(bleProtocolState.RSP_INIT_GROUP_LIGHT_TIMEOUT, null);
|
|
|
+ switchBLEGattWriteRequestCommand(gatt.getDevice().getAddress(),bleProtocol.initGroupDateLightProtocol);
|
|
|
+ DebugLogOutput(TAG, "initGroupDateLightProtocol : " + byteArrayToHex(bleProtocol.initGroupDateLightProtocol));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ private void RequestHandlerSendMessage(int deviceState, String mac) {
|
|
|
+ Message msg = new Message();
|
|
|
+ msg.what = deviceState;
|
|
|
+ if (deviceState == bleProtocolState.BLUETOOTH_GET_NOTIFICATION_FAIL) {
|
|
|
+ switchRegisterHandler.sendMessageDelayed(msg, 5000);
|
|
|
+ } else if (deviceState == bleProtocolState.BLUETOOTH_GET_NOTIFICATION) {
|
|
|
+ msg.obj = mac;
|
|
|
+ switchRegisterHandler.sendMessage(msg);
|
|
|
+ } else if(deviceState == RSP_BUZZER_PROTOCOL_TIMEOUT) {
|
|
|
+ switchRegisterHandler.sendMessageDelayed(msg, 5000);
|
|
|
+ } else if (deviceState == SCAN_RESULT_PROTOCOL_FAIL) {
|
|
|
+ switchRegisterHandler.sendMessageDelayed(msg, (SCAN_COUNT + 3) * 1000);
|
|
|
+ } else if (deviceState == RSP_GROUP_SWITCH_TIMEOUT) {
|
|
|
+ switchRegisterHandler.sendMessageDelayed(msg, 10000);
|
|
|
+ } else if (deviceState == RSP_GROUP_LIGHT_TIMEOUT) {
|
|
|
+ switchRegisterHandler.sendMessageDelayed(msg, 10000);
|
|
|
+ } else if(deviceState == RSP_INIT_GROUP_SWITCH_TIMEOUT) {
|
|
|
+ switchRegisterHandler.sendMessageDelayed(msg, 10000);
|
|
|
+ } else if(deviceState == RSP_INIT_GROUP_LIGHT_TIMEOUT) {
|
|
|
+ switchRegisterHandler.sendMessageDelayed(msg, 10000);
|
|
|
+ } else if(deviceState == RSP_BLINK_PROTOCOL_TIMEOUT) {
|
|
|
+ switchRegisterHandler.sendMessageDelayed(msg, 10000);
|
|
|
+ } else {
|
|
|
+ switchRegisterHandler.sendMessage(msg);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void switchBLEGattWriteRequestCommand(String address, byte[] protocol) {
|
|
|
+ bluetoothGattCharacteristic = connectedDeviceMap.get(address).getService(hdcUUID.SWITCH_GATT_SERVICE_UUID)
|
|
|
+ .getCharacteristic(hdcUUID.SWITCH_GATT_WRITE_CHARACTERISTIC_UUID);
|
|
|
+ bluetoothGattCharacteristic.setValue(protocol);
|
|
|
+ connectedDeviceMap.get(address).writeCharacteristic(bluetoothGattCharacteristic);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void lightBLEGattWriteRequestCommand(String address, byte[] protocol) {
|
|
|
+ bluetoothGattCharacteristic = connectedDeviceMap.get(address).getService(hdcUUID.LIGHT_GATT_SERVICE_UUID)
|
|
|
+ .getCharacteristic(hdcUUID.LIGHT_GATT_WRITE_CHARACTERISTIC_UUID);
|
|
|
+ bluetoothGattCharacteristic.setValue(protocol);
|
|
|
+ connectedDeviceMap.get(address).writeCharacteristic(bluetoothGattCharacteristic);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void retryScanDevice() {
|
|
|
+ if(isRetry) {
|
|
|
+ Intent intent = new Intent(SwitchMapperRegisterActivity.this, PopupActivity.class);
|
|
|
+ intent.putExtra(PopupActivity.POPUP_MODE, PopupActivity.MODE_NORMAL_WITH_ICON);
|
|
|
+ if(swithList.size() == 0 && lightList.size() == 0) {
|
|
|
+ intent.putExtra(PopupActivity.POPUP_TITLE_TEXT, getString(R.string.popup_not_found_switch_light_device_title));
|
|
|
+ } else if(swithList.size() == 0) {
|
|
|
+ intent.putExtra(PopupActivity.POPUP_TITLE_TEXT, getString(R.string.popup_not_found_switch_device_title));
|
|
|
+ } else {
|
|
|
+ intent.putExtra(PopupActivity.POPUP_TITLE_TEXT, getString(R.string.popup_not_found_light_device_title));
|
|
|
+ }
|
|
|
+ intent.putExtra(PopupActivity.POPUP_BODY_TEXT, getString(R.string.popup_not_found_light_device_description_2));
|
|
|
+ intent.putExtra(PopupActivity.POPUP_OK_BUTTON_TEXT, getString(R.string.ok));
|
|
|
+ startActivityForResult(intent, RESULT_RETRY_BUT_NO_DEVICE);
|
|
|
+ } else {
|
|
|
+ Intent intent = new Intent(SwitchMapperRegisterActivity.this, PopupActivity.class);
|
|
|
+ intent.putExtra(PopupActivity.POPUP_MODE, PopupActivity.MODE_YESNO_WITH_ICON);
|
|
|
+ if(swithList.size() == 0 && lightList.size() == 0) {
|
|
|
+ intent.putExtra(PopupActivity.POPUP_TITLE_TEXT, getString(R.string.popup_not_found_switch_light_device_title));
|
|
|
+ } else if(swithList.size() == 0) {
|
|
|
+ intent.putExtra(PopupActivity.POPUP_TITLE_TEXT, getString(R.string.popup_not_found_switch_device_title));
|
|
|
+ } else {
|
|
|
+ intent.putExtra(PopupActivity.POPUP_TITLE_TEXT, getString(R.string.popup_not_found_light_device_title));
|
|
|
+ }
|
|
|
+ intent.putExtra(PopupActivity.POPUP_BODY_TEXT, getString(R.string.popup_not_found_light_device_description_1));
|
|
|
+ intent.putExtra(PopupActivity.POPUP_OK_BUTTON_TEXT, getString(R.string.retry));
|
|
|
+ intent.putExtra(PopupActivity.POPUP_CANCEL_BUTTON_TEXT, getString(R.string.cancel));
|
|
|
+ startActivityForResult(intent, RESULT_RETRY_SCAN_DEVICE);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void checkEnableBluetooth() {
|
|
|
+ if(!isBlueToothEnable(this)){
|
|
|
+ Intent intent = new Intent(this, PopupActivity.class);
|
|
|
+ intent.putExtra(PopupActivity.POPUP_MODE, PopupActivity.MODE_ENABLE_BT);
|
|
|
+ startActivityForResult(intent, RESULT_ENABLE_BT_MAIN);
|
|
|
+ } else {
|
|
|
+ new Handler().postDelayed(new Runnable() {
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ startScanningDevice();
|
|
|
+ }
|
|
|
+ }, FIRST_SCAN_PERIOD);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void checkEnableBluetooth2() {
|
|
|
+ if(!isBlueToothEnable(this)){
|
|
|
+ showNotiMsg(this,"블루투스 활성화를 실패하였습니다.",true);
|
|
|
+ } else {
|
|
|
+ new Handler().postDelayed(new Runnable() {
|
|
|
+ @Override
|
|
|
+ public void run() {
|
|
|
+ startScanningDevice();
|
|
|
+ }
|
|
|
+ }, FIRST_SCAN_PERIOD);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Ble 리스트 아답터
|
|
|
+ */
|
|
|
+ public class DeviceArrayAdapter extends BaseAdapter {
|
|
|
+ // Adapter에 추가된 데이터를 저장하기 위한 ArrayList
|
|
|
+ private List<AmazonBLEinfo> listViewItemList;
|
|
|
+ private int deviceType = 0;
|
|
|
+
|
|
|
+ // ListViewAdapter의 생성자
|
|
|
+ public DeviceArrayAdapter(List<AmazonBLEinfo> listItem, int type) {
|
|
|
+ listViewItemList = listItem;
|
|
|
+ deviceType = type;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Adapter에 사용되는 데이터의 개수를 리턴. : 필수 구현
|
|
|
+ @Override
|
|
|
+ public int getCount() {
|
|
|
+ return listViewItemList==null?0:listViewItemList.size() ;
|
|
|
+ }
|
|
|
+
|
|
|
+ // position에 위치한 데이터를 화면에 출력하는데 사용될 View를 리턴. : 필수 구현
|
|
|
+ @Override
|
|
|
+ public View getView(final int position, View convertView, ViewGroup parent) {
|
|
|
+ final int pos = position;
|
|
|
+ final Context context = parent.getContext();
|
|
|
+
|
|
|
+ // "listview_item" Layout을 inflate하여 convertView 참조 획득.
|
|
|
+ if (convertView == null) {
|
|
|
+ LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
|
|
+ convertView = inflater.inflate(R.layout.listview_add_device_list, parent, false);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 화면에 표시될 View(Layout이 inflate된)으로부터 위젯에 대한 참조 획득
|
|
|
+ LinearLayout layoutDevice = convertView.findViewById(R.id.layoutDevice);
|
|
|
+ TextView txtName = convertView.findViewById(R.id.txtName);
|
|
|
+ ImageView imgIcon = convertView.findViewById(R.id.imgIcon);
|
|
|
+
|
|
|
+ // Data Set(listViewItemList)에서 position에 위치한 데이터 입력
|
|
|
+ if(deviceType == SCAN_TYPE_SWITCH) {
|
|
|
+ imgIcon.setImageResource(R.drawable.icon_add_device_switch_mapper);
|
|
|
+ } else if(deviceType == SCAN_TYPE_LIGHT) {
|
|
|
+ imgIcon.setImageResource(R.drawable.icon_add_device_light);
|
|
|
+ layoutDevice.setSelected(false);
|
|
|
+
|
|
|
+ for(String s : lightListSelected) {
|
|
|
+ if(listViewItemList.get(position).getMacAddr().equals(s)) {
|
|
|
+ layoutDevice.setSelected(true);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ txtName.setText(listViewItemList.get(position).getName());
|
|
|
+
|
|
|
+ return convertView;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 지정한 위치(position)에 있는 데이터와 관계된 아이템(row)의 ID를 리턴. : 필수 구현
|
|
|
+ @Override
|
|
|
+ public long getItemId(int position) {
|
|
|
+ return position ;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 지정한 위치(position)에 있는 데이터 리턴 : 필수 구현
|
|
|
+ @Override
|
|
|
+ public Object getItem(int position) {
|
|
|
+ return listViewItemList.get(position) ;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void removeAll() {
|
|
|
+ listViewItemList.clear();
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|