清单AndroidManifest.xml
添加权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
application里添加
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="sven.com.filedownapplication.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
如果content.FileProvider是红色字体则改为
android:name="androidx.core.content.FileProvider"
添加xml键值对
在res下新建一个Directory,命名xml
在xml下新建一个File 命名为file_paths.xml
添加键值对
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="." path="."/>
</paths>
给main.xml添加一个按钮
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btMain"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
MainActivity
代码
public class MainActivity extends AppCompatActivity {
private String[] perms = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
private final int PERMS_REQUEST_CODE = 200;
Button btMain;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btMain=findViewById(R.id.btMain);
btMain.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1 &&
PackageManager.PERMISSION_GRANTED != checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
//Android 6.0以上版本需要获取临时权限
requestPermissions(perms, PERMS_REQUEST_CODE);
} else {
String filePath = copyFile();//首先把assets下的apk文件复制到sdcard上
installApk(filePath);
}
}
});
}
private void installApk(String fileSavePath) {
File file = new File(fileSavePath);
Log.i("LXH","fileSavePath:"+fileSavePath);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri data;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {//判断版本大于等于7.0
// 通过FileProvider创建一个content类型的Uri
data = FileProvider.getUriForFile(this, "sven.com.filedownapplication.fileprovider", file);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);// 给目标应用一个临时授权
} else {
data = Uri.fromFile(file);
}
intent.setDataAndType(data, "application/vnd.android.package-archive");
startActivity(intent);
}
private String copyFile() {
AssetManager assetManager = this.getAssets();
// String newFilePath = Environment.getExternalStorageDirectory() + "/mwh/OTATestApplication.apk";
String newFilePath = Environment.getExternalStorageDirectory() + "/mwh/Android_8.7.0.5295_537068059.apk";
Log.i("LXH","newFilePath:"+newFilePath);
String Path = Environment.getExternalStorageDirectory() + "/mwh";
Log.i("LXH","Path:"+Path);
try {
File file1 = new File(Path);
if (!file1.exists()) {
file1.mkdir();
}
File file = new File(newFilePath);
if (!file.exists()) {
InputStream in = assetManager.open("Android_8.7.0.5295_537068059.apk");
OutputStream out = new FileOutputStream(newFilePath);
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
in.close();
out.flush();
out.close();
}
} catch (Exception e) {
Log.e("LXH", "异常:"+e.getMessage());
}
return newFilePath;
}
@Override
public void onRequestPermissionsResult(int permsRequestCode, String[] permissions, int[] grantResults) {
switch (permsRequestCode) {
case PERMS_REQUEST_CODE:
boolean storageAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
if (storageAccepted) {
String filePath = copyFile();//首先把assets下的apk文件复制到sdcard上
installApk(filePath);
}
break;
}
}
}
运行结果及代码下载
Log
点击按钮安装apk,这里我用的是qq的apk
完成,很多地方不足,但是起码能运行,感谢互联网资源
有需要项目: 代码link.也可以私信邮箱我看到就发
欢迎指错
常见报错
1.忘记添加xml下的file_paths.xml
AAPT: error: resource xml/file_paths (aka com.example.applicationttt:xml/file_paths) not found.
2.忘记修改AndroidManifest.xml中的provider的authorities属性,修改包名
Installation did not succeed.
The application could not be installed: INSTALL_FAILED_CONFLICTING_PROVIDER
Installation failed due to: ‘null’
3.忘记修改
data = FileProvider.getUriForFile(this, “sven.com.filedownapplication.fileprovider”, file);
中的 包名
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.applicationttt, PID: 10875
java.lang.SecurityException: Uid 10141 does not have permission to uri 0 @ content://sven.com.filedownapplication.fileprovider/./mwh/Android_8.7.0.5295_537068059.apk