2017-05-30 268 views
1

您好,我正在构建一个应用程序,我想访问手机的位置。不过,我似乎无法授予访问的准确位置权限,因此我的应用在我正在测试的Android M手机中不起作用。 这里是我的代码的一部分:无法授予FINE_LOCATION权限

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

在本活动中我要求的权限和才把我可以添加一个新的位置。该应用程序定期移动到下一个活动,即使我第一次安装该应用程序,也会显示授予的敬酒权,这看起来有点不可思议。我使用相同的代码来请求应用程序的另一个功能中的写入外部和相机权限,并且它工作正常。

我也包括我的第二个活动的代码,我想获得位置坐标

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

} 

这里的位置是对象为空并且安全的位置被触发指点,我不具有优良的位置许可。所以请有人指点我正确的方向?我有没有再要求第二次活动的权限?

的日志中显示下面这样:

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

*安全位置被触发指向,我没有良好的位置权限* ...是一个运行时异常或IDE /林特警告......我敢打赌警告......并且它没有任何关系** getLastLocation可能返回null并且您必须忍受这一事实。** – Selvin

+0

需要检查的一件小事,您的元素需要在之外。他们应该是直接根子元素的孩子。有时候,当你把它们放到应用程序启动的时候,例如已经在使用中的位置会引起这样的麻烦。 – koksalb

+0

我编辑了我的问题,也包括日志。权限在之外。我可以在Android 5.0测试中获得坐标,但不能在Android 6.0中测试 – Akis

回答

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; 
      } 
     } 
    }); 

试试这个!!它工作在我的应用程序。

+0

我修改了我的代码并询问了第二个活动中的权限,它可以工作。我也想问一个问题。是否有可能检查用户是否连接到无线或网络,并提示他启用互联网连接?因为我使用它的设置api提示用户只允许访问他的位置 – Akis

+0

是的,你可以检查这个: - public boolean isConnected(){ ConnectivityManager connMgr =(ConnectivityManager)getSystemService(Activity.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); if(networkInfo!= null && networkInfo.isConnected()) return true; else return false; } –