英文:
Trying to call location permission when service is started but app crashes
问题
我在我的应用中有一个按钮,用于启动应用中的一个服务。该服务需要权限才能工作。我已经将权限请求添加到了服务中,但是当我按下按钮启动服务时,我的应用崩溃了。以下是这个服务的代码:
public class MQTTService extends Service {
// ...(此处省略部分代码)
@Override
public void onCreate() {
super.onCreate();
callPermissions();
requestLocationUpdates();
}
// ...(此处省略部分代码)
public void callPermissions() {
String[] permissions = {Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION};
Permissions.check(this/*context*/, permissions, null/*rationale*/, null/*options*/, new PermissionHandler() {
@Override
public void onGranted() {
// do your task.
requestLocationUpdates();
}
@Override
public void onDenied(Context context, ArrayList<String> deniedPermissions) {
super.onDenied(context, deniedPermissions);
callPermissions();
}
});
}
// ...(此处省略部分代码)
}
以下是您提供的堆栈跟踪信息:
2020-05-04 20:32:29.440 17319-17357/com.example.carcrashdetection E/Perf: Fail to get file list com.example.carcrashdetection
2020-05-04 20:32:29.440 17319-17319/com.example.carcrashdetection E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.carcrashdetection, PID: 17319
java.lang.RuntimeException: Unable to create service com.example.carcrashdetection.MQTTService: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
at android.app.ActivityThread.handleCreateService(ActivityThread.java:4082)
at android.app.ActivityThread.access$1800(ActivityThread.java:231)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1968)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
Caused by: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
at android.app.ContextImpl.startActivity(ContextImpl.java:964)
at android.app.ContextImpl.startActivity(ContextImpl.java:940)
at android.content.ContextWrapper.startActivity(ContextWrapper.java:383)
at com.nabinbhandari.android.permissions.Permissions.check(Permissions.java:121)
at com.example.carcrashdetection.MQTTService.callPermissions(MQTTService.java:282)
at com.example.carcrashdetection.MQTTService.onCreate(MQTTService.java:95)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:4070)
at android.app.ActivityThread.access$1800(ActivityThread.java:231)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1968)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
根据堆栈跟踪信息,问题出现在 Permissions.check
方法中的 startActivity
调用,要求添加 FLAG_ACTIVITY_NEW_TASK
标志。这表明您尝试从非活动(Activity)上下文中启动活动,因此需要添加该标志。
在您的 callPermissions
方法中,您可以尝试使用以下代码:
public void callPermissions() {
String[] permissions = {Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION};
Permissions.check(this/*context*/, permissions, null/*rationale*/, null/*options*/, new PermissionHandler() {
@Override
public void onGranted() {
// do your task.
requestLocationUpdates();
}
@Override
public void onDenied(Context context, ArrayList<String> deniedPermissions) {
super.onDenied(context, deniedPermissions);
// Use the service context to start the activity with the FLAG_ACTIVITY_NEW_TASK flag.
Intent dialogIntent = new Intent(MQTTService.this, alert.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(dialogIntent);
}
});
}
在 onDenied
方法中,使用服务的上下文(MQTTService.this
)来启动活动,并添加 FLAG_ACTIVITY_NEW_TASK
标志。
请尝试以上更改,看看是否解决了您的问题。
英文:
I have a button in my app that starts a service in my app. the service requires permission for it to work. I have added the permission request to the service but when I press the button to start the service my app crashes. here is the service
public class MQTTService extends Service {
private PowerManager.WakeLock wakeLock;
private MqttAndroidClient clientPhone;
public static String uri;
private FusedLocationProviderClient fusedLocationClient;
private LocationRequest locationRequest;
public void MQTTService() {
clientPhone = new MqttAndroidClient(this, serverUri, clientId);
clientPhone.setCallback(new MqttCallback() {
public void connectComplete(boolean b, String s) {
}
@Override
public void connectionLost(Throwable throwable) {
}
@Override
public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
Log.w("Mqtt", mqttMessage.toString());
Log.e("message ", String.valueOf(mqttMessage));
Toast.makeText(MQTTService.this, "Crash Occurred", Toast.LENGTH_SHORT).show();
Intent dialogIntent = new Intent(MQTTService.this, alert.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(dialogIntent);
}
@Override
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
}
});
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onCreate() {
super.onCreate();
callPermissions();
requestLocationUpdates();
}
@Override
public void onDestroy() {
super.onDestroy();
if (wakeLock.isHeld()) {
wakeLock.release();
}
if(clientPhone!=null) {
/*unregisterResources is needed,otherwise receive this error:
has leaked ServiceConnection org.eclipse.paho.android.service.MqttAndroidClient*/
try {
clientPhone.unregisterResources();
clientPhone.close();
clientPhone.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
unregisterReceiver(m_ScreenOffReceiver);
m_ScreenOffReceiver = null;
}
public void requestLocationUpdates() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PermissionChecker.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PermissionChecker.PERMISSION_GRANTED) {
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
locationRequest = new LocationRequest();
locationRequest.setInterval(2000);
locationRequest.setFastestInterval(4000);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
fusedLocationClient.requestLocationUpdates(locationRequest, new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
uri = "http://maps.google.com/maps?saddr=" + locationResult.getLastLocation().getLatitude() + "," + locationResult.getLastLocation().getLongitude();
}
}, getMainLooper());
}
}
public void callPermissions(){
String[] permissions = {Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION};
Permissions.check(this/*context*/, permissions, null/*rationale*/, null/*options*/, new PermissionHandler() {
@Override
public void onGranted() {
// do your task.
requestLocationUpdates();
}
@Override
public void onDenied(Context context, ArrayList<String> deniedPermissions) {
super.onDenied(context, deniedPermissions);
callPermissions();
}
});
}
}
this is my stacktrace
2020-05-04 20:32:29.440 17319-17357/com.example.carcrashdetection E/Perf: Fail to get file list com.example.carcrashdetection
2020-05-04 20:32:29.440 17319-17319/com.example.carcrashdetection E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.carcrashdetection, PID: 17319
java.lang.RuntimeException: Unable to create service com.example.carcrashdetection.MQTTService: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
at android.app.ActivityThread.handleCreateService(ActivityThread.java:4082)
at android.app.ActivityThread.access$1800(ActivityThread.java:231)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1968)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
Caused by: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
at android.app.ContextImpl.startActivity(ContextImpl.java:964)
at android.app.ContextImpl.startActivity(ContextImpl.java:940)
at android.content.ContextWrapper.startActivity(ContextWrapper.java:383)
at com.nabinbhandari.android.permissions.Permissions.check(Permissions.java:121)
at com.example.carcrashdetection.MQTTService.callPermissions(MQTTService.java:282)
at com.example.carcrashdetection.MQTTService.onCreate(MQTTService.java:95)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:4070)
at android.app.ActivityThread.access$1800(ActivityThread.java:231) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1968) 
at android.os.Handler.dispatchMessage(Handler.java:107) 
at android.os.Looper.loop(Looper.java:214) 
at android.app.ActivityThread.main(ActivityThread.java:7682) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950) 
2020-05-04 20:32:29.440 17319-17357/com.example.carcrashdetection E/Perf: getFolderSize() : Exception_1 = java.lang.NullPointerException: Attempt to get length of null array
2020-05-04 20:32:29.444 17319-17319/com.example.carcrashdetection I/Process: Sending signal. PID: 17319 SIG: 9
I have more methods in the original service but I got rid of them for the purpose of this question as I dont feel they are the problem. It is ever since I added the location method and the permissions for accessing location that my app started to crash. Am I calling the permissions wrong?
答案1
得分: 0
你的问题与权限无关。你的应用在这里崩溃:
2020-05-04 20:32:29.440 17319-17357/com.example.carcrashdetection E/Perf: getFolderSize() :异常_1 = java.lang.NullPointerException:尝试获取空数组的长度
英文:
Your problem has nothing to do with permissions. Your app is crashing here:
2020-05-04 20:32:29.440 17319-17357/com.example.carcrashdetection E/Perf: getFolderSize() : Exception_1 = java.lang.NullPointerException: Attempt to get length of null array
专注分享java语言的经验与见解,让所有开发者获益!
评论