-3

我在嘗試更新我的compileSdkVersion和TargetSdkversion大於22後出現此錯誤。好像我在執行doInBackground方法中的任何GUI任務,但我是無法弄清楚。我會非常感謝解決方案。致命異常:java.lang.SecurityException:需要ACCESS_COARSE_LOCATION或ACCESS_FINE_LOCATION權限

這是我的堆棧跟蹤:類WlanInfoAdapter.java:72

E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1 
        Process: xy.abc.xyz.xy, PID: 15246 
        java.lang.RuntimeException: An error occurred while executing doInBackground() 
    at android.os.AsyncTask$3.done(AsyncTask.java:309) 
    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354) 
    at java.util.concurrent.FutureTask.setException(FutureTask.java:223) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:242) 
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
at java.lang.Thread.run(Thread.java:818) 
Caused by: java.lang.SecurityException: Need ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission to get scan results 
at android.os.Parcel.readException(Parcel.java:1599) 
at android.os.Parcel.readException(Parcel.java:1552) 
at android.net.wifi.IWifiManager$Stub$Proxy.getScanResults(IWifiManager.java:1066) at android.net.wifi.WifiManager.getScanResults(WifiManager.java:1311) 
at xy.abc.xyz.xy.config.WlanInfoAdapter.getNewItems(WlanInfoAdapter.java:72) 
         at xy.abc.xyz.xy.android.data.ChangeableArrayAdapter$1.doInBackground(ChangeableArrayAdapter.java:78) 
         at xy.abc.xyz.xy.android.data.ChangeableArrayAdapter$1.doInBackground(ChangeableArrayAdapter.java:74) 
         at android.os.AsyncTask$2.call(AsyncTask.java:295) 
         at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
         at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)  
         at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)  
         at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)  
         at java.lang.Thread.run(Thread.java:818)  

方法是在這裏:低於changeableArrayAdapter.java類示值誤差

@Override 
    protected List<WlanInfo> getNewItems() { 
     WifiManager wifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); 
     List<ScanResult> scanResults = wifiManager.getScanResults(); 
     List<WlanInfo> infoList = new ArrayList<>(scanResults.size()); 

     WifiInfo connectionInfo = wifiManager.getConnectionInfo(); 

     try { 
      List<WifiConfiguration> configuredNetworks = wifiManager.getConfiguredNetworks(); 
      Map<String, WifiConfiguration> configuredNetworkIds = new HashMap<>(); 
      for (WifiConfiguration configuredNetwork : configuredNetworks) { 
       if (configuredNetwork.SSID != null) { 
        configuredNetworkIds.put(WlanInfo.cleanSSID(configuredNetwork.SSID), configuredNetwork); 
       } else { 

        wifiManager.removeNetwork(configuredNetwork.networkId); 
       } 
      } 

      for (ScanResult scanResult : scanResults) { 
       WlanInfo wlanInfo = new WlanInfo(scanResult); 
       WifiConfiguration configuration = configuredNetworkIds.get(wlanInfo.getSSID()); 
       wlanInfo.setConfiguration(configuration); 
       wlanInfo.setIsActive(configuration != null && configuration.networkId == connectionInfo.getNetworkId()); 


       if (showUnknown || wlanInfo.isConfigured() || wlanInfo.isOpen()) { 
        infoList.add(wlanInfo); 
       } 
      } 
     } 
     catch (Exception e) { e.printStackTrace(); return null; } 
     return infoList; 
    } 

法中給出。它在那裏getNewItems()方法被調用: ChangeableArrayAdapter.java:78 ChangeableArrayAdapter.java:74

public void triggerRefresh() { 
     AsyncTask<Void, Void, List<T>> asyncTask = new AsyncTask<Void, Void, List<T>>() { 
      @Override 
      protected List<T> doInBackground(Void... objects) { 


       return getNewItems(); 

       //return null; 
      } 

回答

0

這些

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

也加入您的AndroidManifest.xmlapplication標籤的Android版本> = 23,則需要請求在運行時的權限

 if (ContextCompat.checkSelfPermission(YourActivity.this, 
          Manifest.permission.ACCESS_FINE_LOCATION) 
          != PackageManager.PERMISSION_GRANTED 
          && 
          ContextCompat.checkSelfPermission(YourActivity.this, 
            Manifest.permission.ACCESS_COARSE_LOCATION) 
            != PackageManager.PERMISSION_GRANTED) { 
         askForLocationPermissions(); 
     } else { 
      //do your work 
    } 

而且

private void askForLocationPermissions() { 

     // Should we show an explanation? 
     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(YourActivity.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) { 
//          //Do nothing 
         } 
        }) 
        .show(); 

      // Show an expanation to the user *asynchronously* -- don't block 
      // this thread waiting for the user's response! After the user 
      // sees the explanation, try again to request the permission. 

     } else { 

      // No explanation needed, we can request the permission. 
      ActivityCompat.requestPermissions(this, 
        new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 
        LOCATION_PERMISSION_REQUEST_CODE); 

      // MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION is an 
      // app-defined int constant. The callback method gets the 
      // result of the request. 
     } 
    } 

另外

@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)) { 
        //Do you work 
       } 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; 
    } 
+0

粗略位置的運行時權限感謝您的完整解釋。我想知道如果我應該使LOCATION_PERMISSION_REQUEST_CODE最終staic變量並將其值設置爲1? – LanguageMaster

+0

@LanguageMaster是的,這正是它是什麼 –

+0

你是偉大的曼。你讓我今天一整天都感覺很好。非常感謝..工作 – LanguageMaster

0

您需要添加ACCESS_COARSE_LOCATIONACCESS_FINE_LOCATION的權限到您的Android清單文件。

+0

感謝您的回答。 – LanguageMaster

0

如果你的目標API 22只,那麼你需要在你的Android清單文件中添加這2 許可

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

如果你的目標爲Android的棉花糖(API 23及以上)您需要在您的應用中授予運行時權限。

+0

感謝您的回答。我已經在清單文件中添加了兩個權限。我的應用程序仍在崩潰。我想我會嘗試在我的應用程序中授予運行時權限。我想問,這是你在談論什麼https://developer.android.com/training/permissions/requesting.html,如果不是請給我提供正確的鏈接,如果可能的話。會非常感謝 – LanguageMaster

+0

是的,只有這一點。或者你可以谷歌它如何添加在Android –

相關問題