【问题标题】:setMyLocationEnabled() error on Android 6Android 6 上的 setMyLocationEnabled() 错误
【发布时间】:2016-04-08 23:25:23
【问题描述】:

我试图在加载我的地​​图活动时,会出现一个“我的位置”按钮。这是我的代码,使我的活动放大到我当前位置的按钮没有出现。我需要对代码进行哪些更改才能使其正常工作?

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private static final String FIREBASE_URL="https://********.firebaseio.com/";
private Firebase firebaseRef;
private LocationManager locationManager;
private GoogleMap mMap;
SupportMapFragment mapFrag;
boolean bPermissionGranted;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps2);
    Firebase.setAndroidContext(this);
    firebaseRef = new Firebase(FIREBASE_URL);
    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        bPermissionGranted = 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);





    }
private void setUpMapIfNeeded() {
    if (mMap == null) {
        // Try to obtain the map from the SupportMapFragment.
        mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
                .getMap();

        if (mMap != null) {


            CameraUpdate center = CameraUpdateFactory.newLatLng(new LatLng(32.065483, 34.824550));
            CameraUpdate zoom = CameraUpdateFactory.zoomTo(10);
            mMap.moveCamera(center);
            mMap.animateCamera(zoom);

        }
    }
}

public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
public boolean checkLocationPermission(){
    if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {

        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.ACCESS_FINE_LOCATION)) {

            // Show an expanation to the user *asynchronously* -- don't block
            // this thread waiting for the user's response! After the user
            // sees the explanation, try again to request the permission.
            //  TODO: Prompt with explanation!

            //Prompt the user once explanation has been shown
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    MY_PERMISSIONS_REQUEST_LOCATION);

        } else {
            // No explanation needed, we can request the permission.
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    MY_PERMISSIONS_REQUEST_LOCATION);
        }
        return false;
    } else {
        return true;
    }
}



 @Override
 public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_LOCATION: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay!
                if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED &&
                        ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                    mMap.setMyLocationEnabled(true);
                }
            } else {
                // permission denied, boo! Disable the
                // functionality that depends on this permission.
                Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show();
            }
            return;
        }

    }
}


@Override
public void onMapReady(final GoogleMap googleMap) {

    mMap=googleMap;

    mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);

    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (bPermissionGranted) {
            //User has previously accepted this permission
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED &&
                    ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                mMap.setMyLocationEnabled(true);
            }
        }
    }
    else {
        //Not in api-23, no need to prompt
        mMap.setMyLocationEnabled(true);
    }

    firebaseRef.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {

            for (DataSnapshot child : dataSnapshot.child("users").getChildren()) {


                String rightLocation = child.child("location_right").getValue().toString();
                String leftLocation = child.child("location_left").getValue().toString();

                double location_left = Double.parseDouble(leftLocation);
                double location_right = Double.parseDouble(rightLocation);
                String party_title = child.child("party/party_title").getValue().toString();
                LatLng cod = new LatLng(location_left, location_right);
                googleMap.addMarker(new MarkerOptions().position(cod).title(party_title));


            }
        }

        @Override
        public void onCancelled(FirebaseError firebaseError) {

        }
    });
}
}

