问题
I have the following code in a service which is called with an AlarmManager (this works well) but when when I start the wifi scan (which returns true) I never receive the results in the BroadcastReceiver I created:
public class WifiCheckerService extends IntentService {
WifiManager wifiManager;
List<Wifi> savedWifis;
List<Wifi> wifisInRange;
List<ScanResult> wifisInRangeResults;
BroadcastReceiver broadcastReceiver;
public WifiCheckerService() {
super("WifiCheckerService");
}
@Override
public void onCreate() {
super.onCreate();
setScanAlwaysAvailable();
if(broadcastReceiver == null)
broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
check();
}
};
if (wifiManager == null)
wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
registerReceiver(broadcastReceiver,
new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
}
@Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
wifiManager.startScan();
}
}
private void check() {
// irrelevant stuff
Intent intent = new Intent(Constants.BROADCAST_UPDATE_WIFI);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
sendBroadcast(intent);
}
}
public List<Wifi> getSavedWifisInRange(List<Wifi> savedWifis,
List<ScanResult> wifisInRangeResults) {
List<Wifi> wifisInRange = new ArrayList<Wifi>();
for (Wifi wifi : savedWifis) {
for (int i = 0; i < wifisInRangeResults.size(); i++) {
if (wifi.getSsid().equals(wifisInRangeResults.get(i).SSID)) {
wifi.setRssi(String.valueOf(wifisInRangeResults.get(i).level));
wifisInRange.add(wifi);
}
}
}
return wifisInRange;
}
public void setScanAlwaysAvailable() {
/* Set scan always available if it is turned off*/
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR2) {
if (!wifiManager.isScanAlwaysAvailable()) {
startActivity(new Intent(WifiManager.ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE));
}
}
}
public boolean isTetheringActive() {
//irrelevant stuff
return false;
}
private boolean isAnySavedWifiInRange() {
//irrelevant stuff
return true;
}
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(wifiScanReceiver);
}
}
I have used BroadcastReceiver's with wifi scans before, but I don't know why this is not working.
What's wrong?
EDIT: AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.android.vending.BILLING" />
<application
android:name=".WifiSentinelApp"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".activities.MainActivity"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".activities.DonateActivity"
android:label="@string/donate"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar" />
<activity
android:name=".activities.SettingsActivity"
android:label="@string/settings"
android:screenOrientation="portrait" />
<receiver android:name=".receivers.AlarmReceiver" />
<receiver android:name=".receivers.BootReceiver"
android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service android:name=".services.WifiCheckerService" />
</application>
回答1:
My understanding of the IntentService is that it will only be active for the time needed to handle the request (ie, the time needed to run onHandleIntent()). I haven't tested your code, but my guess is that your broadcast receiver is being unregistered right away when onDestroy() runs, before the scan results are delivered. Probably an IntentService is not right for this. You might need to create a "regular" (long living background) service. Or, maybe it just makes more sense to have your BroadcastReceiver in the activity where you will show the scan results and get rid of this IntentService altogether. WifiManager::startScan() is asynchronous so it shouldn't be necessary to call that on a background service anyway.
来源:https://stackoverflow.com/questions/34497948/broadcast-receiver-with-wifi-scan-not-working