一,概述
Android系统升级到5.0之后做了不少的变化(5.0变化),开发人员一定要注意这些变化,要不然就有的折腾了。这次最大的变化应该是把Dalvik虚拟机改成了ART运行时),后续会专门讲解这一块。其他的都是一些零碎的问题,例如前段时间发了一篇Android 5.0之后修改了HashMap的实现(传送门)。这篇主要讲一下遇到跟服务相关的问题。
二。详情
服务身为Android四大组件之一,它的使用频率还是比较高的,并且现在主要都是运用在比较关键的部位,例如升级推送等。在Android 5.0之后google出于安全的角度禁止了隐式声明意图来启动服务。也禁止使用Intent过滤器。否则就会抛出异常出来。
解决方式一:
1 将隐式启动转换为显式启动,兼容编译sdk5.0以后版本
//将隐式启动转换为显式启动,兼容编译sdk5.0以后版本 public Intent getExplicitIntent(Context context,Intent implicitIntent){ PackageManager pm = context.getPackageManager(); List<ResolveInfo> resolveInfos = pm.queryIntentServices(implicitIntent, 0); if (resolveInfos == null || resolveInfos.size()!= 1) { return null; } Intent explicitIntent = null; ResolveInfo info = resolveInfos.get(0); String packageName = info.serviceInfo.packageName; String className = info.serviceInfo.name; ComponentName component = new ComponentName(packageName,className); explicitIntent = new Intent(implicitIntent); explicitIntent.setComponent(component); return explicitIntent; }
复制以上方法
直接使用
//设别服务连接桥 private ServiceConnection conn = new ServiceConnection(){ @Override public void onServiceConnected(ComponentName name, IBinder serviceBinder) { LogUtils.d("aidlService服务连接成功"); if(serviceBinder != null){ //绑定成功 AidlDeviceService serviceManager = AidlDeviceService.Stub.asInterface(serviceBinder); onDeviceConnected(serviceManager); } } @Override public void onServiceDisconnected(ComponentName name) { LogUtils.d("AidlService服务断开了"); } }; //绑定服务 public void bindService(){ BaseMainActivity.this.bindService(getExplicitIntent(this,new Intent(LKL_SERVICE_ACTION)), conn, Context.BIND_AUTO_CREATE); //5.0以后的版本会抛出异常方法已被淘汰 // Intent intent = new Intent(); // intent.setAction(LKL_SERVICE_ACTION); // intent.setPackage(""); // boolean flag = bindService(intent, conn, Context.BIND_AUTO_CREATE); // if(flag){ // LogUtils.d("服务绑定成功"); // }else{ // LogUtils.d("服务绑定失败"); // } }
解决方式二:直接写上包名和标示
Intent intent = new Intent("com.gnss.GNSSService"); intent.setAction(GPSBOARDCONTROL);//Service能够匹配的Action intent.setPackage("com.gnss.ssserver");//应用的包名 context.bindService(intent,serviceConnection, Context.BIND_AUTO_CREATE);
判断应用是否安装的方法:
//判断应用是否安装 public boolean isAppInstalled(Context context, String packageName) { final PackageManager packageManager = context.getPackageManager(); List<PackageInfo> pinfo = packageManager.getInstalledPackages(0); if (pinfo != null) { for (int i = 0; i < pinfo.size(); i++) { if (pinfo.get(i).packageName.contains(packageName)) { return true; } } } return false; }