【问题讨论】:

    标签: java android google-maps location


    【解决方案1】:

    这是我的other answer that also requests location updates 的简化版。

    关键是要确保在您调用setMyLocationEnabled()之前用户已授予您权限。

    也有可能用户在调用onMapReady() 时尚未接受权限提示(很可能是在首次启动应用程序时),因此在onRequestPermissionsResult() 回调中还有另一个对setMyLocationEnabled() 的调用用户接受权限的情况。

    首先,确保您在 AndroidManifest.xml 中(在应用程序标签之外)拥有权限:

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    

    这是一个完整的 Activity 课程,适合您:

    public class MapLocationActivity extends AppCompatActivity
            implements OnMapReadyCallback {
    
        GoogleMap mGoogleMap;
        SupportMapFragment mapFrag;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                checkLocationPermission();
            }
    
            mapFrag = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
            mapFrag.getMapAsync(this);
        }
    
        @Override
        public void onMapReady(GoogleMap googleMap) {
            mGoogleMap = googleMap;
            mGoogleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
    
            if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                //User has previously accepted this permission
                if (ActivityCompat.checkSelfPermission(this,
                        Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                    mGoogleMap.setMyLocationEnabled(true);
                }
            } else {
                //Not in api-23, no need to prompt
                mGoogleMap.setMyLocationEnabled(true);
            }
        }
    
        public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
    
        public boolean checkLocationPermission() {
            if (ContextCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_FINE_LOCATION)
                    != PackageManager.PERMISSION_GRANTED) {
    
                // Should we show an explanation?
                if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                        Manifest.permission.ACCESS_FINE_LOCATION)) {
    
                    // Show an expanation to the user *asynchronously* -- don't block
                    // this thread waiting for the user's response! After the user
                    // sees the explanation, try again to request the permission.
                    //  TODO: Prompt with explanation!
    
                    //Prompt the user once explanation has been shown
                    ActivityCompat.requestPermissions(this,
                            new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                            MY_PERMISSIONS_REQUEST_LOCATION);
    
                } else {
                    // No explanation needed, we can request the permission.
                    ActivityCompat.requestPermissions(this,
                            new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                            MY_PERMISSIONS_REQUEST_LOCATION);
                }
                return false;
            } else {
                return true;
            }
        }
    
        @Override
        public void onRequestPermissionsResult(int requestCode,
                                               String permissions[], int[] grantResults) {
            switch (requestCode) {
                case MY_PERMISSIONS_REQUEST_LOCATION: {
                    // If request is cancelled, the result arrays are empty.
                    if (grantResults.length > 0
                            && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
    
                        // permission was granted, yay!
                        if (ActivityCompat.checkSelfPermission(this,
                                Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                            mGoogleMap.setMyLocationEnabled(true);
                        }
                    } else {
                        // permission denied, boo! Disable the
                        // functionality that depends on this permission.
                        Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show();
                    }
                    return;
                }
    
            }
        }
    }
    

    如果您撤销许可:

    会再次提示:

    【讨论】:

    • 我试过你的答案,但每次写这行时都会出现错误消息:mMap.setMyLocationEnabled(true);。错误说:调用需要权限,可能被用户拒绝:代码应该明确检查权限是否可用(使用'checkPermission')或明确处理潜在的'SecurityExpection'
    • 它甚至没有要求我允许我在手机中使用我的位置。
    • @olash12345 我刚刚再次更新了答案以进一步简化它。有了必要的附加检查,就不需要布尔值了。我刚刚在带有 6.0.1 的 Nexus 5 和带有 6.0.1 的 Nexus 6 上对此进行了测试,它提示输入位置权限,然后启用 MyLocaction 按钮,它按预期工作。
    • 这不是在征求我的同意。而且它也没有显示按钮。我必须在某处调用函数onMapReady()吗?
    • @olash。不,在调用 getMapAsync() 之后会调用 onMapReady()。不知道为什么它不适合你,它对我来说很好。检查您的日志以查找可能的错误。
    【解决方案2】:

    您在 if 和 else 两个块中使用相同的条件。

     if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                        == PackageManager.PERMISSION_GRANTED) 
    

    因此,如果您的上述条件不成立,那么在您的 else 块中,相同的条件将如何成立。这就是原因 mMap.setMyLocationEnabled(true); 永远不会被执行,因为你的条件是假的。

    我猜你想在 else 块中做的是请求权限,如果它不存在。所以会变成这样——

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                        mMap.setMyLocationEnabled(true);
       } else{
    
           ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, <request_code>);
        }
    

    并实现onRequestPermissionsResult回调

     @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            switch (requestCode) {
                case <request_code>:
                    if (grantResults.length <= 0 || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                         mMap.setMyLocationEnabled(true);
                    }
                    break; 
            }
        }
    

    【讨论】:

    • 嘿,我试过你的答案,出现了两个错误:1)你想在case &lt;requestCode&gt;:这一行做什么?它会导致错误。 2) 此行显示错误:mMap.setMyLocationEnabled(true); 表示:调用需要权限,可能会被用户拒绝:代码应明确检查权限是否可用(使用'checkPermission')或明确处理潜在的'SecurityExpection'
    【解决方案3】:

    请在 Build.VERSION_CODES 后写 N 而不是 M。

    在代码的这一行中:

    如果 (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)

    对我有用

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-27
      • 1970-01-01
      • 2016-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多