Sid
Sid

Reputation: 2862

Security Exception: Permission 'android.permission.LOCATION_HARDWARE' not granted

I am developing an app in which I am tracking location using the tower location. So I am using the geo location api to track the location and accessing the phone state to get the network details.

This worked well, suddenly it started giving the security exception for LOCATION_HARDWARE permission.

I also tried to give the permission in manifest as well as requesting the permission runtime. But at runtime it asks for only location and the phone state permission not for the location_hardware permission. And then it crashes with security exception.

I am not getting for which purpose it is asking for the location_hardware permission.

I am stuck up here.

    public class MainActivity extends AppCompatActivity {

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

        setUpUI();
 public void setUpUI()
    {
     TrackingJob.schedulePeriodic(); // crashing here
    }
    }
    }
}

Tracking Job :

    public class TrackingJob extends Job {

    static final String TAG = "tracking";

    @NonNull
    @Override
    protected Result onRunJob(Params params) {

        Intent pi = new Intent(getContext(), GetLocationService.class);

        getContext().startService(pi);

        return Result.SUCCESS;
    }

    public static void schedulePeriodic() {
        new JobRequest.Builder(TrackingJob.TAG)
                .setPeriodic(TimeUnit.MINUTES.toMillis(15), TimeUnit.MINUTES.toMillis(15))
                .setUpdateCurrent(true)
                .setPersisted(true)
                .build()
                .schedule();

    }
}

GetLocationServer :

public class GetLocationService extends IntentService {
    String networkSubType = "";
    SessionData mSessionData;
    private SharedPreferences preferences;

