├── MultipleBLEDeviceConnection ├── .gitignore ├── .idea │ ├── compiler.xml │ ├── copyright │ │ └── profiles_settings.xml │ ├── gradle.xml │ ├── misc.xml │ ├── modules.xml │ ├── runConfigurations.xml │ └── vcs.xml ├── app │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ │ ├── androidTest │ │ └── java │ │ │ └── com │ │ │ └── prompt │ │ │ └── multiplebledeviceconnection │ │ │ └── ExampleInstrumentedTest.java │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── prompt │ │ │ │ └── multiplebledeviceconnection │ │ │ │ ├── base │ │ │ │ └── BaseActivity.java │ │ │ │ ├── bleActivity │ │ │ │ ├── DeviceListActivity.java │ │ │ │ ├── DeviceListAutoConnectActivity.java │ │ │ │ └── MainActivity.java │ │ │ │ ├── bleUtils │ │ │ │ ├── BluetoothLeService.java │ │ │ │ ├── GattConnectReceiver.java │ │ │ │ ├── OnDataReceiveInterface.java │ │ │ │ └── SampleGattAttributes.java │ │ │ │ ├── broadcastReceivers │ │ │ │ └── DataReceiverBle.java │ │ │ │ ├── model │ │ │ │ └── BLEDevice.java │ │ │ │ ├── uicomponents │ │ │ │ └── MyAlertDialog.java │ │ │ │ └── utils │ │ │ │ ├── BleFrames.java │ │ │ │ ├── Const.java │ │ │ │ ├── CustomExceptionHandler.java │ │ │ │ ├── Logger.java │ │ │ │ ├── Prefs.java │ │ │ │ └── Utils.java │ │ └── res │ │ │ ├── anim │ │ │ ├── push_left.xml │ │ │ ├── push_right.xml │ │ │ ├── slide_left.xml │ │ │ └── slide_right.xml │ │ │ ├── drawable │ │ │ ├── ic_alert.png │ │ │ └── ic_success.png │ │ │ ├── layout │ │ │ ├── activity_device_list.xml │ │ │ ├── activity_main.xml │ │ │ ├── alert_dialog.xml │ │ │ ├── dialog_selection.xml │ │ │ ├── listitem_autoconnect_device.xml │ │ │ └── listitem_device.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ └── values │ │ │ ├── colors.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ └── test │ │ └── java │ │ └── com │ │ └── prompt │ │ └── multiplebledeviceconnection │ │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle └── README.md /MultipleBLEDeviceConnection/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Groovy 12 | 13 | 14 | Java 15 | 16 | 17 | Potentially confusing code constructsGroovy 18 | 19 | 20 | Threading issuesJava 21 | 22 | 23 | 24 | 25 | Android 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 47 | 48 | $USER_HOME$/.subversion 49 | 50 | 51 | 52 | 53 | 54 | 1.8 55 | 56 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 25 5 | buildToolsVersion "25.0.2" 6 | defaultConfig { 7 | applicationId "com.prompt.multiplebledeviceconnection" 8 | minSdkVersion 15 9 | targetSdkVersion 25 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 25 | exclude group: 'com.android.support', module: 'support-annotations' 26 | }) 27 | compile 'com.android.support:appcompat-v7:25.3.1' 28 | compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha7' 29 | testCompile 'junit:junit:4.12' 30 | } 31 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /home/prompt/AndroidTools/android-sdk-linux/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/app/src/androidTest/java/com/prompt/multiplebledeviceconnection/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.prompt.multiplebledeviceconnection; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.prompt.multiplebledeviceconnection", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 26 | 29 | 30 | 34 | 37 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/app/src/main/java/com/prompt/multiplebledeviceconnection/base/BaseActivity.java: -------------------------------------------------------------------------------- 1 | package com.prompt.multiplebledeviceconnection.base; 2 | 3 | import android.app.ActivityManager; 4 | import android.app.DatePickerDialog; 5 | import android.app.Dialog; 6 | import android.app.Notification; 7 | import android.app.ProgressDialog; 8 | import android.content.Context; 9 | import android.content.DialogInterface; 10 | import android.content.Intent; 11 | import android.content.pm.PackageManager; 12 | import android.content.res.Resources; 13 | import android.net.Uri; 14 | import android.os.Build; 15 | import android.os.Bundle; 16 | import android.os.Environment; 17 | import android.os.Handler; 18 | import android.support.v7.app.AlertDialog; 19 | import android.support.v7.app.AppCompatActivity; 20 | import android.view.View; 21 | import android.view.Window; 22 | import android.widget.Button; 23 | import android.widget.EditText; 24 | import android.widget.TextView; 25 | 26 | import com.prompt.multiplebledeviceconnection.R; 27 | import com.prompt.multiplebledeviceconnection.bleUtils.BluetoothLeService; 28 | import com.prompt.multiplebledeviceconnection.bleUtils.GattConnectReceiver; 29 | import com.prompt.multiplebledeviceconnection.broadcastReceivers.DataReceiverBle; 30 | import com.prompt.multiplebledeviceconnection.uicomponents.MyAlertDialog; 31 | import com.prompt.multiplebledeviceconnection.utils.Const; 32 | import com.prompt.multiplebledeviceconnection.utils.CustomExceptionHandler; 33 | import com.prompt.multiplebledeviceconnection.utils.Prefs; 34 | import com.prompt.multiplebledeviceconnection.utils.Utils; 35 | 36 | import java.lang.reflect.Method; 37 | import java.util.HashMap; 38 | 39 | 40 | /** 41 | * Created by prompt on 30/1/16. 42 | */ 43 | public abstract class BaseActivity extends AppCompatActivity { 44 | 45 | 46 | public static HashMap SETTINGS = new HashMap<>(); 47 | 48 | 49 | //Inten request code for get BLE address 50 | protected final int BLE1 = 1; 51 | protected final int BLE2 = 2; 52 | protected final int BLE3 = 3; 53 | protected final int BLE4 = 4; 54 | protected final int BLE_HW = 5; 55 | 56 | public static final int REQUEST_CONNECT_DEVICE = 1; 57 | public static final int REQUEST_ENABLE_BT = 2; 58 | public static final int REQUEST_BLE_CONNECT = 3; 59 | 60 | //TODO PRINT FORMATES 61 | public static final java.text.NumberFormat NO3 = new java.text.DecimalFormat("000"); 62 | public static final java.text.NumberFormat NO4 = new java.text.DecimalFormat("0000"); 63 | public static final java.text.NumberFormat NO5 = new java.text.DecimalFormat("00000"); 64 | public static final java.text.NumberFormat PT2 = new java.text.DecimalFormat("#.00"); 65 | public static final java.text.NumberFormat PT1 = new java.text.DecimalFormat("#0.0"); 66 | 67 | protected Intent intent; 68 | protected MyAlertDialog alertDialog; 69 | protected Resources res; 70 | protected ProgressDialog progressDialog; 71 | protected String TAG = "BASE ACTIVITY"; 72 | protected AlertDialog.Builder selectionDialog; 73 | protected Dialog dialog; 74 | protected Handler handler = new Handler(); 75 | private Context context; 76 | private TextView txtMessage; 77 | private Button btnYes, btnNo; 78 | private int ID = 1212; 79 | 80 | protected DataReceiverBle dataReceiverBle; 81 | protected GattConnectReceiver mGattConnectReceiver; 82 | 83 | /** 84 | * Used to manage connections of the Blue tooth LE Device 85 | */ 86 | private static BluetoothLeService mBluetoothLeService; 87 | 88 | public BaseActivity() { 89 | 90 | } 91 | 92 | 93 | @Override 94 | protected void onCreate(Bundle savedInstanceState) { 95 | super.onCreate(savedInstanceState); 96 | this.context = getContext(); 97 | res = getContext().getResources(); 98 | 99 | if (dataReceiverBle == null) 100 | dataReceiverBle = DataReceiverBle.getInstance(context); 101 | if (mGattConnectReceiver == null) 102 | mGattConnectReceiver = GattConnectReceiver.getInstance(context); 103 | 104 | progressDialog = new ProgressDialog(this.context); 105 | 106 | progressDialog.setMessage(res.getString(R.string.please_wait)); 107 | progressDialog.setCancelable(false); 108 | TAG = this.context.getClass().getName(); 109 | 110 | alertDialog = new MyAlertDialog(getContext()); 111 | Const.USER_ROLE = Utils.getInt(Prefs.getvalue(this, Const.PREF_USER_ROLE, "6")); 112 | 113 | 114 | selectionDialog = new AlertDialog.Builder(getContext()); 115 | dialog = new Dialog(getContext()); 116 | dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); 117 | dialog.setContentView(R.layout.dialog_selection); 118 | dialog.setCancelable(false); 119 | 120 | 121 | txtMessage = (TextView) dialog.findViewById(R.id.txtMessage); 122 | btnYes = (Button) dialog.findViewById(R.id.btnYes); 123 | btnNo = (Button) dialog.findViewById(R.id.btnNo); 124 | btnYes.setOnClickListener(new View.OnClickListener() { 125 | @Override 126 | public void onClick(View v) { 127 | btnYes.setEnabled(false); 128 | btnNo.setEnabled(false); 129 | dialogResponse(ID, true); 130 | if (!isActivityFinish()) 131 | dialog.dismiss(); 132 | } 133 | }); 134 | btnNo.setOnClickListener(new View.OnClickListener() { 135 | @Override 136 | public void onClick(View v) { 137 | btnYes.setEnabled(false); 138 | btnNo.setEnabled(false); 139 | dialogResponse(ID, false); 140 | if (!isActivityFinish()) 141 | dialog.dismiss(); 142 | } 143 | }); 144 | 145 | dialog.setOnDismissListener(new DialogInterface.OnDismissListener() { 146 | @Override 147 | public void onDismiss(DialogInterface dialog) { 148 | btnYes.setEnabled(true); 149 | btnNo.setEnabled(true); 150 | } 151 | }); 152 | 153 | if (!(Thread.getDefaultUncaughtExceptionHandler() instanceof CustomExceptionHandler)) { 154 | String path = Environment.getExternalStorageDirectory() + "/" + getString(R.string.app_name); 155 | Thread.setDefaultUncaughtExceptionHandler(new CustomExceptionHandler(path, "")); 156 | } 157 | 158 | } 159 | 160 | public boolean isActivityFinish() { 161 | return BaseActivity.this.isFinishing() || BaseActivity.this.isDestroyed(); 162 | } 163 | 164 | 165 | @Override 166 | protected void onStart() { 167 | super.onStart(); 168 | 169 | initializeWidget(); 170 | bindEvents(); 171 | } 172 | 173 | @Override 174 | protected void onResume() { 175 | super.onResume(); 176 | } 177 | 178 | @Override 179 | protected void onPause() { 180 | super.onPause(); 181 | } 182 | 183 | @Override 184 | public void onStop() { 185 | super.onStop(); 186 | } 187 | 188 | 189 | @Override 190 | protected void onDestroy() { 191 | super.onDestroy(); 192 | } 193 | 194 | protected abstract void initializeWidget(); 195 | 196 | protected abstract void bindEvents(); 197 | 198 | 199 | protected abstract Context getContext(); 200 | 201 | 202 | protected void showProgressDialog() { 203 | if (!progressDialog.isShowing() && !isActivityFinish()) 204 | progressDialog.show(); 205 | } 206 | 207 | protected void showProgressDialog(String message) { 208 | if (!progressDialog.isShowing()) { 209 | progressDialog.setMessage(message); 210 | progressDialog.show(); 211 | } 212 | } 213 | 214 | 215 | protected void showProgressDialog(String title, String message) { 216 | if (!progressDialog.isShowing()) { 217 | progressDialog.setTitle(title); 218 | progressDialog.setMessage(message); 219 | progressDialog.show(); 220 | } 221 | } 222 | 223 | protected void hideProgressDialog() { 224 | if (progressDialog.isShowing() && !isActivityFinish()) 225 | progressDialog.hide(); 226 | } 227 | 228 | protected void showAlert(String message) { 229 | alertDialog.setIcon(R.drawable.ic_alert); 230 | alertDialog.setMessage(message); 231 | alertDialog.show(); 232 | handler.postDelayed(new Runnable() { 233 | @Override 234 | public void run() { 235 | if (alertDialog.isShowing() && !isActivityFinish()) { 236 | 237 | alertDialog.dismiss(); 238 | } 239 | } 240 | }, Const.DIALOG_DISPLAY_TIME); 241 | } 242 | 243 | protected void showAlert(int id, String message) { 244 | this.ID = id; 245 | alertDialog.setIcon(R.drawable.ic_alert); 246 | alertDialog.setMessage(message); 247 | alertDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { 248 | @Override 249 | public void onCancel(DialogInterface dialog) { 250 | dialogResponse(ID, true); 251 | } 252 | }); 253 | alertDialog.show(); 254 | handler.postDelayed(new Runnable() { 255 | @Override 256 | public void run() { 257 | if (alertDialog.isShowing() && !isActivityFinish()) 258 | alertDialog.dismiss(); 259 | } 260 | }, Const.DIALOG_DISPLAY_TIME); 261 | } 262 | 263 | protected void showSuccess(String message) { 264 | alertDialog.setIcon(R.drawable.ic_success); 265 | alertDialog.setMessage(message); 266 | alertDialog.show(); 267 | 268 | handler.postDelayed(new Runnable() { 269 | @Override 270 | public void run() { 271 | if (!isActivityFinish() && alertDialog.isShowing()) 272 | alertDialog.dismiss(); 273 | } 274 | }, Const.DIALOG_DISPLAY_TIME); 275 | } 276 | 277 | 278 | protected void showSuccess(int id, String message) { 279 | alertDialog.setIcon(R.drawable.ic_success); 280 | alertDialog.setMessage(message); 281 | this.ID = id; 282 | alertDialog.setOnCancelListener(new DialogInterface.OnCancelListener() { 283 | @Override 284 | public void onCancel(DialogInterface dialog) { 285 | dialogResponse(ID, true); 286 | } 287 | }); 288 | alertDialog.show(); 289 | handler.postDelayed(new Runnable() { 290 | @Override 291 | public void run() { 292 | if (alertDialog.isShowing() && !isActivityFinish()) 293 | alertDialog.dismiss(); 294 | } 295 | }, Const.DIALOG_DISPLAY_TIME); 296 | } 297 | 298 | protected abstract void dialogResponse(int id, boolean res); 299 | 300 | protected void showSelectionDialog(final int id, String message) { 301 | //selectionDialog.setIcon(icon); 302 | txtMessage.setText(message); 303 | this.ID = id; 304 | dialog.show(); 305 | } 306 | 307 | protected void hideSelectionDialog(final int id, String message) { 308 | if(!isActivityFinish() && dialog.isShowing()){ 309 | dialog.dismiss(); 310 | } 311 | } 312 | 313 | 314 | } 315 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/app/src/main/java/com/prompt/multiplebledeviceconnection/bleActivity/DeviceListActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.prompt.multiplebledeviceconnection.bleActivity; 18 | 19 | import android.app.Activity; 20 | import android.app.AlertDialog; 21 | import android.app.Dialog; 22 | import android.app.ProgressDialog; 23 | import android.bluetooth.BluetoothAdapter; 24 | import android.bluetooth.BluetoothDevice; 25 | import android.bluetooth.BluetoothManager; 26 | import android.content.BroadcastReceiver; 27 | import android.content.Context; 28 | import android.content.DialogInterface; 29 | import android.content.Intent; 30 | import android.content.pm.PackageManager; 31 | import android.os.Build; 32 | import android.os.Bundle; 33 | import android.os.Handler; 34 | import android.text.Editable; 35 | import android.text.TextWatcher; 36 | import android.view.LayoutInflater; 37 | import android.view.View; 38 | import android.view.ViewGroup; 39 | import android.widget.AdapterView; 40 | import android.widget.BaseAdapter; 41 | import android.widget.Button; 42 | import android.widget.Filter; 43 | import android.widget.Filterable; 44 | import android.widget.ListView; 45 | import android.widget.TextView; 46 | import android.widget.Toast; 47 | 48 | 49 | import com.prompt.multiplebledeviceconnection.R; 50 | import com.prompt.multiplebledeviceconnection.base.BaseActivity; 51 | import com.prompt.multiplebledeviceconnection.bleUtils.BluetoothLeService; 52 | import com.prompt.multiplebledeviceconnection.utils.Const; 53 | import com.prompt.multiplebledeviceconnection.utils.Logger; 54 | import com.prompt.multiplebledeviceconnection.utils.Utils; 55 | 56 | import java.util.ArrayList; 57 | import java.util.HashMap; 58 | import java.util.Map; 59 | import java.util.Timer; 60 | import java.util.TimerTask; 61 | 62 | import static com.prompt.multiplebledeviceconnection.utils.Utils.byteToString; 63 | 64 | 65 | /** 66 | * This Activity appears as a dialog. It lists any paired devices and 67 | * devices detected in the area after discovery. When a device is chosen 68 | * by the user, the MAC address of the device is sent back to the parent 69 | * Activity in the result Intent. 70 | */ 71 | public class DeviceListActivity extends BaseActivity { 72 | 73 | // Stops scanning after 2 seconds. 74 | 75 | public static final int CONNECTION_SUCCESS = 1 ; 76 | public static final int CONNECTION_FAILED = 2 ; 77 | 78 | private static final long SCAN_PERIOD_TIMEOUT = 5000; 79 | private Timer mScanTimer; 80 | private boolean mScanning; 81 | 82 | // Connection time out after 10 seconds. 83 | private static final long CONNECTION_TIMEOUT = 10000; 84 | private Timer mConnectTimer; 85 | private boolean mConnectTimerON=false; 86 | 87 | // Activity request constant 88 | private static final int REQUEST_ENABLE_BT = 1; 89 | 90 | // device details 91 | public static String mDeviceName = "name"; 92 | public static String mDeviceAddress = "address"; 93 | 94 | //Pair status button and variables 95 | public static Button mPairButton; 96 | 97 | //Bluetooth adapter 98 | private static BluetoothAdapter mBluetoothAdapter; 99 | 100 | // Devices list variables 101 | private static ArrayList mLeDevices; 102 | private LeDeviceListAdapter mLeDeviceListAdapter; 103 | private Map mDevRssiValues; 104 | 105 | //GUI elements 106 | private ListView mProfileListView; 107 | 108 | private ProgressDialog mProgressdialog; 109 | 110 | // Flags 111 | private boolean mSearchEnabled = false; 112 | 113 | 114 | //Delay Time out 115 | private static final long DELAY_PERIOD = 500; 116 | 117 | private ProgressDialog mpdia; 118 | private AlertDialog mAlert; 119 | /** 120 | *Service Discovery 121 | */ 122 | private Timer mTimer; 123 | private static final long SERVICE_DISCOVERY_TIMEOUT = 7000; 124 | 125 | private TextView txtNoDeviceFound ; 126 | 127 | String hardwareGuid = "" ; 128 | String hardwareName = "" ; 129 | 130 | private static final long ACTIVITY_FINISH_TIMEOUT = 10000; 131 | private Handler activityFinshHandler ; 132 | private Runnable actvitiFinishRunnable; 133 | 134 | 135 | /** 136 | * BroadcastReceiver for receiving the GATT communication status 137 | */ 138 | private final BroadcastReceiver mGattConnectReceiver = new BroadcastReceiver() { 139 | @Override 140 | public void onReceive(Context context, Intent intent) { 141 | final String action = intent.getAction(); 142 | // Status received when connected to GATT Server 143 | 144 | switch (action){ 145 | case BluetoothLeService.ACTION_GATT_CONNECTED : 146 | mProgressdialog.setMessage(getString(R.string.alert_message_bluetooth_connect)); 147 | if (mScanning) { 148 | mBluetoothAdapter.stopLeScan(mLeScanCallback); 149 | mScanning = false; 150 | } 151 | 152 | if(mProgressdialog.isShowing() && !isActivityFinish()) 153 | mProgressdialog.dismiss(); 154 | mLeDevices.clear(); 155 | if(mConnectTimer!=null) 156 | mConnectTimer.cancel(); 157 | mConnectTimerON=false; 158 | Toast.makeText(DeviceListActivity.this, 159 | R.string.successfully_connected_to_the_device, 160 | Toast.LENGTH_SHORT).show(); 161 | 162 | mLeDeviceListAdapter.notifyDataSetChanged(); 163 | mTimer=showServiceDiscoveryAlert(false); 164 | 165 | if(activityFinshHandler != null) 166 | activityFinshHandler.postDelayed(actvitiFinishRunnable,ACTIVITY_FINISH_TIMEOUT); 167 | 168 | /* 169 | / Changes the MTU size to 512 in case LOLLIPOP and above devices 170 | */ 171 | if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 172 | BluetoothLeService.exchangeGattMtu(512,mDeviceAddress); 173 | } 174 | 175 | 176 | // updateWithNewFragment(); 177 | break; 178 | 179 | 180 | case BluetoothLeService.ACTION_GATT_DISCONNECTED : 181 | /** 182 | * Disconnect event.When the connect timer is ON,Reconnect the device 183 | * else show disconnect message 184 | */ 185 | if(mConnectTimerON){ 186 | BluetoothLeService.reconnectForConfiguration(mDeviceAddress); 187 | }else{ 188 | Toast.makeText(DeviceListActivity.this, 189 | R.string.profile_cannot_connect_message, 190 | Toast.LENGTH_SHORT).show(); 191 | } 192 | break; 193 | 194 | 195 | case BluetoothLeService.ACTION_MTU_EXCHANGE : 196 | Handler delayHandler = new Handler(); 197 | delayHandler.postDelayed(new Runnable() { 198 | @Override 199 | public void run() { 200 | Logger.e("Discover service called"); 201 | BluetoothLeService.discoverServicesforConfiguration(); 202 | } 203 | }, DELAY_PERIOD); 204 | 205 | break; 206 | } 207 | } 208 | }; 209 | 210 | 211 | private final BroadcastReceiver mServiceDiscoveryListner=new BroadcastReceiver() { 212 | @Override 213 | public void onReceive(Context context, Intent intent) { 214 | final String action = intent.getAction(); 215 | 216 | switch (action){ 217 | case BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED: 218 | Logger.e("Service discovered"); 219 | if(mTimer!=null) 220 | mTimer.cancel(); 221 | if(mProgressdialog.isShowing() && !isActivityFinish()) 222 | mProgressdialog.dismiss(); 223 | 224 | //Send String For Setting Change 225 | if(Const.CONNECTION_MODE.equals(Const.BLUETOOTH)){ 226 | new Handler().postDelayed(new Runnable() { 227 | @Override 228 | public void run() { 229 | 230 | BluetoothLeService.changeHwBleSetting(); 231 | } 232 | },1000); 233 | }else{ 234 | new Handler().postDelayed(new Runnable() { 235 | @Override 236 | public void run() { 237 | 238 | BluetoothLeService.changeHwBleSetting(); 239 | } 240 | },1000); 241 | } 242 | break; 243 | case BluetoothLeService.ACTION_GATT_SERVICE_DISCOVERY_UNSUCCESSFUL: 244 | if(mProgressdialog.isShowing() && !isActivityFinish()) 245 | mProgressdialog.dismiss(); 246 | if(mTimer!=null) 247 | mTimer.cancel(); 248 | showNoServiceDiscoverAlert(); 249 | scanLeDevice(true); 250 | break; 251 | 252 | } 253 | 254 | } 255 | }; 256 | 257 | private BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() { 258 | @Override 259 | public void onReceive(Context context, Intent intent) { 260 | //Getting the intent action and extras 261 | final String action = intent.getAction(); 262 | Bundle extras = intent.getExtras(); 263 | switch (action){ 264 | case BluetoothLeService.ACTION_DATA_AVAILABLE: 265 | if (extras.containsKey(Const.EXTRA_BYTE_VALUE) 266 | && extras.containsKey(Const.EXTRA_BLE_DEVICE_ADDRESS)) { 267 | 268 | byte[] array = intent.getByteArrayExtra(Const.EXTRA_BYTE_VALUE); 269 | // String deviceAddress = intent.getStringExtra(Const. 270 | // EXTRA_BLE_DEVICE_ADDRESS) ; 271 | 272 | String receivedData= Utils.convertHexToAscci((byteToString(array))); 273 | if(receivedData.contains("ok")){ 274 | sendConnectionStateToActivity(true); 275 | }else{ 276 | sendConnectionStateToActivity(false); 277 | } 278 | } 279 | break; 280 | } 281 | } 282 | 283 | }; 284 | 285 | 286 | 287 | 288 | /** 289 | * Call back for BLE Scan 290 | * This call back is called when a BLE device is found near by. 291 | */ 292 | private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() { 293 | 294 | @Override 295 | public void onLeScan(final BluetoothDevice device, final int rssi, 296 | byte[] scanRecord) { 297 | Activity mActivity = DeviceListActivity.this; 298 | mActivity.runOnUiThread(new Runnable() { 299 | @Override 300 | public void run() { 301 | if (!mSearchEnabled) { 302 | mLeDeviceListAdapter.addDevice(device, rssi); 303 | mLeDeviceListAdapter.notifyDataSetChanged(); 304 | } 305 | } 306 | }); 307 | 308 | } 309 | }; 310 | 311 | /** 312 | * Textwatcher for filtering the list devices 313 | */ 314 | private TextWatcher textWatcher = new TextWatcher() { 315 | 316 | @Override 317 | public void onTextChanged(CharSequence s, int start, int before, 318 | int count) { 319 | mLeDeviceListAdapter.notifyDataSetInvalidated(); 320 | mLeDeviceListAdapter.getFilter().filter(s.toString()); 321 | } 322 | 323 | @Override 324 | public void beforeTextChanged(CharSequence s, int start, int count, 325 | int after) { 326 | } 327 | 328 | @Override 329 | public void afterTextChanged(Editable s) { 330 | } 331 | }; 332 | int cnt = 1 ; 333 | @Override 334 | protected void onCreate(Bundle savedInstanceState) { 335 | super.onCreate(savedInstanceState); 336 | 337 | // Setup the window 338 | setContentView(R.layout.activity_device_list); 339 | this.setFinishOnTouchOutside(false); 340 | getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); 341 | getWindow().setBackgroundDrawableResource(android.R.color.transparent); 342 | mDevRssiValues = new HashMap(); 343 | 344 | 345 | 346 | 347 | checkBleSupportAndInitialize(); 348 | 349 | /** 350 | * Creating the dataLogger file and 351 | * updating the datalogger history 352 | */ 353 | Logger.createDataLoggerFile(this); 354 | 355 | 356 | activityFinshHandler = new Handler(); 357 | 358 | actvitiFinishRunnable = new Runnable() { 359 | @Override 360 | public void run() { 361 | BluetoothLeService.disconnectConfiguration(); 362 | if(activityFinshHandler != null) 363 | activityFinshHandler.removeCallbacks(actvitiFinishRunnable); 364 | 365 | if(!DeviceListActivity.this.isFinishing() || !DeviceListActivity.this.isDestroyed()) 366 | sendConnectionStateToActivity(false); 367 | 368 | 369 | } 370 | }; 371 | 372 | } 373 | 374 | @Override 375 | protected void initializeWidget() { 376 | 377 | txtNoDeviceFound = (TextView) findViewById(android.R.id.empty); 378 | 379 | // mProfileListView = (ListView) findViewById(R.id.listView_profiles); 380 | mProfileListView = (ListView) findViewById(android.R.id.list); 381 | 382 | mLeDeviceListAdapter = new LeDeviceListAdapter(); 383 | mProfileListView.setAdapter(mLeDeviceListAdapter); 384 | mProfileListView.setTextFilterEnabled(true); 385 | mProgressdialog = new ProgressDialog(this); 386 | mProgressdialog.setCancelable(false); 387 | 388 | mpdia = new ProgressDialog(this); 389 | mpdia.setCancelable(false); 390 | mAlert = new AlertDialog.Builder(this).create(); 391 | mAlert.setMessage(getResources().getString( 392 | R.string.alert_message_bluetooth_reconnect)); 393 | mAlert.setCancelable(false); 394 | mAlert.setTitle(getResources().getString(R.string.app_name)); 395 | mAlert.setButton(Dialog.BUTTON_POSITIVE, getResources().getString( 396 | R.string.ok), new DialogInterface.OnClickListener() { 397 | @Override 398 | public void onClick(DialogInterface dialogInterface, int i) { 399 | Intent intentActivity = getIntent(); 400 | finish(); 401 | overridePendingTransition( 402 | R.anim.slide_left, R.anim.push_left); 403 | startActivity(intentActivity); 404 | overridePendingTransition( 405 | R.anim.slide_right, R.anim.push_right); 406 | } 407 | }); 408 | mAlert.setCanceledOnTouchOutside(false); 409 | 410 | mProfileListView.setEmptyView(txtNoDeviceFound); 411 | 412 | } 413 | 414 | @Override 415 | protected void bindEvents() { 416 | mProfileListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 417 | @Override 418 | public void onItemClick(AdapterView adapterView, View view, int position, long l) { 419 | if (mLeDeviceListAdapter.getCount() > 0) { 420 | final BluetoothDevice device = mLeDeviceListAdapter 421 | .getDevice(position); 422 | if (device != null) { 423 | scanLeDevice(false); 424 | //TODO Device Coonect 425 | connectDevice(device,true); 426 | } 427 | } 428 | } 429 | }); 430 | 431 | } 432 | 433 | @Override 434 | protected Context getContext() { 435 | return this; 436 | } 437 | 438 | @Override 439 | protected void dialogResponse(int id, boolean res) { 440 | 441 | } 442 | 443 | 444 | @Override 445 | public void onResume() { 446 | Logger.e("Scanning onResume"); 447 | if(checkBluetoothStatus()){ 448 | prepareList(); 449 | } 450 | Logger.e("Registering receiver in Profile scannng"); 451 | 452 | registerReceiver(mGattConnectReceiver, Utils.makeGattConnectIntentFilter()); 453 | registerReceiver(mServiceDiscoveryListner, Utils.makeGattServiceDiscoveryIntentFilter()); 454 | registerReceiver(mGattUpdateReceiver, Utils.makeGattUpdateIntentFilter()); 455 | 456 | super.onResume(); 457 | } 458 | 459 | @Override 460 | public void onDestroy() { 461 | super.onDestroy(); 462 | scanLeDevice(false); 463 | activityFinshHandler.removeCallbacks(actvitiFinishRunnable); 464 | if (mLeDeviceListAdapter != null) 465 | mLeDeviceListAdapter.clear(); 466 | if (mLeDeviceListAdapter != null) { 467 | try { 468 | mLeDeviceListAdapter.notifyDataSetChanged(); 469 | } catch (Exception e) { 470 | e.printStackTrace(); 471 | } 472 | } 473 | 474 | if (BluetoothLeService.getmConnectionStateConfiguration() == BluetoothLeService.STATE_CONNECTED || 475 | BluetoothLeService.getmConnectionStateConfiguration() == BluetoothLeService.STATE_CONNECTING || 476 | BluetoothLeService.getmConnectionStateConfiguration() == BluetoothLeService.STATE_DISCONNECTING) { 477 | BluetoothLeService.disconnectConfiguration(); 478 | 479 | Toast.makeText(this, getResources().getString(R.string.alert_message_bluetooth_disconnect), Toast.LENGTH_SHORT).show(); 480 | } 481 | 482 | unregisterReceiver(mGattConnectReceiver); 483 | unregisterReceiver(mServiceDiscoveryListner); 484 | unregisterReceiver(mGattUpdateReceiver); 485 | 486 | } 487 | 488 | @Override 489 | public void onActivityResult(int requestCode, int resultCode, Intent data) { 490 | // User chose not to enable BlueTooth. 491 | if (requestCode == REQUEST_ENABLE_BT 492 | && resultCode == Activity.RESULT_CANCELED) { 493 | finish(); 494 | } else { 495 | // Check which request we're responding to 496 | if (requestCode == REQUEST_ENABLE_BT) { 497 | 498 | // Make sure the request was successful 499 | if (resultCode == Activity.RESULT_OK) { 500 | Toast.makeText( 501 | DeviceListActivity.this, 502 | getResources().getString( 503 | R.string.device_bluetooth_on), 504 | Toast.LENGTH_SHORT).show(); 505 | mLeDeviceListAdapter = new LeDeviceListAdapter(); 506 | mProfileListView.setAdapter(mLeDeviceListAdapter); 507 | // scanLeDevice(true); 508 | prepareList(); 509 | } else { 510 | finish(); 511 | } 512 | } 513 | } 514 | } 515 | 516 | @Override 517 | public void onBackPressed() { 518 | super.onBackPressed(); 519 | } 520 | 521 | private void checkBleSupportAndInitialize() { 522 | // Use this check to determine whether BLE is supported on the device. 523 | if (!getPackageManager().hasSystemFeature( 524 | PackageManager.FEATURE_BLUETOOTH_LE)) { 525 | Toast.makeText(DeviceListActivity.this, R.string.device_ble_not_supported, 526 | Toast.LENGTH_SHORT).show(); 527 | finish(); 528 | } 529 | // Initializes a Blue tooth adapter. 530 | final BluetoothManager bluetoothManager = (BluetoothManager) 531 | getSystemService(Context.BLUETOOTH_SERVICE); 532 | mBluetoothAdapter = bluetoothManager.getAdapter(); 533 | 534 | if (mBluetoothAdapter == null) { 535 | // Device does not support Blue tooth 536 | Toast.makeText(DeviceListActivity.this, 537 | R.string.device_bluetooth_not_supported, Toast.LENGTH_SHORT) 538 | .show(); 539 | finish(); 540 | } 541 | } 542 | 543 | public boolean checkBluetoothStatus() { 544 | /** 545 | * Ensures Blue tooth is enabled on the device. If Blue tooth is not 546 | * currently enabled, fire an intent to display a dialog asking the user 547 | * to grant permission to enable it. 548 | */ 549 | if (!mBluetoothAdapter.isEnabled()) { 550 | Intent enableBtIntent = new Intent( 551 | BluetoothAdapter.ACTION_REQUEST_ENABLE); 552 | startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); 553 | return false; 554 | } 555 | return true; 556 | } 557 | 558 | /** 559 | * Preparing the BLE Devicelist 560 | */ 561 | public void prepareList() { 562 | // Initializes ActionBar as required 563 | // setUpActionBar(); 564 | // Prepare list view and initiate scanning 565 | mLeDeviceListAdapter = new LeDeviceListAdapter(); 566 | mProfileListView.setAdapter(mLeDeviceListAdapter); 567 | scanLeDevice(true); 568 | mSearchEnabled = false; 569 | } 570 | 571 | 572 | /** 573 | * Method to scan BLE Devices. The status of the scan will be detected in 574 | * the BluetoothAdapter.LeScanCallback 575 | * 576 | * @param enable 577 | */ 578 | private void scanLeDevice(final boolean enable) { 579 | if (enable) { 580 | if (!mScanning) { 581 | startScanTimer(); 582 | mScanning = true; 583 | 584 | mBluetoothAdapter.startLeScan(mLeScanCallback); 585 | 586 | } 587 | } else { 588 | mScanning = false; 589 | mBluetoothAdapter.stopLeScan(mLeScanCallback); 590 | } 591 | 592 | } 593 | 594 | /** 595 | * Swipe refresh timer 596 | */ 597 | public void startScanTimer(){ 598 | mScanTimer=new Timer(); 599 | mScanTimer.schedule(new TimerTask() { 600 | @Override 601 | public void run() { 602 | mScanning = false; 603 | mBluetoothAdapter.stopLeScan(mLeScanCallback); 604 | scanLeDevice(false); 605 | } 606 | },SCAN_PERIOD_TIMEOUT); 607 | } 608 | 609 | 610 | /** 611 | * Method to connect to the device selected. The time allotted for having a 612 | * connection is 8 seconds. After 8 seconds it will disconnect if not 613 | * connected and initiate scan once more 614 | * 615 | * @param device 616 | */ 617 | 618 | private void connectDevice(BluetoothDevice device, boolean isFirstConnect) { 619 | Logger.v("connectDevice Called..."); 620 | 621 | mDeviceAddress = device.getAddress(); 622 | mDeviceName = device.getName(); 623 | // Get the connection status of the device 624 | if (BluetoothLeService.getmConnectionStateConfiguration() == BluetoothLeService.STATE_DISCONNECTED) { 625 | Logger.v("BLE DISCONNECTED STATE"); 626 | // Disconnected,so connect 627 | BluetoothLeService.connectForConfiguration(mDeviceAddress, mDeviceName,DeviceListActivity.this); 628 | showConnectAlertMessage(mDeviceName, mDeviceAddress); 629 | } 630 | else { 631 | Logger.v("BLE OTHER STATE-->" + BluetoothLeService.getmConnectionStateConfiguration()); 632 | // Connecting to some devices,so disconnect and then connect 633 | BluetoothLeService.disconnectConfiguration(); 634 | 635 | Handler delayHandler = new Handler(); 636 | delayHandler.postDelayed(new Runnable() { 637 | @Override 638 | public void run() { 639 | BluetoothLeService.connectForConfiguration(mDeviceAddress, mDeviceName, DeviceListActivity.this); 640 | showConnectAlertMessage(mDeviceName, mDeviceAddress); 641 | } 642 | }, DELAY_PERIOD); 643 | 644 | } 645 | if(isFirstConnect){ 646 | startConnectTimer(); 647 | mConnectTimerON=true; 648 | } 649 | 650 | } 651 | 652 | private void showConnectAlertMessage(String devicename, String deviceaddress) { 653 | mProgressdialog.setTitle(getResources().getString( 654 | R.string.alert_message_connect_title)); 655 | mProgressdialog.setMessage(getResources().getString( 656 | R.string.alert_message_connect) 657 | + "\n" 658 | + devicename 659 | + "\n" 660 | + deviceaddress 661 | + "\n" 662 | + getResources().getString(R.string.alert_message_wait)); 663 | 664 | if (!DeviceListActivity.this.isDestroyed() && mProgressdialog != null) { 665 | mProgressdialog.show(); 666 | } 667 | } 668 | 669 | /** 670 | * Connect Timer 671 | */ 672 | private void startConnectTimer(){ 673 | mConnectTimer=new Timer(); 674 | mConnectTimer.schedule(new TimerTask() { 675 | @Override 676 | public void run() { 677 | if(!mProgressdialog.isShowing() && !isActivityFinish()) 678 | mProgressdialog.dismiss(); 679 | Logger.v("CONNECTION TIME OUT"); 680 | mConnectTimerON=false; 681 | 682 | // if(mDeviceAddress.equals(BluetoothLeService.BLE_MAC2)) 683 | // BluetoothLeService.disconnectBle2(); 684 | // else 685 | // BluetoothLeService.disconnectBle4(); 686 | 687 | runOnUiThread(new Runnable() { 688 | @Override 689 | public void run() { 690 | Toast.makeText(DeviceListActivity.this, 691 | R.string.profile_cannot_connect_message, 692 | Toast.LENGTH_SHORT).show(); 693 | if (mLeDeviceListAdapter != null) 694 | mLeDeviceListAdapter.clear(); 695 | if (mLeDeviceListAdapter != null) { 696 | try { 697 | mLeDeviceListAdapter.notifyDataSetChanged(); 698 | } catch (Exception e) { 699 | e.printStackTrace(); 700 | } 701 | } 702 | scanLeDevice(true); 703 | mScanning = true; 704 | } 705 | }); 706 | 707 | } 708 | }, CONNECTION_TIMEOUT); 709 | } 710 | 711 | private Timer showServiceDiscoveryAlert(boolean isReconnect) { 712 | mProgressdialog.setTitle(getString(R.string.progress_tile_service_discovering)); 713 | if(!isReconnect){ 714 | mProgressdialog.setMessage(getString(R.string.progress_message_service_discovering)); 715 | }else{ 716 | mProgressdialog.setMessage(getString(R.string.progress_message_reconnect)); 717 | } 718 | mProgressdialog.setIndeterminate(true); 719 | mProgressdialog.setCancelable(false); 720 | mProgressdialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); 721 | 722 | if(mProgressdialog.isShowing() && !isActivityFinish()) 723 | mProgressdialog.dismiss(); 724 | 725 | mProgressdialog.show(); 726 | Timer timer = new Timer(); 727 | timer.schedule(new TimerTask() { 728 | @Override 729 | public void run() { 730 | if(mProgressdialog.isShowing() && !isActivityFinish()){ 731 | mProgressdialog.dismiss(); 732 | runOnUiThread(new Runnable() { 733 | @Override 734 | public void run() { 735 | showNoServiceDiscoverAlert(); 736 | sendConnectionStateToActivity(false) ; 737 | } 738 | }); 739 | } 740 | 741 | } 742 | }, SERVICE_DISCOVERY_TIMEOUT); 743 | return timer; 744 | } 745 | 746 | private void sendConnectionStateToActivity(boolean connectionState){ 747 | Intent intent = new Intent(); 748 | if(connectionState){ 749 | intent.putExtra("ADDRESS",mDeviceAddress); 750 | setResult(CONNECTION_SUCCESS,intent); 751 | }else{ 752 | BluetoothLeService.disconnectConfiguration(); 753 | setResult(CONNECTION_FAILED,intent); 754 | } 755 | finish() ; 756 | } 757 | 758 | 759 | private void showNoServiceDiscoverAlert() { 760 | Toast.makeText(this,"No Service Discovered", Toast.LENGTH_SHORT).show(); 761 | } 762 | 763 | /** 764 | * Holder class for the list view view widgets 765 | */ 766 | static class ViewHolder { 767 | TextView deviceName; 768 | TextView deviceAddress; 769 | TextView deviceRssi; 770 | } 771 | 772 | /** 773 | * List Adapter for holding devices found through scanning. 774 | */ 775 | private class LeDeviceListAdapter extends BaseAdapter implements Filterable { 776 | 777 | ArrayList mFilteredDevices = new ArrayList(); 778 | private LayoutInflater mInflator; 779 | private int rssiValue; 780 | private ItemFilter mFilter = new ItemFilter(); 781 | 782 | public LeDeviceListAdapter() { 783 | super(); 784 | mLeDevices = new ArrayList(); 785 | mInflator = getLayoutInflater(); 786 | } 787 | 788 | private void addDevice(BluetoothDevice device, int rssi) { 789 | this.rssiValue = rssi; 790 | // New device found 791 | if (!mLeDevices.contains(device)) { 792 | mDevRssiValues.put(device.getAddress(), rssi); 793 | mLeDevices.add(device); 794 | } else { 795 | mDevRssiValues.put(device.getAddress(), rssi); 796 | } 797 | } 798 | 799 | public int getRssiValue() { 800 | return rssiValue; 801 | } 802 | 803 | /** 804 | * Getter method to get the blue tooth device 805 | * 806 | * @param position 807 | * @return BluetoothDevice 808 | */ 809 | public BluetoothDevice getDevice(int position) { 810 | return mLeDevices.get(position); 811 | } 812 | 813 | /** 814 | * Clearing all values in the device array list 815 | */ 816 | public void clear() { 817 | mLeDevices.clear(); 818 | } 819 | 820 | @Override 821 | public int getCount() { 822 | return mLeDevices.size(); 823 | } 824 | 825 | 826 | @Override 827 | public Object getItem(int i) { 828 | return mLeDevices.get(i); 829 | } 830 | 831 | @Override 832 | public long getItemId(int i) { 833 | return i; 834 | } 835 | 836 | 837 | @Override 838 | public View getView(final int position, View view, ViewGroup viewGroup) { 839 | final ViewHolder viewHolder; 840 | // General ListView optimization code. 841 | if (view == null) { 842 | view = mInflator.inflate(R.layout.listitem_device, viewGroup, 843 | false); 844 | viewHolder = new ViewHolder(); 845 | viewHolder.deviceAddress = (TextView) view 846 | .findViewById(R.id.device_address); 847 | viewHolder.deviceName = (TextView) view 848 | .findViewById(R.id.device_name); 849 | viewHolder.deviceRssi = (TextView) view 850 | .findViewById(R.id.device_rssi); 851 | view.setTag(viewHolder); 852 | } else { 853 | viewHolder = (ViewHolder) view.getTag(); 854 | } 855 | 856 | /** 857 | * Setting the name and the RSSI of the BluetoothDevice. provided it 858 | * is a valid one 859 | */ 860 | final BluetoothDevice device = mLeDevices.get(position); 861 | final String deviceName = device.getName(); 862 | if (deviceName != null && deviceName.length() > 0) { 863 | try { 864 | viewHolder.deviceName.setText(deviceName); 865 | viewHolder.deviceAddress.setText(device.getAddress()); 866 | byte rssival = (byte) mDevRssiValues.get(device.getAddress()) 867 | .intValue(); 868 | if (rssival != 0) { 869 | viewHolder.deviceRssi.setText(String.valueOf(rssival)); 870 | } 871 | } catch (Exception e) { 872 | e.printStackTrace(); 873 | } 874 | 875 | } else { 876 | viewHolder.deviceName.setText(R.string.device_unknown); 877 | viewHolder.deviceName.setSelected(true); 878 | viewHolder.deviceAddress.setText(device.getAddress()); 879 | } 880 | 881 | return view; 882 | } 883 | 884 | @Override 885 | public Filter getFilter() { 886 | return mFilter; 887 | } 888 | 889 | private class ItemFilter extends Filter { 890 | @Override 891 | protected FilterResults performFiltering(CharSequence constraint) { 892 | 893 | String mFilterString = constraint.toString().toLowerCase(); 894 | 895 | FilterResults mResults = new FilterResults(); 896 | 897 | final ArrayList list = mLeDevices; 898 | 899 | int count = list.size(); 900 | final ArrayList nlist = new ArrayList(count); 901 | 902 | for (int i = 0; i < count; i++) { 903 | if (list.get(i).getName() != null && list.get(i).getName().toLowerCase().contains(mFilterString)) { 904 | nlist.add(list.get(i)); 905 | } 906 | } 907 | 908 | mResults.values = nlist; 909 | mResults.count = nlist.size(); 910 | return mResults; 911 | } 912 | 913 | @SuppressWarnings("unchecked") 914 | @Override 915 | protected void publishResults(CharSequence constraint, FilterResults results) { 916 | mFilteredDevices = (ArrayList) results.values; 917 | clear(); 918 | int count = mFilteredDevices.size(); 919 | for (int i = 0; i < count; i++) { 920 | BluetoothDevice mDevice = mFilteredDevices.get(i); 921 | mLeDeviceListAdapter.addDevice(mDevice, mLeDeviceListAdapter.getRssiValue()); 922 | notifyDataSetChanged(); // notifies the data with new filtered values 923 | } 924 | } 925 | } 926 | } 927 | 928 | } 929 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/app/src/main/java/com/prompt/multiplebledeviceconnection/bleActivity/DeviceListAutoConnectActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.prompt.multiplebledeviceconnection.bleActivity; 18 | 19 | import android.app.Activity; 20 | import android.app.AlertDialog; 21 | import android.app.Dialog; 22 | import android.app.ProgressDialog; 23 | import android.bluetooth.BluetoothAdapter; 24 | import android.bluetooth.BluetoothDevice; 25 | import android.bluetooth.BluetoothManager; 26 | import android.content.BroadcastReceiver; 27 | import android.content.Context; 28 | import android.content.DialogInterface; 29 | import android.content.Intent; 30 | import android.content.pm.PackageManager; 31 | import android.os.Build; 32 | import android.os.Bundle; 33 | import android.os.Handler; 34 | import android.view.KeyEvent; 35 | import android.view.LayoutInflater; 36 | import android.view.View; 37 | import android.view.ViewGroup; 38 | import android.widget.AdapterView; 39 | import android.widget.BaseAdapter; 40 | import android.widget.Button; 41 | import android.widget.CheckBox; 42 | import android.widget.Filter; 43 | import android.widget.Filterable; 44 | import android.widget.ListView; 45 | import android.widget.TextView; 46 | import android.widget.Toast; 47 | 48 | import com.prompt.multiplebledeviceconnection.R; 49 | import com.prompt.multiplebledeviceconnection.base.BaseActivity; 50 | import com.prompt.multiplebledeviceconnection.bleUtils.BluetoothLeService; 51 | import com.prompt.multiplebledeviceconnection.model.BLEDevice; 52 | import com.prompt.multiplebledeviceconnection.utils.Const; 53 | import com.prompt.multiplebledeviceconnection.utils.Logger; 54 | import com.prompt.multiplebledeviceconnection.utils.Prefs; 55 | import com.prompt.multiplebledeviceconnection.utils.Utils; 56 | 57 | import java.util.ArrayList; 58 | import java.util.Timer; 59 | import java.util.TimerTask; 60 | 61 | /** 62 | * This Activity appears as a dialog. It lists any paired devices and 63 | * devices detected in the area after discovery. When a device is chosen 64 | * by the user, the MAC address of the device is sent back to the parent 65 | * Activity in the result Intent. 66 | */ 67 | public class DeviceListAutoConnectActivity extends BaseActivity { 68 | 69 | // Stops scanning after 2 seconds. 70 | private static final long SCAN_PERIOD_TIMEOUT = 2000; 71 | private Timer mScanTimer; 72 | private boolean mScanning; 73 | 74 | private ViewHolder viewHolder; 75 | 76 | // Connection time out after 10 seconds. 77 | private static final long CONNECTION_TIMEOUT = 10000; 78 | private Timer mConnectTimer; 79 | private boolean mConnectTimerON = false; 80 | 81 | // device details 82 | public static String mDeviceName = "name"; 83 | public static String mDeviceAddress = "address"; 84 | 85 | //Pair status button and variables 86 | public static Button mPairButton; 87 | 88 | //Bluetooth adapter 89 | private static BluetoothAdapter mBluetoothAdapter; 90 | 91 | ArrayList checkBoxes; 92 | 93 | // Devices list variables 94 | private LeDeviceListAdapter mLeDeviceListAdapter; 95 | 96 | // Activity request constant 97 | private static final int REQUEST_ENABLE_BT = 1; 98 | //GUI elements 99 | private ListView mProfileListView; 100 | 101 | private ProgressDialog mProgressdialog; 102 | 103 | // Flags 104 | private boolean mSearchEnabled = false; 105 | 106 | 107 | //Delay Time out milisecons 108 | private static final long DELAY_PERIOD = 500; 109 | 110 | private ProgressDialog mpdia; 111 | private AlertDialog mAlert; 112 | /** 113 | * Service Discovery 114 | */ 115 | private Timer mTimer; 116 | //milli seconds 117 | private static final long SERVICE_DISCOVERY_TIMEOUT = 10000; 118 | 119 | private TextView txtHexValue; 120 | private TextView txtAsciivalue, txtNoDeviceFound; 121 | private TextView txtTimevalue; 122 | private Button btnSendData; 123 | 124 | 125 | private int deviceCount = 0; 126 | private int currentDevice = 0; 127 | 128 | /** 129 | * Used to manage connections of the Blue tooth LE Device 130 | */ 131 | private static BluetoothLeService mBluetoothLeService; 132 | private Runnable connectRunnable = null; 133 | private Handler connectionHandler = null; 134 | private Handler activityFinishHandler = null; 135 | private Runnable activityFinishRunnable = null; 136 | 137 | private ArrayList bleDeviceArrayList = new ArrayList<>(); 138 | private ArrayList bluetoothDeviceArrayList = new ArrayList<>(); 139 | BLEDevice currentBLEdevice = null; 140 | 141 | 142 | 143 | /** 144 | * BroadcastReceiver for receiving the GATT communication status 145 | */ 146 | private final BroadcastReceiver mGattConnectReceiver = new BroadcastReceiver() { 147 | @Override 148 | public void onReceive(Context context, Intent intent) { 149 | final String action = intent.getAction(); 150 | // Status received when connected to GATT Server 151 | 152 | switch (action){ 153 | case BluetoothLeService.ACTION_GATT_CONNECTED : 154 | mProgressdialog.setMessage(getString(R.string.alert_message_bluetooth_connect)); 155 | if (mScanning) { 156 | mBluetoothAdapter.stopLeScan(mLeScanCallback); 157 | 158 | scanLeDevice(false); 159 | mScanning = false; 160 | } 161 | if (mProgressdialog != null && mProgressdialog.isShowing()) 162 | mProgressdialog.dismiss(); 163 | // bleDeviceArrayList.clear(); 164 | if (mConnectTimer != null) 165 | mConnectTimer.cancel(); 166 | mConnectTimerON = false; 167 | Toast.makeText(DeviceListAutoConnectActivity.this, 168 | R.string.successfully_connected_to_the_device, 169 | Toast.LENGTH_SHORT).show(); 170 | 171 | 172 | mTimer = showServiceDiscoveryAlert(false); 173 | 174 | stopActivityFinishHandler(); 175 | /* 176 | / Changes the MTU size to 512 in case LOLLIPOP and above devices 177 | */ 178 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 179 | BluetoothLeService.exchangeGattMtu(512, mDeviceAddress); 180 | } 181 | 182 | break; 183 | 184 | case BluetoothLeService.ACTION_GATT_DISCONNECTED : 185 | /** 186 | * Disconnect event.When the connect timer is ON,Reconnect the device 187 | * else show disconnect message 188 | */ 189 | if (mConnectTimerON) { 190 | BluetoothLeService.reconnect(mDeviceAddress); 191 | } else { 192 | startActivityFinishHandler(); 193 | Toast.makeText(DeviceListAutoConnectActivity.this, 194 | R.string.profile_cannot_connect_message, 195 | Toast.LENGTH_SHORT).show(); 196 | 197 | } 198 | 199 | break; 200 | case BluetoothLeService.ACTION_MTU_EXCHANGE : 201 | Handler delayHandler = new Handler(); 202 | delayHandler.postDelayed(new Runnable() { 203 | @Override 204 | public void run() { 205 | Logger.e("Discover service called"); 206 | if (mDeviceAddress.equals(Prefs.getvalue(DeviceListAutoConnectActivity.this, Const.BLE_MAC1, ""))) { 207 | if (BluetoothLeService.getConnectionStateBle1() == BluetoothLeService.STATE_CONNECTED) 208 | BluetoothLeService.discoverServicesforBle1(); 209 | } else if (mDeviceAddress.equals(Prefs.getvalue(DeviceListAutoConnectActivity.this, Const.BLE_MAC2, ""))) { 210 | if (BluetoothLeService.getConnectionStateBle2() == BluetoothLeService.STATE_CONNECTED) 211 | BluetoothLeService.discoverServicesforBle2(); 212 | } else if (mDeviceAddress.equals(Prefs.getvalue(DeviceListAutoConnectActivity.this, Const.BLE_MAC3, ""))) { 213 | if (BluetoothLeService.getConnectionStateBle3() == BluetoothLeService.STATE_CONNECTED) 214 | BluetoothLeService.discoverServicesforBle3(); 215 | } else if (mDeviceAddress.equals(Prefs.getvalue(DeviceListAutoConnectActivity.this, Const.BLE_MAC4, ""))) { 216 | if (BluetoothLeService.getConnectionStateBle4() == BluetoothLeService.STATE_CONNECTED) 217 | BluetoothLeService.discoverServicesforBle4(); 218 | }else if (mDeviceAddress.equals(Prefs.getvalue(DeviceListAutoConnectActivity.this, Const.HW_BLE_MAC, ""))) { 219 | if (BluetoothLeService.getmConnectionStateConfiguration() == BluetoothLeService.STATE_CONNECTED) 220 | BluetoothLeService.discoverServicesforConfiguration(); 221 | } 222 | } 223 | }, DELAY_PERIOD); 224 | break; 225 | } 226 | // if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) { 227 | // 228 | // 229 | // 230 | //// updateWithNewFragment(); 231 | // } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) { 232 | // 233 | // } 234 | } 235 | }; 236 | 237 | 238 | private final BroadcastReceiver mServiceDiscoveryListner = new BroadcastReceiver() { 239 | @Override 240 | public void onReceive(Context context, Intent intent) { 241 | final String action = intent.getAction(); 242 | 243 | switch (action){ 244 | case BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED : 245 | Logger.e("Service discovered"); 246 | if (mTimer != null) 247 | mTimer.cancel(); 248 | 249 | if (mProgressdialog != null && mProgressdialog.isShowing()) 250 | mProgressdialog.dismiss(); 251 | 252 | if(currentBLEdevice != null) 253 | currentBLEdevice.setConnected(true); 254 | 255 | mLeDeviceListAdapter.updateConnectionState(currentBLEdevice); 256 | mLeDeviceListAdapter.notifyDataSetChanged(); 257 | 258 | stopActivityFinishHandler(); 259 | 260 | connectionHandler.postDelayed(connectRunnable, 1000); 261 | 262 | //TODO Check here 263 | // scanLeDevice(true); 264 | // sendResult(); 265 | break; 266 | 267 | 268 | case BluetoothLeService.ACTION_GATT_SERVICE_DISCOVERY_UNSUCCESSFUL : 269 | if (mProgressdialog != null && mProgressdialog.isShowing()) 270 | mProgressdialog.dismiss(); 271 | if (mTimer != null) 272 | mTimer.cancel(); 273 | showNoServiceDiscoverAlert(); 274 | 275 | //TODO Check here 276 | // scanLeDevice(true); 277 | break; 278 | 279 | } 280 | } 281 | }; 282 | 283 | private BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() { 284 | @Override 285 | public void onReceive(Context context, Intent intent) { 286 | //Getting the intent action and extras 287 | final String action = intent.getAction(); 288 | Bundle extras = intent.getExtras(); 289 | 290 | switch (action){ 291 | case BluetoothLeService.ACTION_DATA_AVAILABLE : 292 | if (extras.containsKey(Const.EXTRA_BYTE_VALUE) 293 | && extras.containsKey(Const.EXTRA_BLE_DEVICE_ADDRESS)) { 294 | 295 | byte[] array = intent 296 | .getByteArrayExtra(Const. 297 | EXTRA_BYTE_VALUE); 298 | String deviceAddress = intent.getStringExtra(Const. 299 | EXTRA_BLE_DEVICE_ADDRESS); 300 | 301 | if (deviceAddress.equals(Prefs.getvalue(DeviceListAutoConnectActivity.this, Const.BLE_MAC1, ""))) { 302 | displayASCIIValue2(byteToString(array)); 303 | } else { 304 | displayASCIIValue4(byteToString(array)); 305 | } 306 | displayTimeandDate(); 307 | displayTimeandDate(); 308 | 309 | } 310 | break; 311 | } 312 | 313 | 314 | } 315 | 316 | }; 317 | 318 | 319 | /** 320 | * Call back for BLE Scan 321 | * This call back is called when a BLE device is found near by. 322 | */ 323 | private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() { 324 | 325 | @Override 326 | public void onLeScan(final BluetoothDevice device, final int rssi, 327 | byte[] scanRecord) { 328 | Activity mActivity = DeviceListAutoConnectActivity.this; 329 | mActivity.runOnUiThread(new Runnable() { 330 | @Override 331 | public void run() { 332 | 333 | if (device.getAddress().equals(Prefs.getvalue(DeviceListAutoConnectActivity.this, Const.HW_BLE_MAC, ""))) { 334 | 335 | BLEDevice bleDevice = new BLEDevice(); 336 | 337 | bleDevice.setBluetoothDevice(device); 338 | bleDevice.setConnected(false); 339 | 340 | mLeDeviceListAdapter.addDevice(bleDevice); 341 | mLeDeviceListAdapter.notifyDataSetChanged(); 342 | } 343 | 344 | } 345 | }); 346 | 347 | } 348 | }; 349 | 350 | 351 | @Override 352 | protected void onCreate(Bundle savedInstanceState) { 353 | super.onCreate(savedInstanceState); 354 | 355 | // Setup the window 356 | setContentView(R.layout.activity_device_list); 357 | this.setFinishOnTouchOutside(false); 358 | getWindow().setTitle(""); 359 | getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); 360 | getWindow().setBackgroundDrawableResource(android.R.color.transparent); 361 | mProfileListView = (ListView) findViewById(android.R.id.list); 362 | txtNoDeviceFound = (TextView) findViewById(android.R.id.empty); 363 | txtHexValue = (TextView) findViewById(R.id.txtHex); 364 | txtAsciivalue = (TextView) findViewById(R.id.txtAscci); 365 | txtTimevalue = (TextView) findViewById(R.id.txtTime); 366 | btnSendData = (Button) findViewById(R.id.btnSendData); 367 | 368 | btnSendData.setOnClickListener(new View.OnClickListener() { 369 | @Override 370 | public void onClick(View v) { 371 | 372 | BluetoothLeService.writeCharacteristicGattDb1("Sample Data For 1".getBytes()); 373 | BluetoothLeService.writeCharacteristicGattDb2("Sample Data For 2".getBytes()); 374 | BluetoothLeService.writeCharacteristicGattDb3("Sample Data For 3".getBytes()); 375 | BluetoothLeService.writeCharacteristicGattDb4("Sample Data For 4".getBytes()); 376 | } 377 | }); 378 | 379 | mLeDeviceListAdapter = new LeDeviceListAdapter(); 380 | mProfileListView.setAdapter(mLeDeviceListAdapter); 381 | mProfileListView.setTextFilterEnabled(true); 382 | mProgressdialog = new ProgressDialog(this); 383 | mProgressdialog.setCancelable(false); 384 | 385 | mpdia = new ProgressDialog(this); 386 | mpdia.setCancelable(false); 387 | mAlert = new AlertDialog.Builder(this).create(); 388 | mAlert.setMessage(getResources().getString( 389 | R.string.alert_message_bluetooth_reconnect)); 390 | mAlert.setCancelable(false); 391 | mAlert.setTitle(getResources().getString(R.string.app_name)); 392 | mAlert.setButton(Dialog.BUTTON_POSITIVE, getResources().getString( 393 | R.string.ok), new DialogInterface.OnClickListener() { 394 | @Override 395 | public void onClick(DialogInterface dialogInterface, int i) { 396 | Intent intentActivity = getIntent(); 397 | finish(); 398 | overridePendingTransition( 399 | R.anim.slide_left, R.anim.push_left); 400 | startActivity(intentActivity); 401 | overridePendingTransition( 402 | R.anim.slide_right, R.anim.push_right); 403 | } 404 | }); 405 | mAlert.setCanceledOnTouchOutside(false); 406 | 407 | checkBleSupportAndInitialize(); 408 | 409 | /** 410 | * Creating the dataLogger file and 411 | * updating the datalogger history 412 | */ 413 | Logger.createDataLoggerFile(this); 414 | mProfileListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 415 | @Override 416 | public void onItemClick(AdapterView adapterView, View view, int position, long l) { 417 | if (mLeDeviceListAdapter.getCount() > 0) { 418 | 419 | 420 | final BluetoothDevice device = mLeDeviceListAdapter 421 | .getBLEDevice(position).getBluetoothDevice(); 422 | if (device != null) { 423 | stopActivityFinishHandler(); 424 | scanLeDevice(false); 425 | //TODO Device Coonect 426 | connectDevice(device, true); 427 | } 428 | } 429 | } 430 | }); 431 | 432 | checkBoxes = new ArrayList<>(); 433 | 434 | connectionHandler = new Handler(); 435 | connectRunnable = new Runnable() { 436 | @Override 437 | public void run() { 438 | 439 | if (mLeDeviceListAdapter.getCount() > 0) { 440 | if (deviceCount == 0) { 441 | scanLeDevice(false); 442 | deviceCount = mLeDeviceListAdapter.getCount(); 443 | } 444 | 445 | if (currentDevice < deviceCount) { 446 | currentBLEdevice = mLeDeviceListAdapter.getBLEDevice(currentDevice); 447 | connectDevice(currentBLEdevice.getBluetoothDevice(), true); 448 | currentDevice++; 449 | connectionHandler.removeCallbacks(connectRunnable); 450 | } else { 451 | connectionHandler.removeCallbacks(connectRunnable); 452 | Intent intent = new Intent(); 453 | setResult(Activity.RESULT_OK, intent); 454 | finish(); 455 | } 456 | } else { 457 | finish(); 458 | } 459 | } 460 | }; 461 | 462 | 463 | mProfileListView.setEmptyView(txtNoDeviceFound); 464 | 465 | activityFinishHandler = new Handler(); 466 | activityFinishRunnable = new Runnable() { 467 | @Override 468 | public void run() { 469 | DeviceListAutoConnectActivity.this.finish(); 470 | } 471 | }; 472 | 473 | } 474 | 475 | @Override 476 | protected void initializeWidget() { 477 | 478 | } 479 | 480 | @Override 481 | protected void bindEvents() { 482 | 483 | } 484 | 485 | @Override 486 | protected Context getContext() { 487 | return this; 488 | } 489 | 490 | @Override 491 | protected void dialogResponse(int id, boolean res) { 492 | 493 | } 494 | 495 | // private void sendResult(){ 496 | // Intent intent1 = new Intent(); 497 | // intent1.putExtra("ADDRESS",mDeviceAddress); 498 | // setResult(1,intent1); 499 | // finish(); 500 | // } 501 | 502 | @Override 503 | public void onResume() { 504 | super.onResume(); 505 | Logger.e("Scanning onResume"); 506 | if (checkBluetoothStatus()) { 507 | prepareList(); 508 | } 509 | Logger.e("Registering receiver in Profile scannng"); 510 | registerReceiver(mGattConnectReceiver, 511 | Utils.makeGattConnectIntentFilter()); 512 | registerReceiver(mServiceDiscoveryListner, Utils.makeGattServiceDiscoveryIntentFilter()); 513 | registerReceiver(mGattUpdateReceiver, Utils.makeGattUpdateIntentFilter()); 514 | 515 | } 516 | 517 | @Override 518 | public boolean onKeyUp(int keyCode, KeyEvent event) { 519 | if (keyCode == KeyEvent.KEYCODE_BACK) 520 | return super.onKeyUp(keyCode, event); 521 | else 522 | return true; 523 | } 524 | 525 | @Override 526 | public void onDestroy() { 527 | super.onDestroy(); 528 | scanLeDevice(false); 529 | if (mLeDeviceListAdapter != null) 530 | mLeDeviceListAdapter.clear(); 531 | if (mLeDeviceListAdapter != null) { 532 | try { 533 | mLeDeviceListAdapter.notifyDataSetChanged(); 534 | } catch (Exception e) { 535 | e.printStackTrace(); 536 | } 537 | } 538 | // unregisterReceiver(mBondStateReceiver); 539 | unregisterReceiver(mGattConnectReceiver); 540 | unregisterReceiver(mServiceDiscoveryListner); 541 | unregisterReceiver(mGattUpdateReceiver); 542 | 543 | } 544 | 545 | @Override 546 | public void onActivityResult(int requestCode, int resultCode, Intent data) { 547 | // User chose not to enable BlueTooth. 548 | if (requestCode == REQUEST_ENABLE_BT 549 | && resultCode == Activity.RESULT_CANCELED) { 550 | finish(); 551 | } else { 552 | // Check which request we're responding to 553 | if (requestCode == REQUEST_ENABLE_BT) { 554 | 555 | // Make sure the request was successful 556 | if (resultCode == Activity.RESULT_OK) { 557 | Toast.makeText( 558 | DeviceListAutoConnectActivity.this, 559 | getResources().getString( 560 | R.string.device_bluetooth_on), 561 | Toast.LENGTH_SHORT).show(); 562 | mLeDeviceListAdapter = new LeDeviceListAdapter(); 563 | mProfileListView.setAdapter(mLeDeviceListAdapter); 564 | // scanLeDevice(true); 565 | prepareList(); 566 | } else { 567 | finish(); 568 | } 569 | } 570 | } 571 | } 572 | 573 | 574 | private void checkBleSupportAndInitialize() { 575 | // Use this check to determine whether BLE is supported on the device. 576 | if (!getPackageManager().hasSystemFeature( 577 | PackageManager.FEATURE_BLUETOOTH_LE)) { 578 | Toast.makeText(DeviceListAutoConnectActivity.this, R.string.device_ble_not_supported, 579 | Toast.LENGTH_SHORT).show(); 580 | finish(); 581 | } 582 | // Initializes a Blue tooth adapter. 583 | final BluetoothManager bluetoothManager = (BluetoothManager) 584 | getSystemService(Context.BLUETOOTH_SERVICE); 585 | mBluetoothAdapter = bluetoothManager.getAdapter(); 586 | 587 | if (mBluetoothAdapter == null) { 588 | // Device does not support Blue tooth 589 | Toast.makeText(DeviceListAutoConnectActivity.this, 590 | R.string.device_bluetooth_not_supported, Toast.LENGTH_SHORT) 591 | .show(); 592 | finish(); 593 | } 594 | } 595 | 596 | public boolean checkBluetoothStatus() { 597 | /** 598 | * Ensures Blue tooth is enabled on the device. If Blue tooth is not 599 | * currently enabled, fire an intent to display a dialog asking the user 600 | * to grant permission to enable it. 601 | */ 602 | if (!mBluetoothAdapter.isEnabled()) { 603 | Intent enableBtIntent = new Intent( 604 | BluetoothAdapter.ACTION_REQUEST_ENABLE); 605 | startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); 606 | return false; 607 | } 608 | return true; 609 | } 610 | 611 | /** 612 | * Method to scan BLE Devices. The status of the scan will be detected in 613 | * the BluetoothAdapter.LeScanCallback 614 | * 615 | * @param enable 616 | */ 617 | private void scanLeDevice(final boolean enable) { 618 | if (enable) { 619 | if (!mScanning) { 620 | startScanTimer(); 621 | mScanning = true; 622 | 623 | mBluetoothAdapter.startLeScan(mLeScanCallback); 624 | 625 | } 626 | } else { 627 | mScanning = false; 628 | mBluetoothAdapter.stopLeScan(mLeScanCallback); 629 | } 630 | 631 | } 632 | 633 | 634 | /** 635 | * Preparing the BLE Devicelist 636 | */ 637 | public void prepareList() { 638 | // Initializes ActionBar as required 639 | // setUpActionBar(); 640 | // Prepare list view and initiate scanning 641 | mLeDeviceListAdapter = new LeDeviceListAdapter(); 642 | mProfileListView.setAdapter(mLeDeviceListAdapter); 643 | scanLeDevice(true); 644 | mSearchEnabled = false; 645 | } 646 | 647 | /** 648 | * Swipe refresh timer 649 | */ 650 | public void startScanTimer() { 651 | mScanTimer = new Timer(); 652 | mScanTimer.schedule(new TimerTask() { 653 | @Override 654 | public void run() { 655 | mScanning = false; 656 | 657 | mBluetoothAdapter.stopLeScan(mLeScanCallback); 658 | scanLeDevice(false); 659 | 660 | if (mLeDeviceListAdapter.getCount() == 0) { 661 | DeviceListAutoConnectActivity.this.runOnUiThread(new Runnable() { 662 | @Override 663 | public void run() { 664 | new Handler().postDelayed(new Runnable() { 665 | @Override 666 | public void run() { 667 | finish(); 668 | } 669 | },2000) ; 670 | 671 | } 672 | }); 673 | 674 | } else { 675 | connectionHandler.post(connectRunnable); 676 | } 677 | } 678 | }, SCAN_PERIOD_TIMEOUT); 679 | } 680 | 681 | 682 | /** 683 | * Method to connect to the device selected. The time allotted for having a 684 | * connection is 8 seconds. After 8 seconds it will disconnect if not 685 | * connected and initiate scan once more 686 | * 687 | * @param device 688 | */ 689 | 690 | private void connectDevice(BluetoothDevice device, boolean isFirstConnect) { 691 | Logger.v("connectDevice Called..."); 692 | 693 | mDeviceAddress = device.getAddress(); 694 | mDeviceName = device.getName(); 695 | // Get the connection status of the device 696 | if (BluetoothLeService.getConnectionState(this, mDeviceAddress) == BluetoothLeService.STATE_DISCONNECTED) { 697 | Logger.v("BLE DISCONNECTED STATE"); 698 | // Disconnected,so connect 699 | BluetoothLeService.connect(DeviceListAutoConnectActivity.this, mDeviceAddress, mDeviceName); 700 | showConnectAlertMessage(mDeviceName, mDeviceAddress); 701 | } else { 702 | Logger.v("BLE OTHER STATE-->" + BluetoothLeService.getConnectionState(this, mDeviceAddress)); 703 | // Connecting to some devices,so disconnect and then connect 704 | BluetoothLeService.disconnect(mDeviceAddress); 705 | 706 | Handler delayHandler = new Handler(); 707 | delayHandler.postDelayed(new Runnable() { 708 | @Override 709 | public void run() { 710 | BluetoothLeService.connect(DeviceListAutoConnectActivity.this, mDeviceAddress, mDeviceName); 711 | showConnectAlertMessage(mDeviceName, mDeviceAddress); 712 | } 713 | }, DELAY_PERIOD); 714 | 715 | } 716 | if (isFirstConnect) { 717 | startConnectTimer(); 718 | mConnectTimerON = true; 719 | } 720 | 721 | } 722 | 723 | private void showConnectAlertMessage(String devicename, String deviceaddress) { 724 | mProgressdialog.setTitle(getResources().getString( 725 | R.string.alert_message_connect_title)); 726 | mProgressdialog.setMessage(getResources().getString( 727 | R.string.alert_message_connect) 728 | + "\n" 729 | + devicename 730 | + "\n" 731 | + deviceaddress 732 | + "\n" 733 | + getResources().getString(R.string.alert_message_wait)); 734 | 735 | if (!DeviceListAutoConnectActivity.this.isDestroyed() && mProgressdialog != null) { 736 | mProgressdialog.show(); 737 | } 738 | } 739 | 740 | /** 741 | * Connect Timer 742 | */ 743 | private void startConnectTimer() { 744 | mConnectTimer = new Timer(); 745 | mConnectTimer.schedule(new TimerTask() { 746 | @Override 747 | public void run() { 748 | if (mProgressdialog != null && mProgressdialog.isShowing() 749 | && !isActivityFinish()) 750 | mProgressdialog.dismiss(); 751 | Logger.v("CONNECTION TIME OUT"); 752 | mConnectTimerON = false; 753 | 754 | // if(mDeviceAddress.equals(BluetoothLeService.BLE_MAC2)) 755 | // BluetoothLeService.disconnectBle2(); 756 | // else 757 | // BluetoothLeService.disconnectBle4(); 758 | 759 | runOnUiThread(new Runnable() { 760 | @Override 761 | public void run() { 762 | Toast.makeText(DeviceListAutoConnectActivity.this, 763 | R.string.profile_cannot_connect_message, 764 | Toast.LENGTH_SHORT).show(); 765 | if (mLeDeviceListAdapter != null) 766 | // mLeDeviceListAdapter.clear(); 767 | if (mLeDeviceListAdapter != null) { 768 | try { 769 | mLeDeviceListAdapter.notifyDataSetChanged(); 770 | } catch (Exception e) { 771 | e.printStackTrace(); 772 | } 773 | } 774 | //TODO Check here 775 | // scanLeDevice(true); 776 | mScanning = true; 777 | } 778 | }); 779 | 780 | } 781 | }, CONNECTION_TIMEOUT); 782 | } 783 | 784 | private Timer showServiceDiscoveryAlert(boolean isReconnect) { 785 | mProgressdialog.setTitle(getString(R.string.progress_tile_service_discovering)); 786 | if (!isReconnect) { 787 | mProgressdialog.setMessage(getString(R.string.progress_message_service_discovering)); 788 | } else { 789 | mProgressdialog.setMessage(getString(R.string.progress_message_reconnect)); 790 | } 791 | mProgressdialog.setIndeterminate(true); 792 | mProgressdialog.setCancelable(false); 793 | mProgressdialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); 794 | mProgressdialog.show(); 795 | Timer timer = new Timer(); 796 | timer.schedule(new TimerTask() { 797 | @Override 798 | public void run() { 799 | if (mProgressdialog != null && mProgressdialog.isShowing() 800 | && !isActivityFinish()) { 801 | mProgressdialog.dismiss(); 802 | 803 | runOnUiThread(new Runnable() { 804 | @Override 805 | public void run() { 806 | showNoServiceDiscoverAlert(); 807 | startActivityFinishHandler(); 808 | } 809 | }); 810 | } 811 | 812 | } 813 | }, SERVICE_DISCOVERY_TIMEOUT); 814 | return timer; 815 | } 816 | 817 | private String byteToString(byte[] array) { 818 | StringBuffer sb = new StringBuffer(); 819 | for (byte byteChar : array) { 820 | sb.append(String.format("%02x", byteChar)); 821 | } 822 | 823 | return sb.toString(); 824 | } 825 | 826 | 827 | /** 828 | * Method to convert the hexvalue to ascii value and displaying to the user 829 | * 830 | * @param hexValue 831 | */ 832 | void displayASCIIValue2(String hexValue) { 833 | txtAsciivalue.setText(""); 834 | StringBuilder output = new StringBuilder(""); 835 | try { 836 | for (int i = 0; i < hexValue.length(); i += 2) { 837 | String str = hexValue.substring(i, i + 2); 838 | output.append((char) Integer.parseInt(str, 16)); 839 | } 840 | } catch (Exception e) { 841 | e.printStackTrace(); 842 | } 843 | txtAsciivalue.setText(output.toString()); 844 | } 845 | 846 | void displayASCIIValue4(String hexValue) { 847 | txtHexValue.setText(""); 848 | StringBuilder output = new StringBuilder(""); 849 | try { 850 | for (int i = 0; i < hexValue.length(); i += 2) { 851 | String str = hexValue.substring(i, i + 2); 852 | output.append((char) Integer.parseInt(str, 16)); 853 | } 854 | } catch (Exception e) { 855 | e.printStackTrace(); 856 | } 857 | txtHexValue.setText(output.toString()); 858 | } 859 | 860 | /** 861 | * Method to display time and date 862 | */ 863 | private void displayTimeandDate() { 864 | txtTimevalue.setText(Utils.GetTimeFromMilliseconds()); 865 | } 866 | 867 | 868 | private void showNoServiceDiscoverAlert() { 869 | Toast.makeText(this, "No Service Discovered", Toast.LENGTH_SHORT).show(); 870 | } 871 | 872 | /** 873 | * Holder class for the list view view widgets 874 | */ 875 | static class ViewHolder { 876 | TextView deviceName; 877 | TextView deviceAddress; 878 | CheckBox chkStatus; 879 | } 880 | 881 | /** 882 | * List Adapter for holding devices found through scanning. 883 | */ 884 | private class LeDeviceListAdapter extends BaseAdapter implements Filterable { 885 | 886 | ArrayList mFilteredDevices = new ArrayList<>(); 887 | private LayoutInflater mInflator; 888 | private int rssiValue; 889 | private ItemFilter mFilter = new ItemFilter(); 890 | 891 | public LeDeviceListAdapter() { 892 | super(); 893 | mInflator = getLayoutInflater(); 894 | } 895 | 896 | private void addDevice(BLEDevice device) { 897 | 898 | if (!bluetoothDeviceArrayList.contains(device.getBluetoothDevice())) { 899 | bluetoothDeviceArrayList.add(device.getBluetoothDevice()); 900 | bleDeviceArrayList.add(device); 901 | } 902 | } 903 | 904 | 905 | private void updateConnectionState(BLEDevice device) { 906 | for (int i = 0; i < bleDeviceArrayList.size(); i++) { 907 | BLEDevice bleDevice = bleDeviceArrayList.get(i); 908 | if (bleDevice.getBluetoothDevice().getAddress().equals(device.getBluetoothDevice().getAddress())) { 909 | bleDeviceArrayList.set(i, device); 910 | } 911 | } 912 | } 913 | 914 | /** 915 | * Getter method to get the blue tooth device 916 | * 917 | * @param position 918 | * @return BluetoothDevice 919 | */ 920 | public BLEDevice getBLEDevice(int position) { 921 | return bleDeviceArrayList.get(position); 922 | } 923 | 924 | /** 925 | * Clearing all values in the device array list 926 | */ 927 | public void clear() { 928 | bleDeviceArrayList.clear(); 929 | } 930 | 931 | @Override 932 | public int getCount() { 933 | return bleDeviceArrayList.size(); 934 | } 935 | 936 | 937 | @Override 938 | public Object getItem(int i) { 939 | return bleDeviceArrayList.get(i); 940 | } 941 | 942 | @Override 943 | public long getItemId(int i) { 944 | return i; 945 | } 946 | 947 | 948 | @Override 949 | public View getView(final int position, View view, ViewGroup viewGroup) { 950 | 951 | // General ListView optimization code. 952 | if (view == null) { 953 | view = mInflator.inflate(R.layout.listitem_autoconnect_device, viewGroup, 954 | false); 955 | viewHolder = new ViewHolder(); 956 | viewHolder.deviceAddress = (TextView) view 957 | .findViewById(R.id.device_address); 958 | viewHolder.deviceName = (TextView) view 959 | .findViewById(R.id.device_name); 960 | viewHolder.chkStatus = (CheckBox) view. 961 | findViewById(R.id.chk_connectindicator); 962 | view.setTag(viewHolder); 963 | } else { 964 | viewHolder = (ViewHolder) view.getTag(); 965 | 966 | checkBoxes.add((CheckBox) viewHolder.deviceAddress.getTag()); 967 | } 968 | 969 | /** 970 | * Setting the name and the RSSI of the BluetoothDevice. provided it 971 | * is a valid one 972 | */ 973 | final BLEDevice device = bleDeviceArrayList.get(position); 974 | final String deviceName = device.getBluetoothDevice().getName(); 975 | if (deviceName != null && deviceName.length() > 0) { 976 | try { 977 | viewHolder.deviceName.setText(deviceName); 978 | viewHolder.deviceAddress.setText(device.getBluetoothDevice().getAddress()); 979 | 980 | } catch (Exception e) { 981 | e.printStackTrace(); 982 | } 983 | 984 | } else { 985 | viewHolder.deviceName.setText(R.string.device_unknown); 986 | viewHolder.deviceName.setSelected(true); 987 | viewHolder.deviceAddress.setText(device.getBluetoothDevice().getAddress()); 988 | } 989 | 990 | if (bleDeviceArrayList.get(position).isConnected()) 991 | viewHolder.chkStatus.setChecked(true); 992 | else 993 | viewHolder.chkStatus.setChecked(false); 994 | 995 | 996 | return view; 997 | } 998 | 999 | @Override 1000 | public Filter getFilter() { 1001 | return mFilter; 1002 | } 1003 | 1004 | private class ItemFilter extends Filter { 1005 | @Override 1006 | protected FilterResults performFiltering(CharSequence constraint) { 1007 | 1008 | String mFilterString = constraint.toString().toLowerCase(); 1009 | 1010 | FilterResults mResults = new FilterResults(); 1011 | 1012 | final ArrayList list = bleDeviceArrayList; 1013 | 1014 | int count = list.size(); 1015 | final ArrayList nlist = new ArrayList(count); 1016 | 1017 | for (int i = 0; i < count; i++) { 1018 | if (list.get(i).getBluetoothDevice().getName() != null && list.get(i).getBluetoothDevice().getName().toLowerCase().contains(mFilterString)) { 1019 | nlist.add(list.get(i).getBluetoothDevice()); 1020 | } 1021 | } 1022 | 1023 | mResults.values = nlist; 1024 | mResults.count = nlist.size(); 1025 | return mResults; 1026 | } 1027 | 1028 | @SuppressWarnings("unchecked") 1029 | @Override 1030 | protected void publishResults(CharSequence constraint, FilterResults results) { 1031 | mFilteredDevices = (ArrayList) results.values; 1032 | clear(); 1033 | int count = mFilteredDevices.size(); 1034 | for (int i = 0; i < count; i++) { 1035 | BLEDevice mDevice = mFilteredDevices.get(i); 1036 | mLeDeviceListAdapter.addDevice(mFilteredDevices.get(i)); 1037 | notifyDataSetChanged(); // notifies the data with new filtered values 1038 | } 1039 | } 1040 | } 1041 | } 1042 | 1043 | @Override 1044 | public void onBackPressed() { 1045 | 1046 | // StringBuilder sb = new StringBuilder(); 1047 | // sb.append(""); 1048 | // if (BluetoothLeService.getConnectionStateBle1() == BluetoothLeService.STATE_CONNECTED || 1049 | // BluetoothLeService.getConnectionStateBle1() == BluetoothLeService.STATE_CONNECTING || 1050 | // BluetoothLeService.getConnectionStateBle1() == BluetoothLeService.STATE_DISCONNECTING) { 1051 | // BluetoothLeService.disconnectBle1(); 1052 | // sb.append("1"); 1053 | // } 1054 | // 1055 | // if (BluetoothLeService.getConnectionStateBle2() == BluetoothLeService.STATE_CONNECTED || 1056 | // BluetoothLeService.getConnectionStateBle2() == BluetoothLeService.STATE_CONNECTING || 1057 | // BluetoothLeService.getConnectionStateBle2() == BluetoothLeService.STATE_DISCONNECTING) { 1058 | // BluetoothLeService.disconnectBle2(); 1059 | // sb.append("2"); 1060 | // 1061 | // } 1062 | // if (BluetoothLeService.getConnectionStateBle3() == BluetoothLeService.STATE_CONNECTED || 1063 | // BluetoothLeService.getConnectionStateBle3() == BluetoothLeService.STATE_CONNECTING || 1064 | // BluetoothLeService.getConnectionStateBle3() == BluetoothLeService.STATE_DISCONNECTING) { 1065 | // BluetoothLeService.disconnectBle2(); 1066 | // sb.append("3"); 1067 | // 1068 | // } 1069 | // 1070 | // if (BluetoothLeService.getConnectionStateBle4() == BluetoothLeService.STATE_CONNECTED || 1071 | // BluetoothLeService.getConnectionStateBle4() == BluetoothLeService.STATE_CONNECTING || 1072 | // BluetoothLeService.getConnectionStateBle4() == BluetoothLeService.STATE_DISCONNECTING) { 1073 | // BluetoothLeService.disconnectBle4(); 1074 | // sb.append("4"); 1075 | // 1076 | // } 1077 | 1078 | // if(!sb.toString().equals("")) 1079 | // Toast.makeText(this, getResources().getString(R.string.alert_message_bluetooth_disconnect)+ sb.toString(), Toast.LENGTH_SHORT).show(); 1080 | 1081 | // super.onBackPressed(); 1082 | } 1083 | 1084 | private void startActivityFinishHandler(){ 1085 | if(activityFinishHandler != null && activityFinishRunnable != null) 1086 | activityFinishHandler.postDelayed(activityFinishRunnable,5000); 1087 | } 1088 | private void stopActivityFinishHandler(){ 1089 | if(activityFinishHandler != null && activityFinishRunnable != null) 1090 | activityFinishHandler.removeCallbacks(activityFinishRunnable); 1091 | } 1092 | 1093 | } 1094 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/app/src/main/java/com/prompt/multiplebledeviceconnection/bleActivity/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.prompt.multiplebledeviceconnection.bleActivity; 2 | 3 | import android.content.Intent; 4 | import android.support.v7.app.AppCompatActivity; 5 | import android.os.Bundle; 6 | import android.view.View; 7 | import android.widget.Button; 8 | 9 | import com.prompt.multiplebledeviceconnection.R; 10 | 11 | public class MainActivity extends AppCompatActivity implements View.OnClickListener { 12 | 13 | private Button btnConfigureBLE, btnConnectBLE; 14 | @Override 15 | protected void onCreate(Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | setContentView(R.layout.activity_main); 18 | 19 | 20 | btnConfigureBLE = (Button) findViewById(R.id.btnConfigureBLE); 21 | btnConnectBLE = (Button) findViewById(R.id.btnConnectBLE); 22 | 23 | btnConnectBLE.setOnClickListener(this); 24 | btnConfigureBLE.setOnClickListener(this); 25 | } 26 | 27 | @Override 28 | public void onClick(View v) { 29 | switch (v.getId()){ 30 | case R.id.btnConfigureBLE: 31 | Intent intent = new Intent(this,DeviceListActivity.class); 32 | startActivity(intent); 33 | break; 34 | case R.id.btnConnectBLE: 35 | break; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/app/src/main/java/com/prompt/multiplebledeviceconnection/bleUtils/GattConnectReceiver.java: -------------------------------------------------------------------------------- 1 | package com.prompt.multiplebledeviceconnection.bleUtils; 2 | 3 | import android.content.BroadcastReceiver; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.os.Bundle; 7 | import android.os.Handler; 8 | 9 | import com.prompt.multiplebledeviceconnection.R; 10 | import com.prompt.multiplebledeviceconnection.uicomponents.MyAlertDialog; 11 | import com.prompt.multiplebledeviceconnection.utils.Const; 12 | import com.prompt.multiplebledeviceconnection.utils.Utils; 13 | 14 | 15 | public class GattConnectReceiver extends BroadcastReceiver { 16 | private static GattConnectReceiver gattConnectReceiver ; 17 | private Context mContext ; 18 | private MyAlertDialog alertDialog ; 19 | private Handler handler = new Handler(); 20 | 21 | 22 | public GattConnectReceiver(){ 23 | //Just to ignore Manifest Error Don't use it 24 | } 25 | private GattConnectReceiver(Context context) { 26 | this.mContext = context ; 27 | } 28 | 29 | public static GattConnectReceiver getInstance(Context context){ 30 | if(gattConnectReceiver == null) 31 | gattConnectReceiver = new GattConnectReceiver(context); 32 | return gattConnectReceiver ; 33 | } 34 | 35 | 36 | @Override 37 | public void onReceive(Context context, Intent intent) { 38 | final String action = intent.getAction(); 39 | String deviceAddress = ""; 40 | Bundle extras = intent.getExtras() ; 41 | if(extras != null && extras.containsKey(Const.EXTRA_BLE_DEVICE_ADDRESS)){ 42 | deviceAddress = extras.get(Const.EXTRA_BLE_DEVICE_ADDRESS).toString(); 43 | } 44 | if(deviceAddress == null){ 45 | deviceAddress = "" ; 46 | } 47 | // Status received when connected to GATT Server 48 | if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) { 49 | 50 | //Connected Do nothing 51 | }else if(BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) { 52 | 53 | showAlert(0, mContext.getString(R.string.alert_message_bluetooth_disconnect),deviceAddress); 54 | } 55 | } 56 | 57 | protected void showAlert(int id, String message, String address) { 58 | alertDialog = new MyAlertDialog(mContext); 59 | alertDialog.setIcon(R.drawable.ic_alert); 60 | alertDialog.setMessage(message); 61 | alertDialog.show(); 62 | handler.postDelayed(new Runnable() { 63 | @Override 64 | public void run() { 65 | if (!Utils.isActivityFinish(mContext)) 66 | alertDialog.dismiss(); 67 | } 68 | }, Const.DIALOG_DISPLAY_TIME); 69 | 70 | // BluetoothLeService.connect(mContext, address,""); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/app/src/main/java/com/prompt/multiplebledeviceconnection/bleUtils/OnDataReceiveInterface.java: -------------------------------------------------------------------------------- 1 | package com.prompt.multiplebledeviceconnection.bleUtils; 2 | 3 | import java.util.HashMap; 4 | 5 | /** 6 | * Created by root on 9/9/16. 7 | */ 8 | 9 | public interface OnDataReceiveInterface { 10 | 11 | void onDataReceived(HashMap hashMap); 12 | void onDataHwReceived(String str); 13 | void onPrinterResponseReceived(boolean isPrintSuccess); 14 | } 15 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/app/src/main/java/com/prompt/multiplebledeviceconnection/bleUtils/SampleGattAttributes.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.prompt.multiplebledeviceconnection.bleUtils; 18 | 19 | import java.util.HashMap; 20 | 21 | /** 22 | * This class includes a small subset of standard GATT attributes for demonstration purposes. 23 | */ 24 | public class SampleGattAttributes { 25 | private static HashMap attributes = new HashMap(); 26 | public static String BLE_TX = "0003cdd2-0000-1000-8000-00805f9b0131"; 27 | public static String BLE_RX = "0003cdd1-0000-1000-8000-00805f9b0131"; 28 | // static { 29 | // // Sample Services. 30 | // attributes.put("0000ffe0-0000-1000-8000-00805f9b34fb", "HM 10 Serial"); 31 | // attributes.put("00001800-0000-1000-8000-00805f9b34fb", "Device Information Service"); 32 | // // Sample Characteristics. 33 | // attributes.put(HM_RX_TX,"RX/TX data"); 34 | // attributes.put("00002a29-0000-1000-8000-00805f9b34fb", "Manufacturer Name String"); 35 | // } 36 | 37 | static { 38 | // Sample Services. 39 | attributes.put("0003cdd0-0000-1000-8000-00805f9b0131", "BLE DEVICE"); 40 | attributes.put("00001800-0000-1000-8000-00805f9b34fb", "Device Information Service"); 41 | // Sample Characteristics. 42 | attributes.put(BLE_TX,"RX/TX data"); 43 | attributes.put("0003cdd2-0000-1000-8000-00805f9b0131", "Manufacturer Name String"); 44 | } 45 | 46 | public static String lookup(String uuid, String defaultName) { 47 | String name = attributes.get(uuid); 48 | return name == null ? defaultName : name; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/app/src/main/java/com/prompt/multiplebledeviceconnection/broadcastReceivers/DataReceiverBle.java: -------------------------------------------------------------------------------- 1 | package com.prompt.multiplebledeviceconnection.broadcastReceivers; 2 | 3 | import android.content.BroadcastReceiver; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.os.Bundle; 7 | import android.os.SystemClock; 8 | 9 | import com.prompt.multiplebledeviceconnection.bleUtils.BluetoothLeService; 10 | import com.prompt.multiplebledeviceconnection.utils.BleFrames; 11 | import com.prompt.multiplebledeviceconnection.utils.Const; 12 | import com.prompt.multiplebledeviceconnection.utils.Utils; 13 | 14 | import static com.prompt.multiplebledeviceconnection.utils.Utils.byteToString; 15 | 16 | 17 | public class DataReceiverBle extends BroadcastReceiver { 18 | private static DataReceiverBle dataReceiverBle ; 19 | private long mLastDataArrivalTime = 0; 20 | private Context context; 21 | 22 | public DataReceiverBle(){ 23 | //Just to ignore Manifest Error Don't use it 24 | } 25 | 26 | private DataReceiverBle(Context context) { 27 | this.context = context; 28 | } 29 | 30 | public static DataReceiverBle getInstance(Context context){ 31 | if(dataReceiverBle == null) 32 | dataReceiverBle = new DataReceiverBle(context); 33 | return dataReceiverBle ; 34 | } 35 | 36 | @Override 37 | public void onReceive(Context context, Intent intent) { 38 | final String action = intent.getAction(); 39 | Bundle extras = intent.getExtras(); 40 | if (SystemClock.elapsedRealtime() - mLastDataArrivalTime < 25) { 41 | return; 42 | } 43 | 44 | mLastDataArrivalTime = SystemClock.elapsedRealtime(); 45 | 46 | if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) { 47 | // Data Received 48 | if (extras.containsKey(Const.EXTRA_BYTE_VALUE) 49 | && extras.containsKey(Const.EXTRA_BLE_DEVICE_ADDRESS)) { 50 | 51 | byte[] array = intent.getByteArrayExtra(Const.EXTRA_BYTE_VALUE); 52 | String deviceAddress = intent.getStringExtra(Const.EXTRA_BLE_DEVICE_ADDRESS); 53 | // String deviceName = intent.getStringExtra(Const.EXTRA_BLE_DEVICE_NAME); 54 | 55 | BleFrames.getData(context, Utils.convertHexToAscci(byteToString(array))); 56 | 57 | } 58 | } 59 | } 60 | 61 | } 62 | 63 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/app/src/main/java/com/prompt/multiplebledeviceconnection/model/BLEDevice.java: -------------------------------------------------------------------------------- 1 | package com.prompt.multiplebledeviceconnection.model; 2 | 3 | import android.bluetooth.BluetoothDevice; 4 | 5 | /** 6 | * Created by root on 10/9/16. 7 | */ 8 | 9 | public class BLEDevice { 10 | private BluetoothDevice bluetoothDevice ; 11 | private boolean isConnected ; 12 | 13 | public BluetoothDevice getBluetoothDevice() { 14 | return bluetoothDevice; 15 | } 16 | 17 | public void setBluetoothDevice(BluetoothDevice bluetoothDevice) { 18 | this.bluetoothDevice = bluetoothDevice; 19 | } 20 | 21 | public boolean isConnected() { 22 | return isConnected; 23 | } 24 | 25 | public void setConnected(boolean connected) { 26 | isConnected = connected; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/app/src/main/java/com/prompt/multiplebledeviceconnection/uicomponents/MyAlertDialog.java: -------------------------------------------------------------------------------- 1 | package com.prompt.multiplebledeviceconnection.uicomponents; 2 | 3 | import android.app.Dialog; 4 | import android.content.Context; 5 | import android.view.View; 6 | import android.view.Window; 7 | import android.view.WindowManager; 8 | import android.widget.Button; 9 | import android.widget.ImageView; 10 | import android.widget.TextView; 11 | 12 | import com.prompt.multiplebledeviceconnection.R; 13 | 14 | public class MyAlertDialog extends Dialog { 15 | private Context context; 16 | private ImageView imageView; 17 | private TextView textView; 18 | private Button button; 19 | 20 | public MyAlertDialog(Context context) { 21 | super (context); 22 | this.context = context ; 23 | this.requestWindowFeature (Window.FEATURE_NO_TITLE); 24 | this.setContentView (R.layout.alert_dialog); 25 | this.getWindow ().setType (WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); 26 | this.imageView = (ImageView) this.findViewById (R.id.imgAlert); 27 | this.textView = (TextView) this.findViewById (R.id.textViewAlert); 28 | this.button = (Button) this.findViewById (R.id.buttonAlert); 29 | button.setOnClickListener (new View.OnClickListener () { 30 | @Override 31 | public void onClick(View v) { 32 | MyAlertDialog.this.dismiss (); 33 | } 34 | }); 35 | } 36 | 37 | public void setMessage(String message) { 38 | this.textView.setText (message); 39 | } 40 | 41 | public void setIcon(int icon) { 42 | this.imageView.setImageResource (icon); 43 | switch (icon) { 44 | case R.drawable.ic_alert: 45 | this.textView.setTextColor (context.getResources ().getColor (R.color.colorPrimaryDark)); 46 | break ; 47 | case R.drawable.ic_success: 48 | this.textView.setTextColor (context.getResources ().getColor (R.color.colorPrimary)); 49 | break ; 50 | default: 51 | this.textView.setTextColor (context.getResources ().getColor (R.color.colorPrimaryDark)); 52 | break ; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/app/src/main/java/com/prompt/multiplebledeviceconnection/utils/BleFrames.java: -------------------------------------------------------------------------------- 1 | package com.prompt.multiplebledeviceconnection.utils; 2 | 3 | import android.content.Context; 4 | 5 | 6 | import com.prompt.multiplebledeviceconnection.R; 7 | import com.prompt.multiplebledeviceconnection.base.BaseActivity; 8 | import com.prompt.multiplebledeviceconnection.bleUtils.OnDataReceiveInterface; 9 | 10 | import java.text.DecimalFormat; 11 | import java.text.NumberFormat; 12 | import java.util.HashMap; 13 | 14 | /** 15 | * Created by root on 19/9/16. 16 | */ 17 | 18 | public class BleFrames { 19 | 20 | 21 | private static void noDataFound(Context context){ 22 | HashMap hashMap = new HashMap<>(); 23 | hashMap.put(context.getString(R.string.something_went_wrong),context.getString(R.string.something_went_wrong)); 24 | 25 | OnDataReceiveInterface lisInterface = (OnDataReceiveInterface) context; 26 | lisInterface.onDataReceived(hashMap); 27 | } 28 | 29 | public static void getData(Context context, String data){ 30 | HashMap hashMap = new HashMap<>(); 31 | 32 | OnDataReceiveInterface lisInterface = (OnDataReceiveInterface) context; 33 | lisInterface.onDataReceived(hashMap); 34 | } 35 | 36 | 37 | } 38 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/app/src/main/java/com/prompt/multiplebledeviceconnection/utils/Const.java: -------------------------------------------------------------------------------- 1 | package com.prompt.multiplebledeviceconnection.utils; 2 | 3 | import android.Manifest; 4 | 5 | import java.math.BigDecimal; 6 | import java.text.DecimalFormat; 7 | 8 | public class Const { 9 | public static final String URL_BASE = "http://api.androidhive.info/volley/"; 10 | public static final String URL_IMAGE = "http://api.androidhive.info/volley/volley-image.jpg"; 11 | public static final String METHOD_JSON_OBJECT = "person_object.json"; 12 | public static final String METHOD_JSON_ARRAY = "person_array.json"; 13 | public static final String METHOD_STRING = "string_response.html"; 14 | 15 | 16 | public static final String DATE_YYYY_MM_DD = "yyyy-MM-dd"; 17 | public static final String DATE_DD_MM_YYYY = "dd-MM-yyyy"; 18 | 19 | 20 | public static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#.#"); 21 | public static final BigDecimal INCRE_01 = new BigDecimal("0.1"); 22 | public static final BigDecimal INCRE_1 = new BigDecimal("1"); 23 | 24 | // Storage Permissions 25 | public static final int REQUEST_EXTERNAL_STORAGE = 1; 26 | public static final String DATE_TIME = "yyyy-MM-dd hh:mm:ss"; 27 | public static final int STATUS_MT_NOT_FOUND = 1001; 28 | public static final int STATUS_DIFF_CALCULATION_TYPE = 1002; 29 | public static final int STATUS_SAME_RATE = 1003; 30 | public static final int STATUS_SUCCESS = 1111; 31 | public static final int STATUS_RECORD_NOT_FOUND = 1004; 32 | public static final int MY_PERMISSIONS_REQUEST_SEND_SMS = 0; 33 | 34 | public static String[] PERMISSIONS_STORAGE = { 35 | Manifest.permission.READ_EXTERNAL_STORAGE, 36 | Manifest.permission.WRITE_EXTERNAL_STORAGE 37 | }; 38 | 39 | public static int width; 40 | public static int height; 41 | public static final int DIALOG_DISPLAY_TIME = 1500; 42 | 43 | 44 | //Preferences name 45 | public static final String PREF_FILE = "amcs_prefs"; 46 | public static final String PREF_LOGIN = "login_status"; 47 | public static final String PREF_INSTALLATION_DETAIL = "installation_detail"; 48 | public static final String COL_IS_LOGIN = "is_login"; 49 | public static final String COL_IS_INSTALED = "is_instaled"; 50 | public static final String PREF_SOCIETY_CODE = "societyCode"; 51 | public static final String PREF_USER_ID = "userid"; 52 | public static final String PREF_DPU_TYPE = "dpuType"; 53 | public static final String PREF_DPU_MILKTYPE = "dpuMilkType"; 54 | public static final String PREF_USER_NAME = "username"; 55 | public static final String PREF_PRINTER_TYPE = "printer_type"; 56 | public static final String PREF_USER_ROLE = "userrole"; 57 | // public static final String PRINT_ENGLISH = "\u001B\u0040\u001C\u0043\u0000"; //Nirmal 58 | // public static final String PRINT_ENGLISH = "\u001B@\u001CC\u0000\u001B\u0057\u0002\u001B\u0031\u0003"; //Nirmal 59 | public static final String PREF_SSID = "ssid"; 60 | public static final String PREF_SSID_PASSWORD = "ssidPassword"; 61 | 62 | 63 | public static final String PREF_SOCIETY_ID = "SocietyId"; 64 | public static final String PREF_FINANCIAL_YEAR = "financialYear"; 65 | public static final String PREF_CONNECTION_TYPE = "connectionType"; 66 | //User Roles 67 | public static final int ADMIN = 0; 68 | public static final int SECRETARY = 1; 69 | public static final int OPERATOR = 2; 70 | public static final int TESTER = 3; 71 | public static final int USER = 4; 72 | public static final int SUPERVISOR = 5; 73 | 74 | public static int USER_ROLE = 6; 75 | 76 | public static int USER_ID = 3; 77 | public static final String ACCESS_DENIED = "Access Denied"; 78 | public static String NoOfString = "NoOfString"; 79 | 80 | public static String HardwareId = "HardwareId"; 81 | public static String UpdateSuccessMesssage = "Data Updated Sucessfully"; 82 | 83 | public static String InsertSuccessMesssage = "Data Updated Sucessfully"; 84 | public static final String strFAT = "FAT", strCLR = "CLR", strFKG = "FKG", strSNFFORMULA1 = "SNFFORMULA1", strSNFFORMULA2 = "SNFFORMULA2", 85 | strSNF = "SNF", strQTY = "QTY", strSKG = "SKG", strSKC = "SKC", strDKC = "DKC"; 86 | public static final int ID_ALERT = 8080; 87 | public static String financialYear = "1718"; 88 | 89 | //public static String financialYear = "1516"; 90 | public static String NO_HARDWARE = "No Hardware"; 91 | public static final String START = "^"; 92 | public static final String END = "$"; 93 | public static final String QUOTE = "\""; 94 | public static final String COLON = ":"; 95 | public static final String SEPARATOR = ","; 96 | 97 | public static final int PORT = 8180; 98 | public static final int ACK_NONE = 0; 99 | public static final int ACK_SUCCESS = 1; 100 | 101 | public static final int ACK_FAILURE = 2; 102 | public static final String F_1 = "F1"; 103 | public static final String F_2 = "F2"; 104 | public static final String F_3 = "F3"; 105 | public static final String F_4 = "F4"; 106 | public static final String F_5 = "F5"; 107 | public static final String F_6 = "F6"; 108 | public static final String F_7 = "F7"; 109 | 110 | 111 | public static final String F_8 = "F8"; 112 | public static final String COMPORT_DATA_REQ = "127"; 113 | public static final String COMPORT_DISP_REQ = "8"; 114 | 115 | 116 | public static final String COMPORT_PRINT_REQ = "4"; 117 | public static final int COMM_AUTO = 0; 118 | public static final int COMM_MANN = 1; 119 | 120 | public static final int COMM_REPO = 2; 121 | public static final int COMPORT_NONE = 100; 122 | public static final int COMPORT_SUCC = 101; 123 | 124 | 125 | public static final int COMPORT_FAIL = 102; 126 | public static final int HARDWARE_NONE = 200; 127 | public static final int HARDWARE_SUCC = 201; 128 | 129 | 130 | public static final int HARDWARE_FAIL = 202; 131 | public static final int SYS_SETTING_NONE = 300; 132 | public static final int SYS_SETTING_SUCC = 301; 133 | 134 | public static final int SYS_SETTING_FAIL = 302; 135 | public static final int HARDWARE_DETAIL_NONE = 400; 136 | public static final int HARDWARE_DETAIL_SUCC = 401; 137 | 138 | 139 | public static final int HARDWARE_DETAIL_FAIL = 402; 140 | public static final int WIRELESS_SETT_NONE = 500; 141 | public static final int WIRELESS_SETT_SUCC = 501; 142 | 143 | public static final int WIRELESS_SETT_FAIL = 502; 144 | public static final int TARE_RESPONCE_NONE = 600; 145 | public static final int TARE_RESPONCE_SUCC = 601; 146 | 147 | 148 | public static final int TARE_RESPONCE_FAIL = 602; 149 | public static final int KEY_GUJARATI = 2; 150 | public static final int KEY_ENGLISH = 1; 151 | 152 | 153 | 154 | public static final String PRINTER_SETT_BIG_ENGLISH = "\u001B@\u001CC\u0000\u001BW\u0003\u001B1\u0007";//TODO original 155 | public static final String PRINTER_SETT_SMALL_ENGLISH = "\u001B@\u001CC\u0000\u001BW\u0002\u001B1\u0007"; 156 | 157 | public static final String PRINTER_SETT_REPORT_ENGLISH = "\u001B@\u001CC\u0000\u001BV\u0003\u001BU\u0002\u001B1\u0007"; 158 | public static final String PRINTER_SETT_BIG_HINDI = "\u001B@\u001BC\u0001\u001BW\u0003\u001B1\u0007";//TODO original 159 | public static final String PRINTER_SETT_SMALL_HINDI = "\u001B@\u001BC\u0001\u001BW\u0002\u001B1\u0007"; 160 | 161 | 162 | public static final String PRINTER_SETT_REPORT_HINDI = "\u001B@\u001BC\u0001\u001BV\u0003\u001BU\u0002\u001B1\u0007"; 163 | public static final String PRINTER_SETT_BIG_GUJARATI = "\u001B@\u001BC\u0002\u001BW\u0003\u001B1\u0007";//TODO original 164 | public static final String PRINTER_SETT_SMALL_GUJARATI = "\u001B@\u001BC\u0002\u001BW\u0002\u001B1\u0007"; 165 | 166 | public static final String PRINTER_SETT_REPORT_GUJARATI = "\u001B@\u001BC\u0002\u001BV\u0003\u001BU\u0002\u001B1\u0007"; 167 | //TODO MilkCollection Slip setting for Skipover performance 168 | public static final String PRINTER_SKIP_OVER_SETT = "\u001B\u0043\u0001\u001B\u004E"; 169 | 170 | public static final String PRINTER_FORM_FEED = "\f"; 171 | 172 | //TODO For English 173 | public static final byte[] PRINT_ENGLISH = {0x1B, 0x40, 0x1C, 0x43, 0x00, 0x1B, 0x57, 0x03, 0x1B, 0x31, 0x07};//TODO actual 174 | public static final byte[] PRINT_ENGLISH_SMALL_B = {0x1B, 0x40, 0x1C, 0x43, 0x00, 0x1B, 0x57, 0x01, 0x1B, 0x31, 0x07};//TODO actual 175 | // public static final byte[] PRINT_ENGLISH = {0x1B, 0x40, 0x1C, 0x43, 0x00};//TODO small font 176 | 177 | //TODO for Hindi 178 | public static final byte[] PRINT_HINDI = {0x1C, 0x43, 0x01, 0x1B, 0x55, 0x01, 0x1B, 0x56, 0x02,0x1B, 0x31, 0x01}; //TODO ajay 179 | public static final byte[] PRINT_HINDI_SMALL = {0x1C, 0x43, 0x01, 0x1B, 0x55, 0x01, 0x1B, 0x56, 0x01 ,0x1B, 0x31, 0x01}; //TODO ajay 180 | //TODO For Gujarati 181 | public static final byte[] PRINT_GUJARATI = {0x1B, 0x40, 0x1C, 0x43, 0x02, 0x1B, 0x55, 0x01, 0x1B, 0x56, 0x02, 0x1B, 0x31, 0x01}; //TODO actual 182 | // public static final byte[] PRINT_GUJARATI = {0x1B, 0x40, 0x1C, 0x43, 0x02};//TODO small font 183 | public static final byte[] PRINT_GUJARATI_SMALL = {0x1B, 0x40, 0x1C, 0x43, 0x02, 0x1B, 0x55, 0x01, 0x1B, 0x56, 0x01, 0x1B, 0x31, 0x01}; 184 | 185 | // public static final String PRINT_GUJARATI = "\u001B\u0040\u001C\u0043\u0002\u001B\u0055\u0001\u001B\u0056\u0002\u001B\u0031\u0001"; 186 | 187 | /* 188 | TODO Printer Setting in HEX Format 189 | $1C$43$00 -- english language 190 | $1C$43$01 -- Hindi 191 | $1C$43$02 -- Gujarati 192 | 193 | SET BIG: 194 | 1B 40 195 | 1B 57 03 196 | 1B 31 07 197 | 198 | SET SMALL: 199 | 1B 40 200 | 1B 57 02 201 | 1B 31 07 202 | 203 | SET REPORT: 204 | 1B 40 205 | 1B 56 03 206 | 1B 55 02 207 | 1B 31 07 208 | 209 | */ 210 | public static String strType2[] = new String[5]; 211 | 212 | 213 | public static String strType9[] = new String[5]; 214 | public static final String MATRIX_KEYBOARD = "0"; 215 | public static final String SSID = "AMCS_Tablet_Test2"; 216 | 217 | public static final String PASS = "1234abcd"; 218 | 219 | public static final String PREF_OUT_OF_RANGE = "out_of_range_val"; 220 | 221 | //Prefs for BLE Address 222 | public static final String BLE_MAC1 = "BLE1"; 223 | public static final String BLE_MAC2 = "BLE2"; 224 | public static final String BLE_MAC3 = "BLE3"; 225 | public static final String BLE_MAC4 = "BLE4"; 226 | public static final String HW_BLE_MAC = "BLE_HW"; 227 | 228 | 229 | public static final String EXTRA_BYTE_VALUE = "EXTRA_BYTE_VALUE"; 230 | 231 | public static final String EXTRA_BLE_DEVICE_ADDRESS = "BLE DEVICE ADDRESS"; 232 | public static final String EXTRA_BLE_DEVICE_NAME = "BLE DEVICE NAME"; 233 | 234 | 235 | //TODO Constant for settings 236 | public static final int PRINTER_SELECT = 0; 237 | public static final int PRINTER_SERIAL = 1; 238 | public static final int PRINTER_USB = 2; 239 | 240 | public static final int DEFAULT_MILK_TYPE_SELECT = 0; 241 | public static final int DEFAULT_MILK_TYPE_COW = 1; 242 | public static final int DEFAULT_MILK_TYPE_BUFF = 2; 243 | public static final int DEFAULT_MILK_TYPE_MIX = 3; 244 | 245 | public static final int MENU_VIEW_GRID = 0; 246 | public static final int MENU_VIEW_LIST = 1; 247 | 248 | public static final String COLLECTION_TYPE_LITER = "L"; 249 | public static final String COLLECTION_TYPE_KG = "K"; 250 | 251 | public static final int MILK_RATE_TYPE_SELECT = 0; 252 | public static final int MILK_RATE_TYPE_FAT = 1; 253 | public static final int MILK_RATE_TYPE_FATLR = 2; 254 | public static final int MILK_RATE_TYPE_FATSNF = 3; 255 | public static final int MILK_RATE_TYPE_SOLID = 4; 256 | 257 | public static final int NO = 0; 258 | public static final int YES = 1; 259 | 260 | 261 | public static String STATIC_DEVICE_ID = "868981026653701"; 262 | 263 | public static final String FONTSIZE_20DP = "20"; 264 | public static final String FONTSIZE_23DP = "23"; 265 | public static final String FONTSIZE_26DP = "26"; 266 | public static final String PREF_FONTSIZE = FONTSIZE_20DP; 267 | 268 | public static final String PREF_AUTOBACKUP = "autoBackup"; 269 | public static final String PREF_LAST_BACKUP_DATE = "lastBackupDate"; 270 | 271 | 272 | public static final float DEFAULT_TEXT_SIZE= Float.parseFloat(FONTSIZE_20DP); 273 | 274 | public static String CONNECTION_MODE = "" ; 275 | public static final String WIFI = "Wifi" ; 276 | public static final String BLUETOOTH= "Bluetooth" ; 277 | public static final String BLUETOOTH_HW = "BluetoothHW" ; 278 | public static int USB_PRINTER_LINE_PER_PAGE = 65; 279 | } 280 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/app/src/main/java/com/prompt/multiplebledeviceconnection/utils/CustomExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.prompt.multiplebledeviceconnection.utils; 2 | 3 | import java.io.BufferedWriter; 4 | import java.io.File; 5 | import java.io.FileWriter; 6 | import java.io.PrintWriter; 7 | import java.io.StringWriter; 8 | import java.io.Writer; 9 | import java.lang.Thread.UncaughtExceptionHandler; 10 | 11 | public class CustomExceptionHandler implements UncaughtExceptionHandler { 12 | private UncaughtExceptionHandler defaultUEH; 13 | private String dirName; 14 | private String url; 15 | 16 | /* 17 | * if any of the parameters is null, the respective functionality 18 | * will not be used 19 | */ 20 | public CustomExceptionHandler(String dirName, String url) { 21 | this.dirName = dirName; 22 | this.url = url; 23 | this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler(); 24 | } 25 | 26 | public void uncaughtException(Thread t, Throwable e) { 27 | final Writer result = new StringWriter(); 28 | final PrintWriter printWriter = new PrintWriter(result); 29 | e.printStackTrace(printWriter); 30 | String stacktrace = result.toString(); 31 | printWriter.close(); 32 | 33 | if (dirName != null) { 34 | writeToFile(stacktrace); 35 | } 36 | defaultUEH.uncaughtException(t, e); 37 | } 38 | 39 | private void writeToFile(String stacktrace) { 40 | try { 41 | File myDir = new File(dirName.replace(" ", "") + "_Log"); 42 | if (!myDir.exists()) { 43 | myDir.mkdir(); 44 | } 45 | //Store only 10 file in device because of size. 46 | if (myDir.isDirectory() & myDir.listFiles().length > 20) { 47 | File[] filelist = myDir.listFiles(); 48 | for (int i = 0; i < filelist.length - 20; i++) { 49 | try { 50 | filelist[i].delete(); 51 | } catch (Exception e) { 52 | } 53 | } 54 | } 55 | File f = new File(myDir, Utils.getLogFileName()); 56 | FileWriter fr = new FileWriter(f); 57 | BufferedWriter bos = new BufferedWriter(fr); 58 | bos.write(stacktrace); 59 | bos.flush(); 60 | bos.close(); 61 | } catch (Exception e) { 62 | e.printStackTrace(); 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/app/src/main/java/com/prompt/multiplebledeviceconnection/utils/Logger.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Cypress Semiconductor Corporation, 2014-2015 All rights reserved. 3 | * 4 | * This software, associated documentation and materials ("Software") is 5 | * owned by Cypress Semiconductor Corporation ("Cypress") and is 6 | * protected by and subject to worldwide patent protection (UnitedStates and foreign), United States copyright laws and international 7 | * treaty provisions. Therefore, unless otherwise specified in a separate license agreement between you and Cypress, this Software 8 | * must be treated like any other copyrighted material. Reproduction, 9 | * modification, translation, compilation, or representation of this 10 | * Software in any other form (e.g., paper, magnetic, optical, silicon) 11 | * is prohibited without Cypress's express written permission. 12 | * 13 | * Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY 14 | * KIND, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 15 | * NONINFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 16 | * FOR A PARTICULAR PURPOSE. Cypress reserves the right to make changes 17 | * to the Software without notice. Cypress does not assume any liability 18 | * arising out of the application or use of Software or any product or 19 | * circuit described in the Software. Cypress does not authorize its 20 | * products for use as critical components in any products where a 21 | * malfunction or failure may reasonably be expected to result in 22 | * significant injury or death ("High Risk Product"). By including 23 | * Cypress's product in a High Risk Product, the manufacturer of such 24 | * system or application assumes all risk of such use and in doing so 25 | * indemnifies Cypress against all liability. 26 | * 27 | * Use of this Software may be limited by and subject to the applicable 28 | * Cypress software license agreement. 29 | * 30 | * 31 | */ 32 | 33 | package com.prompt.multiplebledeviceconnection.utils; 34 | 35 | import android.content.Context; 36 | import android.os.Environment; 37 | import android.util.Log; 38 | 39 | import com.prompt.multiplebledeviceconnection.R; 40 | 41 | import java.io.BufferedWriter; 42 | import java.io.File; 43 | import java.io.FileOutputStream; 44 | import java.io.IOException; 45 | import java.io.OutputStreamWriter; 46 | 47 | /** 48 | * This is a custom log class that will manage logs in the project. Using the 49 | * disableLog() all the logs can be disabled in the project during the 50 | * production stage enableLog() will allow to enable the logs , by 51 | * default the logs will be visible.
52 | * * 53 | */ 54 | public class Logger { 55 | 56 | private static String mLogTag = "CySmart Android"; 57 | private static boolean mLogflag = true; 58 | private static File mDataLoggerDirectory; 59 | private static File mDataLoggerFile; 60 | private static File mDataLoggerOldFile; 61 | private static Context mContext; 62 | 63 | public static void d(String message) { 64 | show(Log.DEBUG, mLogTag, message); 65 | 66 | } 67 | 68 | public static void d(String tag, String message) { 69 | show(Log.DEBUG, tag, message); 70 | 71 | } 72 | 73 | public static void w(String message) { 74 | show(Log.WARN, mLogTag, message); 75 | 76 | } 77 | 78 | public static void i(String message) { 79 | show(Log.INFO, mLogTag, message); 80 | 81 | } 82 | 83 | public static void e(String message) { 84 | show(Log.ERROR, mLogTag, message); 85 | 86 | } 87 | 88 | public static void v(String message) { 89 | show(Log.ERROR, mLogTag, message); 90 | 91 | } 92 | 93 | public static void datalog(String message) { 94 | // show(Log.INFO, mLogTag, message); 95 | saveLogData(message); 96 | 97 | } 98 | 99 | /** 100 | * print log for info/error/debug/warn/verbose 101 | * 102 | * @param type :
103 | * Log.INFO
104 | * Log.ERROR
105 | * Log.DEBUG
106 | * Log.WARN
107 | * Log.VERBOSE Log. 108 | */ 109 | private static void show(int type, String tag, String msg) { 110 | 111 | if (msg.length() > 4000) { 112 | Log.i("Length ", msg.length() + ""); 113 | 114 | while (msg.length() > 4000) { 115 | show(type, tag, msg.substring(0, 4000)); 116 | msg = msg.substring(4000, msg.length()); 117 | 118 | } 119 | } 120 | if (mLogflag) 121 | switch (type) { 122 | case Log.INFO: 123 | Log.i(tag, msg); 124 | break; 125 | case Log.ERROR: 126 | Log.e(tag, msg); 127 | break; 128 | case Log.DEBUG: 129 | Log.d(tag, msg); 130 | break; 131 | case Log.WARN: 132 | Log.w(tag, msg); 133 | break; 134 | case Log.VERBOSE: 135 | Log.v(tag, msg); 136 | break; 137 | case Log.ASSERT: 138 | Log.wtf(tag, msg); 139 | break; 140 | default: 141 | break; 142 | } 143 | 144 | } 145 | 146 | /** 147 | * printStackTrace for exception * 148 | */ 149 | private static void show(Exception exception) { 150 | try { 151 | if (mLogflag) 152 | exception.printStackTrace(); 153 | 154 | } catch (NullPointerException e) { 155 | Logger.show(e); 156 | } 157 | } 158 | 159 | public static boolean enableLog() { 160 | mLogflag = true; 161 | return mLogflag; 162 | } 163 | 164 | public static boolean disableLog() { 165 | mLogflag = false; 166 | return mLogflag; 167 | } 168 | 169 | public static void createDataLoggerFile(Context context) { 170 | mContext = context; 171 | try { 172 | /** 173 | * Directory 174 | */ 175 | mDataLoggerDirectory = new File(Environment.getExternalStorageDirectory() + 176 | File.separator 177 | + context.getResources().getString(R.string.dl_directory)); 178 | if (!mDataLoggerDirectory.exists()) { 179 | mDataLoggerDirectory.mkdirs(); 180 | } 181 | /** 182 | * File name 183 | */ 184 | 185 | mDataLoggerFile = new File(mDataLoggerDirectory.getAbsoluteFile() + File.separator 186 | + Utils.GetDate() + context.getResources().getString(R.string.dl_file_extension)); 187 | if (!mDataLoggerFile.exists()) { 188 | mDataLoggerFile.createNewFile(); 189 | } 190 | deleteOLDFiles(); 191 | } catch (IOException e) { 192 | e.printStackTrace(); 193 | } 194 | 195 | } 196 | 197 | public static void deleteOLDFiles() { 198 | /** 199 | * Delete old file 200 | */ 201 | File[] allFilesList = mDataLoggerDirectory.listFiles(); 202 | long cutoff = System.currentTimeMillis() - (7 * 24 * 60 * 60 * 1000); 203 | for (int pos = 0; pos < allFilesList.length; pos++) { 204 | File currentFile = allFilesList[pos]; 205 | if (currentFile.lastModified() < cutoff) { 206 | currentFile.delete(); 207 | } 208 | 209 | } 210 | mDataLoggerOldFile = new File(mDataLoggerDirectory.getAbsoluteFile() + File.separator 211 | + Utils.GetDateSevenDaysBack() + 212 | mContext.getResources().getString(R.string.dl_file_extension)); 213 | if (mDataLoggerOldFile.exists()) { 214 | mDataLoggerOldFile.delete(); 215 | } 216 | 217 | } 218 | 219 | private static void saveLogData(String message) { 220 | mDataLoggerFile = new File(mDataLoggerDirectory.getAbsoluteFile() + File.separator 221 | + Utils.GetDate() + mContext.getResources().getString(R.string.dl_file_extension)); 222 | if (!mDataLoggerFile.exists()) { 223 | try { 224 | mDataLoggerFile.createNewFile(); 225 | } catch (IOException e) { 226 | e.printStackTrace(); 227 | } 228 | } 229 | message = Utils.GetTimeandDate() + message; 230 | try { 231 | OutputStreamWriter writer = new OutputStreamWriter( 232 | new FileOutputStream(mDataLoggerFile, true), 233 | "UTF-8"); 234 | BufferedWriter fbw = new BufferedWriter(writer); 235 | fbw.write(message); 236 | fbw.newLine(); 237 | fbw.flush(); 238 | fbw.close(); 239 | 240 | } catch (IOException e) { 241 | e.printStackTrace(); 242 | } catch (Exception e) { 243 | e.printStackTrace(); 244 | } 245 | 246 | } 247 | 248 | } 249 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/app/src/main/java/com/prompt/multiplebledeviceconnection/utils/Prefs.java: -------------------------------------------------------------------------------- 1 | package com.prompt.multiplebledeviceconnection.utils; 2 | 3 | import android.content.Context; 4 | import android.content.SharedPreferences; 5 | import android.content.SharedPreferences.Editor; 6 | 7 | /** 8 | * @CreatedBy: Hiren Vaghela 9 | * @CreatedOn: 5/2/16 10 | * @purpose: In Whole application Preference value store and retrive from here. 11 | */ 12 | 13 | public class Prefs { 14 | public static SharedPreferences sharedPreferences = null; 15 | 16 | /** 17 | * @CreatedBy: Hiren Vaghela 18 | * @CreatedOn: 5/2/16 19 | * @param: Context 20 | * @purpose: open or initialize Preference 21 | * @return void. 22 | */ 23 | public static void openPrefs(Context context) { 24 | 25 | sharedPreferences = context.getSharedPreferences(Const.PREF_FILE, 26 | Context.MODE_PRIVATE); 27 | } 28 | /** 29 | * @CreatedBy: Hiren Vaghela 30 | * @CreatedOn: 5/2/16 31 | * @param: Context,String fieldName,String defaultVal. 32 | * @purpose: From field name give it value from SharedPreference. 33 | * @return String. 34 | */ 35 | public static String getvalue(Context context, String key, 36 | String defaultValue) { 37 | 38 | Prefs.openPrefs(context); 39 | 40 | String result = Prefs.sharedPreferences.getString(key, defaultValue); 41 | Prefs.sharedPreferences = null; 42 | return result; 43 | } 44 | /** 45 | * @CreatedBy: Hiren Vaghela 46 | * @CreatedOn: 5/2/16 47 | * @param: Context,String FieldName,String value 48 | * @purpose: from FieldName set it Value in SharedPreference. 49 | * @return void. 50 | */ 51 | public static void setValue(Context context, String key, String value) { 52 | Prefs.openPrefs(context); 53 | Editor preferenceEditor = Prefs.sharedPreferences.edit(); 54 | preferenceEditor.putString(key, value); 55 | preferenceEditor.commit(); 56 | preferenceEditor = null; 57 | Prefs.sharedPreferences = null; 58 | } 59 | /** 60 | * @CreatedBy: Hiren Vaghela 61 | * @CreatedOn: 5/2/16 62 | * @param: Context 63 | * @purpose: clear All Preferences. 64 | * @return void. 65 | */ 66 | public static void setClear(Context context) { 67 | Prefs.openPrefs(context); 68 | Editor preferenceEditor = Prefs.sharedPreferences.edit(); 69 | preferenceEditor.clear().commit(); 70 | preferenceEditor = null; 71 | Prefs.sharedPreferences = null; 72 | } 73 | /** 74 | * @CreatedBy: Hiren Vaghela 75 | * @CreatedOn: 5/2/16 76 | * @param: Context,String fieldName 77 | * @purpose: Remove perticular field from SharedPreferences. 78 | * @return void. 79 | */ 80 | public static void remove(Context context, String key) { 81 | Prefs.openPrefs(context); 82 | Editor preferenceEditor = Prefs.sharedPreferences.edit(); 83 | preferenceEditor.remove(key); 84 | preferenceEditor.commit(); 85 | preferenceEditor = null; 86 | Prefs.sharedPreferences = null; 87 | 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/app/src/main/java/com/prompt/multiplebledeviceconnection/utils/Utils.java: -------------------------------------------------------------------------------- 1 | package com.prompt.multiplebledeviceconnection.utils; 2 | 3 | import android.Manifest; 4 | import android.app.Activity; 5 | import android.app.ProgressDialog; 6 | import android.app.Service; 7 | import android.bluetooth.BluetoothDevice; 8 | import android.content.Context; 9 | import android.content.IntentFilter; 10 | import android.content.SharedPreferences; 11 | import android.content.pm.PackageManager; 12 | import android.graphics.Bitmap; 13 | import android.graphics.BitmapFactory; 14 | import android.graphics.Matrix; 15 | import android.graphics.drawable.BitmapDrawable; 16 | import android.graphics.drawable.Drawable; 17 | import android.net.wifi.WifiConfiguration; 18 | import android.net.wifi.WifiManager; 19 | import android.os.Build; 20 | import android.support.v4.app.ActivityCompat; 21 | import android.util.Log; 22 | import android.view.View; 23 | import android.view.WindowManager; 24 | import android.view.inputmethod.InputMethodManager; 25 | import android.widget.EditText; 26 | import android.widget.Toast; 27 | 28 | 29 | import com.prompt.multiplebledeviceconnection.R; 30 | import com.prompt.multiplebledeviceconnection.bleUtils.BluetoothLeService; 31 | 32 | import java.io.File; 33 | import java.io.IOException; 34 | import java.lang.reflect.Method; 35 | import java.net.InetAddress; 36 | import java.net.NetworkInterface; 37 | import java.net.SocketException; 38 | import java.text.DateFormat; 39 | import java.text.ParseException; 40 | import java.text.SimpleDateFormat; 41 | import java.util.ArrayList; 42 | import java.util.Calendar; 43 | import java.util.Date; 44 | import java.util.Enumeration; 45 | import java.util.Timer; 46 | import java.util.TimerTask; 47 | import java.util.UUID; 48 | 49 | public class Utils { 50 | /** 51 | * @return void. 52 | * @CreatedBy: Hiren Vaghela 53 | * @CreatedOn: 5/2/16 54 | * @purpose: It will return the date in yyyy-MM-dd format 55 | */ 56 | public static String getDate() { 57 | return new SimpleDateFormat("yyyy-MM-dd").format(new Date()); 58 | } 59 | 60 | /** 61 | * @return void. 62 | * @CreatedBy: Hiren Vaghela 63 | * @CreatedOn: 5/2/16 64 | * @param: give the format 65 | * @purpose: It will return the date in parameter format 66 | */ 67 | public static String getDate(String dateformat) { 68 | try { 69 | return new SimpleDateFormat(dateformat).format(new Date()); 70 | } catch (Exception e) { 71 | return "date not found"; 72 | } 73 | } 74 | 75 | public static String getDate(String date, String fromDateFormate, String toDateFormate) { 76 | DateFormat fromDate = new SimpleDateFormat(fromDateFormate); 77 | DateFormat toDate = new SimpleDateFormat(toDateFormate); 78 | Date mDate = null; 79 | try { 80 | mDate = fromDate.parse(date); 81 | } catch (ParseException e) { 82 | e.printStackTrace(); 83 | return Utils.getDate(toDateFormate); 84 | 85 | } catch (NullPointerException e) { 86 | e.printStackTrace(); 87 | return Utils.getDate(toDateFormate); 88 | } 89 | return toDate.format(mDate); 90 | } 91 | 92 | /** 93 | * @return void. 94 | * @CreatedBy: Hiren Vaghela 95 | * @CreatedOn: 5/2/16 96 | * @param: void 97 | * @purpose: It will return the DateTime in dd-MM-yyyy HH:mm:ss format 98 | */ 99 | public static String getDateTime() { 100 | return new SimpleDateFormat("dd-MM-yyyy HH:mm:ss").format(new Date()); 101 | } 102 | 103 | /** 104 | * @return void. 105 | * @CreatedBy: Hiren Vaghela 106 | * @CreatedOn: 5/2/16 107 | * @param: void 108 | * @purpose: It will return the DateTime in dd-MM-yyyy HH-mm-ss format 109 | */ 110 | public static String getTimestemp() { 111 | return new SimpleDateFormat("dd-MM-yyyy HH-mm-ss").format(new Date()); 112 | } 113 | 114 | public static String getDefaultTimeStemp() { 115 | return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); 116 | } 117 | 118 | /** 119 | * @return void. 120 | * @CreatedBy: Hiren Vaghela 121 | * @CreatedOn: 5/2/16 122 | * @param: Context and message 123 | * @purpose: It will show toast with long time 124 | */ 125 | public static void showToast(Context context, String text) { 126 | Toast.makeText(context, text, Toast.LENGTH_SHORT).show(); 127 | } 128 | 129 | /** 130 | * @return void. 131 | * @CreatedBy: Hiren Vaghela 132 | * @CreatedOn: 5/2/16 133 | * @param: Context and message 134 | * @purpose: It will show toast with short time 135 | */ 136 | public static void showToastShort(Context context, String text) { 137 | Toast.makeText(context, text, Toast.LENGTH_SHORT).show(); 138 | } 139 | 140 | 141 | 142 | /** 143 | * @return void. 144 | * @CreatedBy: Hiren Vaghela 145 | * @CreatedOn: 5/2/16 146 | * @param: Context 147 | * @purpose: It will give return Application Package Name. 148 | */ 149 | public static String getPackageName(Context context) { 150 | return context.getPackageName(); 151 | } 152 | 153 | /** 154 | * @return String 155 | * @CreatedBy: Hiren Vaghela 156 | * @CreatedOn: 5/2/16 157 | * @param: Context 158 | * @purpose: return backup file name with timestamp 159 | */ 160 | public static String getBackupFileName() { 161 | String path = "backup_amcs_" + Utils.getDate("ddMMyyHHmmss") + ".db"; 162 | // Log.e("Utils Backup Path",path) ; 163 | return path; 164 | } 165 | 166 | public static String getLogFileName() { 167 | String path = "AMCS_" + Utils.getDate("ddMMyyHHmmss") + ".txt"; 168 | // Log.e("Utils Backup Path",path) ; 169 | return path; 170 | } 171 | 172 | 173 | /** 174 | * @return String 175 | * @CreatedBy: Hiren Vaghela 176 | * @CreatedOn: 5/2/16 177 | * @param: int year,int month,int day 178 | * @purpose: It will convert date into String and dd-MM-yyyy formate 179 | */ 180 | public static String formatDate(int year, int month, int day, String dateformat) { 181 | Calendar cal = Calendar.getInstance(); 182 | cal.setTimeInMillis(0); 183 | cal.set(year, month, day); 184 | Date date = cal.getTime(); 185 | SimpleDateFormat sdf = new SimpleDateFormat(dateformat); 186 | return sdf.format(date); 187 | } 188 | 189 | /** 190 | * @return void. 191 | * @CreatedBy: Hiren Vaghela 192 | * @CreatedOn: 5/2/16 193 | * @param: Activity 194 | * @purpose: Checks if the app has permission to write to device storage 195 | * If the app does not has permission then the user will be prompted to grant permissions 196 | */ 197 | public static void verifyStoragePermissions(Activity activity) { 198 | // Check if we have write permission 199 | int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE); 200 | if (permission != PackageManager.PERMISSION_GRANTED) { 201 | // We don't have permission so prompt the user 202 | ActivityCompat.requestPermissions( 203 | activity, 204 | Const.PERMISSIONS_STORAGE, 205 | Const.REQUEST_EXTERNAL_STORAGE 206 | ); 207 | } 208 | } 209 | 210 | /** 211 | * @return int 212 | * @CreatedBy: Hiren Vaghela 213 | * @CreatedOn: 5/2/16 214 | * @param: void 215 | * @purpose: get the device api level 216 | */ 217 | 218 | public static int getAPILevel() { 219 | return Build.VERSION.SDK_INT; 220 | } 221 | 222 | 223 | public static String getVersionCode(Context context) { 224 | String app_ver = "sdf"; 225 | try { 226 | app_ver = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionCode + ".0"; 227 | } catch (PackageManager.NameNotFoundException e) { 228 | Log.e("Exception", e.toString()); 229 | } 230 | return app_ver; 231 | } 232 | 233 | 234 | public static Drawable resizeIcon(Context context, int drawable, int newWidth, int newHeight) { 235 | // load the origial BitMap (500 x 500 px) 236 | Bitmap bitmapOrg = BitmapFactory.decodeResource(context.getResources(), drawable); 237 | 238 | 239 | int width = bitmapOrg.getWidth(); 240 | int height = bitmapOrg.getHeight(); 241 | 242 | // calculate the scale - in this case = 0.4f 243 | float scaleWidth = ((float) newWidth) / width; 244 | float scaleHeight = ((float) newHeight) / height; 245 | Log.e("resizeIcon", "width=" + width + " height=" + height + " newWidth" + newWidth + " newHeight" + newHeight); 246 | 247 | // createa matrix for the manipulation 248 | Matrix matrix = new Matrix(); 249 | // resize the bit map 250 | matrix.postScale(scaleWidth, scaleHeight); 251 | // rotate the Bitmap 252 | 253 | // matrix.postRotate(45); 254 | 255 | // recreate the new Bitmap 256 | Bitmap resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0, 257 | width, height, matrix, true); 258 | 259 | // make a Drawable from Bitmap to allow to set the BitMap 260 | // to the ImageView, ImageButton or what ever 261 | return new BitmapDrawable(resizedBitmap); 262 | } 263 | 264 | 265 | public static String getDeviceIP(Context context) { 266 | // WifiManager wifiMgr = (WifiManager) context.getSystemService(context.WIFI_SERVICE); 267 | // WifiInfo wifiInfo = wifiMgr.getConnectionInfo(); 268 | // return Formatter.formatIpAddress(wifiInfo.getIpAddress()); 269 | 270 | 271 | ArrayList addresses = new ArrayList(); 272 | String str = "0.0.0.0"; 273 | try { 274 | for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) { 275 | NetworkInterface intf = en.nextElement(); 276 | int i = 0; 277 | for (Enumeration enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) { 278 | InetAddress inetAddress = enumIpAddr.nextElement(); 279 | if (!inetAddress.isLoopbackAddress()) { 280 | str = inetAddress.getHostAddress(); 281 | // addresses.add(inetAddress.getHostAddress().toString()); 282 | Log.e("IP Address" + i, inetAddress.getHostAddress()); 283 | // i++; 284 | } 285 | } 286 | } 287 | } catch (SocketException ex) { 288 | String LOG_TAG = null; 289 | Log.e(LOG_TAG, ex.toString()); 290 | } 291 | Log.e("DEVICE IP", str); 292 | return str;//addresses.get(0); 293 | 294 | } 295 | 296 | 297 | public static String getGuid() { 298 | return String.valueOf(UUID.randomUUID()); 299 | } 300 | 301 | 302 | 303 | 304 | 305 | public static boolean isValidDate(String input) { 306 | Date date = null; 307 | SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd-MM-yyyy"); 308 | if (null == input) { 309 | return false; 310 | } 311 | try { 312 | simpleDateFormat.setLenient(false); 313 | date = simpleDateFormat.parse(input); 314 | } catch (ParseException e) { 315 | 316 | } 317 | return date != null; 318 | 319 | } 320 | 321 | 322 | public static void hideSoftKeyboard(Activity activity) { 323 | InputMethodManager objInputMethodManager = (InputMethodManager) activity 324 | .getSystemService(Service.INPUT_METHOD_SERVICE); 325 | activity.getWindow().setSoftInputMode( 326 | WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); 327 | } 328 | 329 | public static void showSoftKeyboard(EditText editText, Activity activity){ 330 | InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); 331 | imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT); 332 | } 333 | 334 | public static double getDouble(String str) { 335 | if (str == null || str.isEmpty()) 336 | return 0.0; 337 | else{ 338 | try { 339 | return Double.parseDouble(str); 340 | }catch (NumberFormatException e){ 341 | return 0.0 ; 342 | } 343 | } 344 | } 345 | 346 | public static float getFloat(String str) { 347 | if (str == null || str.isEmpty()) 348 | return 0.0f; 349 | else{ 350 | try { 351 | return Float.parseFloat(str); 352 | }catch (NumberFormatException e){ 353 | return 0.0f; 354 | } 355 | } 356 | 357 | } 358 | 359 | public static float getRoundFloat(float f) { 360 | return (float) (Math.round(f * 10.0) / 10.0); 361 | } 362 | 363 | public static float getRoundFloat(String f) { 364 | float temp = getFloat(f); 365 | return (float) (Math.round(temp * 10.0) / 10.0); 366 | } 367 | 368 | public static int getInt(String str) { 369 | if (str == null || str.isEmpty()) 370 | return 0; 371 | else{ 372 | try{ 373 | return Integer.parseInt(str); 374 | }catch (NumberFormatException e){ 375 | return 0 ; 376 | } 377 | } 378 | } 379 | 380 | public static int getInt(Double d) { 381 | return d.intValue(); 382 | } 383 | 384 | public static void saveLogcatToFile(Context context, String activityName) { 385 | String fileName = "logcat_" + activityName + getDateTime() + ".txt"; 386 | File outputFile = new File(context.getExternalCacheDir(), fileName); 387 | try { 388 | @SuppressWarnings("unused") 389 | Process process = Runtime.getRuntime().exec("logcat -f " + outputFile.getAbsolutePath()); 390 | //Process process = Runtime.getRuntime().exec("logcat -f "+outputFile.getAbsolutePath()); 391 | } catch (IOException e) { 392 | e.printStackTrace(); 393 | } 394 | } 395 | 396 | public static void getIpAddress() { 397 | String ip = ""; 398 | try { 399 | Enumeration enumNetworkInterfaces = NetworkInterface 400 | .getNetworkInterfaces(); 401 | while (enumNetworkInterfaces.hasMoreElements()) { 402 | NetworkInterface networkInterface = enumNetworkInterfaces 403 | .nextElement(); 404 | Enumeration enumInetAddress = networkInterface 405 | .getInetAddresses(); 406 | while (enumInetAddress.hasMoreElements()) { 407 | InetAddress inetAddress = enumInetAddress.nextElement(); 408 | 409 | if (inetAddress.isSiteLocalAddress()) { 410 | ip += "SiteLocalAddress: " 411 | + inetAddress.getHostAddress() + "\n"; 412 | } 413 | 414 | } 415 | 416 | } 417 | 418 | } catch (SocketException e) { 419 | // TODO Auto-generated catch block 420 | e.printStackTrace(); 421 | ip += "Something Wrong! " + e.toString() + "\n"; 422 | } 423 | 424 | } 425 | 426 | private static int countLines(String str) { 427 | String[] lines = str.split("\r\n|\r|\n"); 428 | return lines.length; 429 | } 430 | 431 | // public static ArrayList chunk_split(String original, int length, boolean isUsb) throws IOException { 432 | // int start = 0, curr = length, index = 0; 433 | //// for (index = 0; index < getInt(BaseActivity.SETTINGS.get(BaseActivity.NoOfBlankLines)); index++) { 434 | //// original += BaseActivity.NEW_LINE; 435 | //// } 436 | // 437 | // int count = 0; 438 | // for (index = 0; index < original.length() && countLines(original) > 60; index++) { 439 | // if (original.charAt(index) == '\n' && count >= 60) { 440 | // count = 0; 441 | // String end = original.substring(index + 1); 442 | // original = original.substring(0, index) + Const.PRINTER_FORM_FEED + end; 443 | // 444 | // } else if (original.charAt(index) == '\n') { 445 | // count++; 446 | // } 447 | // } 448 | // 449 | // int data_length = original.length(); 450 | // ArrayList full_buffer = new ArrayList(); 451 | // 452 | // while ((start + 1) < data_length) { 453 | // if (curr > data_length) { 454 | // curr = data_length - 1; 455 | // full_buffer.add(original.substring(start, curr)); 456 | // } else { 457 | // String temp = original.substring(start, curr); 458 | // int lastOccureIndex = temp.lastIndexOf(BaseActivity.NEW_LINE); 459 | // if (temp.contains(Const.PRINTER_FORM_FEED)) { 460 | // lastOccureIndex = temp.lastIndexOf(Const.PRINTER_FORM_FEED); 461 | // lastOccureIndex++; 462 | // } 463 | // curr = start + lastOccureIndex; 464 | // full_buffer.add(original.substring(start, curr)); 465 | // } 466 | // start = curr; 467 | // curr += length; 468 | // } 469 | // 470 | // return full_buffer; 471 | // } 472 | 473 | 474 | 475 | public static String getDashedLine(int charPrLine) { 476 | //21 for big font printer 477 | //31 for small font printer 478 | String str = ""; 479 | for (int i = 0; i < charPrLine; i++) 480 | str += "-"; 481 | return str; 482 | } 483 | 484 | public static String getSpaceChar(int noOfSpace) { 485 | String str = ""; 486 | for (int i = 0; i < noOfSpace; i++) 487 | str += " "; 488 | return str; 489 | } 490 | 491 | public static void clearError(EditText edt) { 492 | if (!edt.getText().toString().isEmpty() && edt.getError() != null) { 493 | edt.setError(null); 494 | } 495 | } 496 | 497 | public static void hideSoftKeyboard(Context context, View view) { 498 | InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); 499 | imm.hideSoftInputFromWindow(view.getWindowToken(), 0); 500 | } 501 | 502 | 503 | 504 | 505 | public static String getLanguageParse(String str) { 506 | switch (str) { 507 | case "1": 508 | return "en"; 509 | case "2": 510 | return "hi"; 511 | case "3": 512 | return "gu"; 513 | default: 514 | return str; 515 | } 516 | } 517 | 518 | 519 | public static String getLanguageSlipParse(String str) { 520 | switch (str) { 521 | case "0": 522 | return "en"; 523 | case "1": 524 | return "gu"; 525 | case "2": 526 | return "hi"; 527 | default: 528 | return "en"; 529 | } 530 | } 531 | 532 | 533 | public static String convertToUnicode(String str, String printSlipLanguage) { 534 | 535 | StringBuilder retStr = new StringBuilder(); 536 | if (printSlipLanguage.equalsIgnoreCase("1")) { 537 | for (int i = 0; i < str.length(); i++) { 538 | 539 | //TODO Selected Language is GUJARATI 540 | int cp = Character.codePointAt(str, i); 541 | int charCount = Character.charCount(cp); 542 | if (charCount > 1) { 543 | i += charCount - 1; // 2. 544 | if (i >= str.length()) { 545 | throw new IllegalArgumentException("truncated unexpectedly"); 546 | } 547 | } 548 | 549 | if (cp == ' ') 550 | retStr.append("20"); 551 | else if (cp == '.') 552 | retStr.append("0AE4"); 553 | else if (cp == ':') 554 | retStr.append("0AF0"); 555 | else if (cp == '-') 556 | retStr.append("0AE1"); 557 | else if (cp == '(') 558 | retStr.append("0ADE"); 559 | else if (cp == ')') 560 | retStr.append("0ADF"); 561 | else if (cp == '\n') 562 | retStr.append("0d"); 563 | else 564 | retStr.append(String.format("0%x", cp)); 565 | } 566 | retStr.append("0d"); 567 | } else if (printSlipLanguage.equalsIgnoreCase("2")) { 568 | //TODO Selected Language is HINDI 569 | for (int i = 0; i < str.length(); i++) { 570 | int cp = Character.codePointAt(str, i); 571 | int charCount = Character.charCount(cp); 572 | if (charCount > 1) { 573 | i += charCount - 1; // 2. 574 | if (i >= str.length()) { 575 | throw new IllegalArgumentException("truncated unexpectedly"); 576 | } 577 | } 578 | if (cp == ' ') 579 | retStr.append("20"); 580 | else if (cp == '.') 581 | retStr.append("0978"); 582 | else if (cp == ':') 583 | retStr.append("0903"); 584 | else if (cp == '-') 585 | retStr.append("0970"); 586 | else if (cp == '(') 587 | retStr.append("097E"); 588 | else if (cp == ')') 589 | retStr.append("097F"); 590 | else if (cp == '\n') 591 | retStr.append("0d0a"); 592 | else 593 | retStr.append(String.format("0%x", cp)); 594 | } 595 | retStr.append("0d0a"); 596 | } 597 | 598 | return retStr.toString(); 599 | } 600 | 601 | public static String convertToUnicodeAddBlankLine(String str, String printSlipLanguage, String moreLine) { 602 | 603 | StringBuilder retStr = new StringBuilder(); 604 | int mMoreLine = getInt(moreLine); 605 | if (printSlipLanguage.equalsIgnoreCase("1")) { 606 | for (int i = 0; i < str.length(); i++) { 607 | 608 | //TODO Selected Language is GUJARATI 609 | int cp = Character.codePointAt(str, i); 610 | int charCount = Character.charCount(cp); 611 | if (charCount > 1) { 612 | i += charCount - 1; // 2. 613 | if (i >= str.length()) { 614 | throw new IllegalArgumentException("truncated unexpectedly"); 615 | } 616 | } 617 | 618 | if (cp == ' ') 619 | retStr.append("20"); 620 | else if (cp == '.') 621 | retStr.append("0AE4"); 622 | else if (cp == ':') 623 | retStr.append("0AF0"); 624 | else if (cp == '-') 625 | retStr.append("0AE1"); 626 | else if (cp == '(') 627 | retStr.append("0ADE"); 628 | else if (cp == ')') 629 | retStr.append("0ADF"); 630 | /*else if (cp == '\r') 631 | Log.e("Test","Test") ;*/ 632 | else if (cp == '\n') 633 | retStr.append("0d"); 634 | else 635 | retStr.append(String.format("0%x", cp)); 636 | } 637 | retStr.append("0d"); 638 | } else if (printSlipLanguage.equalsIgnoreCase("2")) { 639 | //TODO Selected Language is HINDI 640 | for (int i = 0; i < str.length(); i++) { 641 | int cp = Character.codePointAt(str, i); 642 | int charCount = Character.charCount(cp); 643 | if (charCount > 1) { 644 | i += charCount - 1; // 2. 645 | if (i >= str.length()) { 646 | throw new IllegalArgumentException("truncated unexpectedly"); 647 | } 648 | } 649 | if (cp == ' ') 650 | retStr.append("20"); 651 | else if (cp == '.') 652 | retStr.append("0978"); 653 | else if (cp == ':') 654 | retStr.append("0903"); 655 | else if (cp == '-') 656 | retStr.append("0970"); 657 | else if (cp == '(') 658 | retStr.append("097E"); 659 | else if (cp == ')') 660 | retStr.append("097F"); 661 | else if (cp == '\n') 662 | retStr.append("0d0a"); 663 | else 664 | retStr.append(String.format("0%x", cp)); 665 | } 666 | retStr.append("0d0a"); 667 | for (int count = 0; count < mMoreLine; count++) { 668 | retStr.append("0d0a"); 669 | } 670 | } 671 | /* int mMoreLine = getInt(moreLine); 672 | for (int count = 0; count < mMoreLine; count++) { 673 | retStr.append("0d0a"); 674 | }*/ 675 | return retStr.toString(); 676 | } 677 | 678 | 679 | public static boolean setSsidAndPassword(Context context, String ssid, String ssidPassword) { 680 | try { 681 | WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); 682 | Method getConfigMethod = wifiManager.getClass().getMethod("getWifiApConfiguration"); 683 | WifiConfiguration wifiConfig = (WifiConfiguration) getConfigMethod.invoke(wifiManager); 684 | 685 | wifiConfig.SSID = ssid; 686 | wifiConfig.preSharedKey = ssidPassword; 687 | 688 | Method setConfigMethod = wifiManager.getClass().getMethod("setWifiApConfiguration", WifiConfiguration.class); 689 | setConfigMethod.invoke(wifiManager, wifiConfig); 690 | 691 | return true; 692 | } catch (Exception e) { 693 | e.printStackTrace(); 694 | return false; 695 | } 696 | } 697 | 698 | /** 699 | * Adding the necessary INtent filters for Broadcast receivers 700 | * 701 | * @return {@link IntentFilter} 702 | */ 703 | 704 | public static IntentFilter makeGattConnectIntentFilter() { 705 | final IntentFilter intentFilter = new IntentFilter(); 706 | intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED); 707 | intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED); 708 | intentFilter.addAction(BluetoothLeService.ACTION_MTU_EXCHANGE); 709 | return intentFilter; 710 | } 711 | 712 | public static IntentFilter makeGattServiceDiscoveryIntentFilter() { 713 | final IntentFilter intentFilter = new IntentFilter(); 714 | intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED); 715 | intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICE_DISCOVERY_UNSUCCESSFUL); 716 | return intentFilter; 717 | } 718 | 719 | 720 | public static IntentFilter makeGattUpdateIntentFilter() { 721 | final IntentFilter intentFilter = new IntentFilter(); 722 | intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE); 723 | return intentFilter; 724 | } 725 | 726 | public static String ByteArraytoHex(byte[] bytes) { 727 | if (bytes != null) { 728 | StringBuilder sb = new StringBuilder(); 729 | for (byte b : bytes) { 730 | sb.append(String.format("%02X ", b)); 731 | } 732 | return sb.toString(); 733 | } 734 | return ""; 735 | } 736 | 737 | // Shared preference constant 738 | private static final String SHARED_PREF_NAME = "CySmart Shared Preference"; 739 | private static ProgressDialog mProgressDialog; 740 | private static Timer mTimer; 741 | 742 | 743 | /** 744 | * Get the date 745 | * 746 | * @return {@link String} 747 | */ 748 | public static String GetDate() { 749 | SimpleDateFormat formatter = new SimpleDateFormat("dd-MMM-yyyy"); 750 | Calendar calendar = Calendar.getInstance(); 751 | return formatter.format(calendar.getTime()); 752 | 753 | } 754 | 755 | 756 | /** 757 | * Get the seven days before date 758 | * 759 | * @return {@link String} 760 | */ 761 | 762 | public static String GetDateSevenDaysBack() { 763 | DateFormat formatter = new SimpleDateFormat("dd_MMM_yyyy"); 764 | Calendar calendar = Calendar.getInstance(); 765 | calendar.add(Calendar.DAY_OF_YEAR, -7); 766 | return formatter.format(calendar.getTime()); 767 | 768 | } 769 | 770 | /** 771 | * Get the time from milliseconds 772 | * 773 | * @return {@link String} 774 | */ 775 | public static String GetTimeFromMilliseconds() { 776 | DateFormat formatter = new SimpleDateFormat("HH:mm ss SSS"); 777 | Calendar calendar = Calendar.getInstance(); 778 | return formatter.format(calendar.getTime()); 779 | 780 | } 781 | 782 | /** 783 | * Get time and date 784 | * 785 | * @return {@link String} 786 | */ 787 | 788 | public static String GetTimeandDate() { 789 | DateFormat formatter = new SimpleDateFormat("[dd-MMM-yyyy|HH:mm:ss]"); 790 | Calendar calendar = Calendar.getInstance(); 791 | return formatter.format(calendar.getTime()); 792 | 793 | } 794 | 795 | 796 | public static boolean getBooleanSharedPreference(Context context, 797 | String key) { 798 | boolean value; 799 | SharedPreferences Preference = context.getSharedPreferences( 800 | SHARED_PREF_NAME, Context.MODE_PRIVATE); 801 | value = Preference.getBoolean(key, false); 802 | return value; 803 | } 804 | 805 | public static void bondingProgressDialog(final Activity context, ProgressDialog pDialog, 806 | boolean status) { 807 | mProgressDialog = pDialog; 808 | if (status) { 809 | mProgressDialog.setTitle(context.getResources().getString( 810 | R.string.alert_message_bonding_title)); 811 | mProgressDialog.setMessage((context.getResources().getString( 812 | R.string.alert_message_bonding_message))); 813 | mProgressDialog.setCancelable(false); 814 | mProgressDialog.show(); 815 | mTimer = setDialogTimer(); 816 | 817 | } else { 818 | mProgressDialog.dismiss(); 819 | } 820 | 821 | } 822 | 823 | public static Timer setDialogTimer() { 824 | Logger.e("Started Timer"); 825 | long delayInMillis = 20000; 826 | Timer timer = new Timer(); 827 | timer.schedule(new TimerTask() { 828 | @Override 829 | public void run() { 830 | if (mProgressDialog != null && mProgressDialog.isShowing()) 831 | mProgressDialog.dismiss(); 832 | } 833 | }, delayInMillis); 834 | return timer; 835 | } 836 | 837 | public static void stopDialogTimer() { 838 | if (mTimer != null) { 839 | Logger.e("Stopped Timer"); 840 | mTimer.cancel(); 841 | } 842 | } 843 | 844 | public static String getBleAddress(BluetoothDevice device) { 845 | return device.getAddress().toLowerCase(); 846 | } 847 | 848 | public static String convertHexToAscci(String hexValue) { 849 | StringBuilder output = new StringBuilder(""); 850 | try { 851 | for (int i = 0; i < hexValue.length(); i += 2) { 852 | String str = hexValue.substring(i, i + 2); 853 | output.append((char) Integer.parseInt(str, 16)); 854 | } 855 | } catch (Exception e) { 856 | e.printStackTrace(); 857 | } 858 | 859 | return output.toString(); 860 | 861 | } 862 | 863 | public static String byteToString(byte[] array) { 864 | StringBuffer sb = new StringBuffer(); 865 | for (byte byteChar : array) { 866 | sb.append(String.format("%02x", byteChar)); 867 | } 868 | 869 | return sb.toString(); 870 | } 871 | 872 | public static String addDay(String date, String format, int add) { 873 | try { 874 | DateFormat dateFormat = new SimpleDateFormat(format); 875 | Date mDate = null; 876 | mDate = dateFormat.parse(date); 877 | Calendar cal = Calendar.getInstance(); 878 | cal.setTime(mDate); 879 | cal.add(Calendar.DATE, add); 880 | Date newDate = cal.getTime(); 881 | return dateFormat.format(newDate); 882 | } catch (ParseException e) { 883 | e.printStackTrace(); 884 | } 885 | return date; 886 | 887 | } 888 | 889 | 890 | 891 | 892 | public static boolean isActivityFinish(Context context) { 893 | if(context == null) 894 | return true ; 895 | Activity activity = (Activity)context ; 896 | return activity.isFinishing() || activity.isDestroyed(); 897 | } 898 | 899 | public static long daysBetween(String strBackUpdate) { 900 | 901 | Date backUpDate = null ; 902 | Date curentDate = null; 903 | try { 904 | curentDate = new SimpleDateFormat("yyyy-MM-dd").parse(Utils.getDate()); 905 | backUpDate = new SimpleDateFormat("yyyy-MM-dd").parse(strBackUpdate); 906 | } catch (ParseException e) { 907 | e.printStackTrace(); 908 | } 909 | 910 | long difference = (curentDate.getTime()-backUpDate.getTime())/86400000; 911 | return Math.abs(difference); 912 | } 913 | 914 | 915 | } 916 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/app/src/main/res/anim/push_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | 14 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/app/src/main/res/anim/push_right.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 13 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/app/src/main/res/anim/slide_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | 14 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/app/src/main/res/anim/slide_right.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | 14 | -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/app/src/main/res/drawable/ic_alert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/promptsoft/Android_BLE/c75f6a816341d55b2d54c6a2d4c299fdfc436675/MultipleBLEDeviceConnection/app/src/main/res/drawable/ic_alert.png -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/app/src/main/res/drawable/ic_success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/promptsoft/Android_BLE/c75f6a816341d55b2d54c6a2d4c299fdfc436675/MultipleBLEDeviceConnection/app/src/main/res/drawable/ic_success.png -------------------------------------------------------------------------------- /MultipleBLEDeviceConnection/app/src/main/res/layout/activity_device_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 19 | 20 | 26 | 32 | 33 | 39 | 40 | 46 | 47 |