androidscan
㈠ 【Android初级】android扫描WiFi列表的正确用法
最近有个需求,需要做一个扫描WiFi列表的功能,也在网上找了一些资料,但有些资料是有问题的,然后自己摸索了下,总结如下。
本地环境:
AS版本 3.0.1,DEMO APK 的 Min SDK Version 是 API 23,Target SDK Version 是 API 24,Compile SDK Version是 API 26,真机是Android 7.0
1、打开WiFi,并打开定位服务(在设置内找到定位服务-访问我的位置信息-开启)
2、在 onCreate 里面动态申请权限
String[] PERMS_INITIAL={Manifest.permission.ACCESS_FINE_LOCATION};
requestPermissions(PERMS_INITIAL,127);
3、在 onCreate 里面注册广播
IntentFilter filter =new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
registerReceiver(mReceiver, filter);
4、定义 mReceiver
private BroadcastReceivermReceiver =new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
List results =wifiManager.getScanResults();
if (results !=null) {
Log.d(TAG,"results size: " + results.size());
}
}
}
};
5、在layout里面定义一个Button,点击后开始扫描
WifiManager wifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);
boolean scanResult =wifiManager.startScan(); // 最好检查下返回值,因为这个方法可能会调用失败
Log.d(TAG,"scanResult: " + scanResult);
6、在 AndroidManifest.xml 里面声明权限
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
有人可能会有疑问,为什么在 onCreate里面动态申请了权限 ACCESS_FINE_LOCATION,又在 Manifest 里面重复声明了一次
经过本地验证,去掉其中任意一个,都拿不到WiFi扫描结果,也就是 onReceive 方法不会被执行(有不同结论的请留言共同探讨)
7、错误用法
boolean scanResult =wifiManager.startScan();
List list =wifiManager.getScanResults();
调用 startScan 之后立马调用 getScanResults,这个时候拿到的WiFi列表是上一次的扫描结果,不是最新的,一定要在广播接收器里面获取扫描结果。
㈡ Android蓝牙扫描
蓝牙扫描的目的在于发现设备或者接收设备广播,设备包括经典蓝牙设备和BLE蓝牙设备,这两种设备的扫描方式不同。
对于经典蓝牙设备,扫描是通过调用startDiscovery接口,返回的结果是通过BroadcastReceiver接收的,可以获取设备MAC地址,名称以及RSSI。
startDiscovery是个异步调用,会立即返回。如果不调用cancelDiscovery主动停止扫描的话,最多扫描12s。
广播主要监听以下几个Action:
BluetoothDevice.ACTION_FOUND
BluetoothAdapter.ACTION_DISCOVERY_STARTED
BluetoothAdapter.ACTION_DISCOVERY_FINISHED
另外要注意startDiscovery返回的设备不包括已配对设备,如要获取已配对设备,需要额外调用getBondedDevices。
对于BLE蓝牙设备,扫描是通过调用startLeScan接口,返回的结果是通过onLeScan回调,除了获得设备MAC地址,名称及RSSI之外还能获取设备广播,广播是以byte数组的形式表示的。
较新的Android版本提供了新的扫描接口,可更灵活地配置扫描策略,详情可参考官网文档,此处不再赘述。
一,需要打开以下权限
android.permission.BLUETOOTH
android.permission.ACCESS_COARSE_LOCATION
android.permission.BLUETOOTH_ADMIN
android.permission.ACCESS_FINE_LOCATION
另外还要注意动态权限问题,在Android 6.0(targetSdkVersion>=23)之后,需要动态申请获取用户位置的权限,不然获取不到设备扫描结果。
二,startDiscovery在大多数手机上是可以同时发现经典蓝牙和Ble的,但是startDiscovery的回调无法返回BLE的广播,所以无法通过广播识别设备,且startDiscovery扫描BLE的效率比startLeScan低很多。所以在实际应用中,还是startDiscovery和startLeScan分开扫,前者扫经典蓝牙,后者扫低功耗蓝牙。
三,startLeScan() 的时候,在onLeScan() 中不能做耗时操作,特别是周围的BLE设备多的时候,容易导致底层堵塞,如果有耗时操作请丢到子线程中去处理。如解析广播识别设备等操作可能会较耗时。
四,实践中发现同样一个设备,有的手机很容易就扫出来了,有的手机很难扫出来。这种情况建议可以多扫几次,每次扫描时间短一点。
㈢ android开发 如何实现扫描本地二维码图片
开源的二维码扫描库主要有zxing和zbar,zbar在iPos平台上应用比较成熟,而在Android平台上主流还是用zxing库,因此这里主要讲述如何利用zxing进行二维码开发。
如何将zxing的Android源码导入工程。
在导入zxing的android源码之前,先去官方下载zxing的源码http://code.google.com/p/zxing/downloads/list。
这里以1.6版本为例,zxing 1.6源码结构如下:
<?xmlversion="1.0"encoding="utf-8"?>
<manifestxmlns:android="http://schemas.android.com/apk/res/android"
package="com.qrcode"
android:versionCode="1"
android:versionName="1.0">
<uses-sdkandroid:minSdkVersion="7"/>
<uses-permissionandroid:name="android.permission.VIBRATE"/><!--震动权限-->
<uses-permissionandroid:name="android.permission.CAMERA"/>
<uses-featureandroid:name="android.hardware.camera"/><!--使用照相机权限-->
<uses-featureandroid:name="android.hardware.camera.autofocus"/><!--自动聚焦权限-->
<applicationandroid:icon="@drawable/icon"android:label="@string/app_name">
<activityandroid:name=".MainActivity"
android:label="@string/app_name">
<intent-filter>
<actionandroid:name="android.intent.action.MAIN"/>
<categoryandroid:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!--隐藏键盘--><!--全屏-->
<activity
android:configChanges="orientation|keyboardHidden"
android:name="com.zxing.activity.CaptureActivity"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:windowSoftInputMode="stateAlwaysHidden">
</activity>
</application>
</manifest>这种情况大致就可以实现二维码扫描了,想细化的话,还可以多看看安卓二维码扫描开发相关的教程
㈣ Android保活——蓝牙唤醒(主动kill掉也可唤醒)
项目需要后台保活,但无论怎么保活,只要用户主动kill掉,app依然是活不了。
发现了蓝牙唤醒这个方式,用户主动kill掉也可行。
Android 8.0开始提供了 startscan的方法,
public void startScan(ScanCallback callback)
public void startScan(List<ScanFilter> filters,ScanSettings settings,ScanCallback callback)
public int startScan(List<ScanFilter> filters,ScanSettings settings,PendingIntent callbackIntent)
第一个没有过滤条件,锁屏就停止扫描
第二个可以加过滤条件,锁屏不影响扫描
第三个的扫描结果由PendingIntent发送,即使app没有在运行,系统也可以扫描后唤醒app,这就是我们要的方法了。
PendingIntent是对Intent的封装,是满足某些条件或触发某些事件后才执行指定的行为,主要用于闹钟、通知、桌面部件。Android的四大组件之间通信用Intent,跨进程通信用PendingIntent。
Android 8.0 引进了Context.startForegroundService(),在系统创建服务后,应用需要在ANR发生前调用startForeground(int ,android.app.Notification),如果未及时调用该方法,系统将报ANR错误 。系统给前台服务的ANR时间是20秒。
用startScan蓝牙唤醒的原理是:app向系统订阅了扫描结果(预先加了过滤条件),当蓝牙连接断开的时候,设备就会发广播,这时系统就可以扫描到对应的广播,唤醒对应的service,这时想做什么操作就根据你的项目需要了。至于系统会为你扫描多久,这个还没测试。
(1)setScanMode有四个参数可以选 :
SCAN_MODE_BALANCED:在平衡电源模式下执行蓝牙LE扫描。返回扫描结果的速度能够很好地权衡扫描频率和功耗。
SCAN_MODE_LOW_LATENCY:扫描使用最高占空比。建议只在应用程序在前台运行时使用此模式。
SCAN_MODE_LOW_POWER:在低功耗模式下执行蓝牙LE扫描。这是默认的扫描模式,因为它消耗的能量最少。如果扫描应用程序不在前台,则强制执行此模式。
SCAN_MODE_OPPORTUNISTIC:一种特殊的蓝牙LE扫描模式。使用这种扫描模式的应用程序将被动地侦听其他扫描结果,而不启动BLE扫描本身
(2)settingBuilder.setMatchMode有两个参数可以选:
MATCH_MODE_AGGRESSIVE: 信号弱也会报告
MATCH_MODE_STICKY: 信号比较强和扫描到的次数比较多才会报告
(3)settingBuilder.setCallbackType也有其他参数可选,但适用的就一个
(4) ScanFilter 的过滤方法有几个,如下图,打勾的是测试了可行的,但只有第一个DeviceAddress有唯一性
㈤ 淫技:android无屏操作之adb操控wifi
1.开启wpa_supplicant服启樱务端
meta_wpa_supplicant.conf是配置文件,ctrl_interface是wpa_supplicant与wpa_cli通信的接口,ssid为要连接的wifi热点名称,key_mgmt为加密方式(NONE表示不加密 O(∩_∩)O~)。
2.wpa_cli连接wpa_supplicant
3.扫描wifi
4.使能network0
上面都是完整的语句,我们可以直接使用/system/bin/wpa_cli -iwlan0 -p /data/misc/wifi/sockets进入wifi命令模式,如下图所示,wifi命令模式下可以直接使用scan,status等指令
成功连上了TE-NonSignal的wifi,你可能会纳闷,怎么执行enable_network 0就连上了呢?手机怎悄旁丛么知道network 0是什么鬼呢?上面说了有个配置文件meta_wpa_supplicant.conf,有了这个配置文件就会自动连接TE-NonSignal网络了。
上面是使用配置文件去连接网络,当然我们也可以用命令行去连接网络啦
执行scan
然后执行scan_result,下图为扫描结果
例如我们要连启数个公共网络OPPO-SZ,首先我们执行
add_network 如下图返回4,说明接下来要连接的network的id为4
依次执行
set_network 4 ssid "OPPO-SZ"
set_network 4 key_mgmt NONE
enable_network 4
如下图,说明成功连接上wifi了