    public GetLocationService() {
        super("GetLocationService");
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        if (ContextCompat.checkSelfPermission(GetLocationService.this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
                && ContextCompat.checkSelfPermission(GetLocationService.this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {


            mSessionData = new SessionData(GetLocationService.this);

            Calendar calendarSet = Calendar.getInstance();
            Calendar calendarNow = Calendar.getInstance();

            calendarSet.set(Calendar.HOUR_OF_DAY, 7); // hour
            calendarSet.set(Calendar.MINUTE, 00); // minute
            calendarSet.set(Calendar.SECOND, 0); // second

            Calendar calendarEnd = Calendar.getInstance();

            calendarEnd.set(Calendar.HOUR_OF_DAY, 20); // hour
            calendarEnd.set(Calendar.MINUTE, 00); // minute
            calendarEnd.set(Calendar.SECOND, 0); // second


            SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            System.out.println(calendarNow.getTime());
// Output "Wed Sep 26 14:23:28 EST 2012"

            String currentTime = format1.format(calendarNow.getTime());
            System.out.println(currentTime);

            if (calendarNow.compareTo(calendarSet) >= 0 && calendarNow.compareTo(calendarEnd) <= 0) {

                TelephonyManager telephonyManager = (TelephonyManager) GetLocationService.this.getSystemService(Context.TELEPHONY_SERVICE);
                GsmCellLocation cellLocation = (GsmCellLocation) telephonyManager.getCellLocation();

                ConnectivityManager connectivityManager = (ConnectivityManager) GetLocationService.this.getSystemService(Context.CONNECTIVITY_SERVICE);//?????????
                NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo();

                if (cellLocation != null) {

                    int cellid = cellLocation.getCid();
                    int celllac = cellLocation.getLac();

                    if (activeNetInfo != null) {
                        networkSubType = activeNetInfo.getSubtypeName();
                    }

                    String networkOperator = telephonyManager.getNetworkOperator();

                    int mcc = Integer.parseInt(networkOperator.substring(0, 3));
                    int mnc = Integer.parseInt(networkOperator.substring(3));

                    String networkOperatorName = telephonyManager.getNetworkOperatorName();
                    int type = telephonyManager.getNetworkType();


                    Log.d("CellLocation", cellLocation.toString());
                    Log.d("GSM CELL ID", String.valueOf(cellid));
                    Log.d("GSM Location Code", String.valueOf(celllac));


                    Log.d("MCC", String.valueOf(mcc));
                    Log.d("MNC", String.valueOf(mnc));
                    Log.d("NetworkOperatorName", networkOperatorName);
                    Log.d("radioType", String.valueOf(type));
                    Log.d("Network subtype name", networkSubType);


                    AddLocationAsyncTask addLocationAsyncTask = new AddLocationAsyncTask(GetLocationService.this);
                    addLocationAsyncTask.execute(mSessionData.getString("user_id", ""), String.valueOf(cellid), String.valueOf(celllac), String.valueOf(mcc), String.valueOf(mnc),
                            networkOperatorName, networkSubType, currentTime);

                //    LocationUtility.scheduleJob(getApplicationContext());

                }
            }
        }
    }
}

How can I solve this? Please help with this.

Thank you..

EDIT : Runtime permissions:

public class StartUpActivity extends AppCompatActivity {

    RelativeLayout relativeLayout;
    public int mShortAnimationDuration = 5000;
    private Button btnRegister,btnLogin;
    private final static int MY_PERMISSIONS_REQUEST_ACCESS_LOCATION = 10;
    private SessionData mSessionData;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_start_up);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        mSessionData = new SessionData(StartUpActivity.this);


        if (ContextCompat.checkSelfPermission(StartUpActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                && ContextCompat.checkSelfPermission(StartUpActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
                && ContextCompat.checkSelfPermission(StartUpActivity.this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED
                && ContextCompat.checkSelfPermission(StartUpActivity.this, Manifest.permission.LOCATION_HARDWARE) != PackageManager.PERMISSION_GRANTED) {

            ActivityCompat.requestPermissions(StartUpActivity.this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.READ_PHONE_STATE,Manifest.permission.LOCATION_HARDWARE},
                    MY_PERMISSIONS_REQUEST_ACCESS_LOCATION);

        }
        else {

            if(!mSessionData.getString("user_id","").equals(""))
            {
                Intent i = (new Intent(StartUpActivity.this, MainActivity.class));
                i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
                i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
                i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(i);
                finish();
            }
            else {

                setUpUI();
                listeners();
            }
        }
    }

    public void setUpUI()
    {

        relativeLayout = (RelativeLayout) findViewById(R.id.relativeLayout);
        btnLogin = (Button) findViewById(R.id.button_login);
        btnRegister = (Button) findViewById(R.id.button_register);
    }

    public void listeners()
    {

        btnRegister.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                Intent i = (new Intent(StartUpActivity.this, SignUpActivity.class));
                i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
                i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
                i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(i);
                finish();

            }
        });

        btnLogin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                Intent i = (new Intent(StartUpActivity.this, LoginActivity.class));
                i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
                i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
                i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(i);
                finish();
            }
        });
    }
    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        switch (requestCode) {

            case MY_PERMISSIONS_REQUEST_ACCESS_LOCATION: {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    setUpUI();
                    listeners();

                } else {

                    CommonUtils.showAlert(StartUpActivity.this,"Please accept the permissions to proceed.",getString(R.string.app_name));
                    ActivityCompat.requestPermissions(StartUpActivity.this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.READ_PHONE_STATE,Manifest.permission.LOCATION_HARDWARE},
                            MY_PERMISSIONS_REQUEST_ACCESS_LOCATION);
                }
                return;
            }     
        }
    }
}

Manifest permissions:

   <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_COARSE_LOCATION" />

    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-feature android:name="android.hardware.location.network"/>

Upvotes: 1

Views: 1823

Answers (2)

user9619255
user9619255

Reputation:

add ACCESS_FINE_LOCATION with targeting APIs 20 and below

Upvotes: 0

HedeH
HedeH

Reputation: 3034

Quoted from here: https://developer.android.com/guide/topics/manifest/uses-feature-element.html#permissions

If your app targets Android 5.0 (API level 21) or higher and uses the ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission in order to receive location updates from the network or a GPS, respectively, you must also explicitly declare that your app uses the android.hardware.location.network or android.hardware.location.gps hardware features.

Add it like this to your AndroidManifest.xml file outside of your <application/> tag:

<uses-feature android:name="android.hardware.location.network"/>

<application>
  ...
</application>

If the location feature is not a "must have" feature in your app in order for the app to work properly, also add this to the uses-feature tag - android:required="false"

You still have to ask for location permission at runtime

Upvotes: 1

Related Questions