アクティビティレイアウトのボタンをクリックしたときにGPS座標が表示されるようにします。ボタンをクリックしたときに呼び出されるメソッドは次のとおりです。
public void getLocation(View view) {
TextView tv = (TextView) findViewById(R.id.gps_coord_view);
LocationManager lm = (LocationManager) getSystemService(LOCATION_SERVICE);
Location loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
tv.setText("Latitude: " + loc.getLatitude() + "\nLongitude: " + loc.getLongitude());
}
というエラーが出ます
通話には許可が必要ですが、ユーザーが拒否することがあります。コードは、許可があるかどうかを明示的に確認する必要があります。
私はAndroidManifest
で既にこれらの許可を与えています。 lm.getLastKnownLocation
を呼び出す前に次のコードを追加すると、エラーが処理され、アプリがコンパイルされます。
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
しかし、クリックしたときにgetLocationを呼び出すボタンを押すと、アプリがクラッシュします。何が起こっている?デバイスのGPS座標を取得するためのより良い/より簡単な方法はありますか?
Android APIレベル(23)では、権限を確認する必要があります。 https://developer.Android.com/training/permissions/requesting.html
私はあなたと同じ問題を抱えていました、しかし、以下は私のために働きました、そして私は首尾よく位置データを検索することができます:
(1)あなたの許可がマニフェストに記載されていることを確認してください。
<uses-permission Android:name="Android.permission.ACCESS_FINE_LOCATION" />
<uses-permission Android:name="Android.permission.ACCESS_COARSE_LOCATION"/>
(2)ユーザーから許可を要求していることを確認します。
if ( ContextCompat.checkSelfPermission( this, Android.Manifest.permission.ACCESS_COARSE_LOCATION ) != PackageManager.PERMISSION_GRANTED ) {
ActivityCompat.requestPermissions( this, new String[] { Android.Manifest.permission.ACCESS_COARSE_LOCATION },
LocationService.MY_PERMISSION_ACCESS_COURSE_LOCATION );
}
(3)ContextCompatは、古いAPIレベルと互換性があるため、必ず使用してください。
(4)あなたの位置情報サービス、またはあなたのLocationManagerを初期化して最後の既知の位置を取得するクラスでは、パーミッションをチェックする必要があります:
if ( Build.VERSION.SDK_INT >= 23 &&
ContextCompat.checkSelfPermission( context, Android.Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission( context, Android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return ;
}
(5)このアプローチは、initLocationServiceメソッドの先頭に@TargetApi(23)を含めた後にのみ有効でした。
(6)これを私のgradle buildにも追加しました:
compile 'com.Android.support:support-v4:23.0.1'
これが私のLocationServiceです。
public class LocationService implements LocationListener {
//The minimum distance to change updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 0; // 10 meters
//The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 0;//1000 * 60 * 1; // 1 minute
private final static boolean forceNetwork = false;
private static LocationService instance = null;
private LocationManager locationManager;
public Location location;
public double longitude;
public double latitude;
/**
* Singleton implementation
* @return
*/
public static LocationService getLocationManager(Context context) {
if (instance == null) {
instance = new LocationService(context);
}
return instance;
}
/**
* Local constructor
*/
private LocationService( Context context ) {
initLocationService(context);
LogService.log("LocationService created");
}
/**
* Sets up location service after permissions is granted
*/
@TargetApi(23)
private void initLocationService(Context context) {
if ( Build.VERSION.SDK_INT >= 23 &&
ContextCompat.checkSelfPermission( context, Android.Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission( context, Android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return ;
}
try {
this.longitude = 0.0;
this.latitude = 0.0;
this.locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
// Get GPS and network status
this.isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
this.isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (forceNetwork) isGPSEnabled = false;
if (!isNetworkEnabled && !isGPSEnabled) {
// cannot get location
this.locationServiceAvailable = false;
}
//else
{
this.locationServiceAvailable = true;
if (isNetworkEnabled) {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
if (locationManager != null) {
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
updateCoordinates();
}
}//end if
if (isGPSEnabled) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
if (locationManager != null) {
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
updateCoordinates();
}
}
}
} catch (Exception ex) {
LogService.log( "Error creating location service: " + ex.getMessage() );
}
}
@Override
public void onLocationChanged(Location location) {
// do stuff here with location object
}
}
私はこれまでのところアンドロイドロリポップデバイスでテストしました。これがあなたのために働くことを願っています。
私はapi 23より前のアプリをサポートしたいと思っていましたが、checkSelfPermission
を使う代わりにtry/catchを使っていました
try {
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
} catch (SecurityException e) {
dialogGPS(this.getContext()); // lets the user know there is a problem with the gps
}
あなたが引用したエラーメッセージの最後の部分は次のように述べています:...with ("checkPermission") or explicitly handle a potential "SecurityException"
あなたがパーミッションを持っているかどうかをチェックするもっと早くて簡単な方法はあなたのコードをtry { ... } catch (SecurityException e) { [insert error handling code here] }
で囲むことです。あなたがパーミッションを持っていれば、 'try'部分が実行され、あなたが持っていなければ 'catch'部分が実行されます。
動的なパーミッションやACCESS_FINE_LOCATIONのようなパーミッション、エラーを与えるACCESS_COARSE_LOCATION "はメソッドPERMISSION_NAMEを解決できません" この場合、パーミッション名でコードを書いてからプロジェクトを再構築するとマニフェストが再生成されます。許可)ファイル。
カスタムクラスを使用して権限を確認またはリクエストする
public class Permissons {
//Request Permisson
public static void Request_STORAGE(Activity act,int code)
{
ActivityCompat.requestPermissions(act, new
String[]{Android.Manifest.permission.WRITE_EXTERNAL_STORAGE},code);
}
public static void Request_CAMERA(Activity act,int code)
{
ActivityCompat.requestPermissions(act, new
String[]{Manifest.permission.CAMERA},code);
}
public static void Request_FINE_LOCATION(Activity act,int code)
{
ActivityCompat.requestPermissions(act, new
String[]{Manifest.permission.ACCESS_FINE_LOCATION},code);
}
public static void Request_READ_SMS(Activity act,int code)
{
ActivityCompat.requestPermissions(act, new
String[]{Manifest.permission.READ_SMS},code);
}
public static void Request_READ_CONTACTS(Activity act,int code)
{
ActivityCompat.requestPermissions(act, new
String[]{Manifest.permission.READ_CONTACTS},code);
}
public static void Request_READ_CALENDAR(Activity act,int code)
{
ActivityCompat.requestPermissions(act, new
String[]{Manifest.permission.READ_CALENDAR},code);
}
public static void Request_RECORD_AUDIO(Activity act,int code)
{
ActivityCompat.requestPermissions(act, new
String[]{Manifest.permission.RECORD_AUDIO},code);
}
//Check Permisson
public static boolean Check_STORAGE(Activity act)
{
int result = ContextCompat.checkSelfPermission(act,Android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
return result == PackageManager.PERMISSION_GRANTED;
}
public static boolean Check_CAMERA(Activity act)
{
int result = ContextCompat.checkSelfPermission(act, Manifest.permission.CAMERA);
return result == PackageManager.PERMISSION_GRANTED;
}
public static boolean Check_FINE_LOCATION(Activity act)
{
int result = ContextCompat.checkSelfPermission(act, Manifest.permission.ACCESS_FINE_LOCATION);
return result == PackageManager.PERMISSION_GRANTED;
}
public static boolean Check_READ_SMS(Activity act)
{
int result = ContextCompat.checkSelfPermission(act, Manifest.permission.READ_SMS);
return result == PackageManager.PERMISSION_GRANTED;
}
public static boolean Check_READ_CONTACTS(Activity act)
{
int result = ContextCompat.checkSelfPermission(act, Manifest.permission.READ_CONTACTS);
return result == PackageManager.PERMISSION_GRANTED;
}
public static boolean Check_READ_CALENDAR(Activity act)
{
int result = ContextCompat.checkSelfPermission(act, Manifest.permission.READ_CALENDAR);
return result == PackageManager.PERMISSION_GRANTED;
}
public static boolean Check_RECORD_AUDIO(Activity act)
{
int result = ContextCompat.checkSelfPermission(act, Manifest.permission.RECORD_AUDIO);
return result == PackageManager.PERMISSION_GRANTED;
}
}
if(!Permissons.Check_STORAGE(MainActivity.this)) { //if not permisson granted so request permisson with request code Permissons.Request_STORAGE(MainActivity.this,22); }