2017-10-05 127 views
-4

我正在創建一個應用程序,它將爲用戶提供網絡信號強度。我搜索了一下,我發現這個link,我們可以使用CellInfoGsm。但我得到安全例外:ACCESS_COARSE_LOCATION的安全例外

登錄:

Process: com.checksignal.checksignal, PID: 9732 
                      java.lang.SecurityException: getAllCellInfo: Neither user 10122 nor current process has android.permission.ACCESS_COARSE_LOCATION. 
                       at android.os.Parcel.readException(Parcel.java:1620) 
                       at android.os.Parcel.readException(Parcel.java:1573) 
                       at com.android.internal.telephony.ITelephony$Stub$Proxy.getAllCellInfo(ITelephony.java:3096) 
                       at android.telephony.TelephonyManager.getAllCellInfo(TelephonyManager.java:2894) 
                       at com.checksignal.checksignal.MainActivity$1.run(MainActivity.java:98) 
                       at android.os.Handler.handleCallback(Handler.java:746) 
                       at android.os.Handler.dispatchMessage(Handler.java:95) 
                       at android.os.Looper.loop(Looper.java:148) 
                       at android.app.ActivityThread.main(ActivityThread.java:5443) 
                       at java.lang.reflect.Method.invoke(Native Method) 
                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728) 
                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 

我在清單文件中添加所需的權限也。

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.checksignal.checksignal"> 
    <uses-permission android:name="android.permission.INTERNET" /> 
    <uses-permission android:name="android.permission.ACCESS_NETWORK_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:roundIcon="@mipmap/ic_launcher_round" 
     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> 

</manifest> 

這裏是我的MainActivity:

public class MainActivity extends AppCompatActivity { 

    Button _getGsmSignalStrengthButton; 
    TelephonyManager _telephonyManager; 
    ImageView _gmsStrengthImageView; 
    TextView _gmsStrengthTextView, _operatorName, _networkSpeed; 
    MyPhoneStateListener MyListener; 


    public static final int NETWORK_TYPE_EHRPD = 14; // Level 11 
    public static final int NETWORK_TYPE_EVDO_B = 12; // Level 9 
    public static final int NETWORK_TYPE_HSPAP = 15; // Level 13 
    public static final int NETWORK_TYPE_IDEN = 11; // Level 8 
    public static final int NETWORK_TYPE_LTE = 13; // Level 11 

    private Handler mHandler = new Handler(); 
    private long mStartRX = 0; 
    private long mStartTX = 0; 

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

     initializeViews(); 

     // Get a reference to the TelephonyManager and instantiate the GsmSignalStrengthListener. 
     // These will be used by the Button's OnClick event handler. 

     MyListener = new MyPhoneStateListener(); 
     _telephonyManager.listen(MyListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS); 
     _operatorName.setText(_telephonyManager.getNetworkOperatorName()); 
     Toast.makeText(getApplicationContext(),checkConnectivity(),Toast.LENGTH_LONG); 

     Log.d("connectivity",checkConnectivity()); 




     mStartRX = TrafficStats.getTotalRxBytes(); 
     mStartTX = TrafficStats.getTotalTxBytes(); 

