Android Apk在手机上安装失败问题解决

  • 之前在做App版本更新的时候,发现在5.0以上的手机上会出现安装失败崩溃的问题,之前一直好好的,突然出现这个问题,直接是蒙蔽状态,但又必须解决,所以只有对出现的问题进行跟踪,最后解决了,在这里做一下记录
问题1
  • APK在7.0以上手机若不设置FileProvider会直接安装崩溃并抛类似下面的异常,刚才是还以为是安装包路径写错了,后来才发现是在7.0中为了提高应用的安全性,引入私有目录被限制访问和StrictMode API(禁止向你的应用外公开file://url,若有一项包含文件file://url类型的Intent离开你的应用,则会抛出异常)

    android.os.FileUriExposedException: file:///XXX exposed beyond app through ClipData.Item.getUri() at android.os.StrictMode.onFileUriExposed(StrictMode.java:1799) at android.net.Uri.checkFileUriExposed(Uri.java:2346) at android.content.ClipData.prepareToLeaveProcess(ClipData.java:832) at android.content.Intent.prepareToLeaveProcess(Intent.java:8909)

  • 如何解决该问题了?

    • 针对这个问题google提供了FileProvider,使用它可以生成content://url 来替代file://url

      • 首先我们在res目录下新建一个xml的目录,然后创建一个file_paths.xml,然后配置你安装包目录,第一个参数可随意指定,第二参数为目录路径,需要准确指定,那它几种标签,可根据需要进行配置

在这里插入图片描述

					   	<files-path name="name" path="path" /> 物理路径相当于Context.getFilesDir() + /path/
						 
						<cache-path name="name" path="path" /> 物理路径相当于Context.getCacheDir() + /path/
						 
						<external-path name="name" path="path" /> 物理路径相当于Environment.getExternalStorageDirectory() + /path/
						 
						<external-files-path name="name" path="path" /> 物理路径相当于Context.getExternalFilesDir(String) + /path/
						 
						<external-cache-path name="name" path="path" /> 物理路径相当于Context.getExternalCacheDir() + /path/
  • 在清单文件中进行注册

       		           <provider
       		            android:name="android.support.v4.content.FileProvider"
       		            android:authorities="你的包名.fileprovider"
       		            android:exported="false"
       		            android:grantUriPermissions="true">
       		        <meta-data
       		            android:name="android.support.FILE_PROVIDER_PATHS"
       		            android:resource="@xml/file_paths" />
       		        </provider>
    
  • 代码

    	if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N) {//判读版本是否在7.0以上
    	       Uri apkUri = FileProvider.getUriForFile(this, "你的包名.fileprovider", apkFile);//在AndroidManifest中的android:authorities值
    	       Intent install = new Intent(Intent.ACTION_VIEW);
    	       install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    	       install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);//添加这一句表示对目标应用临时授权该Uri所代表的文件
    	       install.setDataAndType(apkUri, "application/vnd.android.package-archive");
    	       startActivity(install);
    	} else{
    	       Intent install = new Intent(Intent.ACTION_VIEW);
    	       install.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
    	       install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    	       startActivity(install);
    	}
    
问题2
  • Android为了进一步提高应用的安全性,设置了未知来源应用安装权限,根据用户的需求来是否允许安装不是从应用商店下载的apk,所以刚开始的时候,发现8.0.9.0的手机上即使设置FileProvider同样会安装失败,真是是崩溃,又的找google爸爸了。。。

  • 如何解决该问题了?

    • 在安装apk的时候我们需要检测我们是否有安装权限,若有我们在进行安装,若没有该权限,我们可以提示用户需要该权限,并且跳转到对应应用的应用权限管理中,让用户开启,之后再应用检测用户是拒绝了还是打开了,若打开了,表示我们有安装权限,此时我们才可以正常安装升级包了

      • 1.再清单文件中加入权限

             <!--安卓8.0打开apk安装更新-->
          <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
        
      • 检测是否允许安装未知来源的app

           @RequiresApi(api = Build.VERSION_CODES.O)
           public static boolean isHasInstallPermissionWithO(Context context){
               if (context == null){
                   return false;
               }
               return context.getPackageManager().canRequestPackageInstalls();
           }
        
    • 若返回true,直接启动Activity进行安装,反之,跳转到应用权限设置界面让用户去主动打开

       	    /**
       	     * 开启设置安装未知来源应用权限界面
       	     * @param context
       	     */
       	    @RequiresApi (api = Build.VERSION_CODES.O)
       	    public static void startInstallPermissionSettingActivity(Context context) {
       	        if (context == null){
       	            return;
       	        }
       	        Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
       	        ((Activity)context).startActivityForResult(intent,REQUEST_CODE_APP_INSTALL);
                 }
      
    • 在用户设置后可通过onActivityResult()进行监测,判断是否打开了权限,不知道为什么我在这里获取到的resultCode不是Activity_OK,但权限的确是打开了,可以安装,所以比较建议再次检测一次应用是否有安装权限,若返回true,则开始安装更新包

       		       fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
       		          if (requestCode == AppUtils.REQUEST_CODE_APP_INSTALL) {
       		              if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
       		                  val hasInstallPermission = AppUtils.isHasInstallPermissionWithO(mContext)
       		                  if (!hasInstallPermission) {
       		                      return
       		                  } else {
       		                      instaillApp()
       		                  }
       		              } else {
       		                  instaillApp()
       		              }
       		          }
       		    }
      }
       		              } else {
       		                  instaillApp()
       		              }
       		          }
       		    }
      
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Android Studio中创建的APKAndroid Package)文件通常是在完成应用开发和测试后,用于在实际设备或模拟器上安装和运行的。下面是安装步骤: 1. **确保环境准备**: - 确保您的Android设备连接到电脑,或者开启USB调试模式并连接到电脑。 - 如果是模拟器,选择一个支持您目标API版本的AVD(Android虚拟设备)。 2. **编译APK**: - 在Android Studio中打开项目,点击菜单栏的"Build",然后选择"Generate Signed Bundle / APK"。如果您还没创建签名(keystore),系统会提示您设置。 - 选择"APK"作为生成类型,然后点击"Build"按钮。 3. **找到APK文件**: - 完成编译后,会在"buildoutputsapk"文件夹中找到打包好的APK文件(通常是app-debug.apk或app-release.apk)。 4. **安装APK**: - 如果是连接的设备,打开文件管理器,将APK直接拖拽到设备的"Download"或"Apps"文件夹。 - 或者,点击设备通知栏中的"连接设备"或"安装未知来源的应用"(可能需要在设置中启用)。 - 在设备上打开文件管理器,找到APK,点击安装。 5. **确认安装**: - 如果有安全提示,按照提示进行操作,比如输入设备密码或确认安装权限。 6. **首次启动**: - 安装完成后,您可以在设备的应用列表中找到新安装的应用并点击打开。 相关问题: 1. 如何在Android Studio中设置签名(keystore)? 2. 安卓设备如何开启USB调试模式? 3. 如果安装失败,可能有哪些常见问题

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值