【问题标题】:How to get available wifi list from backend android service?如何从后端 android 服务获取可用的 wifi 列表?
【发布时间】:2018-07-02 13:26:17
【问题描述】:

我正在开发一个 android 应用程序,它需要定期检查可用的 wifi 列表,即使应用程序从后台被杀死也是如此。所以我正在考虑使用服务从后端检查它。在这种情况下,我在从服务中获取可用的 wifi 列表时遇到了一些问题。我在互联网上搜索,发现大部分仅针对活动的解决方案。虽然我试过了但没有用。

请注意。当我在直接活动中使用它们时,相同的代码也有效。但它在服务类中不起作用。

我的服务代码是.....

package com.example.sodrulaminshaon.ringmodecontroller;


import android.Manifest;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.os.IBinder;
import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.support.v4.content.ContextCompat;
import android.util.Log;

import java.util.List;
import java.util.Set;

/**
 * Created by Sodrul Amin Shaon on 22-Jun-18.
 */

public class MyService extends Service {
WifiManager wifiManager;
WifiReceiver receiverWifi;
private static final String LIST_TESTING = "ListTest";
@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    SharedPreferences preferences = getSharedPreferences(Constants.PREFERENCE_NAME,MODE_PRIVATE);
    boolean auto = preferences.getBoolean(Constants.AUTO_CONTROL_STR,false);
    //if(MainActivity.getAutoControl())
    if(auto)
    {
        wifiManager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
        if (!wifiManager.isWifiEnabled())
        {
            wifiManager.setWifiEnabled(true);
        }
        Log.i(LIST_TESTING,"Wifi is enabled. Now going to check the available list.");
        receiverWifi = new WifiReceiver();
        registerReceiver(receiverWifi,
                new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
        wifiManager.startScan();
    }
    stopSelf();
    return START_STICKY;
}

class WifiReceiver extends BroadcastReceiver {

    // This method call when number of wifi connections changed
    public void onReceive(Context c, Intent intent) {

        StringBuilder sb = new StringBuilder();
        List<ScanResult> wifiList = wifiManager.getScanResults();
        Log.i(LIST_TESTING,"Inside scan result receiver. Scan result size: "+wifiList.size());
        sb.append("\n        Number Of Wifi connections :"+wifiList.size()+"\n\n");

        for(int i = 0; i < wifiList.size(); i++){

            sb.append(new Integer(i+1).toString() + ". ");
            sb.append(wifiList.get(i).SSID).toString();
            sb.append("\n\n");
        }
        Log.i(LIST_TESTING,sb.toString());
    }


}
@Override
public IBinder onBind(Intent intent) {
    return null;
}
@Override
public void onDestroy() {
    // I want to restart this service again in one hour
    SharedPreferences preferences = getSharedPreferences(Constants.PREFERENCE_NAME,MODE_PRIVATE);
    boolean auto = preferences.getBoolean(Constants.AUTO_CONTROL_STR,false);
    if(auto)
    {
        if(wifiManager.isWifiEnabled())unregisterReceiver(receiverWifi);
        AlarmManager alarm = (AlarmManager) getSystemService(ALARM_SERVICE);
        alarm.set(
                alarm.RTC_WAKEUP,
                System.currentTimeMillis() + (1000 * 10),
                PendingIntent.getService(this, 0, new Intent(this, MyService.class), 0)
        );
    }
}

}

无需担心权限问题。我在应用程序启动时获得了必要的权限。我仍然在分享参与的许可。

private void getPermission(){
    if (ContextCompat.checkSelfPermission(MainActivity.this,
            Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED
            &&
            ContextCompat.checkSelfPermission(MainActivity.this,
                    Manifest.permission.ACCESS_COARSE_LOCATION)
                    != PackageManager.PERMISSION_GRANTED) {
        askForLocationPermissions();
    }
}
private void askForLocationPermissions() {

    if (ActivityCompat.shouldShowRequestPermissionRationale(this,
            Manifest.permission.ACCESS_FINE_LOCATION)) {

        new android.support.v7.app.AlertDialog.Builder(this)
                .setTitle("Location permessions needed")
                .setMessage("you need to allow this permission!")
                .setPositiveButton("Sure", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        ActivityCompat.requestPermissions(MainActivity.this,
                                new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                                LOCATION_PERMISSION_REQUEST_CODE);
                    }
                })
                .setNegativeButton("Not now", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {

                    }
                })
                .show();

    } else {

        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                LOCATION_PERMISSION_REQUEST_CODE);
    }
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
    switch (requestCode) {
        case LOCATION_PERMISSION_REQUEST_CODE:
            if (isPermissionGranted(permissions, grantResults, Manifest.permission.ACCESS_FINE_LOCATION)) {
            } else {
                Toast.makeText(this, "Can not proceed! i need permission" , Toast.LENGTH_SHORT).show();
            }
            break;
    }
}
public static boolean isPermissionGranted(@NonNull String[] grantPermissions, @NonNull int[] grantResults,
                                          @NonNull String permission) {
    for (int i = 0; i < grantPermissions.length; i++) {
        if (permission.equals(grantPermissions[i])) {
            return grantResults[i] == PackageManager.PERMISSION_GRANTED;
        }
    }
    return false;
} 

我可以保证我的服务运行良好。它尝试每隔 10 秒检查一次可用的 wifi 列表。

我想知道的是。此代码无法打印可用的 wifi 列表。仅用于 MyService 类中的信息

Log.i(LIST_TESTING,"Wifi is enabled. Now going to check the available list.");

此行正在连续打印。但其他两行

Log.i(LIST_TESTING,"Inside scan result receiver. Scan result size: "+wifiList.size());
Log.i(LIST_TESTING,sb.toString());

没有被执行。谁能帮帮我....

【问题讨论】:

  • 当你有不工作的代码,然后提出minimal reproducible example。我们不知道您读过什么,尝试过什么,以及为什么不起作用。所以请不要指望我们会重复之前写下的内容。您还应该在help center 上花一些时间来了解如何/在这里问什么。不是这样的。
  • 嗨。感谢您的意见。我已经编辑了我的问题。请立即检查,看看您是否可以帮助我。当您将此问题标记为重复时,我向您保证此代码在活动中运行得很好。但不能在服务中工作。

标签: java android


【解决方案1】:

因为没有人回答。我进一步尝试并发现了我的代码的问题。在我的代码中,我调用了 stopSelf(); 里面 public int onStartCommand(Intent intent, int flags, int startId) 方法。这导致我的服务在启动后立即停止。这意味着我注册的broadCastReceiver 也被丢弃了。结果没有打印wifi列表。我很愚蠢地编写了这段代码并发现了错误。

【讨论】:

    【解决方案2】:

    您应该创建一个广播接收器来获取可用 wifi 网络的列表。

    private final BroadcastReceiver mWifiScanReceiver = new BroadcastReceiver() {
    
            @Override
            public void onReceive(Context c, Intent intent) {
                if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
                    List<ScanResult> mScanResults = mWifiManager.getScanResults();
    
                }
            }
        }
    

    也在清单中添加这些行。

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    

    在 oncreate() 方法中注册监听器

    mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
    registerReceiver(mWifiScanReceiver,
            new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
    mWifiManager.startScan();
    

    有关此POST 的更多详细信息。

    【讨论】:

    • 您好,先生。如果您检查我的代码,我已经添加了该部分。而且我已经看过这个帖子,你已经链接了很多次,它只适用于我已经提到过的活动。谢谢。
    猜你喜欢
    • 2022-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-02
    • 2012-04-12
    相关资源
    最近更新 更多