ユーザーの現在の位置を取得し、Google マップを読み込んで、その地域に関心のあるマーカーをプロットするアプリがあります。マシュマロ以下のすべてで問題なく動作します。実行時のアクセス許可チェックを追加しました。プロンプトが表示されると設定されます。同意すると、電話の設定からアプリの詳細にアクセス許可が表示されます。しかし、なぜ場所が返ってこないのか、一生理解できません。
ここにある例を使用しています https://developer.android.com/training/location/retrieve-current.html
マニフェストのタグですべての権限が設定されています。Fragment に LocationListener を実装することさえあります。ただし、onLocationChanged メソッドが呼び出されることはありません。以下のように、Google API Client の onConnected メソッド内で呼び出しています。
@Override
public void onConnected(@Nullable Bundle bundle) {
try {
Log.d("MYAPPTAG","isConnected: " + mGoogleApiClient.isConnected());
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
myLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
} catch (SecurityException ex) {
myLocation = null;
}
}
ログをコンソールに取得するため、onConnected メソッドが呼び出されます。ただし、 myLocation は常に null です。getLastLocation を呼び出すたびに、コンソールにメッセージが表示されます。
No Location to return for getLastLocation()
GoogleSignatureVerifier: com.myappname.android signature not valid. Found: LONG KEY HERE
マシュマロで何か特別なことをする必要がありますか?
私の OnLocationChanged メソッド
@Override
public void onLocationChanged(Location location) {
myLocation = location;
Log.d("MYAPPTAG", "LocatinChngListner, loc: " + location.getLatitude() + "," + location.getLongitude());
}
AndroidManifest.xml - 権限セクション (ノードの上)
<!--- App permissions -->
<permission android:name="com.myappname.android.permission.MAPS_RECEIVE" android:protectionLevel="signature"/>
<uses-permission android:name="com.myappname.android.permission.MAPS_RECEIVE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:name="com.myappname.android.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<uses-permission android:name="com.myappname.android.permission.C2D_MESSAGE"/>
onCreate メソッド スニペット
createLocationRequest();
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
createLocationRequest メソッド
private void createLocationRequest(){
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(5000);
mLocationRequest.setFastestInterval(1000);
}
onStart() onStop() メソッド
@Override
public void onStart() {
if (!mGoogleApiClient.isConnected()) mGoogleApiClient.connect();
super.onStart();
}
@Override
public void onStop() {
if (mGoogleApiClient.isConnected()) mGoogleApiClient.disconnect();
super.onStop();
}
Fragment onCreate メソッドの直後に、以下のこのコードを呼び出します
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1 && (ContextCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)) {
requestPermissions(new String[] { Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION }, REQUEST_PERMISSION_USER_LOCATION);
} else {
googleMapsLocationPermissionContainer.setVisibility(View.GONE);
getUserLocationAndInitializeMap();
}
googleMapsLocationPermissionContainer は、アクセス許可が付与されるまでマップ上にオーバーレイする単なるレイアウトです。
getUserLocationAndInitializeMap()
try {
MapsInitializer.initialize(getActivity());
// Set reference for map object
if (map == null) {
mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
// Here I set the map to invisible then after I plot all the markers I set it to visible again
mapFragment.getView().setVisibility(View.INVISIBLE);
}
} catch (Exception e) {
// Show the google maps alert dialog
showGoogleMapsErrorDialog();
}