2015-11-16 2 views
5

Ich entwickle eine App, um WLAN-Zugangspunkte zu überprüfen.Android WifiManager getScanResult beschwert sich ACCESS_COARSE_LOCATION oder ACCESS_FINE_LOCATION Erlaubnis, obwohl die Berechtigung erklärt wurde

Ich erhalte den Fehler "java.lang.SecurityException: Brauche ACCESS_COARSE_LOCATION oder ACCESS_FINE_LOCATION Erlaubnis, Scan-Ergebnisse zu erhalten" bei wifiManager.getScanResults(), obwohl ich diese Berechtigungen bereits deklariert habe.

Haupttätigkeit

public class MainActivity extends AppCompatActivity { 

WifiManager wifiManager; 
String[] wifis; 
WifiReceiver wifiReceiver; 

ListView wifiListView; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    wifiListView = (ListView) findViewById(R.id.wifi_list); 

    wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE); 
    wifiReceiver = new WifiReceiver(); 
    wifiManager.startScan(); 
} 

protected void onPause() { 
    unregisterReceiver(wifiReceiver); 
    super.onPause(); 
} 

protected void onResume() { 
    registerReceiver(wifiReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)); 
    super.onResume(); 
} 

private class WifiReceiver extends BroadcastReceiver { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     List<ScanResult> wifiScanList = wifiManager.getScanResults(); 
     wifis = new String[wifiScanList.size()]; 

     for (int i = 0; i < wifiScanList.size(); i++) { 
      wifis[i] = wifiScanList.get(i).toString(); 
     } 

     wifiListView.setAdapter(new ArrayAdapter<>(getApplicationContext(), android.R.layout.simple_list_item_1, wifis)); 
    } 
} 

manifest

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
package="com.example.sample"> 

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

<application 
    android:allowBackup="true" 
    android:icon="@mipmap/ic_launcher" 
    android:label="@string/app_name" 
    android:supportsRtl="true" 
    android:theme="@style/AppTheme"> 
    <activity android:name=".MainActivity"> 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 
</application> 

Ich bin auf SDK 6.0

Ich beobachtete ähnliche question, aber Lösung gilt nicht, da ich bereits die Erlaubnis erklärt.

Wer weiß, was Problem sein könnte? Vielen Dank.

+0

Versuchen Sie, Ihre IDE neu zu starten. –

+1

Versuchen Sie sauber und bauen – sean

+0

versuchte IDE neu starten, App deinstallieren, Projekt löschen, Projekt erstellen, immer noch gleichen Fehler – kevin0228ca

Antwort

5

In Android M, müssen Sie für die Erlaubnis bitten, die vor als gefährlich PermissionModel den Benutzer definiert wird beginnen jedes Mal mit, es als solches:

