Android 安装assets目录下的其他apk
2017-12-18 18:44
411 查看
在实际开发中,可能会遇到将其他apk打包在自己的应用里面一起安装,下面来看一下具体步骤:
首先将test.apk拷贝到main/assets目录下,在清单文件中申请读写存储卡的权限:
ok,准备工作完成了,下面正式开始:
把test.apk从assets目录下拷贝到存储卡中:
然后安装test.apk,
首先将test.apk拷贝到main/assets目录下,在清单文件中申请读写存储卡的权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />另外6.0以上的手机还需要在代码中申请动态权限:
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this,Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_CODE); }
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { // super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_CODE) { if (grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) { ... } else { finish(); } return; } }为了兼容7.0以上的手机,要使用到provider,在清单文件中application节点下添加provider:
<manifest> ... <application> ... <provider android:name="android.support.v4.content.FileProvider" android:authorities="com.example.app.fileprovider" //自定义名字 为避免重复建议设为:包名.fileprovider android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths" /> </provider> ... </application> </manifest>然后在res目录下新建xml文件夹,在xml文件夹中新建provider_paths.xml文件(对应provide中的resource):
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <!--"."表示所有路径--> <external-path name="external_files" path="."/> <!--填写自己的包名--> <external-path path="Android/data/com.example.app/" name="share_files_path" /> <external-path path="." name="root_path" /> </paths>
ok,准备工作完成了,下面正式开始:
把test.apk从assets目录下拷贝到存储卡中:
/** * 复制文件到SD卡 * @param context * @param fileName 复制的文件名 * @param path 保存的目录路径 * @return */ public static Uri copyAssetsFile(Context context, String fileName, String path) { try { InputStream mInputStream = context.getAssets().open(fileName); File file = new File(path); if (!file.exists()) { file.mkdir(); } File mFile = new File(path + File.separator + "test.apk"); if(!mFile.exists()) mFile.createNewFile(); LogUtil.e(TAG,"开始拷贝"); FileOutputStream mFileOutputStream = new FileOutputStream(mFile); byte[] mbyte = new byte[1024]; int i = 0; while((i = mInputStream.read(mbyte)) > 0){ mFileOutputStream.write(mbyte, 0, i); } mInputStream.close(); mFileOutputStream.close(); Uri uri = null; try{ if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){ //包名.fileprovider uri = FileProvider.getUriForFile(context, "com.example.app.fileprovider", mFile); }else{ uri = Uri.fromFile(mFile); } }catch (ActivityNotFoundException anfe){ LogUtil.e(TAG,anfe.getMessage()); } MediaScannerConnection.scanFile(context, new String[]{mFile.getAbsolutePath()}, null, null); LogUtil.e(TAG,"拷贝完毕:" + uri); return uri; } catch (IOException e) { e.printStackTrace(); Log.e(TAG, fileName + "not exists" + "or write err"); return null; } catch (Exception e) { return null; } }
然后安装test.apk,
/** * 安装apk * @param uri apk存放的路径 * @param context */ public static void openApk(Uri uri, Context context) { Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); if (Build.VERSION.SDK_INT >= 24) { intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.setDataAndType(uri, "application/vnd.android.package-archive"); } else { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); } intent.setDataAndType(uri, "application/vnd.android.package-archive"); context.startActivity(intent); }最后可以检测有没有安装test.apk:
/** * App是否已安装 * @param mContext * @param packageName 包名 * @return */ private boolean isAppInstall(Context mContext, String packageName){ PackageInfo mInfo; try { mInfo = mContext.getPackageManager().getPackageInfo(packageName, 0 ); } catch (Exception e) { // TODO: handle exception mInfo = null; Log.i(TAG, "没有发现安装的包名"); } if(mInfo == null){ return false; }else { return true; } }
相关文章推荐
- Android:从assets资源目录下安装apk
- Android:从assets资源目录下安装apk
- Android 的apk在覆盖安装的时如何重新读取raw或assets目录下的数据库
- android创建文件夹和文件和安装其他apk
- 关于android 如何安装 assets文件下的apk
- Android apk安装过程及Java、JNI读取安装包内assets资源文件的两种方法(附源码实例)
- (转)android apk安装与目录结构
- android拷贝assets目录下文件到其他目录
- android studio 安装assets目录下的apk包出现解析错误的问题
- android 安装assets下的apk
- assets目录下apk的安装
- Android 使用系统限制的权限的apk应安装到 /system/app 目录下
- android创建目录和文件和安装其它apk
- Android 如何查找so文件所在目录,安装APK时so安装到哪个目录
- android apk安装与目录结构
- Android apk安装过程 目录
- Android 读取Assets资源文件或目录,并拷贝到其他目录下
- 关于android 如何安装 assets文件下的apk
- 关于android 怎样安装 assets文件下的apk
- Android /data/data/app_file/目录下面安装apk无权限问题