授予弹出对话框权限后,谷歌地图 V2 未初始化
Posted
技术标签:
【中文标题】授予弹出对话框权限后,谷歌地图 V2 未初始化【英文标题】:Google map V2 not initializing after granting permission on pop up dialog 【发布时间】:2018-03-22 23:23:24 【问题描述】:我已经为我的应用程序实现了谷歌地图和谷歌地点。我已经意识到,当我第一次安装应用程序时,谷歌地图没有正确初始化,即当使用通过权限弹出对话框允许谷歌地图权限时,谷歌地图窗口默认为其原始地图,而不显示我当前的位置和地点自动完成字段不起作用(意味着谷歌地图没有初始化)。但是,当我第二次和第三次运行该应用程序时,它运行良好。
以下是我的代码:
public class MapsActivity extends AppCompatActivity implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
View.OnClickListener, OnMapReadyCallback,
LocationListener
protected GoogleApiClient mGoogleApiClient;
private boolean executeOnStart = false;
LocationRequest mLocationRequest;
private static final LatLngBounds BOUNDS_INDIA = new LatLngBounds(
new LatLng(-0, 0), new LatLng(0, 0));
public GoogleMap mMap;
Location mLastLocation;
Marker mCurrLocationMarker;
private String mapAddress = null;
private ImageView imageView;
private Button checkAvailability;
private StringBuilder sb = null;
private EditText mAutocompleteView;
private Geocoder geocoder;
private MarkerOptions markerOptions;
private LatLng latLng;
private Marker marker;
private RecyclerView mRecyclerView;
private LinearLayoutManager mLinearLayoutManager;
private PlacesAutoCompleteAdapter mAutoCompleteAdapter;
PlacesAutoCompleteAdapter.PlaceAutocomplete item;
String featureName, locality, countryName;
String placeId;
ImageView delete;
SupportMapFragment mapFragment;
private boolean allowEditTextChangeListener = true;
private LatLng pos;
static boolean invalidLocation = false;
private LinearLayout linearLayout;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
buildGoogleApiClient();
setContentView(R.layout.activity_search);
mAutocompleteView = (EditText) findViewById(R.id.autocomplete_places);
mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(MapsActivity.this);
linearLayout = (LinearLayout) findViewById(R.id.linear_layout);
Log.d("allowEditTextChange1",allowEditTextChangeListener + "");
checkAvailability = (Button) findViewById(R.id.check_availability);
checkAvailability.setTypeface(Display.displayTypeface(getApplicationContext(), 1));
geocoder = new Geocoder(this, Locale.getDefault());
markerOptions = new MarkerOptions();
buildGoogleApiClient();
delete = (ImageView) findViewById(R.id.cross);
mAutoCompleteAdapter = new PlacesAutoCompleteAdapter(this, R.layout.searchview_adapter,
mGoogleApiClient, BOUNDS_INDIA, null);
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
mLinearLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLinearLayoutManager);
mRecyclerView.setAdapter(mAutoCompleteAdapter);
// mRecyclerView.setLayoutFrozen(true);
delete.setOnClickListener(this);
if (allowEditTextChangeListener)
Log.d("allowEditTextChangz1",allowEditTextChangeListener + "");
mAutocompleteView.addTextChangedListener(new TextWatcher()
public void onTextChanged(CharSequence s, int start, int before,
int count)
Log.d("allowEditTextChangz1","jo");
if (!s.toString().equals("") && mGoogleApiClient.isConnected())
mAutoCompleteAdapter.getFilter().filter(s.toString());
else if (!mGoogleApiClient.isConnected())
// Toast.makeText(getApplicationContext(), Constants.API_NOT_CONNECTED, Toast.LENGTH_SHORT).show();
Log.e(Constants.PlacesTag, Constants.API_NOT_CONNECTED);
public void beforeTextChanged(CharSequence s, int start, int count, int after)
public void afterTextChanged(Editable s)
);
mRecyclerView.addOnItemTouchListener(
new RecyclerItemClickListener(this, new RecyclerItemClickListener.OnItemClickListener()
@Override
public void onItemClick(View view, int position)
item = mAutoCompleteAdapter.getItem(position);
placeId = String.valueOf(item.placeId);PendingResult<PlaceBuffer> placeResult = Places.GeoDataApi
.getPlaceById(mGoogleApiClient, placeId);
placeResult.setResultCallback(new ResultCallback<PlaceBuffer>()
@Override
public void onResult(PlaceBuffer places)
if (places.getCount() == 1)
mAutoCompleteAdapter.clear();
mAutocompleteView.setText("");
String country = "";
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(places.get(0).getLatLng()) // Sets the center of the map to Mountain View
.zoom(12) // Sets the zoom
.bearing(90) // Sets the orientation of the camera to east
.tilt(30) // Sets the tilt of the camera to 30 degrees
.build(); // Creates a CameraPosition from the builder
marker.remove(); // remove any marker from maponclick or maponlonclick
marker = mMap.addMarker(new MarkerOptions().position(places.get(0).getLatLng())
.title("My Location"));
mMap.setTrafficEnabled(true);
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
);
Log.i("TAG", "Clicked: " + item.description);
Log.i("TAG", "Called getPlaceById to get Place details for " + item.placeId);
)
);
imageView = (ImageView) findViewById(R.id.maps_close);
imageView.setOnClickListener(new View.OnClickListener()
public void onClick(View v)
Log.d("close", "close");
if (mAutoCompleteAdapter.getItemCount() != 0)
mAutoCompleteAdapter.clear();
mAutocompleteView.setText("");
);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
checkLocationPermission();
@Override
public void onMapReady(GoogleMap googleMap)
mMap = googleMap;
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED)
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
else
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
@Override
public void onLocationChanged(Location location)
mLastLocation = location;
if (mCurrLocationMarker != null)
mCurrLocationMarker.remove();
final Double lat = location.getLatitude();
final Double lng = location.getLongitude();
Log.d("LATLANGz", lat + "|" + lng);
latLng = new LatLng(lat, lng);
markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Current Positionn");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
marker = mMap.addMarker(markerOptions);
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(11));
if (mGoogleApiClient != null)
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
protected synchronized void buildGoogleApiClient()
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.addApi(Places.GEO_DATA_API)
.build();
mGoogleApiClient.connect();
@Override
public void onConnectionSuspended(int i)
@Override
public void onConnectionFailed(ConnectionResult connectionResult)
@Override
public void onClick(View v)
if(v==delete)
mAutocompleteView.setText("");
@Override
public void onResume()
super.onResume();
if (!mGoogleApiClient.isConnected() && !mGoogleApiClient.isConnecting())
Log.v("Google API","Connecting");
mGoogleApiClient.connect();
@Override
public void onPause()
super.onPause();
if(mGoogleApiClient.isConnected())
Log.v("Google API","Dis-Connecting");
mGoogleApiClient.disconnect();
@Override
public void onBackPressed()
super.onBackPressed();
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
public boolean checkLocationPermission()
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED)
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION))
ActivityCompat.requestPermissions(this,
new String[]Manifest.permission.ACCESS_FINE_LOCATION,
MY_PERMISSIONS_REQUEST_LOCATION);
else
ActivityCompat.requestPermissions(this,
new String[]Manifest.permission.ACCESS_FINE_LOCATION,
MY_PERMISSIONS_REQUEST_LOCATION);
return false;
else
return true;
@Override
public void onConnected(Bundle bundle)
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if (mGoogleApiClient.isConnected())
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED)
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults)
switch (requestCode)
case MY_PERMISSIONS_REQUEST_LOCATION:
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED)
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED)
if (mGoogleApiClient == null)
buildGoogleApiClient();
else
return;
@Override
public void onStart()
super.onStart();
if (isNetworkAvailable() == true)
if (isLocationEnabled(getApplicationContext()))
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
checkLocationPermission();
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
else
showLocationDialog();
else
showInternetDialog();
public void showInternetDialog()
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Please turn on mobile network or Wi-Fi in Settings.")
.setTitle("WIFI Disabled")
.setCancelable(false)
.setPositiveButton("Settings",
new DialogInterface.OnClickListener()
public void onClick(DialogInterface dialog, int id)
Intent i = new Intent(Settings.ACTION_WIRELESS_SETTINGS);
startActivity(i);
)
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener()
public void onClick(DialogInterface dialog, int id)
MapsActivity.this.finish();
);
AlertDialog alert = builder.create();
alert.show();
// check internet connectivity
public boolean isNetworkAvailable()
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager
.getActiveNetworkInfo();
return activeNetworkInfo != null;
public static boolean isLocationEnabled(Context context)
int locationMode = 0;
String locationProviders;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
try
locationMode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE);
catch (Settings.SettingNotFoundException e)
e.printStackTrace();
return false;
return locationMode != Settings.Secure.LOCATION_MODE_OFF;
else
locationProviders = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
return !TextUtils.isEmpty(locationProviders);
public void showLocationDialog()
executeOnStart = true;
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.gps_not_found_message)
.setTitle(R.string.gps_not_found_title)
.setCancelable(false)
.setPositiveButton("Settings",
new DialogInterface.OnClickListener()
public void onClick(DialogInterface dialog, int id)
Intent i = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(i);
)
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener()
public void onClick(DialogInterface dg, int id)
MapsActivity.this.finish();
);
AlertDialog alert = builder.create();
alert.show();
【问题讨论】:
【参考方案1】:也许你没有正确加载它
onRequestPermissionsResult
方法。
在启动页面活动期间尝试一些技巧询问权限请求。
【讨论】:
这是个好主意,所以我应该询问我所有的应用程序对启动屏幕活动的权限吗? 是的,在您的应用启动画面第一次运行时 我认为这是最好的选择,因为如果您在地图活动中调用您的权限,您将需要执行两次 onMapready 中的内容,因为如果这是第一次运行应用程序,它将执行到 onMapReady,然后从那里询问权限,在你的 onRequestPermissionResults 中,你需要处理重复的逻辑,因为你需要触发 onMapReady 内的东西两次,当你接受权限时,然后在 onMapReady 上再次启动应用程序,做初始屏幕中的 this 可以防止这种情况发生,因此您进入应用时授予所有权限。【参考方案2】:对于当前位置:这是因为在onMapReady()
你做的:
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
如果已经授予权限,并且仅:
if (mGoogleApiClient == null)
buildGoogleApiClient();
在onRequestPermissionsResult()
。只需像这样将mMap.setMyLocationEnabled(true);
添加到onRequestPermissionsResult()
:
if (mGoogleApiClient == null)
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
对于自动完成:在protected void onCreate(Bundle savedInstanceState)
中,您调用buildGoogleApiClient();
并在获得许可之前创建mAutoCompleteAdapter
(在首次应用启动时):
...
buildGoogleApiClient();
delete = (ImageView) findViewById(R.id.cross);
mAutoCompleteAdapter = new PlacesAutoCompleteAdapter(this, R.layout.searchview_adapter, mGoogleApiClient, BOUNDS_INDIA, null);
....
所以,你也应该在onRequestPermissionsResult()
中调用mAutoCompleteAdapter = new PlacesAutoCompleteAdapter(...)
。
【讨论】:
所以,你可以接受答案 :) (要做到这一点,你应该点击问题率下的复选标记,在投票箭头的左下方,它应该变成绿色。) @G.Joe 谢谢!祝你好运!以上是关于授予弹出对话框权限后,谷歌地图 V2 未初始化的主要内容,如果未能解决你的问题,请参考以下文章
即使在 Flutter 中授予权限后,通知访问屏幕也会不断弹出