Update samples prebuilts for lmp-mr1-ub-docs
Synced to developers/samples/android commit 54bab34b386e343e9d0ea75a5fb8d13db2c71eb5. Change-Id: I1c9d9d2c1f53a051d7b4d85303d5c01ab6f16e68
@@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright 2013 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.example.android.bluetoothadvertisements"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
|
||||
<uses-permission android:name="android.permission.BLUETOOTH"/>
|
||||
|
||||
<application android:allowBackup="true"
|
||||
android:label="@string/app_name"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:theme="@style/AppTheme">
|
||||
|
||||
<activity android:name=".MainActivity"
|
||||
android:label="@string/app_name">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
10
samples/browseable/BluetoothAdvertisements/_index.jd
Normal file
@@ -0,0 +1,10 @@
|
||||
page.tags="BluetoothAdvertisements"
|
||||
sample.group=Connectivity
|
||||
@jd:body
|
||||
|
||||
<p>
|
||||
|
||||
This samples demonstrates how to use the Bluetooth Low Power Advertisements API
|
||||
with a single device acting as both scanner and advertiser.
|
||||
|
||||
</p>
|
||||
|
After Width: | Height: | Size: 663 B |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 196 B |
|
After Width: | Height: | Size: 508 B |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 895 B |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 11 KiB |
55
samples/browseable/BluetoothAdvertisements/res/layout/activity_main.xml
Executable file
@@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2013 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:id="@+id/sample_main_layout">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/scanner_fragment_container"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0px" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/error_textview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:freezesText="true" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/advertiser_fragment_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<!--<fragment-->
|
||||
<!--android:name="com.example.android.bluetoothadvertisements.ScannerFragment"-->
|
||||
<!--android:id="@+id/scanner_fragment"-->
|
||||
<!--android:layout_width="match_parent"-->
|
||||
<!--android:layout_height="wrap_content" />-->
|
||||
|
||||
<!--<fragment-->
|
||||
<!--android:name="com.example.android.bluetoothadvertisements.AdvertiserFragment"-->
|
||||
<!--android:id="@+id/advertiser_fragment"-->
|
||||
<!--android:layout_width="match_parent"-->
|
||||
<!--android:layout_height="wrap_content" />-->
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2013 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:context="com.example.android.bluetoothadvertisements.AdvertiserFragment">
|
||||
|
||||
<!-- Horizontal Divider -->
|
||||
<View
|
||||
android:layout_width="250dp"
|
||||
android:layout_height="1dp"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:background="@android:color/darker_gray"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_centerInParent="true"
|
||||
android:paddingTop="20dp"
|
||||
android:paddingBottom="20dp" >
|
||||
|
||||
<TextView
|
||||
android:text="@string/broadcast_device"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:minWidth="100dp"
|
||||
android:padding="5dp"/>
|
||||
|
||||
<Switch
|
||||
android:id="@+id/advertise_switch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:switchMinWidth="80dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2013 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="20dp"
|
||||
android:paddingLeft="100dp"
|
||||
android:paddingRight="100dp">
|
||||
<TextView android:id="@+id/device_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="16dp"/>
|
||||
|
||||
<TextView android:id="@+id/device_address"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="12dp"/>
|
||||
<TextView android:id="@+id/last_seen"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="12dp"/>
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:id="@+id/refresh"
|
||||
android:title="@string/refresh"
|
||||
android:showAsAction="always"
|
||||
android:icon="@drawable/ic_action_refresh"
|
||||
/>
|
||||
</menu>
|
||||
@@ -0,0 +1,24 @@
|
||||
<!--
|
||||
Copyright 2013 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
|
||||
<!-- Semantic definitions -->
|
||||
|
||||
<dimen name="horizontal_page_margin">@dimen/margin_huge</dimen>
|
||||
<dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
|
||||
|
||||
</resources>
|
||||
@@ -0,0 +1,25 @@
|
||||
<!--
|
||||
Copyright 2013 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
|
||||
<style name="Widget.SampleMessage">
|
||||
<item name="android:textAppearance">?android:textAppearanceLarge</item>
|
||||
<item name="android:lineSpacingMultiplier">1.2</item>
|
||||
<item name="android:shadowDy">-6.5</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
@@ -0,0 +1,22 @@
|
||||
<!--
|
||||
Copyright 2013 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
|
||||
<!-- Activity themes -->
|
||||
<style name="Theme.Base" parent="android:Theme.Holo.Light" />
|
||||
|
||||
</resources>
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright 2013 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
|
||||
<color name="colorPrimary">#434AB3</color>
|
||||
<color name="colorPrimaryDark">#34379D</color>
|
||||
<color name="textColorPrimary">#FFFFFF</color>
|
||||
|
||||
</resources>
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright 2013 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
|
||||
<!-- Activity themes -->
|
||||
<style name="Theme.Base" parent="android:Theme.Material.Light">
|
||||
<item name="android:colorPrimary">@color/colorPrimary</item>
|
||||
<item name="android:colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="android:textColorPrimary">@color/textColorPrimary</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright 2013 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<resources>
|
||||
<string name="app_name">BluetoothAdvertisements</string>
|
||||
<string name="intro_message">
|
||||
<![CDATA[
|
||||
|
||||
|
||||
This samples demonstrates how to use the Bluetooth Low Power Advertisements API
|
||||
with a single device acting as both scanner and advertiser.
|
||||
|
||||
|
||||
]]>
|
||||
</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="bt_not_enabled_leaving">User declined to enable Bluetooth, exiting Bluetooth Advertisements.</string>
|
||||
<string name="activity_main_title">Nearby Devices</string>
|
||||
<string name="broadcast_device">Broadcast Device</string>
|
||||
|
||||
<string name="bt_not_supported">Bluetooth is not supported on this device.</string>
|
||||
<string name="bt_ads_not_supported">Bluetooth Advertisements are not supported on this device.</string>
|
||||
|
||||
<string name="refresh">Refresh</string>
|
||||
<string name="start_error_prefix">Start Advertising failed: </string>
|
||||
<string name="start_error_already_started">already started.</string>
|
||||
<string name="start_error_too_large">data packet exceeded 31 Byte limit.</string>
|
||||
<string name="start_error_unsupported">not supported on this device.</string>
|
||||
<string name="start_error_internal">internal error.</string>
|
||||
<string name="start_error_too_many">too many advertisers.</string>
|
||||
<string name="bt_null">Error: Bluetooth object null</string>
|
||||
<string name="last_seen">Last Seen:</string>
|
||||
<string name="just_now">just now</string>
|
||||
<string name="minute_ago">minute ago</string>
|
||||
<string name="hour_ago">hour ago</string>
|
||||
<string name="seconds_ago">seconds ago</string>
|
||||
<string name="minutes_ago">minutes ago</string>
|
||||
<string name="hours_ago">hours ago</string>
|
||||
<string name="empty_list">No devices found - refresh to try again.</string>
|
||||
<string name="seconds">seconds.</string>
|
||||
<string name="scan_start_toast">Scanning for</string>
|
||||
<string name="already_scanning">Scanning already started.</string>
|
||||
|
||||
</resources>
|
||||
@@ -0,0 +1,32 @@
|
||||
<!--
|
||||
Copyright 2013 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
|
||||
<!-- Define standard dimensions to comply with Holo-style grids and rhythm. -->
|
||||
|
||||
<dimen name="margin_tiny">4dp</dimen>
|
||||
<dimen name="margin_small">8dp</dimen>
|
||||
<dimen name="margin_medium">16dp</dimen>
|
||||
<dimen name="margin_large">32dp</dimen>
|
||||
<dimen name="margin_huge">64dp</dimen>
|
||||
|
||||
<!-- Semantic definitions -->
|
||||
|
||||
<dimen name="horizontal_page_margin">@dimen/margin_medium</dimen>
|
||||
<dimen name="vertical_page_margin">@dimen/margin_medium</dimen>
|
||||
|
||||
</resources>
|
||||
@@ -0,0 +1,42 @@
|
||||
<!--
|
||||
Copyright 2013 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
|
||||
<!-- Activity themes -->
|
||||
|
||||
<style name="Theme.Base" parent="android:Theme.Light" />
|
||||
|
||||
<style name="Theme.Sample" parent="Theme.Base" />
|
||||
|
||||
<style name="AppTheme" parent="Theme.Sample" />
|
||||
<!-- Widget styling -->
|
||||
|
||||
<style name="Widget" />
|
||||
|
||||
<style name="Widget.SampleMessage">
|
||||
<item name="android:textAppearance">?android:textAppearanceMedium</item>
|
||||
<item name="android:lineSpacingMultiplier">1.1</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.SampleMessageTile">
|
||||
<item name="android:background">@drawable/tile</item>
|
||||
<item name="android:shadowColor">#7F000000</item>
|
||||
<item name="android:shadowDy">-3.5</item>
|
||||
<item name="android:shadowRadius">2</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
@@ -0,0 +1,190 @@
|
||||
package com.example.android.bluetoothadvertisements;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.le.AdvertiseCallback;
|
||||
import android.bluetooth.le.AdvertiseData;
|
||||
import android.bluetooth.le.AdvertiseSettings;
|
||||
import android.bluetooth.le.BluetoothLeAdvertiser;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Switch;
|
||||
import android.widget.Toast;
|
||||
|
||||
/**
|
||||
* Allows user to start & stop Bluetooth LE Advertising of their device.
|
||||
*/
|
||||
public class AdvertiserFragment extends Fragment {
|
||||
|
||||
private BluetoothAdapter mBluetoothAdapter;
|
||||
|
||||
private BluetoothLeAdvertiser mBluetoothLeAdvertiser;
|
||||
|
||||
private AdvertiseCallback mAdvertiseCallback;
|
||||
|
||||
private Switch mSwitch;
|
||||
|
||||
/**
|
||||
* Must be called after object creation by MainActivity.
|
||||
*
|
||||
* @param btAdapter the local BluetoothAdapter
|
||||
*/
|
||||
public void setBluetoothAdapter(BluetoothAdapter btAdapter) {
|
||||
this.mBluetoothAdapter = btAdapter;
|
||||
mBluetoothLeAdvertiser = mBluetoothAdapter.getBluetoothLeAdvertiser();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setRetainInstance(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
|
||||
View view = inflater.inflate(R.layout.fragment_advertiser, container, false);
|
||||
|
||||
mSwitch = (Switch) view.findViewById(R.id.advertise_switch);
|
||||
mSwitch.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
onSwitchClicked(v);
|
||||
}
|
||||
});
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
|
||||
if(mAdvertiseCallback != null){
|
||||
stopAdvertising();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when switch is toggled - starts or stops advertising.
|
||||
*
|
||||
* @param view is the Switch View object
|
||||
*/
|
||||
public void onSwitchClicked(View view) {
|
||||
|
||||
// Is the toggle on?
|
||||
boolean on = ((Switch) view).isChecked();
|
||||
|
||||
if (on) {
|
||||
startAdvertising();
|
||||
} else {
|
||||
stopAdvertising();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts BLE Advertising.
|
||||
*/
|
||||
private void startAdvertising() {
|
||||
|
||||
mAdvertiseCallback = new SampleAdvertiseCallback();
|
||||
|
||||
if (mBluetoothLeAdvertiser != null) {
|
||||
mBluetoothLeAdvertiser.startAdvertising(buildAdvertiseSettings(), buildAdvertiseData(),
|
||||
mAdvertiseCallback);
|
||||
} else {
|
||||
mSwitch.setChecked(false);
|
||||
Toast.makeText(getActivity(), getString(R.string.bt_null), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops BLE Advertising.
|
||||
*/
|
||||
private void stopAdvertising() {
|
||||
|
||||
if (mBluetoothLeAdvertiser != null) {
|
||||
|
||||
mBluetoothLeAdvertiser.stopAdvertising(mAdvertiseCallback);
|
||||
mAdvertiseCallback = null;
|
||||
|
||||
} else {
|
||||
mSwitch.setChecked(false);
|
||||
Toast.makeText(getActivity(), getString(R.string.bt_null), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an AdvertiseData object which includes the Service UUID and Device Name.
|
||||
*/
|
||||
private AdvertiseData buildAdvertiseData() {
|
||||
|
||||
// Note: There is a strict limit of 31 Bytes on packets sent over BLE Advertisements.
|
||||
// This includes everything put into AdvertiseData including UUIDs, device info, &
|
||||
// arbitrary service or manufacturer data.
|
||||
// Attempting to send packets over this limit will result in a failure with error code
|
||||
// AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE. Catch this error in the
|
||||
// onStartFailure() method of an AdvertiseCallback implementation.
|
||||
|
||||
AdvertiseData.Builder dataBuilder = new AdvertiseData.Builder();
|
||||
dataBuilder.addServiceUuid(Constants.Service_UUID);
|
||||
dataBuilder.setIncludeDeviceName(true);
|
||||
|
||||
return dataBuilder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an AdvertiseSettings object set to use low power (to help preserve battery life).
|
||||
*/
|
||||
private AdvertiseSettings buildAdvertiseSettings() {
|
||||
AdvertiseSettings.Builder settingsBuilder = new AdvertiseSettings.Builder();
|
||||
settingsBuilder.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_POWER);
|
||||
|
||||
return settingsBuilder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom callback after Advertising succeeds or fails to start.
|
||||
*/
|
||||
private class SampleAdvertiseCallback extends AdvertiseCallback {
|
||||
|
||||
@Override
|
||||
public void onStartFailure(int errorCode) {
|
||||
super.onStartFailure(errorCode);
|
||||
|
||||
mSwitch.setChecked(false);
|
||||
|
||||
String errorMessage = getString(R.string.start_error_prefix);
|
||||
switch (errorCode) {
|
||||
case AdvertiseCallback.ADVERTISE_FAILED_ALREADY_STARTED:
|
||||
errorMessage += " " + getString(R.string.start_error_already_started);
|
||||
break;
|
||||
case AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE:
|
||||
errorMessage += " " + getString(R.string.start_error_too_large);
|
||||
break;
|
||||
case AdvertiseCallback.ADVERTISE_FAILED_FEATURE_UNSUPPORTED:
|
||||
errorMessage += " " + getString(R.string.start_error_unsupported);
|
||||
break;
|
||||
case AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR:
|
||||
errorMessage += " " + getString(R.string.start_error_internal);
|
||||
break;
|
||||
case AdvertiseCallback.ADVERTISE_FAILED_TOO_MANY_ADVERTISERS:
|
||||
errorMessage += " " + getString(R.string.start_error_too_many);
|
||||
break;
|
||||
}
|
||||
|
||||
Toast.makeText(getActivity(), errorMessage, Toast.LENGTH_LONG).show();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartSuccess(AdvertiseSettings settingsInEffect) {
|
||||
super.onStartSuccess(settingsInEffect);
|
||||
// Don't need to do anything here, advertising successfully started.
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.example.android.bluetoothadvertisements;
|
||||
|
||||
import android.os.ParcelUuid;
|
||||
|
||||
/**
|
||||
* Constants for use in the Bluetooth Advertisements sample
|
||||
*/
|
||||
public class Constants {
|
||||
|
||||
/**
|
||||
* UUID identified with this app - set as Service UUID for BLE Advertisements.
|
||||
*
|
||||
* Bluetooth requires a certain format for UUIDs associated with Services.
|
||||
* The official specification can be found here:
|
||||
* {@link https://www.bluetooth.org/en-us/specification/assigned-numbers/service-discovery}
|
||||
*/
|
||||
public static final ParcelUuid Service_UUID = ParcelUuid
|
||||
.fromString("0000b81d-0000-1000-8000-00805f9b34fb");
|
||||
|
||||
public static final int REQUEST_ENABLE_BT = 1;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.example.android.bluetoothadvertisements;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
/**
|
||||
* Setup display fragments and ensure the device supports Bluetooth.
|
||||
*/
|
||||
public class MainActivity extends FragmentActivity {
|
||||
|
||||
private BluetoothAdapter mBluetoothAdapter;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
setTitle(R.string.activity_main_title);
|
||||
|
||||
if (savedInstanceState == null ) {
|
||||
|
||||
mBluetoothAdapter = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE))
|
||||
.getAdapter();
|
||||
|
||||
// Is Bluetooth supported on this device?
|
||||
if (mBluetoothAdapter != null) {
|
||||
|
||||
// Is Bluetooth turned on?
|
||||
if (mBluetoothAdapter.isEnabled()) {
|
||||
|
||||
// Are Bluetooth Advertisements supported on this device?
|
||||
if (mBluetoothAdapter.isMultipleAdvertisementSupported()) {
|
||||
|
||||
// Everything is supported and enabled, load the fragments.
|
||||
setupFragments();
|
||||
|
||||
} else {
|
||||
|
||||
// Bluetooth Advertisements are not supported.
|
||||
showErrorText(R.string.bt_ads_not_supported);
|
||||
}
|
||||
} else {
|
||||
|
||||
// Prompt user to turn on Bluetooth (logic continues in onActivityResult()).
|
||||
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
|
||||
startActivityForResult(enableBtIntent, Constants.REQUEST_ENABLE_BT);
|
||||
}
|
||||
} else {
|
||||
|
||||
// Bluetooth is not supported.
|
||||
showErrorText(R.string.bt_not_supported);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
switch (requestCode) {
|
||||
case Constants.REQUEST_ENABLE_BT:
|
||||
|
||||
if (resultCode == RESULT_OK) {
|
||||
|
||||
// Bluetooth is now Enabled, are Bluetooth Advertisements supported on
|
||||
// this device?
|
||||
if (mBluetoothAdapter.isMultipleAdvertisementSupported()) {
|
||||
|
||||
// Everything is supported and enabled, load the fragments.
|
||||
setupFragments();
|
||||
|
||||
} else {
|
||||
|
||||
// Bluetooth Advertisements are not supported.
|
||||
showErrorText(R.string.bt_ads_not_supported);
|
||||
}
|
||||
} else {
|
||||
|
||||
// User declined to enable Bluetooth, exit the app.
|
||||
Toast.makeText(this, R.string.bt_not_enabled_leaving,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
finish();
|
||||
}
|
||||
|
||||
default:
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
}
|
||||
|
||||
private void setupFragments() {
|
||||
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
|
||||
|
||||
ScannerFragment scannerFragment = new ScannerFragment();
|
||||
scannerFragment.setBluetoothAdapter(mBluetoothAdapter);
|
||||
transaction.replace(R.id.scanner_fragment_container, scannerFragment);
|
||||
|
||||
AdvertiserFragment advertiserFragment = new AdvertiserFragment();
|
||||
advertiserFragment.setBluetoothAdapter(mBluetoothAdapter);
|
||||
transaction.replace(R.id.advertiser_fragment_container, advertiserFragment);
|
||||
|
||||
transaction.commit();
|
||||
}
|
||||
|
||||
private void showErrorText(int messageId) {
|
||||
|
||||
TextView view = (TextView) findViewById(R.id.error_textview);
|
||||
view.setText(getString(messageId));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
package com.example.android.bluetoothadvertisements;
|
||||
|
||||
import android.bluetooth.le.ScanResult;
|
||||
import android.content.Context;
|
||||
import android.os.SystemClock;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Holds and displays {@link ScanResult}s, used by {@link ScannerFragment}.
|
||||
*/
|
||||
public class ScanResultAdapter extends BaseAdapter {
|
||||
|
||||
private ArrayList<ScanResult> mArrayList;
|
||||
|
||||
private Context mContext;
|
||||
|
||||
private LayoutInflater mInflater;
|
||||
|
||||
ScanResultAdapter(Context context, LayoutInflater inflater) {
|
||||
super();
|
||||
mContext = context;
|
||||
mInflater = inflater;
|
||||
mArrayList = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return mArrayList.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItem(int position) {
|
||||
return mArrayList.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return mArrayList.get(position).getDevice().getAddress().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View view, ViewGroup parent) {
|
||||
|
||||
// Reuse an old view if we can, otherwise create a new one.
|
||||
if (view == null) {
|
||||
view = mInflater.inflate(R.layout.listitem_scanresult, null);
|
||||
}
|
||||
|
||||
TextView deviceNameView = (TextView) view.findViewById(R.id.device_name);
|
||||
TextView deviceAddressView = (TextView) view.findViewById(R.id.device_address);
|
||||
TextView lastSeenView = (TextView) view.findViewById(R.id.last_seen);
|
||||
|
||||
ScanResult scanResult = mArrayList.get(position);
|
||||
|
||||
deviceNameView.setText(scanResult.getDevice().getName());
|
||||
deviceAddressView.setText(scanResult.getDevice().getAddress());
|
||||
lastSeenView.setText(getTimeSinceString(mContext, scanResult.getTimestampNanos()));
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search the adapter for an existing device address and return it, otherwise return -1.
|
||||
*/
|
||||
private int getPosition(String address) {
|
||||
int position = -1;
|
||||
for (int i = 0; i < mArrayList.size(); i++) {
|
||||
if (mArrayList.get(i).getDevice().getAddress().equals(address)) {
|
||||
position = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a ScanResult item to the adapter if a result from that device isn't already present.
|
||||
* Otherwise updates the existing position with the new ScanResult.
|
||||
*/
|
||||
public void add(ScanResult scanResult) {
|
||||
|
||||
int existingPosition = getPosition(scanResult.getDevice().getAddress());
|
||||
|
||||
if (existingPosition >= 0) {
|
||||
// Device is already in list, update its record.
|
||||
mArrayList.set(existingPosition, scanResult);
|
||||
} else {
|
||||
// Add new Device's ScanResult to list.
|
||||
mArrayList.add(scanResult);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear out the adapter.
|
||||
*/
|
||||
public void clear() {
|
||||
mArrayList.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes in a number of nanoseconds and returns a human-readable string giving a vague
|
||||
* description of how long ago that was.
|
||||
*/
|
||||
public static String getTimeSinceString(Context context, long timeNanoseconds) {
|
||||
String lastSeenText = context.getResources().getString(R.string.last_seen) + " ";
|
||||
|
||||
long timeSince = SystemClock.elapsedRealtimeNanos() - timeNanoseconds;
|
||||
long secondsSince = TimeUnit.SECONDS.convert(timeSince, TimeUnit.NANOSECONDS);
|
||||
|
||||
if (secondsSince < 5) {
|
||||
lastSeenText += context.getResources().getString(R.string.just_now);
|
||||
} else if (secondsSince < 60) {
|
||||
lastSeenText += secondsSince + " " + context.getResources()
|
||||
.getString(R.string.seconds_ago);
|
||||
} else {
|
||||
long minutesSince = TimeUnit.MINUTES.convert(secondsSince, TimeUnit.SECONDS);
|
||||
if (minutesSince < 60) {
|
||||
if (minutesSince == 1) {
|
||||
lastSeenText += minutesSince + " " + context.getResources()
|
||||
.getString(R.string.minute_ago);
|
||||
} else {
|
||||
lastSeenText += minutesSince + " " + context.getResources()
|
||||
.getString(R.string.minutes_ago);
|
||||
}
|
||||
} else {
|
||||
long hoursSince = TimeUnit.HOURS.convert(minutesSince, TimeUnit.MINUTES);
|
||||
if (hoursSince == 1) {
|
||||
lastSeenText += hoursSince + " " + context.getResources()
|
||||
.getString(R.string.hour_ago);
|
||||
} else {
|
||||
lastSeenText += hoursSince + " " + context.getResources()
|
||||
.getString(R.string.hours_ago);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return lastSeenText;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
package com.example.android.bluetoothadvertisements;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.le.BluetoothLeScanner;
|
||||
import android.bluetooth.le.ScanCallback;
|
||||
import android.bluetooth.le.ScanFilter;
|
||||
import android.bluetooth.le.ScanResult;
|
||||
import android.bluetooth.le.ScanSettings;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.support.v4.app.ListFragment;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
||||
/**
|
||||
* Scans for Bluetooth Low Energy Advertisements matching a filter and displays them to the user.
|
||||
*/
|
||||
public class ScannerFragment extends ListFragment {
|
||||
|
||||
private static final String TAG = ScannerFragment.class.getSimpleName();
|
||||
|
||||
/**
|
||||
* Stops scanning after 5 seconds.
|
||||
*/
|
||||
private static final long SCAN_PERIOD = 5000;
|
||||
|
||||
private BluetoothAdapter mBluetoothAdapter;
|
||||
|
||||
private BluetoothLeScanner mBluetoothLeScanner;
|
||||
|
||||
private ScanCallback mScanCallback;
|
||||
|
||||
private ScanResultAdapter mAdapter;
|
||||
|
||||
private Handler mHandler;
|
||||
|
||||
/**
|
||||
* Must be called after object creation by MainActivity.
|
||||
*
|
||||
* @param btAdapter the local BluetoothAdapter
|
||||
*/
|
||||
public void setBluetoothAdapter(BluetoothAdapter btAdapter) {
|
||||
this.mBluetoothAdapter = btAdapter;
|
||||
mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setHasOptionsMenu(true);
|
||||
setRetainInstance(true);
|
||||
|
||||
// Use getActivity().getApplicationContext() instead of just getActivity() because this
|
||||
// object lives in a fragment and needs to be kept separate from the Activity lifecycle.
|
||||
//
|
||||
// We could get a LayoutInflater from the ApplicationContext but it messes with the
|
||||
// default theme, so generate it from getActivity() and pass it in separately.
|
||||
mAdapter = new ScanResultAdapter(getActivity().getApplicationContext(),
|
||||
LayoutInflater.from(getActivity()));
|
||||
mHandler = new Handler();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
|
||||
final View view = super.onCreateView(inflater, container, savedInstanceState);
|
||||
|
||||
setListAdapter(mAdapter);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
getListView().setDivider(null);
|
||||
getListView().setDividerHeight(0);
|
||||
|
||||
setEmptyText(getString(R.string.empty_list));
|
||||
|
||||
// Trigger refresh on app's 1st load
|
||||
startScanning();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
inflater.inflate(R.menu.scanner_menu, menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case R.id.refresh:
|
||||
startScanning();
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Start scanning for BLE Advertisements (& set it up to stop after a set period of time).
|
||||
*/
|
||||
public void startScanning() {
|
||||
if (mScanCallback == null) {
|
||||
Log.d(TAG, "Starting Scanning");
|
||||
|
||||
// Will stop the scanning after a set time.
|
||||
mHandler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
stopScanning();
|
||||
}
|
||||
}, SCAN_PERIOD);
|
||||
|
||||
// Kick off a new scan.
|
||||
mScanCallback = new SampleScanCallback();
|
||||
mBluetoothLeScanner.startScan(buildScanFilters(), buildScanSettings(), mScanCallback);
|
||||
|
||||
String toastText = getString(R.string.scan_start_toast) + " "
|
||||
+ TimeUnit.SECONDS.convert(SCAN_PERIOD, TimeUnit.MILLISECONDS) + " "
|
||||
+ getString(R.string.seconds);
|
||||
Toast.makeText(getActivity(), toastText, Toast.LENGTH_LONG).show();
|
||||
} else {
|
||||
Toast.makeText(getActivity(), R.string.already_scanning, Toast.LENGTH_SHORT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop scanning for BLE Advertisements.
|
||||
*/
|
||||
public void stopScanning() {
|
||||
Log.d(TAG, "Stopping Scanning");
|
||||
|
||||
// Stop the scan, wipe the callback.
|
||||
mBluetoothLeScanner.stopScan(mScanCallback);
|
||||
mScanCallback = null;
|
||||
|
||||
// Even if no new results, update 'last seen' times.
|
||||
mAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a List of {@link ScanFilter} objects to filter by Service UUID.
|
||||
*/
|
||||
private List<ScanFilter> buildScanFilters() {
|
||||
List<ScanFilter> scanFilters = new ArrayList<>();
|
||||
|
||||
ScanFilter.Builder builder = new ScanFilter.Builder();
|
||||
builder.setServiceUuid(Constants.Service_UUID);
|
||||
scanFilters.add(builder.build());
|
||||
|
||||
return scanFilters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@link ScanSettings} object set to use low power (to preserve battery life).
|
||||
*/
|
||||
private ScanSettings buildScanSettings() {
|
||||
ScanSettings.Builder builder = new ScanSettings.Builder();
|
||||
builder.setScanMode(ScanSettings.SCAN_MODE_LOW_POWER);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom ScanCallback object - adds to adapter on success, displays error on failure.
|
||||
*/
|
||||
private class SampleScanCallback extends ScanCallback {
|
||||
|
||||
@Override
|
||||
public void onBatchScanResults(List<ScanResult> results) {
|
||||
super.onBatchScanResults(results);
|
||||
|
||||
for (ScanResult result : results) {
|
||||
mAdapter.add(result);
|
||||
}
|
||||
mAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScanResult(int callbackType, ScanResult result) {
|
||||
super.onScanResult(callbackType, result);
|
||||
|
||||
mAdapter.add(result);
|
||||
mAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScanFailed(int errorCode) {
|
||||
super.onScanFailed(errorCode);
|
||||
Toast.makeText(getActivity(), "Scan failed with error: " + errorCode, Toast.LENGTH_LONG)
|
||||
.show();
|
||||
}
|
||||
}
|
||||
}
|
||||