2015-11-16 8 views
5

मैं वाईफ़ाई अंक की जांच करने के लिए एक ऐप विकसित कर रहा हूं।एंड्रॉइड वाईफाईमेनगर getScanResult शिकायतें ACCESS_COARSE_LOCATION या ACCESS_FINE_LOCATION अनुमति की आवश्यकता है हालांकि घोषित अनुमति

मुझे त्रुटि मिल रही है "java.lang.SecurityException: wifiManager.getScanResults() पर स्कैन परिणामों को प्राप्त करने के लिए ACCESS_COARSE_LOCATION या ACCESS_FINE_LOCATION अनुमति की आवश्यकता है, भले ही मैंने पहले ही उन अनुमतियों को घोषित किया हो।

मुख्य गतिविधि

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

मैं कर रहा हूँ एसडीके 6.0

पर मैं इसी तरह की question मनाया, लेकिन समाधान लागू नहीं होता है के बाद से मैं पहले से ही अनुमति की घोषणा की।

कोई भी जानता है कि समस्या क्या हो सकती है? धन्यवाद।

+0

अपना आईडीई पुनरारंभ करने का प्रयास करें। –

+1

साफ करने और – sean

+0

बनाने का प्रयास करें आईडीई को पुनरारंभ करने का प्रयास करें, ऐप अनइंस्टॉल करें, क्लीन प्रोजेक्ट बनाएं, अभी भी एक ही त्रुटि – kevin0228ca

उत्तर

5

Android M में, आप से पहले हर बार का उपयोग शुरू अनुमति, जो उपयोगकर्ताओं पर PermissionModel में खतरनाक के रूप में परिभाषित किया गया है के लिए पूछने की जरूरत है, यह इस तरह के रूप में:

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; 
    } 

अपनी गतिविधि को यह करें:

private static final int REQUEST_FINE_LOCATION=0 

और साथ रनटाइम के दौरान इसे लोड:

loadPermissions(Manifest.permission.ACCESS_FINE_LOCATION,REQUEST_FINE_LOCATION); 

वें मूल्यांकन करने के लिए आपकी अनुमति के अनुरोध के ई परिणाम, आप विधि onRequestPermissionsResult ओवरराइड कर सकते हैं:

@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 या ACCESS_COARSE_LOCATION आवश्यक है। वैध परिणाम प्राप्त करने के लिए, आपको Setting जैसी अनुमति को जीपीएस चालू करना होगा या PEERS_MAC_ADDRESS प्राप्त करना होगा।

1

MADAO is right: आपको वाईफ़ाई एक्सेस पॉइंट सूची प्राप्त करने के लिए जीपीएस चालू करना चाहिए।

लेकिन मुझे PEERS_MAC_ADDRESS के बारे में निश्चित नहीं है।

/** 
* 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); 
    } 
} 

पहले ifcanReadPeerMacAddresses जाँच कर रहा है जो checkPeersMacAddress() के लिए कोड है:: आप the source code (लाइन 957) को देखें, तो

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

आप अनुमति जोड़ देते हैं तो आप if (!canReadPeerMacAddresses && !isActiveNetworkScorer && !isLocationEnabled()) { बायपास कर सकते हैं। मैंने परीक्षण किया है लेकिन मुझे अनुमति और अक्षम स्थान का उपयोग करके वाईफ़ाई मैक सूची नहीं मिल सकती है।

+0

क्या आप कह रहे हैं कि आपने यह सत्यापित किया है कि आप यह अनुमति देते हैं और जब आप 'mContext.checkCallingOrSelfPermission ( एंड्रॉइड.Manifest.permission.PEERS_MAC_ADDRESS) कहते हैं == PackageManager.PERMISSION_GRANTED' आप सच हो जाते हैं? यदि हां, तो संभवतः कॉल को 'ApplyAccessPermission() 'पर कॉल अवरुद्ध कर दिया गया है? – davidgyoung

+0

नहीं। जैसा कि मैंने बताया है कि मैंने अनुमति PEERS_MAC_ADDRESS जोड़ दी है लेकिन स्थान को चालू किए बिना पहुंच बिंदु सूची प्राप्त करने में सफलता नहीं मिली है। इसके अलावा मैं अपने ऐप को एक सिस्टम एप बना देता हूं लेकिन फिर भी स्थान चालू किए बिना एक्सेस पॉइंट सूची प्राप्त करने में विफलता करता हूं। निजी शून्य enforceAccessPermission() { mContext.enforceCallingOrSelfPermission (android.Manifest.permission.ACCESS_WIFI_STATE, "WifiService") ';: –

+0

' enforceAccessPermission के लिए कोड() 'नीचे की तरह है } 'और मेरे पास मैनिफेस्ट में 'ACCESS_WIFI_STATE' अनुमति है। –

संबंधित मुद्दे