     if (mStartRX == TrafficStats.UNSUPPORTED || mStartTX == TrafficStats.UNSUPPORTED) { 
      AlertDialog.Builder alert = new AlertDialog.Builder(this); 
      alert.setTitle("Uh Oh!"); 
      alert.setMessage("Your device does not support traffic stat monitoring."); 
      alert.show(); 
     } else { 
      mHandler.postDelayed(mRunnable, 1000); 
     } 

    } 

    private void initializeViews() { 

     _telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); 
     _gmsStrengthTextView = (TextView) findViewById(R.id.operator_name); 
     _operatorName = (TextView) findViewById(R.id.op_name); 
     _networkSpeed = (TextView)findViewById(R.id.network_speed); 
     // _gmsStrengthImageView = (ImageView) findViewById(R.id.imageView1); 
     _getGsmSignalStrengthButton = (Button) findViewById(R.id.myButton); 
    } 

    private final Runnable mRunnable = new Runnable() { 
     public void run() { 
      TextView RX = (TextView) findViewById(R.id.RX); 
      TextView TX = (TextView) findViewById(R.id.TX); 
      long rxBytes = TrafficStats.getTotalRxBytes() - mStartRX; 
      double receiveKb = rxBytes/1024; 
      RX.setText("receive Bytes:" + Double.toString(receiveKb)); 
      long txBytes = TrafficStats.getTotalTxBytes() - mStartTX; 
      double transmitKb = txBytes/1024; 
      TX.setText("Transmit Bytes: " + Double.toString(transmitKb)); 

      //GET SIGNAL STRENGTH OF MOBILE NETWORK 
      CellInfoGsm cellinfogsm = (CellInfoGsm)_telephonyManager.getAllCellInfo().get(0); 
      CellSignalStrengthGsm cellSignalStrengthGsm = cellinfogsm.getCellSignalStrength(); 
      cellSignalStrengthGsm.getDbm(); 
      _networkSpeed.setText(cellSignalStrengthGsm.getDbm()); 
      mHandler.postDelayed(mRunnable, 1000); 

     } 
    }; 

    private String checkConnectivity() { 
     ConnectivityManager manager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE); 
     NetworkInfo activeNetwork = manager.getActiveNetworkInfo(); 
     boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting(); 
     String networkType =""; 


     if (isConnected) { 
      if (activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE) { 

       Toast.makeText(getApplicationContext(), "your mobile network is connected", Toast.LENGTH_LONG).show(); 
       switch (activeNetwork.getSubtype()) { 
        case TelephonyManager.NETWORK_TYPE_1xRTT: 
         networkType = "NETWORK TYPE 1xRTT"; // ~ 50-100 kbps 
         break; 
        case TelephonyManager.NETWORK_TYPE_CDMA: 
         networkType = "NETWORK TYPE CDMA (3G) Speed: 2 Mbps";// ~ 14-64 kbps 
         break; 
        case TelephonyManager.NETWORK_TYPE_EDGE: 

         networkType = "NETWORK TYPE EDGE (2.75G) Speed: 100-120 Kbps"; // ~ 
        // 50-100 
        // kbps 

         break; 
        case TelephonyManager.NETWORK_TYPE_EVDO_0: 
         networkType = "NETWORK TYPE EVDO_0"; // ~ 400-1000 kbps 

         break; 
        case TelephonyManager.NETWORK_TYPE_EVDO_A: 
         networkType = "NETWORK TYPE EVDO_A"; // ~ 600-1400 kbps 

         break; 
        case TelephonyManager.NETWORK_TYPE_GPRS: 
         networkType = "NETWORK TYPE GPRS (2.5G) Speed: 40-50 Kbps"; // ~ 100 
        // kbps 

         break; 
        case TelephonyManager.NETWORK_TYPE_HSDPA: 
         networkType = "NETWORK TYPE HSDPA (4G) Speed: 2-14 Mbps"; // ~ 2-14 
        // Mbps 

         break; 
        case TelephonyManager.NETWORK_TYPE_HSPA: 
         networkType = "NETWORK TYPE HSPA (4G) Speed: 0.7-1.7 Mbps"; // ~ 
        // 700-1700 
        // kbps 

         break; 
        case TelephonyManager.NETWORK_TYPE_HSUPA: 
         networkType = "NETWORK TYPE HSUPA (3G) Speed: 1-23 Mbps"; // ~ 1-23 
        // Mbps 

         break; 
        case TelephonyManager.NETWORK_TYPE_UMTS: 
         networkType = "NETWORK TYPE UMTS (3G) Speed: 0.4-7 Mbps"; // ~ 400-7000 
        // kbps 
        // NOT AVAILABLE YET IN API LEVEL 7 

         break; 
        case MainActivity.NETWORK_TYPE_EHRPD: 
         networkType = "NETWORK TYPE EHRPD"; // ~ 1-2 Mbps 

         break; 
        case MainActivity.NETWORK_TYPE_EVDO_B: 
         networkType = "NETWORK_TYPE_EVDO_B"; // ~ 5 Mbps 

         break; 
        case MainActivity.NETWORK_TYPE_HSPAP: 
         networkType = "NETWORK TYPE HSPA+ (4G) Speed: 10-20 Mbps"; // ~ 10-20 
        // Mbps 

         break; 
        case MainActivity.NETWORK_TYPE_IDEN: 
         networkType = "NETWORK TYPE IDEN"; // ~25 kbps 

         break; 
        case MainActivity.NETWORK_TYPE_LTE: 
         networkType = "NETWORK TYPE LTE (4G) Speed: 10+ Mbps"; // ~ 10+ Mbps 

         break; 
        // Unknown 
        case TelephonyManager.NETWORK_TYPE_UNKNOWN: 
         networkType = "NETWORK TYPE UNKNOWN"; 

         break; 
        default: 
         networkType = ""; 
         break; 
       } 
      } 
      else if(activeNetwork.getType() == ConnectivityManager.TYPE_WIFI){ 
       networkType = "You are connected to WIFI"; 

      } 
     } 

     else{ 
      networkType = "You are not connected to any network"; 
     } 

     return networkType ; 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 

     _telephonyManager.listen(MyListener, PhoneStateListener.LISTEN_NONE); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     _telephonyManager.listen(MyListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS); 
    } 

    public class MyPhoneStateListener extends PhoneStateListener { 
     @Override 
     public void onSignalStrengthsChanged(SignalStrength signalStrength) { 
      super.onSignalStrengthsChanged(signalStrength); 

      /*Toast.makeText(getApplicationContext(), "Go to Firstdroid!!! GSM Cinr = " 
        + String.valueOf(signalStrength.getGsmSignalStrength()), Toast.LENGTH_SHORT).show();*/ 

     } 
    } 
} 

如何解決這個安全異常,或有任何其他方式輪。

+0

你需要問運行許可ACCESS_COARSE_LOCATION如果您運行的APK> = 23 API –

+1

可能重複[如何在運行時檢查的權限授予?(https://stackoverflow.com/questions/30549561/how-to-check-grants-permissions-at-run-time)和bazillions類似的問題 – Selvin

+0

[Android權限可能重複不起作用,即使我已經聲明](https://stackoverflow.com/questions/ 32635704/android-permission-doesnt-work-even-if-i-have-declared-it) – Selvin

回答

0

從Android 6.0開始,您需要在清單中添加權限並在運行時檢查位置權限。

您可以使用我的庫輕鬆處理運行時權限。 https://github.com/nabinbhandari/Android-Permissions

+0

不要使用這個庫,因爲它是錯誤的...它會導致內存泄漏並且不起作用與「不要保持活動」 – Selvin

+0

不,它不會導致內存泄漏,因爲我已經在調用回調之前使靜態引用無效。 –

+0

它泄漏活動...作爲處理程序可能比它引用的活動壽命更長... [這與此類似的情況](https://android-developers.googleblog.com/2009/01/avoiding-memory -leaks.html) – Selvin