2017-05-30 201 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; } –