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()