Android端末で位置情報を取得したいです。
googlePixel4aをエミュレーターに使用して位置情報を取得し、緯度と経度を表示させたいです。
現在エラー文が出ていません。しかし、実行後に緯度と経度が表示されません。
もし、お時間があれば[SDK tools]から[Google Play Services]をダウンロードしソースコードを試していただいたり、対処方法を教えていただけないでしょうか。
ソースコードのAndroidManifest.xmlは文字数制限のため一部のみになっています。
対処としては参考書に載っていたコードのMainActivity67行目に
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
を追加してエラー文が出ないようにしました。
また、build.gradle35行目のバージョンを17.1.0から18.0.0へ最新のものへ変更しています。
implementation 'com.google.android.gms:play-services-location:18.0.0'
現在基礎&応用力をしっかり育成!Androidアプリ開発の教科書 第2版 Java対応 なんちゃって開発者にならないための実践ハンズオンという書籍の14章に載っている位置情報機能の利用を学習しています。
AndroidManifest.xml
xml
1<manifest ... > 2 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 3 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" / 4</manifest>
###MainActivity
Java
1package android.wings.websarva; 2 3import androidx.appcompat.app.AppCompatActivity; 4import androidx.core.app.ActivityCompat; 5 6import android.Manifest; 7import android.content.pm.PackageManager; 8import android.location.Location; 9import android.os.Bundle; 10import android.os.Looper; 11import android.widget.TextView; 12import com.google.android.gms.location.FusedLocationProviderClient; 13import com.google.android.gms.location.LocationCallback; 14import com.google.android.gms.location.LocationRequest; 15import com.google.android.gms.location.LocationResult; 16import com.google.android.gms.location.LocationServices; 17 18import java.io.UnsupportedEncodingException; 19import java.net.URLEncoder; 20 21public class MainActivity extends AppCompatActivity { 22 23 private double _latitude = 0; //緯度 24 private double _longitude = 0; //経度 25 26 private FusedLocationProviderClient _fusedLocationClient; //FusedLocationProviderClientオブジェクトフィールド。 27 28 private LocationRequest _locationRequest; //LocationRequestオブジェクトフィールド。 29 30 private OnUpdateLocation _onUpdateLocation; //位置情報が変更された時の処理を行うコールバックオブジェクトフィールド。 31 32 @Override 33 protected void onCreate(Bundle savedInstanceState) { 34 super.onCreate(savedInstanceState); 35 setContentView(R.layout.activity_main); 36 37 _fusedLocationClient = LocationServices.getFusedLocationProviderClient(MainActivity.this); // FusedLocationProviderClientオブジェクトを取得。 38 39 _locationRequest = LocationRequest.create(); // LocationRequestオブジェクトを生成。 40 41 _locationRequest.setInterval(5000); // 位置情報の更新間隔を設定。 42 43 _locationRequest.setFastestInterval(1000); // 位置情報の最短更新間隔を設定。 44 45 _locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); // 位置情報の取得精度を設定。 46 47 _onUpdateLocation = new OnUpdateLocation(); // 位置情報が変更された時の処理を行うコールバックオブジェクトを生成。 48 } 49 50 @Override 51 protected void onResume() { 52 super.onResume(); 53 54 // ACCESS_FINE_LOCATIONの許可が下りていないなら… 55 if(ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 56 // ACCESS_FINE_LOCATIONの許可を求めるダイアログを表示。その際、リクエストコードを1000に設定。 57 String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION}; 58 ActivityCompat.requestPermissions(MainActivity.this, permissions, 1000); 59 // onResume()メソッドを終了。 60 return; 61 } 62 _fusedLocationClient.requestLocationUpdates(_locationRequest, _onUpdateLocation, Looper.getMainLooper()); // 位置情報の追跡を開始。 63 } 64 65 @Override 66 public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { 67 super.onRequestPermissionsResult(requestCode, permissions, grantResults); //67行目追加 68 // ACCESS_FINE_LOCATIONに対するパーミションダイアログでかつ許可を選択したなら… 69 if(requestCode == 1000 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 70 // 再度ACCESS_FINE_LOCATIONの許可が下りていないかどうかのチェックをし、降りていないなら処理を中止。 71 if(ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 72 return; 73 } 74 // 位置情報の追跡を開始。 75 _fusedLocationClient.requestLocationUpdates(_locationRequest, _onUpdateLocation, Looper.getMainLooper()); 76 } 77 } 78 79 @Override 80 protected void onPause() { 81 super.onPause(); 82 83 _fusedLocationClient.removeLocationUpdates(_onUpdateLocation); // 位置情報の追跡を停止。 84 } 85 86 private class OnUpdateLocation extends LocationCallback{ 87 @Override 88 public void onLocationResult(LocationResult locationResult){ 89 if(locationResult != null){ 90 Location location = locationResult.getLastLocation(); //直近の位置情報取得 91 92 if(location != null){ //もし、直近の位置情報取得ができたら 93 94 95 _latitude = location.getLatitude(); // locationオブジェクトから緯度を取得 96 _longitude = location.getLongitude(); // locationオブジェクトから経度を取得 97 98 TextView tvLatitude = findViewById(R.id.tvLatitude); 99 tvLatitude.setText(Double.toString(_latitude)); // 取得した緯度をTextViewに表示 100 101 TextView tvLongitude = findViewById(R.id.tvLongitude); 102 tvLongitude.setText(Double.toString(_longitude)); // 取得した経度をTextViewに表示 103 } 104 } 105 } 106 } 107}
###activity_main.xml
xml
1<?xml version="1.0" encoding="utf-8"?> 2<LinearLayout 3 xmlns:android ="http://schemas.android.com/apk/res/android" 4 android:layout_width ="match_parent" 5 android:layout_height ="match_parent" 6 android:orientation ="vertical"> 7 8 9 <LinearLayout 10 android:layout_width="match_parent" 11 android:layout_height="wrap_content" 12 android:orientation="horizontal"> 13 14 <TextView 15 android:layout_width="wrap_content" 16 android:layout_height="wrap_content" 17 android:layout_marginRight="5dp" 18 android:text ="@string/tv_current_title"/> 19 20 <TextView 21 android:layout_width="wrap_content" 22 android:layout_height="wrap_content" 23 android:layout_marginRight ="5dp" 24 android:text="@string/tv_latitude_title"/> 25 26 <TextView 27 android:id ="@+id/tvLatitude" 28 android:layout_width ="0dp" 29 android:layout_height="wrap_content" 30 android:layout_marginRight ="5dp" 31 android:layout_weight="0.5" 32 android:maxLines="1"/> 33 34 <TextView 35 android:layout_width="wrap_content" 36 android:layout_height="wrap_content" 37 android:layout_marginRight="5dp" 38 android:text="@string/tv_longitude_title"/> 39 40 <TextView 41 android:id ="@+id/tvLongitude" 42 android:layout_width="0dp" 43 android:layout_height="wrap_content" 44 android:layout_weight ="0.5" 45 android:maxLines ="1"/> 46 47 </LinearLayout> 48 49</LinearLayout>
###strings.xml
xml
1<?xml version="1.0" encoding="utf-8" ?> 2<resources> 3 <string name="app_name">location information</string> 4 <string name ="bt_map_search">地図検索</string > 5 <string name ="tv_current_title">現在地</string > 6 <string name ="tv_latitude_title">緯度:</string > 7 <string name ="tv_longitude_title">経度:</string > 8 <string name ="bt_map_current">地図表示</string > 9</resources>
###build.gradle
plugins { id 'com.android.application' } android { compileSdk 31 defaultConfig { applicationId "android.wings.websarva" minSdk 23 targetSdk 31 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } } dependencies { implementation 'androidx.appcompat:appcompat:1.3.1' implementation 'com.google.android.material:material:1.4.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.0' implementation 'com.google.android.gms:play-services-location:18.0.0' //35行目 変更 17.1.0 → 18.0.0 testImplementation 'junit:junit:4.+' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' }
試したこと
参考書に載っていたコードのMainActivity67行目に
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
を追加してエラー文が出ないようにしました。
また、build.gradle35行目のバージョンを17.1.0から18.0.0へ最新のものへ変更しています。
implementation 'com.google.android.gms:play-services-location:18.0.0'
補足情報(FW/ツールのバージョンなど)
エミュレーターPixel 4a API30
Android Studio Arctic Fox | 2020.3.1
Build #AI-203.7717.56.2031.7583922, built on July 27, 2021
ランタイム・バージョン: 11.0.10+0-b96-7249189 amd64
VM: OpenJDK 64-Bit Server VM by Oracle Corporation
Windows 10 10.0
GC: G1 Young Generation, G1 Old Generation
Memory: 1280M
Cores: 8
Registry: external.system.auto.import.disabled=true