-4

I am creating an application which will give user signal strength of a network. I searched a bit and I found this link that we can use CellInfoGsm. But I am getting security exception:

Log:

 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)

I have added the required permission also in my manifest file.

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

Here is my 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();*/

        }
    }
}

How to resolve this security exception, or is there any other way round.

gaurav tiwari
  • 1,093
  • 1
  • 9
  • 28
  • you need to ask runtime permission for ACCESS_COARSE_LOCATION if you are running your apk >=23 api – AskNilesh Oct 05 '17 at 12:03
  • 1
    Possible duplicate of [How to check Grants Permissions at Run-Time?](https://stackoverflow.com/questions/30549561/how-to-check-grants-permissions-at-run-time) and bazillions similar questions – Selvin Oct 05 '17 at 12:11
  • Possible duplicate of [Android permission doesn't work even if I have declared it](https://stackoverflow.com/questions/32635704/android-permission-doesnt-work-even-if-i-have-declared-it) – Selvin Oct 05 '17 at 12:13
  • @Selvin sorry done – AskNilesh Oct 05 '17 at 12:16

1 Answers1

0

Starting from Android 6.0, You need to add permission in manifest as well as check for location permission during the runtime.

You can use my library to handle runtime permissions easily. https://github.com/nabinbhandari/Android-Permissions

Nabin Bhandari
  • 15,949
  • 6
  • 45
  • 59
  • Don't use this library becuase it is wrong ... it cause memory leak and doesn't work with "Don't keep activities" – Selvin Jan 17 '18 at 13:04
  • No it does not cause memory leak as I have nullified the static reference before the callback is called. – Nabin Bhandari Jan 17 '18 at 14:23
  • It leaks Activity ... as handler may live longer than Activity which is referenced in it ... [this is similar situation to this](https://android-developers.googleblog.com/2009/01/avoiding-memory-leaks.html) – Selvin Jan 17 '18 at 14:24