您好我正在构建一个应用程序我想访问手机的位置。但是,我似乎无法授予访问精确位置权限,因此我的应用程序在我正在测试的Android M手机中无法正常运行。 这是我的代码的一部分:
public class LocationMainActivity extends AppCompatActivity {
private ListView listView;
private static final String EXTERNAL_PERMISSIONS[] = new String[]{
Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.INTERNET};
private static final int EXTERNAL_CODE=1;
private boolean perm;
private Cursor cursor;
private DatabaseAdapt dbAdapt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_location_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar4);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
listView = (ListView)findViewById(R.id.locationContainer);
dbAdapt = new DatabaseAdapt(this);
dbAdapt.open();
cursor =dbAdapt.loadLocationTitles();
String [] from = new String[]{DatabaseAdapt.LOCATION_TITLE};
int [] to = new int[] {android.R.id.text1};
CursorAdapter cursorAdapter = new SimpleCursorAdapter(this,android.R.layout.simple_list_item_1,cursor,
from,to,0);
listView.setAdapter(cursorAdapter);
}
public void onDestroy(){
super.onDestroy();
cursor.close();
dbAdapt.close();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main,menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if(id==R.id.add_button);{
askForPerm();
if(perm){
Intent intent = new Intent(LocationMainActivity.this,LocationSecondActivity.class);
startActivity(intent);
}
else {
askForPerm();
}
}
return super.onOptionsItemSelected(item);
}
private void askForPerm () {
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
int w = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
int r = ContextCompat.checkSelfPermission(this, Manifest.permission.INTERNET);
if (w != PackageManager.PERMISSION_GRANTED && r != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, EXTERNAL_PERMISSIONS, EXTERNAL_CODE);
} else {
Toast.makeText(this, "Permissions already granted", Toast.LENGTH_SHORT).show();
perm=true;
}
}
@Override
public void onRequestPermissionsResult(int requestCode,String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case EXTERNAL_CODE:
if(ActivityCompat.checkSelfPermission(this,permissions[0])==PackageManager.PERMISSION_GRANTED)
{
perm=true;
}
else {
Toast.makeText(this,"Permissions denied",Toast.LENGTH_LONG).show();
perm=false;
}
break;
}
}
}
在此活动中,我要求权限,然后我才能添加新位置。应用程序定期移动到下一个活动,即使我第一次安装应用程序,也会显示授予toast的权限,这看起来有点奇怪。我使用相同的代码在应用程序的另一个功能中请求写入外部和相机权限,它工作正常。
我还包含了我想要获取位置坐标的第二个活动的代码
private EditText editTitleLocation, addressText, latText,longText;
private Button saveLocationButton, deleteLocationButton, navigateButton,findLocationButton;
private static final int UPDATE_TIME = 15000;
private static final int FASTER_UPDATE_TIME = 10000;
private GoogleApiClient myGoogleApi;
private Location location;
private LocationRequest myLocationRequest;
private static final int CHECK_CODE=1;
private double longitude,latitude;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_location_second);
ActionBar actionBar = getSupportActionBar();
actionBar.setHomeButtonEnabled(true);
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowHomeEnabled(true);
initializeViews();
buildGoogleApi();
}
private void initializeViews(){
editTitleLocation = (EditText)findViewById(R.id.editTitleLocation);
addressText = (EditText)findViewById(R.id.addressText);
latText = (EditText)findViewById(R.id.latitudeText);
longText=(EditText)findViewById(R.id.longitudeText);
saveLocationButton = (Button)findViewById(R.id.saveLocation);
deleteLocationButton = (Button)findViewById(R.id.deleteLocation);
findLocationButton = (Button)findViewById(R.id.findLocation);
navigateButton= (Button)findViewById(R.id.navigateLocation);
saveLocationButton.setOnClickListener(this);
deleteLocationButton.setOnClickListener(this);
findLocationButton.setOnClickListener(this);
navigateButton.setOnClickListener(this);
}
public void onStart(){
super.onStart();
if(myGoogleApi!=null){
myGoogleApi.connect();
}
}
public void onPause(){
super.onPause();
if(myGoogleApi!=null)
LocationServices.FusedLocationApi.removeLocationUpdates(myGoogleApi,LocationSecondActivity.this);
}
public void onStop(){
super.onStop();
myGoogleApi.disconnect();
}
private synchronized void buildGoogleApi(){
myGoogleApi = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API).build();
}
private void createRequest (){
myLocationRequest = new LocationRequest();
myLocationRequest.setInterval(UPDATE_TIME)
.setFastestInterval(FASTER_UPDATE_TIME)
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(myLocationRequest);
PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(myGoogleApi,builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
@Override
public void onResult(LocationSettingsResult result) {
final Status status = result.getStatus();
switch (status.getStatusCode()){
case LocationSettingsStatusCodes.SUCCESS:
retrieveLocation();
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
try{
status.startResolutionForResult(LocationSecondActivity.this,CHECK_CODE);
}catch (IntentSender.SendIntentException e){
e.printStackTrace();
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
Toast.makeText(LocationSecondActivity.this,"Settings Change Unavailable",Toast.LENGTH_SHORT).show();
break;
}
}
});
}
private void retrieveLocation(){
try {
location = LocationServices.FusedLocationApi.getLastLocation(myGoogleApi);
}catch (SecurityException ex){
ex.printStackTrace();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode){
case CHECK_CODE:
switch (requestCode){
case Activity.RESULT_OK:
retrieveLocation();
break;
case Activity.RESULT_CANCELED:
break;
}
break;
}
}
@Override
public void onConnected(Bundle bundle) {
createRequest();
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Toast.makeText(this,"Google Api can not connect",Toast.LENGTH_LONG).show();
}
@Override
public void onLocationChanged(Location location) {
this.location=location;
longitude=location.getLongitude();
latitude=location.getLatitude();
}
@Override
public void onClick(View v) {
int id = v.getId();
switch (id){
case R.id.saveLocation:
break;
case R.id.deleteLocation:
break;
case R.id.navigateLocation:
break;
case R.id.findLocation:
if(location!=null){
latitude = location.getLatitude();
Log.e("MALAKIS",String.valueOf(latitude));
longitude=location.getLongitude();
latText.setText(String.valueOf(latitude));
longText.setText(String.valueOf(longitude));
}else {
if(!myGoogleApi.isConnected()){
myGoogleApi.connect();
Log.e("ELSE","fdsfddsd");
}
try {
LocationServices.FusedLocationApi.requestLocationUpdates(myGoogleApi, myLocationRequest, this);
}catch (SecurityException ex){
ex.printStackTrace();
}
}
break;
}
}
这里的位置是对象是null并且触发了安全位置,指出我没有精确的位置权限。那么请有人指出我正确的方向吗?我是否再次询问第二项活动的权限?
日志显示如下:
W/System.err: java.lang.SecurityException: Client must have
ACCESS_FINE_LOCATION permission to request PRIORITY_HIGH_ACCURACY
locations.
05-30 10:50:40.516 32177-32177/com.example.notepad.isidorosioannou.notepad
W/System.err: at android.os.Parcel.readException(Parcel.java:1602)
05-30 10:50:40.516 32177-32177/com.example.notepad.isidorosioannou.notepad
W/System.err: at android.os.Parcel.readException(Parcel.java:1555)
05-30 10:50:40.516 32177-32177/com.example.notepad.isidorosioannou.notepad
W/System.err: at
com.google.android.gms.internal.zzase$zza$zza.zza(Unknown Source)
05-30 10:50:40.516 32177-32177/com.example.notepad.isidorosioannou.notepad
W/System.err: at com.google.android.gms.internal.zzasg.zza(Unknown
Source)
05-30 10:50:40.516 32177-32177/com.example.notepad.isidorosioannou.notepad
W/System.err: at com.google.android.gms.internal.zzash.zza(Unknown
Source)
05-30 10:50:40.516 32177-32177/com.example.notepad.isidorosioannou.notepad
W/System.err: at com.google.android.gms.internal.zzary$1.zza(Unknown
Source)
05-30 10:50:40.516 32177-32177/com.example.notepad.isidorosioannou.notepad
W/System.err: at com.google.android.gms.internal.zzary$1.zza(Unknown
Source)
05-30 10:50:40.516 32177-32177/com.example.notepad.isidorosioannou.notepad
W/System.err: at com.google.android.gms.internal.zzaad$zza.zzb(Unknown
Source)
答案 0 :(得分:1)
将以下代码放在askForPerm()方法中: -
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(30 * 1000);
locationRequest.setFastestInterval(5 * 1000);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest);
builder.setAlwaysShow(true); //this is the key ingredient
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
@Override
public void onResult(LocationSettingsResult result) {
final Status status = result.getStatus();
final LocationSettingsStates state = result.getLocationSettingsStates();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
// All location settings are satisfied. The client can initialize location
// requests here.
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
// Location settings are not satisfied. But could be fixed by showing the user
// a dialog.
try {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
status.startResolutionForResult(MainActivity.this, REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException e) {
// Ignore the error.
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
// Location settings are not satisfied. However, we have no way to fix the
// settings so we won't show the dialog.
break;
}
}
});
试试这个!!它适用于我的应用程序。