Android 8.0自动安装APP安装界面不显示问题解决方案(记录)

问题描述:Android 8.0之后,在开发过程中通过代码自动安装APP的时候,安装界面弹不出来,即不显示。而在Android 8.0之前没有这个问题。

原因:Android 8.0 Oreo 中,Google 移除掉了容易被滥用的“允许位置来源”应用的开关,在安装 Play Store 之外的第三方来源的 Android 应用的时候,竟然没有了“允许未知来源”的检查框,如果你还是想要安装某个被自己所信任的开发者的 app,则需要在每一次都手动授予“安装未知应用”的许可。

但是,每次总不能让用户去找这个应用开关吧,还是得我们从代码端解决问题。

解决方案如下:

1、在清单文件中添加权限:

<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>

2、Android 7.0之后,读取修改本地sd卡的权限也得动态获取。

// 判断android版本号,弹出申请权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    showConfirmAppPermissions(MainActivity.this);
}

// 7.0 动态申请权限 public void showConfirmAppPermissions(Context mContext) { if (ContextCompat. checkSelfPermission(mContext , Manifest.permission. WRITE_EXTERNAL_STORAGE) != PackageManager. PERMISSION_GRANTED) { if (ActivityCompat. shouldShowRequestPermissionRationale((Activity)mContext , Manifest.permission. WRITE_EXTERNAL_STORAGE)) { } else { ActivityCompat. requestPermissions((Activity)mContext , new String[]{Manifest.permission. WRITE_EXTERNAL_STORAGE , Manifest.permission. READ_EXTERNAL_STORAGE , Manifest.permission. REQUEST_INSTALL_PACKAGES} , 1) ; } }}

3、引导用户打开允许未知来源的开关

package com.deepreality.installappdemo;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends AppCompatActivity {

    private final static int INSTALL_PACKAGES_REQUESTCODE = 0x12;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 判断android版本号,弹出申请权限
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            showConfirmAppPermissions(MainActivity.this);
        }

        checkIsAndroidO();
    }

    // 7.0动态申请权限
    public void showConfirmAppPermissions(Context mContext) {
        if (ContextCompat.checkSelfPermission(mContext,
                Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            if (ActivityCompat.shouldShowRequestPermissionRationale((Activity)mContext,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            } else {
                ActivityCompat.requestPermissions((Activity)mContext,
                        new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
                                Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.REQUEST_INSTALL_PACKAGES}, 1);
            }
        }
    }

    /**
     * 判断是否是8.0系统,是的话需要获取此权限,判断开没开,没开的话处理未知应用来源权限问题,否则直接安装
     */
    public void checkIsAndroidO() {
        if (Build.VERSION.SDK_INT >= 26) {
            //PackageManager类中在Android Oreo版本中添加了一个方法:判断是否可以安装未知来源的应用
            boolean b = getPackageManager().canRequestPackageInstalls();
            if (b) {
                Log.e("结果", "开始安装");
                //安装应用的逻辑(写自己的就可以)
            } else {
                //请求安装未知应用来源的权限
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.REQUEST_INSTALL_PACKAGES}, INSTALL_PACKAGES_REQUESTCODE);
            }
        } else {
            Log.e("结果", "版本<26,开始安装");
        }

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case INSTALL_PACKAGES_REQUESTCODE:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    //installApk();
                    Log.e("结果", "开始安装");
                } else {
                    Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
                    startActivityForResult(intent, 0x12);
                }
                break;

        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == 0x12) {
            checkIsAndroidO();
        }
    }
}

至此,Android 8.0的安装App的兼容问题已解决。下面贴一下通过代码安装Apk文件的方法:

1、清单文件里,添加用户权限

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.deepreality.installappdemo">

    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="${applicationId}.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>

    </application>

</manifest>

2、安装app,输入apk文件目录以及文件名

// TODO 试验静默安装 安装app
private static void installApk(String resourcePath, String resourceName) {
    File file = new File(resourcePath, resourceName);
    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_VIEW);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        CommonMethod.Log("e","sdk版本低于7");
        Uri uriForFile = FileProvider.getUriForFile(MainActivity.mainActivity, MainActivity.mainActivity.getApplicationContext().getPackageName() + ".provider", file);
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        intent.setDataAndType(uriForFile, MainActivity.mainActivity.getContentResolver().getType(uriForFile));
    }else {
        intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
    }
    MainActivity.mainActivity.startActivity(intent);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值