質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Q&A

解決済

1回答

1115閲覧

googlemap で現在地の位置情報を取得したいが NullPointerException となる件

vitabrevisarsl1

総合スコア57

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

1グッド

0クリップ

投稿2018/12/14 16:29

[MapsActivity.java]

Java

1public class MapsActivity extends FragmentActivity 2 implements OnMapReadyCallback, LocationListener, 3 CompoundButton.OnCheckedChangeListener { 4 private GoogleMap mMap; 5 private LatLng latlong; 6 private static Location location1; 7 LocationManager locationmanager1; 8 9 10 @Override 11 protected void onCreate(Bundle savedInstanceState) { 12 super.onCreate(savedInstanceState); 13 setContentView(R.layout.activity_maps); 14 SupportMapFragment mapFragment = 15 (SupportMapFragment) getSupportFragmentManager() 16 .findFragmentById(R.id.map_goo_fra); 17 mapFragment.getMapAsync(this); 18 19 locationmanager1 = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 20 Criteria criteria = new Criteria(); 21 criteria.setAccuracy(Criteria.ACCURACY_FINE); 22 String provider = locationmanager1.getBestProvider(criteria, true); 23 if (ActivityCompat.checkSelfPermission(this, 24 Manifest.permission.ACCESS_FINE_LOCATION) != 25 PackageManager.PERMISSION_GRANTED && 26 ActivityCompat.checkSelfPermission(this, 27 Manifest.permission.ACCESS_COARSE_LOCATION) != 28 PackageManager.PERMISSION_GRANTED) { 29 // ↓「アクセスを許可しますか?」 30 requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_CODE); 31 return; 32 } else { 33 locationmanager1.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); 34 } 35 location1 = locationmanager1.getLastKnownLocation(provider); 36 } 37 38 39 @Override 40 public void onMapReady(GoogleMap googleMap) { 41 mMap = googleMap; 42 lat = location1.getLatitude(); // ★186行目 43 lon = location1.getLongitude(); 44 latlong = new LatLng(lat, lon); 45 mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latlong, 19)); 46 locationmanager1.removeUpdates(this); 47 } 48 49 50 @Override 51 public void onStatusChanged(String provider, int status, Bundle extras) { 52 switch (status) { 53 case LocationProvider.AVAILABLE: 54 Log.d("debug", "LocationProvider.AVAILABLE"); 55 break; 56 case LocationProvider.OUT_OF_SERVICE: 57 Log.d("debug", "LocationProvider.OUT_OF_SERVICE"); 58 break; 59 case LocationProvider.TEMPORARILY_UNAVAILABLE: 60 Log.d("debug", "LocationProvider.TEMPORARILY_UNAVAILABLE"); 61 break; 62 } 63 } 64 @Override 65 public void onLocationChanged(Location location) { 66 LatLng curr = new LatLng(location.getLatitude(), location.getLongitude()); 67 mMap.animateCamera(CameraUpdateFactory.newLatLng(curr)); 68 } 69 @Override 70 public void onProviderEnabled(String s) { 71 } 72 @Override 73 public void onProviderDisabled(String s) { 74 } 75}

アプリ起動時だけ現在位置座標を取得し、ぞの座標位置を画面の中央に表示させる、ということをしたいです。


.getLatitude()、.getLongitude() で緯度経度の数値を取得したいのですが、上記のコードを実行すると

2-15 01:16:49.256 11700-11700/jp.path.appname E/AndroidRuntime: FATAL EXCEPTION: main Process: jp.path.appname, PID: 11700 java.lang.NullPointerException: Attempt to invoke virtual method 'double android.location.Location.getLatitude()' on a null object reference at jp.path.appname.MapsActivity.onMapReady(MapsActivity.java:186)

とのエラーから、onMapReady において location1 が空だという内容です。
.getLastKnownLocation の代入が効いていないようにも読めます。

お知恵をお借りできますと幸いです。

keicha_hrs👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

java

1 if (ActivityCompat.checkSelfPermission(this, 2 Manifest.permission.ACCESS_FINE_LOCATION) != 3 PackageManager.PERMISSION_GRANTED && 4 ActivityCompat.checkSelfPermission(this, 5 Manifest.permission.ACCESS_COARSE_LOCATION) != 6 PackageManager.PERMISSION_GRANTED) { 7 // ↓「アクセスを許可しますか?」 8 requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_CODE); 9 return; 10 } else { 11 locationmanager1.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); 12 } 13 location1 = locationmanager1.getLastKnownLocation(provider);

この構造だと、初回の起動でrequestPermissions()側に進むと、許可を得たら即座にreturnによって抜けてしまい、location1が設定されることなく進行してしまうので、NullPointerExceptionになるのは必然と思われます。returnを除去することで解決できませんか?

なお、許可しない選択をしたときもやはり同様に落ちると思われますので、その処理は別途必要になるでしょう。


(15:13追記)
許可を得られる前にonMapReady()が走ってしまったりとか、いろいろ前後関係がありそうですね。処理を組み直さないと解決できなさそうなので、ざっと書いてみましたが、こんな感じで解決できるでしょうか?

java

1public class MapsActivity extends FragmentActivity 2 implements OnMapReadyCallback, LocationListener, 3 CompoundButton.OnCheckedChangeListener { 4 private GoogleMap mMap; 5 private LatLng latlong; 6 private static Location location1; 7 LocationManager locationmanager1; 8 private static final int LOCATION_CODE = 100; 9 private static final String[] LOCATION_PERMISSION = { 10 Manifest.permission.ACCESS_FINE_LOCATION, 11 Manifest.permission.ACCESS_COARSE_LOCATION 12 }; 13 private static final int GRANTED = PackageManager.PERMISSION_GRANTED; 14 15 @Override 16 protected void onCreate(Bundle savedInstanceState) { 17 super.onCreate(savedInstanceState); 18 // ここではまだsetContentView()は呼ばない 19 20 locationmanager1 = (LocationManager) getSystemService(Context.LOCATION_SERVICE); 21 22 if (ActivityCompat.checkSelfPermission(this, LOCATION_PERMISSION[0]) != GRANTED && 23 ActivityCompat.checkSelfPermission(this, LOCATION_PERMISSION[1]) != GRANTED) { 24 // ↓「アクセスを許可しますか?」 25 requestPermissions(LOCATION_PERMISSION, LOCATION_CODE); 26 } else { 27 startLocation(); 28 } 29 } 30 31 32 @Override 33 public void onMapReady(GoogleMap googleMap) { 34 35 mMap = googleMap; 36 double lat = location1.getLatitude(); 37 double lon = location1.getLongitude(); 38 latlong = new LatLng(lat, lon); 39 mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latlong, 19)); 40 locationmanager1.removeUpdates(this); 41 } 42 43 // アクセス許可のダイアログで操作を行ったときに呼ばれるメソッド 44 @Override 45 public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 46 super.onRequestPermissionsResult(requestCode, permissions, grantResults); 47 if (requestCode == LOCATION_CODE) { 48 if (grantResults[0] == GRANTED) { 49 startLocation(); 50 } else { 51 // 拒否されたのならアプリ続行不可能 52 finish(); 53 } 54 } 55 56 } 57 58 void startLocation() { 59 if (ActivityCompat.checkSelfPermission(this, LOCATION_PERMISSION[0]) == GRANTED || 60 ActivityCompat.checkSelfPermission(this, LOCATION_PERMISSION[1]) == GRANTED) { 61 62 // 許可を得られたことを確認できた段階で初めてsetContentView()を呼ぶ 63 // onMapReady()が走るのはこれ以後になる 64 setContentView(R.layout.activity_maps); 65 SupportMapFragment mapFragment = 66 (SupportMapFragment) getSupportFragmentManager() 67 .findFragmentById(R.id.map_goo_fra); 68 mapFragment.getMapAsync(this); 69 70 Criteria criteria = new Criteria(); 71 criteria.setAccuracy(Criteria.ACCURACY_FINE); 72 String provider = locationmanager1.getBestProvider(criteria, true); 73 locationmanager1.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); 74 location1 = locationmanager1.getLastKnownLocation(provider); 75 } 76 } 77 78 @Override 79 protected void onDestroy() { 80 super.onDestroy(); 81 locationmanager1.removeUpdates(this); 82 } 83 84 @Override 85 public void onStatusChanged(String provider, int status, Bundle extras) { 86 switch (status) { 87 case LocationProvider.AVAILABLE: 88 Log.d("debug", "LocationProvider.AVAILABLE"); 89 break; 90 case LocationProvider.OUT_OF_SERVICE: 91 Log.d("debug", "LocationProvider.OUT_OF_SERVICE"); 92 break; 93 case LocationProvider.TEMPORARILY_UNAVAILABLE: 94 Log.d("debug", "LocationProvider.TEMPORARILY_UNAVAILABLE"); 95 break; 96 } 97 } 98 99 @Override 100 public void onLocationChanged(Location location) { 101 //LatLng curr = new LatLng(location.getLatitude(), location.getLongitude()); 102 //mMap.animateCamera(CameraUpdateFactory.newLatLng(curr)); 103 } 104 105 @Override 106 public void onProviderEnabled(String s) { 107 } 108 109 @Override 110 public void onProviderDisabled(String s) { 111 } 112 113 @Override 114 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 115 116 } 117}

投稿2018/12/15 02:56

編集2018/12/15 06:57
keicha_hrs

総合スコア6766

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

vitabrevisarsl1

2018/12/15 04:07

ご回答ありがとうございます。 return; 除去→同じエラー という状況です。 書籍で緯度経度を取得するだけのサンプルを比較のために試しています。・・・
vitabrevisarsl1

2018/12/18 10:58 編集

【解消】現在地座標取得および画面上での中心表示、できました。 setContentView の切り離し、とても思いつきません。 いや、すばらしいです。ただただ感謝です。 【経緯】 1. Android認定試験参考書のサンプルコードや受講している講義で使用した書籍のそれをそのまま試しても全て同エラーにて失敗しました。 2. 比較のために試みた、緯度経度の取得→テキストで通知表示については、私が調べた中では唯一 https://techblog.recochoku.jp/705 さんのコードが動いてくれました。 しかしそれを上記作成中コードにあてはめても、挿入箇所をいろいろ試しましたが、全て失敗でした。 onCreate, onMapReady, onStatusChanged, onLocationChanged、そしてstartLocation, onDestroy が重要ですね。制御の順番を見抜く目がないといけませんね。勉強になりました。 --- --- --- 【追記】 日が変わっておもむろに起動したところ、同エラーが再発し、アプリがすぐに落ちました。 試行錯誤の結果、.getLastKnownLocation(provider) のほかに、.getLastKnownLocation(LocationManager.GPS_PROVIDER) および .getLastKnownLocation(LocationManager.NETWORK_PROVIDER) も加えて3重にチェック網を築いたところ、さらに日が変わって様子を見てますが、現在地を捕捉するようです。 void startLocation() { if (ActivityCompat.checkSelfPermission(this, LOCATION_PERMISSION[0]) == GRANTED || ActivityCompat.checkSelfPermission(this, LOCATION_PERMISSION[1]) == GRANTED) { // 許可を得られたことを確認できた段階で初めてsetContentView()を呼ぶ // onMapReady()が走るのはこれ以後になる setContentView(R.layout.activity_maps); SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map_goo_fra); mapFragment.getMapAsync(this); Criteria criteria = new Criteria(); criteria.setAccuracy(Criteria.ACCURACY_FINE); String provider = locationmanager1.getBestProvider(criteria, true); // ↓第2引数は0以上が好ましいようです locationmanager1.requestLocationUpdates(provider, 10000, 0, this); location1 = locationmanager1.getLastKnownLocation(provider); if (location1 == null) { location1 = locationmanager1.getLastKnownLocation(LocationManager.GPS_PROVIDER); } if (location1 == null) { location1 = locationmanager1.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); } } } 最初の質問のコードに3重チェック網を追記しても、同エラーでした。そのことからでも、setContentView の切り離し以下のロジックの有効性が明らかになりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問