diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 9c9035b0ff2709ba6291bbd67c5cb34b2822afa6..0000000000000000000000000000000000000000 --- a/.gitignore +++ /dev/null @@ -1,29 +0,0 @@ -# Built application files -*.apk -*.ap_ - -# Files for the Dalvik VM -*.dex - -# Java class files -*.class - -# Generated files -bin/ -gen/ - -# Gradle files -.gradle/ -build/ -/*/build/ - -# Local configuration file (sdk path, etc) -local.properties -/.idea -*.iml - -# Proguard folder generated by Eclipse -proguard/ - -# Log Files -*.log diff --git a/ChangeLog.md b/ChangeLog.md new file mode 100644 index 0000000000000000000000000000000000000000..d057e0a2faa0501e0cc7f343de8e7124151bdaa4 --- /dev/null +++ b/ChangeLog.md @@ -0,0 +1,2 @@ +## 0.0.1-SNAPSHOT +* 发布beta版本 \ No newline at end of file diff --git a/LICENSE b/LICENSE index dc4ed99c92792afc10c4d61ff43b3c5fc226a50f..fa3ac9af016a9a02ebf08f741a0dc6a12d9c2195 100644 --- a/LICENSE +++ b/LICENSE @@ -11,7 +11,7 @@ modification, are permitted provided that the following conditions are met: this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -* Neither the name of Android-Scanner-Compat-Library nor the names of its +* Neither the name of Scanner-Compat-Library nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. diff --git a/README.OPENSOURCE b/README.OPENSOURCE new file mode 100644 index 0000000000000000000000000000000000000000..79684771198ab0de37d0cc873c40ed0d455a15ea --- /dev/null +++ b/README.OPENSOURCE @@ -0,0 +1,10 @@ +[ + { + "Name": " Scanner-Compat-Library ", + "License": " Apache License ", + "License File": " LICENSE ", + "Version Number": " 1.4.3 ", + "Upstream URL": " https://github.com/NordicSemiconductor/Android-Scanner-Compat-Library ", + "Description": " 蓝牙的操作 " + } +] \ No newline at end of file diff --git a/README.md b/README.md index ef3839a6e65472d346ee99e20ef53abf541f1691..a929c857632c77ed95beafe3deb9035d6febd9ad 100644 --- a/README.md +++ b/README.md @@ -1,61 +1,49 @@ -# Android BLE Scanner Compat library +# Scanner-Compat-Library -[ ![Download](https://api.bintray.com/packages/nordic/android/no.nordicsemi.android.support.v18%3Ascanner/images/download.svg) ](https://bintray.com/nordic/android/no.nordicsemi.android.support.v18%3Ascanner/_latestVersion) -The Scanner Compat library solves the problem with scanning for Bluetooth Low Energy devices on Android. -The scanner API, initially created in Android 4.3, has changed in Android 5.0 and has been extended in 6.0 and 8.0. -This library allows to use modern API even on older phones, emulating not supported features. If a feature -(for example offloaded filtering or batching) is not available natively, it will be emulated by -the compat library. Also, native filtering, batching and reporting first match or match lost may -be disabled if you find them not working on some devices. Advertising Extension (`ScanSetting#setLegacy(boolean)` -or `setPhy(int)`) is available only on Android Oreo or newer and such calls will be ignored on -older platforms where only legacy advertising packets on PHY LE 1M will be reported, -due to the Bluetooth chipset capabilities. +#### 项目介绍 +- 项目名称:蓝牙库 +- 所属系列:鸿蒙的第三方组件适配移植 +- 功能:蓝牙的操作 +- 项目移植状态:主功能完成 +- 调用差异:无 +- 开发版本:sdk5,DevEco Studio2.1 beta4 +- 基线版本:Tag v1.4.3 -### Background scanning -`SCAN_MODE_LOW_POWER` or `SCAN_MODE_OPPORTUNISTIC` should be used when scanning in background. -Note, that newer Android versions will enforce using low power mode in background, even if another one has been set. -This library allows to emulate [scanning with PendingIntent](https://developer.android.com/reference/android/bluetooth/le/BluetoothLeScanner.html#startScan(java.util.List%3Candroid.bluetooth.le.ScanFilter%3E,%20android.bluetooth.le.ScanSettings,%20android.app.PendingIntent)) -on pre-Oreo devices by starting a background service that will scan with requested scan mode. -This is much less battery friendly than when the original method is used, but works and saves -a lot of development time if such feature should be implemented anyway. Please read below -for more details. +#### 效果演示 +![效果演示] +![效果演示](https://images.gitee.com/uploads/images/2021/0521/164648_eb2f2a46_5739850.jpeg "7302f680-5145-4371-f804-3998170e768e.jpg") +![效果演示](https://images.gitee.com/uploads/images/2021/0521/164715_b41a86ec_5739850.jpeg "d4fb6897-ad78-4c8d-e520-1647e89529f5.jpg") -## Usage - -The compat library may be found on jcenter repository. Add it to your project by adding the -following dependency: - -```Groovy -implementation 'no.nordicsemi.android.support.v18:scanner:1.4.2' +#### 安装教程 +1.在项目根目录下的build.gradle文件中添加 ``` - -Projects not migrated to Android Jetpack should use version 1.3.1, which is feature-equal to 1.4.0. - -## API - -The Scanner Compat API is very similar to the original one, known from Android Oreo. - -Instead of getting it from the **BluetoothAdapter**, acquire the scanner instance using: - -```java -BluetoothLeScannerCompat scanner = BluetoothLeScannerCompat.getScanner(); +allprojects { + repositories { + maven { + url 'https://s01.oss.sonatype.org/content/repositories/snapshots/' + } + } +} ``` - -You also need to change the packets for **ScanSettings**, **ScanFilter** and **ScanCallback** -classes to: - -```java -no.nordicsemi.android.support.v18.scanner +2.在entry模块下的build.gradle文件中添加依赖。 +``` +dependencies { + implementation('com.gitee.chinasoft_ohos:Scanner-Compat-Library:0.0.1-SNAPSHOT') + ...... +} ``` +在sdk4,DevEco Studio2.1 beta4下项目可直接运行 +如无法运行,删除项目.gradle,.idea,build,gradle,build.gradle文件, +并依据自己的版本创建新项目,将新项目的对应文件复制到根目录下 -## Sample +#### 使用说明 -To start scanning use (example): +使用该库非常简单,只需查看提供的示例的源代码。 ```java - BluetoothLeScannerCompat scanner = BluetoothLeScannerCompat.getScanner(); + BluetoothLeScannerCompat scanner = BluetoothLeScannerCompat.getScanner(); ScanSettings settings = new ScanSettings.Builder() .setLegacy(false) .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) @@ -67,133 +55,21 @@ To start scanning use (example): scanner.startScan(filters, settings, scanCallback); ``` -to stop scanning use: -```java - BluetoothLeScannerCompat scanner = BluetoothLeScannerCompat.getScanner(); - scanner.stopScan(scanCallback); -``` - -### Scanning modes - -There are 4 scanning modes available in native [ScanSettings](https://developer.android.com/reference/android/bluetooth/le/ScanSettings). -3 of them are available since Android Lollipop while the opportunistic scan mode has been added in Marshmallow. -This library tries to emulate them on platforms where they are not supported natively. -1. [SCAN_MODE_LOW_POWER](https://developer.android.com/reference/android/bluetooth/le/ScanSettings#SCAN_MODE_LOW_POWER) - -Perform Bluetooth LE scan in low power mode. This is the default scan mode as it consumes the least power. -The scanner will scan for 0.5 second and rest for 4.5 seconds. A Bluetooth LE device should advertise -very often (at least once per 100 ms) in order to be found with this mode, otherwise the scanning interval may miss some or even all -advertising events. This mode may be enforced if the scanning application is not in foreground. -2. [SCAN_MODE_BALANCED](https://developer.android.com/reference/android/bluetooth/le/ScanSettings#SCAN_MODE_BALANCED) - -Perform Bluetooth LE scan in balanced power mode. Scan results are returned at a rate that provides a -good trade-off between scan frequency and power consumption. The scanner will scan for 2 seconds followed -by 3 seconds of idle. -3. [SCAN_MODE_LOW_LATENCY](https://developer.android.com/reference/android/bluetooth/le/ScanSettings#SCAN_MODE_LOW_LATENCY) - -Scan using highest duty cycle. It's recommended to only use this mode when the application is running in the foreground. -4. [SCAN_MODE_OPPORTUNISTIC](https://developer.android.com/reference/android/bluetooth/le/ScanSettings#SCAN_MODE_OPPORTUNISTIC) - -A special Bluetooth LE scan mode. Applications using this scan mode will passively listen for other scan results -without starting BLE scans themselves. - -3 first modes are emulated on Android 4.3 and 4.4.x by starting a handler task that scans for a period of time -and rests in between. To set scanning and rest intervals use `Builder#setPowerSave(long,long)`. - -Opportunistic scanning is not possible to emulate and will fallback to `SCAN_MODE_LOW_POWER` on Lollipop and -power save settings on pre-Lollipop devices. That means that this library actually will initiate scanning -on its own. This may have impact on battery consumption and should be used with care. - -### Scan filters and batching - -Offloaded filtering is available on Lollipop or newer devices where -[BluetoothAdapter#isOffloadedFilteringSupported()](https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#isOffloadedFilteringSupported()) -returns *true* (when Bluetooth is enabled). If it is not supported, this library will scan without a filter and -apply the filter to the results. If you find offloaded filtering unreliable you may force using compat filtering by calling -`Builder#useHardwareFilteringIfSupported(false)`. Keep in mind that, newer Android versions may prohibit -background scanning without native filters to save battery, so this method should be used with care. - -Android Scanner Compat Library may also emulate batching. To enable scan batching call `Builder#setScanDelay(interval)` -with an interval greater than 0. For intervals less 5 seconds the actual interval may vary. -If you want to get results in lower intervals, call `Builder#useHardwareBatchingIfSupported(false)`, which will -start a normal scan and report results in given interval. Emulated batching uses significantly more battery -than offloaded as it wakes CPU with every device found. - -### Scanning with Pending Intent - -Android 8.0 Oreo introduced [Background Execution Limits](https://developer.android.com/about/versions/oreo/background) -which made background running services short-lived. At the same time, to make background scanning possible, a new -[method](https://developer.android.com/reference/android/bluetooth/le/BluetoothLeScanner.html#startScan(java.util.List%3Candroid.bluetooth.le.ScanFilter%3E,%20android.bluetooth.le.ScanSettings,%20android.app.PendingIntent)) -was added to [BluetoothLeScanner](https://developer.android.com/reference/android/bluetooth/le/BluetoothLeScanner.html) -which allows registering a [PendingIntent](https://developer.android.com/reference/android/app/PendingIntent) -that will be sent whenever a device matching filter criteria is found. This will also work after -your application has been killed (the receiver must be added in *AndroidManifest* and the -`PendingIntent` must be created with an explicit Intent). - -Starting from version 1.3.0, this library may emulate such feature on older Android versions. -In order to do that, a background service will be started after calling -`scanner.startScan(filters, settings, context, pendingIntent)`, which will be scanning in -background with given settings and will send the given `PendingIntent` when a device -matching filter is found. To lower battery consumption it is recommended to set -`ScanSettings.SCAN_MODE_LOW_POWER` scanning mode and use filter, but even with those conditions fulfilled -**the battery consumption will be significantly higher than on Oreo+**. To stop scanning call -`scanner.stopScan(context, pendingIntent)` with -[the same](https://developer.android.com/reference/android/app/PendingIntent) intent in parameter. -The service will be stopped when the last scan was stopped. - -On Android Oreo or newer this library will use the native scanning mechanism. However, as it may also -emulate batching or apply filtering (when `useHardwareBatchingIfSupported` or `useHardwareFilteringIfSupported` -were called with parameter *false*) the library will register its own broadcast -receiver that will translate results from native to compat classes. - -The receiver and service will be added automatically to the manifest even if they are not used by -the application. No changes are required to make it work. - -To use this feature: - -```java - Intent intent = new Intent(context, MyReceiver.class); // explicite intent - intent.setAction("com.example.ACTION_FOUND"); - intent.putExtra("some.extra", value); // optional - PendingIntent pendingIntent = PendingIntent.getBroadcast(context, id, intent, PendingIntent.FLAG_UPDATE_CURRENT); - - BluetoothLeScannerCompat scanner = BluetoothLeScannerCompat.getScanner(); - ScanSettings settings = new ScanSettings.Builder() - .setScanMode(ScanSettings.SCAN_MODE_LOW_POWER) - .setReportDelay(10000) - .build(); - List filters = new ArrayList<>(); - filters.add(new ScanFilter.Builder().setServiceUuid(mUuid).build()); - scanner.startScan(filters, settings, context, pendingIntent); -``` +#### 测试信息 -Add your `MyRecever` to *AndroidManifest*, as the application context might have been released -and all broadcast receivers registered to it together with it. +CodeCheck代码测试无异常 -To stop scanning call: - -```java - // To stop scanning use the same or an equal PendingIntent (check PendingIntent documentation) - Intent intent = new Intent(context, MyReceiver.class); - intent.setAction("com.example.ACTION_FOUND"); - PendingIntent pendingIntent = PendingIntent.getBroadcast(context, id, intent, PendingIntent.FLAG_CANCEL_CURRENT); - - BluetoothLeScannerCompat scanner = BluetoothLeScannerCompat.getScanner(); - scanner.stopScan(context, pendingIntent); -``` +CloudTest代码测试无异常 -**Note:** Android versions 6 and 7 will not report any advertising packets when in Doze mode. -Read more about it here: https://developer.android.com/training/monitoring-device-state/doze-standby +火绒安全病毒安全检测通过 -## Background scanning guidelines +当前版本demo功能与安卓原组件基本无差异 -To save power it is recommended to use as low power settings as possible and and use filters. -However, the more battery friendly settings are used, the longest time to finding a device. -In general, scanning with `PendingIntent` and `SCAN_MODE_LOW_POWER` or `SCAN_MODE_OPPORTUNISTIC` -should be used, together with report delay set and filters used. -`useHardwareFilteringIfSupported` and `useHardwareBatchingIfSupported` should be set to *true* (default). +#### 版本迭代 -Background scanning on Android 4.3 and 4.4.x will use a lot of power, as all those properties -will have to be emulated. It is recommended to scan in background only on Lollipop or newer, or -even Oreo or newer devices and giving the user an option to disable this feature. +- v0.0.1_SNAPSHOT -## License +#### 版权和许可信息 -The Scanner Compat library is available under BSD 3-Clause license. See the LICENSE file for more info. \ No newline at end of file + The Scanner Compat library is available under BSD 3-Clause license. See the LICENSE file for more info. \ No newline at end of file diff --git a/build.gradle b/build.gradle index 8da322c631295ac04d26e5ed4126a1165424ac37..2368e1d63380a3fe53798b21625a9e8dc5b1f91a 100644 --- a/build.gradle +++ b/build.gradle @@ -1,22 +1,37 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. +apply plugin: 'com.huawei.ohos.app' + +ohos { + compileSdkVersion 5 + defaultConfig { + compatibleSdkVersion 5 + } +} buildscript { repositories { - google() + maven { + url 'https://mirrors.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.5.2' - - classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4' - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files + classpath 'com.huawei.ohos:hap:2.4.2.7' + classpath 'com.huawei.ohos:decctest:1.0.0.6' } } allprojects { repositories { - google() + maven { + url 'https://mirrors.huaweicloud.com/repository/maven/' + } + maven { + url 'https://developer.huawei.com/repo/' + } jcenter() } -} \ No newline at end of file +} diff --git a/entry/.gitignore b/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..796b96d1c402326528b4ba3c12ee9d92d0e212e9 --- /dev/null +++ b/entry/.gitignore @@ -0,0 +1 @@ +/build diff --git a/entry/build.gradle b/entry/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..18fad72ab26a49aad281ab3dea45b0cab0c36801 --- /dev/null +++ b/entry/build.gradle @@ -0,0 +1,14 @@ +apply plugin: 'com.huawei.ohos.hap' +ohos { + compileSdkVersion 5 + defaultConfig { + compatibleSdkVersion 5 + } + +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar', '*.har']) + testCompile 'junit:junit:4.12' + implementation project(':scanner') +} diff --git a/entry/src/main/config.json b/entry/src/main/config.json new file mode 100644 index 0000000000000000000000000000000000000000..4a1be10f8ded255b4c6cd7581cc1e45b8dc5abfc --- /dev/null +++ b/entry/src/main/config.json @@ -0,0 +1,110 @@ +{ + "app": { + "bundleName": "com.example.myapplication", + "vendor": "example", + "version": { + "code": 1, + "name": "1.0" + }, + "apiVersion": { + "compatible": 5, + "target": 5 + } + }, + "deviceConfig": {}, + "module": { + "package": "com.example.myapplication", + "name": ".MyApplication", + "deviceType": [ + "phone" + ], + "distro": { + "deliveryWithInstall": true, + "moduleName": "entry", + "moduleType": "entry" + }, + "abilities": [ + { + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ], + "orientation": "unspecified", + "name": "com.example.myapplication.MainAbility", + "icon": "$media:icon", + "description": "$string:mainability_description", + "label": "MyApplication", + "type": "page", + "launchType": "standard" + }, + { + "name": "no.nordicsemi.support.v18.scanner.ScannerService", + "type": "service", + "visible": true + } + ], + "reqPermissions": [ + { + "name": "ohos.permission.USE_BLUETOOTH", + "reason": "使用蓝牙权限", + "usedScene": { + "ability": [ + "com.example.myapplication.slice.MainAbility", + "no.nordicsemi.support.v18.scanner.ScannerService" + ], + "when": "always" + } + }, + { + "name": "ohos.permission.DISCOVER_BLUETOOTH", + "reason": "搜索蓝牙权限", + "usedScene": { + "ability": [ + "com.example.myapplication.slice.MainAbility", + "no.nordicsemi.support.v18.scanner.ScannerService" + ], + "when": "always" + } + }, + { + "name": "ohos.permission.LOCATION", + "reason": "允许前台获取权限", + "usedScene": { + "ability": [ + "com.example.myapplication.slice.MainAbility", + "no.nordicsemi.support.v18.scanner.ScannerService" + ], + "when": "always" + } + }, + { + "name": "ohos.permission.LOCATION_IN_BACKGROUND", + "reason": "允许后台获取权限", + "usedScene": { + "ability": [ + "com.example.myapplication.slice.MainAbility", + "no.nordicsemi.support.v18.scanner.ScannerService" + ], + "when": "always" + } + }, + { + "name": "ohos.permission.GET_NETWORK_INFO", + "reason": "允许应用获取数据网络信息", + "usedScene": { + "ability": [ + "com.example.myapplication.slice.MainAbility", + "no.nordicsemi.support.v18.scanner.ScannerService" + ], + "when": "always" + } + } + ] + } +} \ No newline at end of file diff --git a/entry/src/main/java/com/example/myapplication/HistoryBean.java b/entry/src/main/java/com/example/myapplication/HistoryBean.java new file mode 100644 index 0000000000000000000000000000000000000000..1c5894396a1fcaaf26565b635ae4764fa13abc70 --- /dev/null +++ b/entry/src/main/java/com/example/myapplication/HistoryBean.java @@ -0,0 +1,16 @@ +package com.example.myapplication; + +public class HistoryBean { + + private String name; + public HistoryBean(String name) { + this.name = name; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + +} diff --git a/entry/src/main/java/com/example/myapplication/HistoryItemProvider.java b/entry/src/main/java/com/example/myapplication/HistoryItemProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..e958f113987bfea0e3b2d5ba8d35560211406334 --- /dev/null +++ b/entry/src/main/java/com/example/myapplication/HistoryItemProvider.java @@ -0,0 +1,70 @@ +package com.example.myapplication; + +import no.nordicsemi.support.v18.scanner.ScanResult; +import ohos.aafwk.ability.AbilitySlice; +import ohos.agp.components.*; +import ohos.bluetooth.ble.BleScanResult; + +import java.util.ArrayList; +import java.util.List; + +public class HistoryItemProvider extends BaseItemProvider { + private List list; + private AbilitySlice slice; + private int layout; + + public HistoryItemProvider(List list, AbilitySlice slice, int layout) { + this.list = list; + this.slice = slice; + this.layout = layout; + } + + @Override + public int getCount() { + return list == null ? 0 : list.size(); + } + + public List getList() { + if (list == null) { + return new ArrayList<>(); + } + return list; + } + + @Override + public Object getItem(int i) { + if (list != null && i >= 0 && i < list.size()) { + return list.get(i); + } + return null; + } + + @Override + public long getItemId(int i) { + return i; + } + + @Override + public Component getComponent(int i, Component component, ComponentContainer componentContainer) { + final Component comp; + if (component == null) { + comp = LayoutScatter.getInstance(slice).parse(layout, null, false); + } else { + comp = component; + } + List list = getList(); + ScanResult historyBean = list.get(i); + BleScanResult bleScanResult = (BleScanResult) historyBean.getDevice(); + String str = bleScanResult.getPeripheralDevice().getDeviceName().toString(); + str = str.replace("Optional[", ""); + str = str.replace("]", ""); + Text text = (Text) comp.findComponentById(ResourceTable.Id_text); + if (str.equals("Optional.empty")) { + String strs = bleScanResult.getPeripheralDevice().getDeviceAddr().toString(); + text.setText(strs); + } else { + text.setText(str); + } + return comp; + } +} \ No newline at end of file diff --git a/entry/src/main/java/com/example/myapplication/MainAbility.java b/entry/src/main/java/com/example/myapplication/MainAbility.java new file mode 100644 index 0000000000000000000000000000000000000000..d184331d82957d055552c81610186524a42ba1db --- /dev/null +++ b/entry/src/main/java/com/example/myapplication/MainAbility.java @@ -0,0 +1,15 @@ +package com.example.myapplication; + +import com.example.myapplication.slice.MainAbilitySlice; +import ohos.aafwk.ability.Ability; +import ohos.aafwk.content.Intent; +import ohos.aafwk.content.Operation; + +public class MainAbility extends Ability { + @Override + public void onStart(Intent intent) { + super.onStart(intent); + super.setMainRoute(MainAbilitySlice.class.getName()); + } + +} diff --git a/entry/src/main/java/com/example/myapplication/MyApplication.java b/entry/src/main/java/com/example/myapplication/MyApplication.java new file mode 100644 index 0000000000000000000000000000000000000000..33915e2cc691b0fa169fd0a13e2262ac3925bafd --- /dev/null +++ b/entry/src/main/java/com/example/myapplication/MyApplication.java @@ -0,0 +1,10 @@ +package com.example.myapplication; + +import ohos.aafwk.ability.AbilityPackage; + +public class MyApplication extends AbilityPackage { + @Override + public void onInitialize() { + super.onInitialize(); + } +} diff --git a/entry/src/main/java/com/example/myapplication/slice/MainAbilitySlice.java b/entry/src/main/java/com/example/myapplication/slice/MainAbilitySlice.java new file mode 100644 index 0000000000000000000000000000000000000000..086862509ef8cdddd689d070aca7be32fc8fe633 --- /dev/null +++ b/entry/src/main/java/com/example/myapplication/slice/MainAbilitySlice.java @@ -0,0 +1,267 @@ +package com.example.myapplication.slice; + +import com.example.myapplication.HistoryItemProvider; +import com.example.myapplication.ResourceTable; +import no.nordicsemi.support.v18.scanner.*; +import ohos.aafwk.ability.AbilitySlice; +import ohos.aafwk.content.Intent; +import ohos.agp.components.*; +import ohos.agp.window.dialog.ToastDialog; +import ohos.app.Context; +import ohos.bluetooth.ble.BleScanFilter; +import ohos.bluetooth.ble.BleScanResult; +import ohos.bundle.IBundleManager; +import ohos.hiviewdfx.HiLog; +import ohos.hiviewdfx.HiLogLabel; + +import java.util.*; + +public class MainAbilitySlice extends AbilitySlice implements Component.ClickedListener { + + private Button btnStartScan, btnStopScan; + private RadioButton one, two, three, four; + private RadioContainer rabut; + private BluetoothLeScannerCompat scanner; + + private List beans = new ArrayList<>(); + Context context; + private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201, "MY_TAG"); + //设置蓝牙扫描过滤器集合 + private List scanFilterList; + //设置蓝牙扫描过滤器 + private ScanFilter.Builder scanFilterBuilder; + //设置蓝牙扫描设置 + private ScanSettings.Builder scanSettingBuilder; + private ListContainer dialog; + private HistoryItemProvider historyItemProvider; + private boolean isBut = false; + + @Override + public void onStart(Intent intent) { + super.onStart(intent); + super.setUIContent(ResourceTable.Layout_ability_main); + initView(); + initClick(); + String[] permission = {"ohos.permission.LOCATION", "ohos.permission.USE_BLUETOOTH" + , "ohos.permission.DISCOVER_BLUETOOTH", "ohos.permission.LOCATION_IN_BACKGROUND" + , "ohos.permission.GET_NETWORK_INFO"}; + requestPermissionsFromUser(permission, 0); + return; + } + + private void initView() { + dialog = (ListContainer) findComponentById(ResourceTable.Id_dialog); + btnStartScan = (Button) findComponentById(ResourceTable.Id_btn_start_scan); + btnStopScan = (Button) findComponentById(ResourceTable.Id_btn_stop_scan); + one = (RadioButton) findComponentById(ResourceTable.Id_one); + two = (RadioButton) findComponentById(ResourceTable.Id_two); + three = (RadioButton) findComponentById(ResourceTable.Id_three); + four = (RadioButton) findComponentById(ResourceTable.Id_four); + rabut = (RadioContainer) findComponentById(ResourceTable.Id_rabut); + scanner = BluetoothLeScannerCompat.getScanner(); + historyItemProvider = new HistoryItemProvider(beans, MainAbilitySlice.this, ResourceTable.Layout_item_layout); + dialog.setItemProvider(historyItemProvider); + rabut.mark(0); + } + + private void initClick() { + btnStartScan.setClickedListener(this); + btnStopScan.setClickedListener(this); + rabut.setMarkChangedListener(new RadioContainer.CheckedStateChangedListener() { + @Override + public void onCheckedChanged(RadioContainer radioContainer, int i) { + if (i == 0) { + if (isBut == false) { + ScanSettings settings = new ScanSettings.Builder() + .setLegacy(false) + .setScanMode(ScanSettings.SCAN_MODE_LOW_POWER) + .setReportDelay(10000) + .setUseHardwareBatchingIfSupported(false) + .build(); + } else { + new ToastDialog(getContext()) + .setText("搜索中,请结束当前搜索") + .show(); + } + } else if (i == 1) { + if (isBut == false) { + ScanSettings settings = new ScanSettings.Builder() + .setLegacy(false) + .setScanMode(ScanSettings.SCAN_MODE_BALANCED) + .setReportDelay(10000) + .setUseHardwareBatchingIfSupported(false) + .build(); + } else { + new ToastDialog(getContext()) + .setText("搜索中,请结束当前搜索") + .show(); + } + } else if (i == 2) { + if (isBut == false) { + ScanSettings settings = new ScanSettings.Builder() + .setLegacy(false) + .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) + .setReportDelay(10000) + .setUseHardwareBatchingIfSupported(false) + .build(); + } else { + new ToastDialog(getContext()) + .setText("搜索中,请结束当前搜索") + .show(); + } + } else { + if (isBut == false) { + ScanSettings settings = new ScanSettings.Builder() + .setLegacy(false) + .setScanMode(ScanSettings.SCAN_MODE_OPPORTUNISTIC) + .setReportDelay(10000) + .setUseHardwareBatchingIfSupported(false) + .build(); + } else { + new ToastDialog(getContext()) + .setText("搜索中,请结束当前搜索") + .show(); + } + } + } + }); + } + + @Override + public void onActive() { + super.onActive(); + } + + @Override + public void onForeground(Intent intent) { + super.onForeground(intent); + } + + private ScanSettings buildScanSettings() { + scanSettingBuilder = new ScanSettings.Builder(); + scanSettingBuilder.setUseHardwareBatchingIfSupported(false); + //设置蓝牙LE扫描的扫描模式。 + //使用最高占空比进行扫描。建议只在应用程序处于此模式时使用此模式在前台运行 + scanSettingBuilder.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY); + //设置蓝牙LE扫描滤波器硬件匹配的匹配模式 + //在主动模式下,即使信号强度较弱,hw也会更快地确定匹配.在一段时间内很少有目击/匹配。 + scanSettingBuilder.setMatchMode(ScanSettings.MATCH_MODE_AGGRESSIVE); + //设置蓝牙LE扫描的回调类型 + //为每一个匹配过滤条件的蓝牙广告触发一个回调。如果没有过滤器是活动的,所有的广告包被报告 + scanSettingBuilder.setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES); + scanSettingBuilder.setReportDelay(10000); + scanSettingBuilder.setUseHardwareBatchingIfSupported(false); + return scanSettingBuilder.build(); + } + + @Override + public void onClick(Component component) { + switch (component.getId()) { + case ResourceTable.Id_btn_start_scan: + if (isBut == false) { + start(); + new ToastDialog(getContext()) + .setText("开始") + .show(); + } else { + new ToastDialog(getContext()) + .setText("搜索中") + .show(); + } + break; + case ResourceTable.Id_btn_stop_scan: + if (isBut == true) { + stop(); + new ToastDialog(getContext()) + .setText("结束") + .show(); + } else { + new ToastDialog(getContext()) + .setText("已结束") + .show(); + } + break; + } + } + + private void start() { + isBut = true; + List filters = new ArrayList<>(); + UUID uuid = UUID.randomUUID(); + scanner.startScan(this, null, buildScanSettings(), scanCallback); + scanner.startScan(filters, buildScanSettings(), this, null); + } + + private void stop() { + isBut = false; + scanner.stopScan(scanCallback); + beans.clear(); + getUITaskDispatcher().asyncDispatch(new Runnable() { + @Override + public void run() { + historyItemProvider.notifyDataChanged(); + } + }); + } + + private ScanCallback scanCallback = new ScanCallback() { + @Override + public void onScanResult(int callbackType, ScanResult result) { + super.onScanResult(callbackType, result); + System.out.println("LOGLIST" + "/**/" + "RESULTDEVICE-------------------------------" + result.getDevice()); + } + + @Override + public void onBatchScanResults(List results) { + super.onBatchScanResults(results); + if (results.size() > 0) { + beans.clear(); + beans.addAll(results); + } + + getUITaskDispatcher().asyncDispatch(new Runnable() { + @Override + public void run() { + if (results.size() > 0) { + int size = results.size(); + } + } + }); + + for (ScanResult scanResult : results) { + + String deviceName = scanResult.getScanRecord().getDeviceName(); + if (deviceName != null && !deviceName.isEmpty()) { + System.out.println("LOGLISTALL" + "/--/--/ " + + "DEVICE =" + ((BleScanResult)scanResult.getDevice()).getPeripheralDevice().getDeviceAddr()+ ", " + +"DEVICENAME ="+scanResult.getScanRecord().getDeviceName()+", " + +"DATASTATUS ="+scanResult.getDataStatus()); + } + int size = results.size(); + System.out.println("LOGLISTALL" + "/**/" + "ALLSIZE = " + size); + } + getUITaskDispatcher().asyncDispatch(new Runnable() { + @Override + public void run() { + historyItemProvider.notifyDataChanged(); + } + }); + } + + @Override + public void onScanFailed(int errorCode) { + super.onScanFailed(errorCode); + System.out.println("onScanFailed"); + } + }; + + @Override + protected void onBackground() { + super.onBackground(); + } + + @Override + protected void onStop() { + super.onStop(); + } +} \ No newline at end of file diff --git a/entry/src/main/resources/base/element/string.json b/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..6becfe43fc3852c05cb8654d79518be7487f6947 --- /dev/null +++ b/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "app_name", + "value": "MyApplication" + }, + { + "name": "mainability_description", + "value": "Java_Phone_Empty Feature Ability" + }, + { + "name": "HelloWorld", + "value": "Hello World" + } + ] +} \ No newline at end of file diff --git a/entry/src/main/resources/base/graphic/background_ability_main.xml b/entry/src/main/resources/base/graphic/background_ability_main.xml new file mode 100644 index 0000000000000000000000000000000000000000..c0c0a3df480fa387a452b9c40ca191cc918a3fc0 --- /dev/null +++ b/entry/src/main/resources/base/graphic/background_ability_main.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/entry/src/main/resources/base/graphic/background_list.xml b/entry/src/main/resources/base/graphic/background_list.xml new file mode 100644 index 0000000000000000000000000000000000000000..1629bd1a5ce8d90ff3c1a9c9ab543bb6079c7a0d --- /dev/null +++ b/entry/src/main/resources/base/graphic/background_list.xml @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/entry/src/main/resources/base/layout/ability_main.xml b/entry/src/main/resources/base/layout/ability_main.xml new file mode 100644 index 0000000000000000000000000000000000000000..84da3f7f39bcfac4b040cb6dc5f0fa8c319e9bd5 --- /dev/null +++ b/entry/src/main/resources/base/layout/ability_main.xml @@ -0,0 +1,83 @@ + + + + + +