授予弹出对话框权限后,谷歌地图 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 中授予权限后,通知访问屏幕也会不断弹出

如果未授予/拒绝访问,则 navigator.geolocation.getCurrentPosition 超时

谷歌地图怎么测距离?

禁用 supersu 权限对话框

Android 权限管理(持续整理)

Android Studio 中未授予 Action_Call 权限