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"/>
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);
}
}
}
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は二重引用符で囲まれています。
マニフェストで許可をリクエストする必要があります:
<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 "";
}
}
API 29(Android 10)をターゲットにしている場合、要求されるロケーション許可は、ACCESS_COARSE_LOCATIONだけでなく、ACCESS_FINE_LOCATIONに対するものでなければなりません。上記のサンプルコードの大部分は問題ありませんが、一部の回答はテキストで誤解を招く可能性があります。
https://developer.Android.com/about/versions/10/privacy/changes
Yaswant Narayanとbehelitの回答を試しても問題が発生する場合は、SSIDを取得する際にデバイスでロケーション/ GPSが有効になっていることを確認してください。 Android Oreo以上のデバイスで関連する権限を取得しましたが、ユーザーがロケーション/ GPSをオフにすると、それらのデバイスから取得できます。
電話状態の読み取りのランタイム許可を要求する必要があります。これは、セキュリティを強化するために含まれています。
コードは次のとおりです。
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();
}
}