Reputation: 2862
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
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