Android 后台 Wifi 扫描前台服务
Android Background Wifi Scanning Foreground Service
我正在尝试每 10 秒扫描一次 Wifi。我制作了一个 Android 前台服务来实现这一点。该应用程序具有所有正确的权限,并且确实 获取本地 Wifi 热点列表。但是,它只执行一次。我试图实现一个线程每 10 秒执行一次,如下面的代码所示。 Log.d()
消息每 10 秒记录一次,但 Wifi 在第一次打印后未打印。
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.IBinder;
import android.os.Looper;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class ForegroundService extends Service {
private WifiManager wifiManager;
public static final String CHANNEL_ID = "ForegroundServiceChannel";
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
String input = intent.getStringExtra("inputExtra");
createNotificationChannel();
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Foreground Service")
.setContentText(input)
.setSmallIcon(R.drawable.ic_stat_name)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
//do heavy work on a background thread
wifiManager = (WifiManager) getApplicationContext().getSystemService(getApplicationContext().WIFI_SERVICE);
if (!wifiManager.isWifiEnabled()) {
//Toast.makeText(this, "WiFi is disabled ... We need to enable it", Toast.LENGTH_LONG).show();
wifiManager.setWifiEnabled(true);
}
registerReceiver(wifiReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
while (true) {
Log.d("Test","00000000000000");
scanWifi();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
//stopSelf();
return START_NOT_STICKY;
}
private void scanWifi() {
wifiManager.startScan();
Toast.makeText(this, "Scanning WiFi ...", Toast.LENGTH_SHORT).show();
}
BroadcastReceiver wifiReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
List<ScanResult> results = wifiManager.getScanResults();
unregisterReceiver(this);
for (ScanResult scanResult : results) {
Log.d("WIFI",scanResult.SSID + " - " + scanResult.capabilities);
}
}
};
@Override
public void onDestroy() {
super.onDestroy();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel serviceChannel = new NotificationChannel(
CHANNEL_ID,
"Foreground Service Channel",
NotificationManager.IMPORTANCE_DEFAULT
);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(serviceChannel);
}
}
}
public class NetworkStateChecker {
public static int TYPE_WIFI = 1;
public static int TYPE_MOBILE = 2;
public static int TYPE_NOT_CONNECTED = 0;
public static int getConnectivityStatus(Context context) {
try {
TimeUnit.SECONDS.sleep(10); // Sleeps 10 seconds.
} catch (InterruptedException e) {
e.printStackTrace();
}
ConnectivityManager cm = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
if (activeNetwork!=null) {
if(activeNetwork.getType() == ConnectivityManager.TYPE_WIFI)
return TYPE_WIFI;
if(activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE)
return TYPE_MOBILE;
}
return TYPE_NOT_CONNECTED;
}
public static String getConnectivityStatusString(Context context) {
int conn = NetworkStateChecker.getConnectivityStatus(context);
String status = null;
if (conn == NetworkStateChecker.TYPE_WIFI) {
status = "Wifi enabled";
} else if (conn == NetworkStateChecker.TYPE_MOBILE) {
status = "Mobile data enabled";
} else if (conn == NetworkStateChecker.TYPE_NOT_CONNECTED) {
status = "Not connected to Internet";
}
return status;
}
}
使用上述方法class 每 10 秒检查一次可用的网络连接...
接下来在 broadcase 接收器中输入以下代码
String status = NetworkStateChecker.getConnectivityStatusString(context);
使用以下权限
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
..............
<receiver
android:name="in.phoenix.services.NetworkChangeReceiver"
android:label="NetworkChangeReceiver" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="android.net.wifi.WIFI_STATE_CHANGED"/>
</intent-filter>
</receiver>
我认为你应该删除 unregisterReceiver(this);从 onRecieve 并将其放在 onDestroy()
我正在尝试每 10 秒扫描一次 Wifi。我制作了一个 Android 前台服务来实现这一点。该应用程序具有所有正确的权限,并且确实 获取本地 Wifi 热点列表。但是,它只执行一次。我试图实现一个线程每 10 秒执行一次,如下面的代码所示。 Log.d()
消息每 10 秒记录一次,但 Wifi 在第一次打印后未打印。
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.IBinder;
import android.os.Looper;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class ForegroundService extends Service {
private WifiManager wifiManager;
public static final String CHANNEL_ID = "ForegroundServiceChannel";
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
String input = intent.getStringExtra("inputExtra");
createNotificationChannel();
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Foreground Service")
.setContentText(input)
.setSmallIcon(R.drawable.ic_stat_name)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
//do heavy work on a background thread
wifiManager = (WifiManager) getApplicationContext().getSystemService(getApplicationContext().WIFI_SERVICE);
if (!wifiManager.isWifiEnabled()) {
//Toast.makeText(this, "WiFi is disabled ... We need to enable it", Toast.LENGTH_LONG).show();
wifiManager.setWifiEnabled(true);
}
registerReceiver(wifiReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
while (true) {
Log.d("Test","00000000000000");
scanWifi();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
//stopSelf();
return START_NOT_STICKY;
}
private void scanWifi() {
wifiManager.startScan();
Toast.makeText(this, "Scanning WiFi ...", Toast.LENGTH_SHORT).show();
}
BroadcastReceiver wifiReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
List<ScanResult> results = wifiManager.getScanResults();
unregisterReceiver(this);
for (ScanResult scanResult : results) {
Log.d("WIFI",scanResult.SSID + " - " + scanResult.capabilities);
}
}
};
@Override
public void onDestroy() {
super.onDestroy();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel serviceChannel = new NotificationChannel(
CHANNEL_ID,
"Foreground Service Channel",
NotificationManager.IMPORTANCE_DEFAULT
);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(serviceChannel);
}
}
}
public class NetworkStateChecker {
public static int TYPE_WIFI = 1;
public static int TYPE_MOBILE = 2;
public static int TYPE_NOT_CONNECTED = 0;
public static int getConnectivityStatus(Context context) {
try {
TimeUnit.SECONDS.sleep(10); // Sleeps 10 seconds.
} catch (InterruptedException e) {
e.printStackTrace();
}
ConnectivityManager cm = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
if (activeNetwork!=null) {
if(activeNetwork.getType() == ConnectivityManager.TYPE_WIFI)
return TYPE_WIFI;
if(activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE)
return TYPE_MOBILE;
}
return TYPE_NOT_CONNECTED;
}
public static String getConnectivityStatusString(Context context) {
int conn = NetworkStateChecker.getConnectivityStatus(context);
String status = null;
if (conn == NetworkStateChecker.TYPE_WIFI) {
status = "Wifi enabled";
} else if (conn == NetworkStateChecker.TYPE_MOBILE) {
status = "Mobile data enabled";
} else if (conn == NetworkStateChecker.TYPE_NOT_CONNECTED) {
status = "Not connected to Internet";
}
return status;
}
}
使用上述方法class 每 10 秒检查一次可用的网络连接...
接下来在 broadcase 接收器中输入以下代码
String status = NetworkStateChecker.getConnectivityStatusString(context);
使用以下权限
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
..............
<receiver
android:name="in.phoenix.services.NetworkChangeReceiver"
android:label="NetworkChangeReceiver" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="android.net.wifi.WIFI_STATE_CHANGED"/>
</intent-filter>
</receiver>
我认为你应该删除 unregisterReceiver(this);从 onRecieve 并将其放在 onDestroy()