web-dev-qa-db-ja.com

Oreo(8.1.0)では、正しいWifi SSIDを取得できません。 SSIDを使用してwifiに接続されているにもかかわらず、<unknown ssid>を表示しています

Androidで現在接続されているwifi SSIDを確認する必要があります。それぞれOreo 8.1.0およびOreo 8.0を搭載したNokia 6およびOnePlus 5で確認しました。異なるOSバージョンのその他の電話は、このコードで正常に機能しています。私のコードに何か問題はありますか?

private WifiInfo wifiInfo;
private String ssid = "";
private WifiManager wifiManager;

private boolean getWifiStatus() {
    wifiManager= (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
    wifiInfo = wifiManager.getConnectionInfo();
    ssid = "";
    ssid = wifiInfo.getSSID();
    ConnectivityManager cm =
            (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    boolean isWiFi = false;
    if(activeNetwork != null){
        isWiFi = activeNetwork.getType() == ConnectivityManager.TYPE_WIFI;
    }

    Log.d(TAG, "getWifiStatus: " + ssid);
    if(ssid.contains("TripleMZim") && wifiManager.isWifiEnabled() && isWiFi ){
        return true;
    }
    else{
        return false;
    }
}

マニフェストファイルの権限:

<uses-permission Android:name="Android.permission.ACCESS_WIFI_STATE"/>
<uses-permission Android:name="Android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission Android:name="Android.permission.INTERNET"/>
9
Zim

Oreo 8.1以降のデバイスでは、ユーザーの位置を推測できるため、接続されたSSIDを取得する前に、粗いロケーションランタイム許可とロケーションサービスをオンにする必要があります。

詳細は こちらから入手可能

this に関連する

9
behelit

AndroidでWIFI情報(SSIDなど)を取得する方法はさまざまです。

WifiManager serviceなど、それらの一部はすでにここにリストされています。

しかし、OPの質問の場合:

私のコードに何か問題はありますか?

いいえ、問題はコードにありません。予期しない動作の主な理由は、最新のAndroidリリースのセキュリティパッチが原因です。

パッチ(またはアップデートを取得しなかったデバイス)の前に、ハッカーはwifi情報から漏洩した機密情報を盗むことができました。

たとえば、ハッカーは Dangerous Permission[〜#〜] location [〜#〜] でのみアクセス可能なデバイスジオロケーションを取得できます。ランタイムであり、いつでも取り消すことができます。しかし他方では、 WifiInfo は、インストール時に付与されて取り消せない Normal PermissionAndroid.permission.ACCESS_WIFI_STATEでのみアクセス可能です。そうすれば、ハッカーは許可メカニズムをバイパスし、通常の許可のみを使用して危険な許可からデータにアクセスできます。

この問題はCVE-2018-9489によって報告および追跡されました。詳細については、こちらをご覧ください。 WIFIを介した機密情報の公開

したがって、これらの問題が発生する理由は、アプリがACCESS_COARSE_LOCATIONまたはACCESS_FINE_LOCATIONを保持していない限り、Androidが敏感なwifi情報をブロックするためです。

したがって、これらのアクセス許可を明示的に要求した場合(およびユーザーによって許可された場合)、コードは正常に機能するはずです。

例えば:

マニフェスト

<uses-permission Android:name="Android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission Android:name="Android.permission.ACCESS_WIFI_STATE"/>

アクティビティ

private static final int LOCATION = 1;
protected void onStart() {
   super.onStart();
   //Assume you want to read the SSID when the activity is started
   tryToReadSSID();
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    if(grantResults[0] == PackageManager.PERMISSION_GRANTED && requestCode == LOCATION){
        //User allowed the location and you can read it now
        tryToReadSSID();
    }
}

private void tryToReadSSID() {
    //If requested permission isn't Granted yet
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        //Request permission from user
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION);
    }else{//Permission already granted 
        WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
        if(wifiInfo.getSupplicantState() == SupplicantState.COMPLETED){
            String ssid = wifiInfo.getSSID();//Here you can access your SSID
            System.out.println(ssid);
        }
    }
}
13
Nikita Kurtin

Android Oreoでは、ConnectivityManagerを使用してwifi SSIDを知ることができます。

許可

<uses-permission Android:name="Android.permission.ACCESS_NETWORK_STATE"/>

SSIDを取得するコード

ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo();
if (info != null && info.isConnected()) {
    String ssid = info.getExtraInfo();
    Log.d(TAG, "WiFi SSID: " + ssid);
}

これはAndroid Oreo 8.1.0でテストされています。SSIDは二重引用符で囲まれています。

9
Yaswant Narayan

マニフェストで許可をリクエストする必要があります:

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

あなたの活動でそれを要求します:

    private void grantPermm()
{

    try
    {
        if (ContextCompat.checkSelfPermission(MainScreenActivity.this,
                  Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED)

        {

        }
        else
        {

            ActivityCompat.requestPermissions(MainScreenActivity.this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    101);
        }

    }
    catch (Exception xx){}

}

次に、この関数を使用します。

    public  static String  getWifiName(Context context)
{
    String result="";
    try {
        WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        if (manager.isWifiEnabled())
        {
            WifiInfo wifiInfo = manager.getConnectionInfo();
            if (wifiInfo != null)
            {
                NetworkInfo.DetailedState state = WifiInfo.getDetailedStateOf(wifiInfo.getSupplicantState());
                if (state == NetworkInfo.DetailedState.CONNECTED || state == NetworkInfo.DetailedState.OBTAINING_IPADDR)
                {
                    result = wifiInfo.getSSID();
                    if(result.equalsIgnoreCase("<unknown ssid>"))
                    {
                        Toast.makeText(context,"You are connected to mobile data", Toast.LENGTH_SHORT).show();
                        result="";
                    }

                    return result;
                }
                else
                {
                    Toast.makeText(context,"WIFI not connected", Toast.LENGTH_SHORT).show();
                    return "";
                }
            }
            else
            {
                Toast.makeText(context,"No WIFI Information", Toast.LENGTH_SHORT).show();
                return "";
            }
        }
        else
        {
            Toast.makeText(context,"WIFI not enabled", Toast.LENGTH_SHORT).show();
            return "";
        }
    }
    catch (Exception xx)
    {
        Toast.makeText(context, xx.getMessage().toString(), Toast.LENGTH_SHORT).show();
        return "";
    }
}
1
Osama Ibrahim

API 29(Android 10)をターゲットにしている場合、要求されるロケーション許可は、ACCESS_COARSE_LOCATIONだけでなく、ACCESS_FINE_LOCATIONに対するものでなければなりません。上記のサンプルコードの大部分は問題ありませんが、一部の回答はテキストで誤解を招く可能性があります。

https://developer.Android.com/about/versions/10/privacy/changes

0
Nicholas Hardy

Yaswant Narayanとbehelitの回答を試しても問題が発生する場合は、SSIDを取得する際にデバイスでロケーション/ GPSが有効になっていることを確認してください。 Android Oreo以上のデバイスで関連する権限を取得しましたが、ユーザーがロケーション/ GPSをオフにすると、それらのデバイスから取得できます。

0
venkat

電話状態の読み取りのランタイム許可を要求する必要があります。これは、セキュリティを強化するために含まれています。

コードは次のとおりです。

    TelephonyManager telephonyManager = (TelephonyManager) getContext()
            .getSystemService(Context.TELEPHONY_SERVICE);

    String IMEI ="";

    if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
       ActivityCompat.requestPermissions(getActivity(),
               new String[]{Manifest.permission.READ_PHONE_STATE},
               123);

    }
    int permission = ContextCompat.checkSelfPermission(getContext(),
            Manifest.permission.READ_PHONE_STATE);
    if(permission == PackageManager.PERMISSION_GRANTED){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            IMEI = telephonyManager.getImei();
        }
        else{
            IMEI = telephonyManager.getDeviceId();
        }
    }
0
Abhishek Kumar