尝试在服务启动时调用位置权限,但应用程序崩溃。

huangapple 未分类评论48阅读模式
英文:

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(&quot;Mqtt&quot;, mqttMessage.toString());
                    Log.e(&quot;message &quot;, String.valueOf(mqttMessage));
                    Toast.makeText(MQTTService.this, &quot;Crash Occurred&quot;, 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(&quot;Not yet implemented&quot;);
        }

        @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 &amp;&amp; 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 = &quot;http://maps.google.com/maps?saddr=&quot; + locationResult.getLastLocation().getLatitude() + &quot;,&quot; + 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&lt;String&gt; 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)&#160;
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1968)&#160;
        at android.os.Handler.dispatchMessage(Handler.java:107)&#160;
        at android.os.Looper.loop(Looper.java:214)&#160;
        at android.app.ActivityThread.main(ActivityThread.java:7682)&#160;
        at java.lang.reflect.Method.invoke(Native Method)&#160;
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516)&#160;
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)&#160;
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

huangapple
  • 本文由 发表于 2020年5月5日 03:36:30
  • 转载请务必保留本文链接:https://java.coder-hub.com/61600182.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定