private boolean mayRequestLocation() { 
     if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { 
      return true; 
     } 
     if (checkSelfPermission(ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { 
      return true; 
     } 
     if (shouldShowRequestPermissionRationale(ACCESS_FINE_LOCATION)) { 
      Snackbar.make(mView, R.string.permission_rationale, Snackbar.LENGTH_INDEFINITE) 
        .setAction(android.R.string.ok, new View.OnClickListener() { 
         @Override 
         @TargetApi(Build.VERSION_CODES.M) 
         public void onClick(View v) { 
          requestPermissions(new String[]{ACCESS_FINE_LOCATION}, REQUEST_FINE_LOCATION); 
         } 
        }); 
     } else { 
      requestPermissions(new String[]{ACCESS_FINE_LOCATION}, REQUEST_FINE_LOCATION); 
     } 
     return false; 
    } 

diese Aktivität zu Ihrer hinzufügen:

private static final int REQUEST_FINE_LOCATION=0 

und laden sie es während der Laufzeit mit:

loadPermissions(Manifest.permission.ACCESS_FINE_LOCATION,REQUEST_FINE_LOCATION); 

zu bewerten th e Ergebnisse Ihrer Berechtigungsanfrage, können Sie onRequestPermissionsResult Methode überschreiben:

@Override 
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { 
    switch (requestCode) { 
     case REQUEST_FINE_LOCATION: { 
      // If request is cancelled, the result arrays are empty. 
      if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
       // The requested permission is granted. 
      } 
      else{ 
       // The user disallowed the requested permission. 
      } 
      return; 
     } 

} 
0

ACCESS_FINE_LOCATION oder ACCESS_COARSE_LOCATION notwendig. Um ein gültiges Ergebnis zu erhalten, müssen Sie auch GPS aktivieren oder eine PEERS_MAC_ADDRESS Erlaubnis wie Setting erhalten.

1

MADAO is right: Sie sollten GPS einschalten, um die WIFI Access Point Liste zu bekommen.

Aber ich bin nicht sicher über PEERS_MAC_ADDRESS. Wenn Sie bei the source code (Linie 957) aussehen:

/** 
* Return the results of the most recent access point scan, in the form of 
* a list of {@link ScanResult} objects. 
* @return the list of results 
*/ 
public List<ScanResult> getScanResults(String callingPackage) { 
    enforceAccessPermission(); 
    int userId = UserHandle.getCallingUserId(); 
    int uid = Binder.getCallingUid(); 
    boolean canReadPeerMacAddresses = checkPeersMacAddress(); 
    boolean isActiveNetworkScorer = 
      NetworkScorerAppManager.isCallerActiveScorer(mContext, uid); 
    boolean hasInteractUsersFull = checkInteractAcrossUsersFull(); 
    long ident = Binder.clearCallingIdentity(); 
    try { 
     if (!canReadPeerMacAddresses && !isActiveNetworkScorer 
       && !isLocationEnabled()) { 
      return new ArrayList<ScanResult>(); 
     } 
     if (!canReadPeerMacAddresses && !isActiveNetworkScorer 
       && !checkCallerCanAccessScanResults(callingPackage, uid)) { 
      return new ArrayList<ScanResult>(); 
     } 
     if (mAppOps.noteOp(AppOpsManager.OP_WIFI_SCAN, uid, callingPackage) 
       != AppOpsManager.MODE_ALLOWED) { 
      return new ArrayList<ScanResult>(); 
     } 
     if (!isCurrentProfile(userId) && !hasInteractUsersFull) { 
      return new ArrayList<ScanResult>(); 
     } 
     return mWifiStateMachine.syncGetScanResultsList(); 
    } finally { 
     Binder.restoreCallingIdentity(ident); 
    } 
} 

Die erste if Überprüfung wird canReadPeerMacAddresses, die den Code für checkPeersMacAddress() ist:

/** 
* Returns true if the caller holds PEERS_MAC_ADDRESS. 
*/ 
private boolean checkPeersMacAddress() { 
    return mContext.checkCallingOrSelfPermission(
      android.Manifest.permission.PEERS_MAC_ADDRESS) == PackageManager.PERMISSION_GRANTED; 
} 

Wenn Sie die Berechtigung hinzufügen können Sie if (!canReadPeerMacAddresses && !isActiveNetworkScorer && !isLocationEnabled()) { umgehen. Ich habe getestet, aber ich kann keine WIFI-MAC-Liste bekommen, indem ich nur die Erlaubnis benutze und den Standort deaktiviere.

+0

Sagen Sie, dass Sie überprüft haben, dass Sie diese Berechtigung verwenden, und wenn Sie 'mContext.checkCallingOrSelfPermission ( android.Manifest.permission.PEERS_MAC_ADDRESS) == PackageManager.PERMISSION_GRANTED 'aufrufen, werden Sie wahr? Wenn ja, wird der Zugriff möglicherweise durch den Aufruf von 'enforceAccessPermission()' blockiert? – davidgyoung

+0

Nein. Wie ich gesagt habe, habe ich die Erlaubnis PEERS_MAC_ADDRESS hinzugefügt, aber es ist mir nicht gelungen, die Liste der Access Points zu bekommen, ohne den Standort einzuschalten. Darüber hinaus mache ich meine App zu einer System-App, scheitere aber immer noch die Access-Point-Liste, ohne den Standort einzuschalten. –

+0

Der Code für 'enforceAccessPermission()' ist wie folgt: 'private void EnforceAccessPermission() { mContext.enforceCallingOrSelfPermission (android.Manifest.permission.ACCESS_WIFI_STATE, " WifiService "); } 'Und ich habe die' ACCESS_WIFI_STATE' Berechtigung in Manifest. –

Verwandte Themen