wifiManager.getScanResult() returns 空值
wifiManager.getScanResult() returns null value
我正在搜索扫描可用的 wifi 网络,但方法 getScanResults() returns 为空列表。
我包含了所有需要的权限:
android.permission.ACCESS_COARSE_LOCATION
android.permission.CHANGE_WIFI_STATE
android.permission.ACCESS_FINE_LOCATION
android.permission.ACCESS_WIFI_STATE
主要activityclass是:
public class Home extends Activity {`
Context context;
WifiManager wifiManager = null;
WiFiReceiver wifiReceiver = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home);
context = this;
wifiManager = (WifiManager)
context.getSystemService(Context.WIFI_SERVICE);
wifiReceiver = new WiFiReceiver(wifiManager);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
registerReceiver(wifiReceiver, intentFilter);
wifiManager.startScan();
List<ScanResult> results = wifiReceiver.results;
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(wifiReceiver);
}
}
广播接收器是:
public class WiFiReceiver extends BroadcastReceiver {`
public List<ScanResult> results;
private WifiManager wifiManager;
public WiFiReceiver(WifiManager wifiManager) {
this.wifiManager = wifiManager;
}
@Override
public void onReceive(Context context, Intent intent) {
boolean success = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false);
if (success) {
results = wifiManager.getScanResults();
Log.e("wiFi Manager", "Done");
} else {
Log.e("wiFi Manager", "Scan failure");
}
}
}
问题是您假设 startScan()
会立即产生结果,但实际上它只执行所说的,开始扫描。在 WiFiReceiver
中的 onReceive
之前,您正在访问 results
变量,这就是为什么它始终为空的原因(您的日志记录应该确认这一点)。
您需要做的是像代码 here 那样在准备就绪时使用回调来获取结果。请注意 onReceive
方法如何调用 scanSuccess()
,结果仅在 scanSuccess()
中访问,而不是在调用 startScan()
后立即访问。
还要注意他们如何通过检查布尔值 startScan()
returns
来检查启动扫描是否真的成功
从 API 级别 23 (Android 6.0 Marshmallow) 我们需要请求 运行-time 用户端的许可。具体来说 ACCESS_FINE_LOCATION。在wifiManager.startScan()之前需要检查权限是否被授予,如果没有授予权限,则需要调用requestPermissions()。
这里有一个例子:
public void startScanningWifi(){if ( Build.VERSION.SDK_INT >= 23){
if (ActivityCompat.checkSelfPermission(context, Manifest.
permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(context,
Manifest.permission.ACCESS_COARSE_LOCATION) !=
PackageManager.PERMISSION_GRANTED ){
requestPermissions(new String[]{
Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_CODE_ASK_PERMISSIONS);
Log.i(TAG, "User location NOT ENABLED, waiting for permission");
}else{
//Start scanning for wifi
}}
您还需要在 activity
中包含此方法
@Override
public void onRequestPermissionsResult(int requestCode,
String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_ASK_PERMISSIONS:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//start scanning
wifiManager.startScan();
} else {
// Permission for location Denied
Toast.makeText( this,"Well cant help you then!" ,
Toast.LENGTH_SHORT)
.show();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
别忘了在您的 activity 中声明这一点
private final int REQUEST_CODE_ASK_PERMISSIONS = 1;
我正在搜索扫描可用的 wifi 网络,但方法 getScanResults() returns 为空列表。
我包含了所有需要的权限:
android.permission.ACCESS_COARSE_LOCATION
android.permission.CHANGE_WIFI_STATE
android.permission.ACCESS_FINE_LOCATION
android.permission.ACCESS_WIFI_STATE
主要activityclass是:
public class Home extends Activity {`
Context context;
WifiManager wifiManager = null;
WiFiReceiver wifiReceiver = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home);
context = this;
wifiManager = (WifiManager)
context.getSystemService(Context.WIFI_SERVICE);
wifiReceiver = new WiFiReceiver(wifiManager);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
registerReceiver(wifiReceiver, intentFilter);
wifiManager.startScan();
List<ScanResult> results = wifiReceiver.results;
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(wifiReceiver);
}
}
广播接收器是:
public class WiFiReceiver extends BroadcastReceiver {`
public List<ScanResult> results;
private WifiManager wifiManager;
public WiFiReceiver(WifiManager wifiManager) {
this.wifiManager = wifiManager;
}
@Override
public void onReceive(Context context, Intent intent) {
boolean success = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false);
if (success) {
results = wifiManager.getScanResults();
Log.e("wiFi Manager", "Done");
} else {
Log.e("wiFi Manager", "Scan failure");
}
}
}
问题是您假设 startScan()
会立即产生结果,但实际上它只执行所说的,开始扫描。在 WiFiReceiver
中的 onReceive
之前,您正在访问 results
变量,这就是为什么它始终为空的原因(您的日志记录应该确认这一点)。
您需要做的是像代码 here 那样在准备就绪时使用回调来获取结果。请注意 onReceive
方法如何调用 scanSuccess()
,结果仅在 scanSuccess()
中访问,而不是在调用 startScan()
后立即访问。
还要注意他们如何通过检查布尔值 startScan()
returns
从 API 级别 23 (Android 6.0 Marshmallow) 我们需要请求 运行-time 用户端的许可。具体来说 ACCESS_FINE_LOCATION。在wifiManager.startScan()之前需要检查权限是否被授予,如果没有授予权限,则需要调用requestPermissions()。
这里有一个例子:
public void startScanningWifi(){if ( Build.VERSION.SDK_INT >= 23){
if (ActivityCompat.checkSelfPermission(context, Manifest.
permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(context,
Manifest.permission.ACCESS_COARSE_LOCATION) !=
PackageManager.PERMISSION_GRANTED ){
requestPermissions(new String[]{
Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_CODE_ASK_PERMISSIONS);
Log.i(TAG, "User location NOT ENABLED, waiting for permission");
}else{
//Start scanning for wifi
}}
您还需要在 activity
中包含此方法 @Override
public void onRequestPermissionsResult(int requestCode,
String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_ASK_PERMISSIONS:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//start scanning
wifiManager.startScan();
} else {
// Permission for location Denied
Toast.makeText( this,"Well cant help you then!" ,
Toast.LENGTH_SHORT)
.show();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
别忘了在您的 activity 中声明这一点
private final int REQUEST_CODE_ASK_PERMISSIONS = 1;