2015-07-22 11 views
10

Her birkaç dakikada bir kablosuz tarama başlatmak için AlarmManager (setRepeating ile) kullanarak bir PendingIntent kullanıyorum (IntentService kullanarak). Çoğu cihazda ve çoğu durumda, bununla ilgili bir sorun yoktur.SecurityException

java.lang.RuntimeException: Unable to start service [email protected] with Intent { act=com.myapp.android.ACTION_PERFORM_WIFI_SCAN flg=0x4 cmp=com.myapp/com.mayapp.android.service.MyService (has extras) }: java.lang.SecurityException: Permission Denial: broadcast from android asks to run as user -1 but is calling from user 0; this requires android.permission.INTERACT_ACROSS_USERS_FULL or android.permission.INTERACT_ACROSS_USERS 
     at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3021) 
     at android.app.ActivityThread.-wrap17(ActivityThread.java) 
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1443) 
     at android.os.Handler.dispatchMessage(Handler.java:102) 
     at android.os.Looper.loop(Looper.java:148) 
     at android.app.ActivityThread.main(ActivityThread.java:5415) 
     at java.lang.reflect.Method.invoke(Method.java) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:725) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:615) 
Caused by: java.lang.SecurityException: Permission Denial: broadcast from android asks to run as user -1 but is calling from user 0; this requires android.permission.INTERACT_ACROSS_USERS_FULL or android.permission.INTERACT_ACROSS_USERS 
     at android.os.Parcel.readException(Parcel.java:1599) 
     at android.os.Parcel.readException(Parcel.java:1552) 
     at android.net.wifi.IWifiManager$Stub$Proxy.startScan(IWifiManager.java:1045) 
     at android.net.wifi.WifiManager.startScan(WifiManager.java:1088) 
     ... 

Benim uygulamasından PendingIntent yaratıyorum: Ancak birkaç cihaz üzerinde aşağıdaki hatayı alıyorum (. Herhangi bir test cihazda hatayı yeniden Could Bu kullanıcının cihazdan kilitlenme günlük olan) bu yüzden WifiManager'dan atılan SecurityException için bir neden göremiyorum (Bu özellikle nadiren gerçekleştiği için). bu neden ne

mContext.registerReceiver(mWifiScanReceiver, new IntentFilter(
        WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)); 

boolean ok = mWifiManager.startScan(); 

Herhangi bir fikir şöyledir:

PendingIntent koddan başlattı IntentService

mı?

+0

Bu Bildiriminize içine biraz eklemeye çalıştım, bu android.permission.INTERACT_ACROSS_USERS_FULL veya android.permission.INTERACT_ACROSS_USERS premission gerektirdiğini söylüyor? –

+3

@ Berťák, bu izin bir sistem izni ve hiçbir uygulama (bir sistem uygulaması olmadığı sürece) bunu isteyebilir. Ayrıca, 'startScan'ı çağırmak ve sonuçları 'SCAN_RESULTS_AVAILABLE_ACTION' üzerinden yayınlamak için gerekli değildir. Garip olan şey budur ... – Muzikant

+0

IntentService'iniz farklı bir kullanıcı bağlamında çalışır. Telefonunuzda bir veya daha fazla kullanıcı oturum açmış gibi görünüyor. – ShihabSoft

cevap

3

Bu, android m için yeni uygulama izinleri nedeniyle oluyor. wifimanager's getScanResults() for api 23 kaynak kodunun üzerindeki yoruma bakın - Dolayısıyla

/** 
    * Return the results of the latest access point scan. 
    * @return the list of access points found in the most recent scan. An app must hold 
    * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or 
    * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission 
    * in order to get valid results. 
    */ 
public List<ScanResult> getScanResults() { 
     try { 
      return mService.getScanResults(mContext.getOpPackageName()); 
     } catch (RemoteException e) { 
      return null; 
     } 
    } 

, çalışma zamanında ilgili izinleri kullanıcıya sormak zorunda kalacaktır. senin manifest- API 23 Gönderen

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

bu izinleri koyun itibaren bunu kullanmak için kullanıcı Konuma erişim için izin alınması gerekmektedir. Api düzeyine bağlı olarak bir izin denetimi kullanmanızı ve yalnızca izinler verildiğinde niyetini başlatmanızı öneririm. Daha bu-

if (Build.VERSION.SDK_INT >= 23) { 
int hasReadLocationPermission = checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION); 
     if (hasReadLocationPermission != PackageManager.PERMISSION_GRANTED) { 
     if (!ActivityCompat.shouldShowRequestPermissionRationale(HomeActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)) { 
      showMessageOKCancel("You need to allow access to GPS", 
       new DialogInterface.OnClickListener() { 
       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        ActivityCompat.requestPermissions(HomeActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, GPS_ENABLE_REQUEST); 
       } 
       }); 
      return; 
     } 
     ActivityCompat.requestPermissions(HomeActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, GPS_ENABLE_REQUEST); 
     return; 
     } 
     if (locationManager != null && !locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { 
     gotoGPSEnableScreen(); 
     } else { 
     //Permissions granted and gps is on 
     launchService(true); 
     } 
} 

gibi şey sonuçları-

@Override 
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { 
    switch (requestCode) { 
     case GPS_ENABLE_REQUEST: 
     if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
      if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { 
      gotoGPSEnableScreen(); 
      } 
     } else { 
      launchService(false); 
     } 
     default: 
     return; 
    } 
    } 

UPDATE kontrol etmek:

android.permission.INTERACT_ACROSS_USERS_FULL imza seviyesi izindir. Sadece bu android ekleyin: protectionLevel = "signature" manifestinizde.

diğer ayrıntılar için sur bu daha sonra yapmak için

IntentService, 

yılında

onCreate() 

geçersiz kılmak için

http://developer.android.com/guide/topics/manifest/permission-element.html

<permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" android:protectionLevel="signature"/> 
+0

Ayrıntılı cevap için teşekkürler ama bu sorun için bir çözüm sunmuyor. SDK 23'teki izin değişikliklerinin farkındayım ve bildirimde sizden bahsettiğiniz izinler var, ancak bu, 'android'den yayınla' kullanıcı -1 olarak çalıştırmak için sorar, ancak kullanıcı 0'ı çağırıyor; Bu android.permission.INTERACT_ACROSS_USERS_FULL veya android.permission.INTERACT_ACROSS_USERS' gerektirir. Ayrıca, bu çok nadiren olur ve aynı hatayı aynı API düzeyinde aynı hatayı yeniden üretemedim – Muzikant

+0

Bir şey daha, cevabınızdaki kod parçacığı, hata alırken 'getScanResults' anlamına gelir startScan' – Muzikant

+0

@Muzikant wifimanager, startcsan'i çağırdıktan sonra tarama sonuçlarını almak için getScanResults'u çağırır. Ayrıca cevabımı güncelledim. –

0

gidiyoruz kontrol edebilirsiniz İçinde

super.onCreate() 

içinde arama yapın. Bu muhtemelen senin problemin gibi görünüyor.

-1

Sorununuz, farklı kullanıcılardan arıyor ve farklı kullanıcılarla çalışmayı istiyor ve android.permission.INTERACT_ACROSS_USERS_FULL gerektirir ve bu, imza düzeyi izni gerektirir.Sadece manifestosunda bu android:protectionLevel="signature"'u ekleyin.

fazla ayrıntı için kontrol edebilirsiniz bu

http://developer.android.com/guide/topics/manifest/permission-element.html

<permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" android:protectionLevel="signature"/>