Caused by:java.lang.IllegalArgumentException: provider “network“ does not exist

问题: 手机定位权限开启,在安装某些厂商定制的apk时,首次安装正常启动,再次启动,则应用崩溃.根据系统日志,定位到问题是在LocationManager.java中.系统日志如下图:

问题分析: app中会申请定位的权限,但是系统中,现在network provider不存在,当provider不存在时,调用LocationManagerService.java 的 requestLocationUpdates(),安卓系统会抛出异常.

---------------------------------分析---------------------------------------------------------------

(1) 当app 获取定位时,会通过LocationManager.java 提供的api,获取定位,

源码路径:frameworks/base/location/java/android/location/LocationManager.java
 

/**
      * @param provider 由 {@link #getAllProviders()} 列出的提供者
      * @param locationRequest 包含位置参数的位置请求
      * @param executor 处理监听器回调的执行器
      * @param Listener 接收位置更新的监听器
      *
      * 如果提供者为 null 或不存在,则抛出 IllegalArgumentException
      * 如果 locationRequest 为 null,则抛出 IllegalArgumentException
      * 如果侦听器为空,则@抛出 IllegalArgumentException
      * 如果没有合适的权限,则抛出@抛出SecurityException
      */

 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
    public void requestLocationUpdates(@NonNull String provider,
            @NonNull LocationRequest locationRequest,
            @NonNull @CallbackExecutor Executor executor,
            @NonNull LocationListener listener) {
        Preconditions.checkArgument(provider != null, "invalid null provider");
        Preconditions.checkArgument(locationRequest != null, "invalid null location request");

        try {
            synchronized (sLocationListeners) {
                WeakReference<LocationListenerTransport> reference = sLocationListeners.get(
                        listener);
                LocationListenerTransport transport = reference != null ? reference.get() : null;
                if (transport == null) {
                    transport = new LocationListenerTransport(listener, executor);
                } else {
                    Preconditions.checkState(transport.isRegistered());
                    transport.setExecutor(executor);
                }

                //调用LocationManagerService的方法
                mService.registerLocationListener(provider, locationRequest, transport,
                        mContext.getPackageName(), mContext.getAttributionTag(),
                        AppOpsManager.toReceiverId(listener));

                sLocationListeners.put(listener, new WeakReference<>(transport));
            }
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

(2)接着着调用LocationManagerService 的 registerLocationListenner() 方法.

源码路径:frameworks/base/services/core/java/com/android/server/location/LocationManagerService.java

  @Override
    public void registerLocationListener(String provider, LocationRequest request,
            ILocationListener listener, String packageName, @Nullable String attributionTag,
            String listenerId) {
        CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, attributionTag,
                listenerId);
        int permissionLevel = LocationPermissions.getPermissionLevel(mContext, identity.getUid(),
                identity.getPid());
        LocationPermissions.enforceLocationPermission(identity.getUid(), permissionLevel,
                PERMISSION_COARSE);

        // clients in the system process should have an attribution tag set
        if (identity.getPid() == Process.myPid() && attributionTag == null) {
            Log.w(TAG, "system location request with no attribution tag",
                    new IllegalArgumentException());
        }

        request = validateLocationRequest(provider, request, identity);

        LocationProviderManager manager = getLocationProviderManager(provider);
        //当provider不存在时,抛出异常
        Preconditions.checkArgument(manager != null,
                "provider \"" + provider + "\" does not exist");

        manager.registerLocationRequest(request, identity, permissionLevel, listener);
    }

(3)上面源码上可以看到,当LocationProvider 为 null 时,系统会抛出异常,这就是日志中看到的异常,因此,可以在 locationProvider 不为为 null 的时,才执行后面的步骤,在LocationManager.java中,提供了一个 isProviderEnabled()方法去判断provider是否可用.

源码路径:frameworks/base/location/java/android/location/LocationManager.java
 


//如果提供程序存在并且已启用返回true;如果provider为null,则抛出 IllegalArgumentException

 public boolean isProviderEnabled(@NonNull String provider) {
        return isProviderEnabledForUser(provider, Process.myUserHandle());
    }

(4) 因此,最终的解决方案为:

源码路径:frameworks/base/services/core/java/com/android/server/LocationManagerService.java

 @Override
    public void registerLocationListener(String provider, LocationRequest request,
            ILocationListener listener, String packageName, @Nullable String attributionTag,
            String listenerId) {
        CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, attributionTag,
                listenerId);
        int permissionLevel = LocationPermissions.getPermissionLevel(mContext, identity.getUid(),
                identity.getPid());
        LocationPermissions.enforceLocationPermission(identity.getUid(), permissionLevel,
                PERMISSION_COARSE);

        // clients in the system process should have an attribution tag set
        if (identity.getPid() == Process.myPid() && attributionTag == null) {
            Log.w(TAG, "system location request with no attribution tag",
                    new IllegalArgumentException());
        }

        request = validateLocationRequest(provider, request, identity);

        LocationProviderManager manager = getLocationProviderManager(provider);
        
        //当provider不存在时,抛出异常,因此需要将异常注释掉

+ //       Preconditions.checkArgument(manager != null,
+ //               "provider \"" + provider + "\" does not exist");

+       if (manager != null ) 
        manager.registerLocationRequest(request, identity, permissionLevel, listener);


    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值