├── 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 |
46 |
47 |
48 | $USER_HOME$/.subversion
49 |
50 |
51 |
52 |
53 |
54 | 1.8
55 |
56 |
57 |
58 |
59 |
60 |
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 |
5 |
6 |
7 |
8 |
9 |
10 |
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 |
56 |
65 |
72 |
--------------------------------------------------------------------------------
/MultipleBLEDeviceConnection/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
15 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/MultipleBLEDeviceConnection/app/src/main/res/layout/alert_dialog.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
15 |
20 |
21 |
22 |
23 |
32 |
33 |
38 |
39 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/MultipleBLEDeviceConnection/app/src/main/res/layout/dialog_selection.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
15 |
16 |
25 |
26 |
33 |
34 |
46 |
47 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/MultipleBLEDeviceConnection/app/src/main/res/layout/listitem_autoconnect_device.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
15 |
16 |
25 |
26 |
35 |
36 |
37 |
44 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/MultipleBLEDeviceConnection/app/src/main/res/layout/listitem_device.xml:
--------------------------------------------------------------------------------
1 |
16 |
22 |
23 |
28 |
29 |
38 |
39 |
48 |
49 |
50 |
55 |
56 |
63 |
64 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/MultipleBLEDeviceConnection/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/promptsoft/Android_BLE/c75f6a816341d55b2d54c6a2d4c299fdfc436675/MultipleBLEDeviceConnection/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/MultipleBLEDeviceConnection/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/promptsoft/Android_BLE/c75f6a816341d55b2d54c6a2d4c299fdfc436675/MultipleBLEDeviceConnection/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/MultipleBLEDeviceConnection/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/promptsoft/Android_BLE/c75f6a816341d55b2d54c6a2d4c299fdfc436675/MultipleBLEDeviceConnection/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/MultipleBLEDeviceConnection/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/promptsoft/Android_BLE/c75f6a816341d55b2d54c6a2d4c299fdfc436675/MultipleBLEDeviceConnection/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/MultipleBLEDeviceConnection/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/promptsoft/Android_BLE/c75f6a816341d55b2d54c6a2d4c299fdfc436675/MultipleBLEDeviceConnection/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/MultipleBLEDeviceConnection/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/promptsoft/Android_BLE/c75f6a816341d55b2d54c6a2d4c299fdfc436675/MultipleBLEDeviceConnection/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/MultipleBLEDeviceConnection/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/promptsoft/Android_BLE/c75f6a816341d55b2d54c6a2d4c299fdfc436675/MultipleBLEDeviceConnection/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/MultipleBLEDeviceConnection/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/promptsoft/Android_BLE/c75f6a816341d55b2d54c6a2d4c299fdfc436675/MultipleBLEDeviceConnection/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/MultipleBLEDeviceConnection/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/promptsoft/Android_BLE/c75f6a816341d55b2d54c6a2d4c299fdfc436675/MultipleBLEDeviceConnection/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/MultipleBLEDeviceConnection/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/promptsoft/Android_BLE/c75f6a816341d55b2d54c6a2d4c299fdfc436675/MultipleBLEDeviceConnection/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/MultipleBLEDeviceConnection/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 | #FFFFFF
7 | #0000FF
8 |
9 |
--------------------------------------------------------------------------------
/MultipleBLEDeviceConnection/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | MultipleBLEDeviceConnection
3 | " , "
4 | Connection established
5 | Disconnected
6 | Connection establishing
7 | Service discovery status
8 | " - Success"
9 | " - Failed with error code : "
10 | "[%1$s | %2$s] %3$s request completed, MTU: %4$d, Status: %5$d"
11 | "Exchange GATT MTU"
12 | Write request sent with value
13 | Connection request sent
14 | Disconnection request sent
15 | Service discovery request sent
16 | .txt
17 | Bonding
18 | MultipleBLE
19 | Bonding is in process \nPlease wait..
20 | Something went wrong
21 | BLE Device disconnected
22 | OK
23 | Alert message
24 | Please wait...
25 | Cancel
26 | Successfully connected to the Device
27 | The BLE device is connected
28 | No Device Found
29 | Please Turn Bluetooth ON
30 | Bluetooth turned on successfully
31 | Bluetooth Low Energy not supported on device
32 | Bluetooth not supported on device
33 | Device Connection
34 | Connecting to the device
35 | Please wait..
36 | Cannot connect to the device
37 | Service Discovery
38 | Discovering services. Please wait.
39 | Reconnecting to device. Please wait.
40 | Device signal strength
41 | Unknown Device
42 |
43 |
--------------------------------------------------------------------------------
/MultipleBLEDeviceConnection/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/MultipleBLEDeviceConnection/app/src/test/java/com/prompt/multiplebledeviceconnection/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.prompt.multiplebledeviceconnection;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/MultipleBLEDeviceConnection/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.3.2'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | }
19 | }
20 |
21 | task clean(type: Delete) {
22 | delete rootProject.buildDir
23 | }
24 |
--------------------------------------------------------------------------------
/MultipleBLEDeviceConnection/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/MultipleBLEDeviceConnection/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/promptsoft/Android_BLE/c75f6a816341d55b2d54c6a2d4c299fdfc436675/MultipleBLEDeviceConnection/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/MultipleBLEDeviceConnection/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 09 15:23:04 IST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
7 |
--------------------------------------------------------------------------------
/MultipleBLEDeviceConnection/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/MultipleBLEDeviceConnection/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/MultipleBLEDeviceConnection/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Multiple BLE Device Connection
2 | This test app demonstrate how to connect and communicate android app with multiple BLE devices using BluetoothLeGatt interface.
3 |
4 | # Prerequisites
5 | 1.Android Device with android 4.4.2 and above
6 | 2.Bluetooth Low Energy Device which can work in Peripheral Module.
7 |
8 | # Installation
9 | 1.Import project in Android Studio.
10 | 2.Please verify that application have BLUETOOTH and BLUETOOTH_ADMIN permission in menifest file.
11 |
12 | If Android Device has Marshmallow or above version then add extra permissions of LOCATION and GPS.
13 |
14 | Currently this app supports connection with 2 BLE devices but we can add connection upto 4-7 devices (most device support 4 connection at a time) by implementing BluetoothLeGatt callback method. Each callback method stands for one BLE connection.
15 |
16 |
17 | Please modify class BluetoothLeSevice to add more BLE devices connection.
18 |
--------------------------------------------------------------------------------