android智能终端(广告机)开发问题 静默安装 升级自启动 隐藏导航栏和虚拟按键

大致描述:公司的板子是淘宝买的,系统android6.0,有root权限,没有任何技术支持

需求:1 实现广告机导航栏隐藏以及禁止下滑,也就是说用户只能看见我的app,不能退出进入android系统桌面

           2 开机自启,自动升级且不能让用户点击,也就是静默安装,而后自启动应用,

实现经历:由于没有技术支持,且个人只是android应用层开发,所以修改源码方案不现实,自己也没有这个能力,只能从应用方面解决,经过几天面向搜索编程,有如下解决方案。

需求1实现:wm命令修改屏幕的显示范围。(修改系统主题和window flag方案没有找到较好的实现方式,虚拟按键还是会弹出来)

adb shell wm overscan 0,-30,0,-168

如上:通过adb命令将屏幕上边距和下边距分别移除屏幕外,在屏幕外就无法触摸了,这样就不会下拉出菜单了,而虚拟按键也在屏幕外,也不用担心用户点击退出应用的问题了。

0,-30,0,-168对应左上右下,具体参数根据屏幕调整,也可以通过代码获取状态栏和虚拟按键高度调整。

进一步思考:如何实现

wm overscan 0,-30,0,-168 代码执行时

<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />//需要加权限
代码如下:
object OverscanUtil {
    /**
     * 修改屏幕左上右下的margin距离
     * left:20
     * 相当于:android:layout_marginLeft="20px"
     * @param left 距离真实屏幕左边距
     * @param top 距离真实屏幕上边距
     * @param right 距离真实屏幕右边距
     * @param bottom 距离真实屏幕下边距
     */
    fun changeOverscan(left:Int=0,top:Int=0,right:Int=0,bottom:Int=0){
        val split = "wm overscan $left,$top,$right,$bottom".split(" ").toTypedArray()
        try {
            Runtime.getRuntime().exec(split)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

}
implementation 'com.blankj:utilcode:1.23.2' //依赖此工具类用于计算app状态栏高度和底部虚拟按键高度

监听进入app:执行一下代码隐藏底部虚拟按键,和状态栏。

 

val statusBarHeight = BarUtils.getStatusBarHeight()+10
val navBarHeight = BarUtils.getNavBarHeight()
OverscanUtil.changeOverscan(top = -statusBarHeight,bottom = -navBarHeight)

退出app,显示虚拟按键和状态栏

 

OverscanUtil.changeOverscan()

为了方便可以在debug模式不隐藏虚拟按键,也可以通过  adb shell wm overscan 0,0,0,0 还原。

需求2实现:静默安装与静默安装后自启动以及开机自启动

注意:当前版本和需要升级的版本apk最好都用release包,而且升级版本要高于当前版本,否则可能升级失败。

<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

静默安装工具类,需要root权限

public class InstallUtils {
   //com.xx.xx 需要被静默安装app包名 apkAbsolutePath安装的apk路径
    public boolean silentInstall(String apkAbsolutePath)
    {
        String[] args =
                {"pm", "install", "-i", "com.xx.xx", "-r",
                        apkAbsolutePath};
        if (Build.VERSION.SDK_INT >= 24)
        {
            args = new String[]
                    {"pm", "install", "-r", "-i", "com.xx.xx", "--user",
                            "0", apkAbsolutePath};
        }
        String result = "EMPTY";
        ProcessBuilder processBuilder = new ProcessBuilder(args);
        Process process = null;
        InputStream inIs = null;
        try
        {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            int read = -1;
            process = processBuilder.start();
            baos.write('/');
            inIs = process.getInputStream();
            while ((read = inIs.read()) != -1)
            {
                baos.write(read);
            }
            byte[] data = baos.toByteArray();
            result = new String(data, StandardCharsets.UTF_8);
            Log.e(TAG, "resultString-------->>>" + result);
            baos.close();
        } catch (IOException e)
        {
            Log.e(TAG, "静默安装无效!!!");
        } finally
        {
            try
            {
                if (inIs != null)
                {
                    inIs.close();
                }
            } catch (IOException e)
            {
            }
            if (process != null)
            {
                process.destroy();
            }
        }
        return result.contains("Success");
    }

AndroidManifest.xml添加如下广播:
<receiver
        android:name=".SelfStartReceiver"
        android:enabled="true"
        android:exported="true">
    <intent-filter android:priority="1000">
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
        <category android:name="android.intent.category.LAUNCHER"/>
    </intent-filter>
 
</receiver>
<receiver
        android:name=".ReplaceReceiver"
        android:enabled="true"
        android:exported="true">

    <intent-filter android:priority="1000">
       
        <action android:name="android.intent.action.PACKAGE_REPLACED"/>
        <data android:scheme="package"/>
    </intent-filter>


</receiver>
具体广播类:
class ReplaceReceiver:BroadcastReceiver(){
    override fun onReceive(context: Context, intent: Intent) {
        Log.e("ReplaceReceiver",intent.action)
         if (intent.action=="android.intent.action.PACKAGE_REPLACED") {
            val packageName = intent.dataString?.substring(8)
            if (packageName == "com.xx.xx") {//这里是你的包名
                startSelf(context)
            }
        }
    }
    private fun startSelf(context: Context) {
        val i = Intent(context, MainActivity::class.java)
        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        context.startActivity(i)
    }

}
class SelfStartReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        Log.e("SelfStartReceiver",intent.action)
        if (intent.action == "android.intent.action.BOOT_COMPLETED") {
            startSelf(context)
        }
    }

   
    private fun startSelf(context: Context) {
        val i = Intent(context, MainActivity::class.java)
        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
        context.startActivity(i)
    }

}
,注意,安装之前将你的apk放到system/priv-app目录也就是说低版本的apk

adb remount

adb push /你的路径/app-release.apk /system/priv-app

adb reboot //等待重启

 

然后调用此代码开始静默安装,最好子线程里

InstallUtils.silentInstall("/sdcard/yuehuiot/xxx.apk")//这里面填写需要更新apk版本

 

           
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值