在请求权限之前 Android 应用程序已关闭?怎么解决?
Before asking for permissions Android application closed ? How resolve that?
我第一次安装这个应用程序,当我启动 MapsActivity 时,我被要求权限,这是正常的。但问题是应用程序同时关闭。我如何修改我的代码以保持应用程序打开,并且权限弹出窗口只是重叠。非常感谢您的回答。
logcat 中的错误代码:
2020-02-02 11:17:01.340 11559-11574/? E/le.rsr_pechhlu: Unable to peek into adb socket due to error. Closing socket.: Connection reset by peer
2020-02-02 11:17:01.470 11559-11636/? E/AwareLog:AtomicFileUtils:readFileLines 文件不存在:android.util.AtomicFile@2f88384
2020-02-02 11:17:01.470 11559-11636/? E/AwareLog:AtomicFileUtils:readFileLines 文件不存在:android.util.AtomicFile@7fa676d
2020-02-02 11:17:01.471 11559-11603/? E/MemoryLeakMonitorManager: MemoryLeakMonitor.jar 不存在!
2020-02-02 11:17:10.787 11559-11559/com.example.rsr_pechhlup E/AndroidRuntime:致命异常:主要
进程:com.example.rsr_pechhlup,PID:11559
java.lang.RuntimeException:无法暂停 activity {com.example.rsr_pechhlup/com.example.rsr_pechhlup.MapsActivity}:java.lang.NullPointerException:尝试调用虚拟方法 'void android.location.LocationManager.removeUpdates(android.location.LocationListener)'在空对象引用上
在 android.app.ActivityThread.performPauseActivityIfNeeded(ActivityThread.java:4742)
在 android.app.ActivityThread.performPauseActivity(ActivityThread.java:4691)
在 android.app.ActivityThread.handlePauseActivity(ActivityThread.java:4626)
在 android.app.servertransaction.PauseActivityItem.execute(PauseActivityItem.java:45)
在 android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:145)
在 android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:2199)
在 android.os.Handler.dispatchMessage(Handler.java:112)
在 android.os.Looper.loop(Looper.java:216)
在 android.app.ActivityThread.main(ActivityThread.java:7625)
在 java.lang.reflect.Method.invoke(本机方法)
在 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)
原因:java.lang.NullPointerException:尝试在空对象引用上调用虚方法 'void android.location.LocationManager.removeUpdates(android.location.LocationListener)'
在 com.example.rsr_pechhlup.MapsActivity.onPause(MapsActivity.java:159)
在 android.app.Activity.performPause(Activity.java:7663)
在 android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1536)
在 android.app.ActivityThread.performPauseActivityIfNeeded(ActivityThread.java:4726)
在 android.app.ActivityThread.performPauseActivity(ActivityThread.java:4691)
在 android.app.ActivityThread.handlePauseActivity(ActivityThread.java:4626)
在 android.app.servertransaction.PauseActivityItem.execute(PauseActivityItem.java:45)
在 android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:145)
在 android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:2199)
在 android.os.Handler.dispatchMessage(Handler.java:112)
在 android.os.Looper.loop(Looper.java:216)
在 android.app.ActivityThread.main(ActivityThread.java:7625)
在 java.lang.reflect.Method.invoke(本机方法)
在 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)
public class MapsActivity extends FragmentActivity implements LocationListener {
private GoogleMap googleMap; //google map is contained in the fragment work on it to change the position of the map and so on.
private Marker marker;
private Button buttonCallNow;
private RelativeLayout callPanelWrapper;
private static final int PERMS_CALL_ID = 1234; //permission identifier, unique identifier
private static final int REQUEST_PHONE_CALL = 4321;
private LocationManager locationManager; // Android manager service of android platform.
private SupportMapFragment mapFragment;
private Utils utils;
private PhoneCallListener phoneCallListener;
private boolean firstTime;
private String adresse;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps2);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
mapFragment= (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
}
/**
* //When the activity comes back to the foreground, I have to subscribe to the different location information providers, so I will receive the new location information and I will be able to resynchronize my mapping on this location.
*/
@Override
protected void onResume() {
super.onResume();
checkPermissions();
firstTime=true;
}
private void checkPermissions(){
//For older versions of android we check that the ACCES_FINE_LOCATION and ACCES_COARSE_LOCATION permissions are enabled.
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)!=PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this, new String[]{ Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION },PERMS_CALL_ID); //We must provide three parameters: it is the activity that requires the activation of these permissions (here it is this), then a table that specifies the set of permissions to allow. And we need a request code.
return;
}
locationManager= (LocationManager) getSystemService(LOCATION_SERVICE);//I ask android to give me that service locationManager. LOCATION SERVICE comes inheritance FragmentActivity, which inherits from Context, which contains this constant.
if(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){//If on this locationManager, a particular provider here : LocationManager.GPS_PROVIDER is allowed. If I have a GPS type sensor that is enabled, on the locationManager I will be able to subscribe to events.
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000,0,this);//This function requires the type of provider: LocationManager.GPS.it needs the frequency in milliseconds at which I want new location information(Here all the seconds).It needs to notify a person, who is going to receive this notification information, it's the MapsActivity, so this.
}
if(locationManager.isProviderEnabled(LocationManager.PASSIVE_PROVIDER)){//If on this locationManager, a particular provider here : LocationManager.PASIVE_PROVIDER is allowed. If I have a GPS type sensor that is enabled, on the locationManager I will be able to subscribe to events.
locationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER,1000,0,this);//This function requires the type of provider: LocationManager.GPS.it needs the frequency in milliseconds at which I want new location information(Here all the seconds).It needs to notify a person, who is going to receive this notification information, it's the MapsActivity, so this.
}
if(locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){//If on this locationManager, a particular provider here : NETWORK is allowed. If I have a GPS type sensor that is enabled, on the locationManager I will be able to subscribe to events.
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,1000,0,this);//This function requires the type of provider: LocationManager.GPS.it needs the frequency in milliseconds at which I want new location information(Here all the seconds).It needs to notify a person, who is going to receive this notification information, it's the MapsActivity, so this.
}
dispMap();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode==PERMS_CALL_ID){ //This method will be activated each time a permission request is made. And to know where I'm coming from I need the requestCode. This request is coupled with this requestCode here.
checkPermissions(); //i call again chack permission do disp again pop-up permission.
}
}
/**
* //When my application leaves the foreground, I unsubscribe from the different providers of location information so as not to consume a lot of resources.
*/
@Override
protected void onPause() {
super.onPause();
//If the locationManager has been initialized, I make one of this, one of the earphone of all suppliers
locationManager.removeUpdates(this);
}
private void dispMap(){
mapFragment.getMapAsync(new OnMapReadyCallback() {
@Override
public void onMapReady(GoogleMap googleMap) {
MapsActivity.this.googleMap=googleMap;
marker = googleMap.addMarker(new MarkerOptions().position(new LatLng(43.799345,6.725426)));
}
});
}
/**
* React each time new positioning information is calculated
* @param location
*/
@Override
public void onLocationChanged(Location location) { //This location is obtained through the provider. Of course this can be any provider, GPS_PROVIDER is more accurate than PASSIVE_PROVIDER etc..
double latitude= location.getLatitude();//I'm getting the latitude.
double longitude=location.getLongitude();// I'm getting the longitude.
Toast.makeText(this, "Location: " + latitude + "/" + longitude,Toast.LENGTH_SHORT).show();
LatLng googleLocation=new LatLng(latitude,longitude);
if(firstTime){
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(googleLocation, 16.2f));
adresse= Utils.getCompleteAddressString(latitude, longitude,this);
BitmapDescriptor subwayBitmapDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.map_marker);
marker = googleMap.addMarker(new MarkerOptions().position(googleLocation).icon(subwayBitmapDescriptor).title(adresse));
googleMap.setInfoWindowAdapter(new CustomInfoWindowAdapter(this));
}
firstTime=false;
if(this.googleMap!=null){//If my map is correctly displayed
adresse = Utils.getCompleteAddressString(latitude, longitude,this);
googleMap.setInfoWindowAdapter(new CustomInfoWindowAdapter(this));
marker.setTitle(adresse);
marker.setPosition(googleLocation);
marker.showInfoWindow();
}
}
/**
* To react to every change of state
* @param provider
* @param status
* @param extras
*/
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
/**
* When a location provider is closed.
* @param provider
*/
@Override
public void onProviderEnabled(String provider) {
}
/**
* When a location provider is closed.
* @param provider
*/
@Override
public void onProviderDisabled(String provider) {
}
public void btnBackClick(View view) {
Intent myIntent = new Intent(this, HomeActivity.class);
startActivity(myIntent);
}
public void btnCallMapclicked(View view) {
callPanelWrapper.setVisibility(View.VISIBLE);
buttonCallNow.setVisibility(View.GONE);
}
public void buttonFinalCallClicked(View view) {
call();
}
public void popupClosedClicked(View view) {
callPanelWrapper.setVisibility(View.GONE);
buttonCallNow.setVisibility(View.VISIBLE);
}
}
}
尝试使用此代码初始化具有所需 运行 时间权限的地图。
public class MapActivity extends AppCompatActivity implements OnMapReadyCallback,
GoogleApiClient.OnConnectionFailedListener{
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
@Override
public void onMapReady(GoogleMap googleMap) {
Toast.makeText(this, "Map is Ready", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onMapReady: map is ready");
mMap = googleMap;
if (mLocationPermissionsGranted) {
getDeviceLocation();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mMap.setMyLocationEnabled(true);
mMap.getUiSettings().setMyLocationButtonEnabled(false);
init();
}
}
private static final String TAG = "MapActivity";
private static final String FINE_LOCATION = Manifest.permission.ACCESS_FINE_LOCATION;
private static final String COURSE_LOCATION = Manifest.permission.ACCESS_COARSE_LOCATION;
private static final int LOCATION_PERMISSION_REQUEST_CODE = 1234;
//vars
private Boolean mLocationPermissionsGranted = false;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
getLocationPermission();
}
private void initMap(){
Log.d(TAG, "initMap: initializing map");
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(MapActivity.this);
}
private void getLocationPermission(){
Log.d(TAG, "getLocationPermission: getting location permissions");
String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION};
if(ContextCompat.checkSelfPermission(this.getApplicationContext(),
FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){
if(ContextCompat.checkSelfPermission(this.getApplicationContext(),
COURSE_LOCATION) == PackageManager.PERMISSION_GRANTED){
mLocationPermissionsGranted = true;
initMap();
}else{
ActivityCompat.requestPermissions(this,
permissions,
LOCATION_PERMISSION_REQUEST_CODE);
}
}else{
ActivityCompat.requestPermissions(this,
permissions,
LOCATION_PERMISSION_REQUEST_CODE);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
Log.d(TAG, "onRequestPermissionsResult: called.");
mLocationPermissionsGranted = false;
switch(requestCode){
case LOCATION_PERMISSION_REQUEST_CODE:{
if(grantResults.length > 0){
for(int i = 0; i < grantResults.length; i++){
if(grantResults[i] != PackageManager.PERMISSION_GRANTED){
mLocationPermissionsGranted = false;
Log.d(TAG, "onRequestPermissionsResult: permission failed");
return;
}
}
Log.d(TAG, "onRequestPermissionsResult: permission granted");
mLocationPermissionsGranted = true;
initMap(); // once permission granted then only initMap()
}
}
}
}
}
我无法发表评论,因此将我的回答转发为post。
您可能应该更多地描述您的问题,但是您是否添加了 ACCESS_FINE_LOCATION
和
ACCESS_COARSE_LOCATION
到您的清单文件?
编辑:
只需将 onPause
更改为以下内容:
@Override
protected void onPause() {
super.onPause();
if(locationManager != null) // add this line to your code
locationManager.removeUpdates(this);
}
原因:
当显示权限对话框时,您的 activity onPause()
被调用,并且由于您尚未初始化位置管理器,它会抛出 NullPointerException
.
我第一次安装这个应用程序,当我启动 MapsActivity 时,我被要求权限,这是正常的。但问题是应用程序同时关闭。我如何修改我的代码以保持应用程序打开,并且权限弹出窗口只是重叠。非常感谢您的回答。
logcat 中的错误代码:
2020-02-02 11:17:01.340 11559-11574/? E/le.rsr_pechhlu: Unable to peek into adb socket due to error. Closing socket.: Connection reset by peer
2020-02-02 11:17:01.470 11559-11636/? E/AwareLog:AtomicFileUtils:readFileLines 文件不存在:android.util.AtomicFile@2f88384 2020-02-02 11:17:01.470 11559-11636/? E/AwareLog:AtomicFileUtils:readFileLines 文件不存在:android.util.AtomicFile@7fa676d 2020-02-02 11:17:01.471 11559-11603/? E/MemoryLeakMonitorManager: MemoryLeakMonitor.jar 不存在! 2020-02-02 11:17:10.787 11559-11559/com.example.rsr_pechhlup E/AndroidRuntime:致命异常:主要 进程:com.example.rsr_pechhlup,PID:11559 java.lang.RuntimeException:无法暂停 activity {com.example.rsr_pechhlup/com.example.rsr_pechhlup.MapsActivity}:java.lang.NullPointerException:尝试调用虚拟方法 'void android.location.LocationManager.removeUpdates(android.location.LocationListener)'在空对象引用上 在 android.app.ActivityThread.performPauseActivityIfNeeded(ActivityThread.java:4742) 在 android.app.ActivityThread.performPauseActivity(ActivityThread.java:4691) 在 android.app.ActivityThread.handlePauseActivity(ActivityThread.java:4626) 在 android.app.servertransaction.PauseActivityItem.execute(PauseActivityItem.java:45) 在 android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:145) 在 android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:2199) 在 android.os.Handler.dispatchMessage(Handler.java:112) 在 android.os.Looper.loop(Looper.java:216) 在 android.app.ActivityThread.main(ActivityThread.java:7625) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987) 原因:java.lang.NullPointerException:尝试在空对象引用上调用虚方法 'void android.location.LocationManager.removeUpdates(android.location.LocationListener)' 在 com.example.rsr_pechhlup.MapsActivity.onPause(MapsActivity.java:159) 在 android.app.Activity.performPause(Activity.java:7663) 在 android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1536) 在 android.app.ActivityThread.performPauseActivityIfNeeded(ActivityThread.java:4726) 在 android.app.ActivityThread.performPauseActivity(ActivityThread.java:4691) 在 android.app.ActivityThread.handlePauseActivity(ActivityThread.java:4626) 在 android.app.servertransaction.PauseActivityItem.execute(PauseActivityItem.java:45) 在 android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:145) 在 android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:2199) 在 android.os.Handler.dispatchMessage(Handler.java:112) 在 android.os.Looper.loop(Looper.java:216) 在 android.app.ActivityThread.main(ActivityThread.java:7625) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)
public class MapsActivity extends FragmentActivity implements LocationListener {
private GoogleMap googleMap; //google map is contained in the fragment work on it to change the position of the map and so on.
private Marker marker;
private Button buttonCallNow;
private RelativeLayout callPanelWrapper;
private static final int PERMS_CALL_ID = 1234; //permission identifier, unique identifier
private static final int REQUEST_PHONE_CALL = 4321;
private LocationManager locationManager; // Android manager service of android platform.
private SupportMapFragment mapFragment;
private Utils utils;
private PhoneCallListener phoneCallListener;
private boolean firstTime;
private String adresse;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps2);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
mapFragment= (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
}
/**
* //When the activity comes back to the foreground, I have to subscribe to the different location information providers, so I will receive the new location information and I will be able to resynchronize my mapping on this location.
*/
@Override
protected void onResume() {
super.onResume();
checkPermissions();
firstTime=true;
}
private void checkPermissions(){
//For older versions of android we check that the ACCES_FINE_LOCATION and ACCES_COARSE_LOCATION permissions are enabled.
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)!=PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this, new String[]{ Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION },PERMS_CALL_ID); //We must provide three parameters: it is the activity that requires the activation of these permissions (here it is this), then a table that specifies the set of permissions to allow. And we need a request code.
return;
}
locationManager= (LocationManager) getSystemService(LOCATION_SERVICE);//I ask android to give me that service locationManager. LOCATION SERVICE comes inheritance FragmentActivity, which inherits from Context, which contains this constant.
if(locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){//If on this locationManager, a particular provider here : LocationManager.GPS_PROVIDER is allowed. If I have a GPS type sensor that is enabled, on the locationManager I will be able to subscribe to events.
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000,0,this);//This function requires the type of provider: LocationManager.GPS.it needs the frequency in milliseconds at which I want new location information(Here all the seconds).It needs to notify a person, who is going to receive this notification information, it's the MapsActivity, so this.
}
if(locationManager.isProviderEnabled(LocationManager.PASSIVE_PROVIDER)){//If on this locationManager, a particular provider here : LocationManager.PASIVE_PROVIDER is allowed. If I have a GPS type sensor that is enabled, on the locationManager I will be able to subscribe to events.
locationManager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER,1000,0,this);//This function requires the type of provider: LocationManager.GPS.it needs the frequency in milliseconds at which I want new location information(Here all the seconds).It needs to notify a person, who is going to receive this notification information, it's the MapsActivity, so this.
}
if(locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){//If on this locationManager, a particular provider here : NETWORK is allowed. If I have a GPS type sensor that is enabled, on the locationManager I will be able to subscribe to events.
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,1000,0,this);//This function requires the type of provider: LocationManager.GPS.it needs the frequency in milliseconds at which I want new location information(Here all the seconds).It needs to notify a person, who is going to receive this notification information, it's the MapsActivity, so this.
}
dispMap();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode==PERMS_CALL_ID){ //This method will be activated each time a permission request is made. And to know where I'm coming from I need the requestCode. This request is coupled with this requestCode here.
checkPermissions(); //i call again chack permission do disp again pop-up permission.
}
}
/**
* //When my application leaves the foreground, I unsubscribe from the different providers of location information so as not to consume a lot of resources.
*/
@Override
protected void onPause() {
super.onPause();
//If the locationManager has been initialized, I make one of this, one of the earphone of all suppliers
locationManager.removeUpdates(this);
}
private void dispMap(){
mapFragment.getMapAsync(new OnMapReadyCallback() {
@Override
public void onMapReady(GoogleMap googleMap) {
MapsActivity.this.googleMap=googleMap;
marker = googleMap.addMarker(new MarkerOptions().position(new LatLng(43.799345,6.725426)));
}
});
}
/**
* React each time new positioning information is calculated
* @param location
*/
@Override
public void onLocationChanged(Location location) { //This location is obtained through the provider. Of course this can be any provider, GPS_PROVIDER is more accurate than PASSIVE_PROVIDER etc..
double latitude= location.getLatitude();//I'm getting the latitude.
double longitude=location.getLongitude();// I'm getting the longitude.
Toast.makeText(this, "Location: " + latitude + "/" + longitude,Toast.LENGTH_SHORT).show();
LatLng googleLocation=new LatLng(latitude,longitude);
if(firstTime){
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(googleLocation, 16.2f));
adresse= Utils.getCompleteAddressString(latitude, longitude,this);
BitmapDescriptor subwayBitmapDescriptor = BitmapDescriptorFactory.fromResource(R.drawable.map_marker);
marker = googleMap.addMarker(new MarkerOptions().position(googleLocation).icon(subwayBitmapDescriptor).title(adresse));
googleMap.setInfoWindowAdapter(new CustomInfoWindowAdapter(this));
}
firstTime=false;
if(this.googleMap!=null){//If my map is correctly displayed
adresse = Utils.getCompleteAddressString(latitude, longitude,this);
googleMap.setInfoWindowAdapter(new CustomInfoWindowAdapter(this));
marker.setTitle(adresse);
marker.setPosition(googleLocation);
marker.showInfoWindow();
}
}
/**
* To react to every change of state
* @param provider
* @param status
* @param extras
*/
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
/**
* When a location provider is closed.
* @param provider
*/
@Override
public void onProviderEnabled(String provider) {
}
/**
* When a location provider is closed.
* @param provider
*/
@Override
public void onProviderDisabled(String provider) {
}
public void btnBackClick(View view) {
Intent myIntent = new Intent(this, HomeActivity.class);
startActivity(myIntent);
}
public void btnCallMapclicked(View view) {
callPanelWrapper.setVisibility(View.VISIBLE);
buttonCallNow.setVisibility(View.GONE);
}
public void buttonFinalCallClicked(View view) {
call();
}
public void popupClosedClicked(View view) {
callPanelWrapper.setVisibility(View.GONE);
buttonCallNow.setVisibility(View.VISIBLE);
}
}
}
尝试使用此代码初始化具有所需 运行 时间权限的地图。
public class MapActivity extends AppCompatActivity implements OnMapReadyCallback,
GoogleApiClient.OnConnectionFailedListener{
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
@Override
public void onMapReady(GoogleMap googleMap) {
Toast.makeText(this, "Map is Ready", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onMapReady: map is ready");
mMap = googleMap;
if (mLocationPermissionsGranted) {
getDeviceLocation();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mMap.setMyLocationEnabled(true);
mMap.getUiSettings().setMyLocationButtonEnabled(false);
init();
}
}
private static final String TAG = "MapActivity";
private static final String FINE_LOCATION = Manifest.permission.ACCESS_FINE_LOCATION;
private static final String COURSE_LOCATION = Manifest.permission.ACCESS_COARSE_LOCATION;
private static final int LOCATION_PERMISSION_REQUEST_CODE = 1234;
//vars
private Boolean mLocationPermissionsGranted = false;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
getLocationPermission();
}
private void initMap(){
Log.d(TAG, "initMap: initializing map");
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(MapActivity.this);
}
private void getLocationPermission(){
Log.d(TAG, "getLocationPermission: getting location permissions");
String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION};
if(ContextCompat.checkSelfPermission(this.getApplicationContext(),
FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){
if(ContextCompat.checkSelfPermission(this.getApplicationContext(),
COURSE_LOCATION) == PackageManager.PERMISSION_GRANTED){
mLocationPermissionsGranted = true;
initMap();
}else{
ActivityCompat.requestPermissions(this,
permissions,
LOCATION_PERMISSION_REQUEST_CODE);
}
}else{
ActivityCompat.requestPermissions(this,
permissions,
LOCATION_PERMISSION_REQUEST_CODE);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
Log.d(TAG, "onRequestPermissionsResult: called.");
mLocationPermissionsGranted = false;
switch(requestCode){
case LOCATION_PERMISSION_REQUEST_CODE:{
if(grantResults.length > 0){
for(int i = 0; i < grantResults.length; i++){
if(grantResults[i] != PackageManager.PERMISSION_GRANTED){
mLocationPermissionsGranted = false;
Log.d(TAG, "onRequestPermissionsResult: permission failed");
return;
}
}
Log.d(TAG, "onRequestPermissionsResult: permission granted");
mLocationPermissionsGranted = true;
initMap(); // once permission granted then only initMap()
}
}
}
}
}
我无法发表评论,因此将我的回答转发为post。
您可能应该更多地描述您的问题,但是您是否添加了 ACCESS_FINE_LOCATION
和
ACCESS_COARSE_LOCATION
到您的清单文件?
编辑:
只需将 onPause
更改为以下内容:
@Override
protected void onPause() {
super.onPause();
if(locationManager != null) // add this line to your code
locationManager.removeUpdates(this);
}
原因:
当显示权限对话框时,您的 activity onPause()
被调用,并且由于您尚未初始化位置管理器,它会抛出 NullPointerException
.