• Android开发 launchar开发


    前言

      记录一些launchar开发的技术细节

    清单里需要注意的内容

    注意,要添加singleTask,否则会出现home键多次创建launchar 应用

      <application>
            <activity
                android:name=".ui.MainActivity"
                android:exported="true"
                android:launchMode="singleTask">
                <intent-filter>
                    <!--  隐藏图标   -->
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                    <!-- 设置为 launcher -->
                    <category android:name="android.intent.category.HOME" />
                    <category android:name="android.intent.category.DEFAULT" />
                    <category android:name="android.intent.category.rayland.home" />
                </intent-filter>
            </activity>
        </application>

    屏蔽一些按键防止launchar受影响

        override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean {
            if (keyCode == KeyEvent.KEYCODE_BACK) {
                return true
            }
            if (keyCode == KeyEvent.KEYCODE_MENU) {
                return true
            }
            if (keyCode == KeyEvent.KEYCODE_HOME) {
                return true
            }
    }

    启动桌面应用的方式

        /**
         * 启动应用
         */
        fun startApp(packageName: String) {
            try {
                this@MainActivity.packageManager.getLaunchIntentForPackage(packageName)?.let { intent ->
                    startActivity(intent)
                }
            } catch (e: Exception) {
                e.printStackTrace()
                Toast.makeText(this, "应用启动失败", Toast.LENGTH_SHORT).show()
            }
        }
    
        /**
         * 启动应用
         * [packageName] 包名
         * [className] 类名(请注意需要路径+类名)
         */
        fun startApp(packageName: String, className: String) {
            try {
                startActivity(Intent().apply {
                    setClassName(packageName, className)
                })
            } catch (e: Exception) {
                e.printStackTrace()
                Log.e("zh", "应用启动失败 : $e" )
                Toast.makeText(this, "应用启动失败", Toast.LENGTH_SHORT).show()
            }
        }

    获取系统中安装的应用列表

    bean

    data class ApplyBean(val name: String?, val icon: Drawable?, val packageName: String?)

    获取数据

        private fun getAllApps(): List<ApplyBean> {
            val packageInfoArray = mutableListOf<PackageInfo>()
            val applyBeanArray = mutableListOf<ApplyBean>()
            val pManager = MainApp.getApp().packageManager
    
            // 获取手机内所有应用
            val packlist = pManager.getInstalledPackages(0)
            for (i in packlist.indices) {
                val pak = packlist[i] as PackageInfo
                // if()里的值如果<=0则为自己装的程序,否则为系统工程自带
                if (pak.applicationInfo.flags and ApplicationInfo.FLAG_SYSTEM <= 0) {
                    // 添加自己已经安装的应用程序
                    packageInfoArray.add(pak)
                } else {
                    //apps.add(pak)
                }
            }
            for (pinfo in packageInfoArray) {
                //设置图片
                val icon = pManager.getApplicationIcon(pinfo.applicationInfo)
                //设置应用程序名字
                val appName = pManager.getApplicationLabel(pinfo.applicationInfo).toString()
                //设置应用程序的包名
                val packageName = pinfo.applicationInfo.packageName
                val app = ApplyBean(appName, icon, packageName)
                applyBeanArray.add(app)
            }
            return applyBeanArray
        }

    应用变化监听

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(Intent.ACTION_PACKAGE_ADDED)
                    || intent.getAction().equals(Intent.ACTION_PACKAGE_REMOVED)
                    || intent.getAction().equals(Intent.ACTION_PACKAGE_REPLACED)) {
                for (AppPackageListener appPackageListener: mAppPackageListener) {
                    appPackageListener.onAppPackageChanged(intent.getAction(), intent.getData());
                }
            }
        }
        
        
        public static void registerReceiver(Context context) {
            mIntentFilter = new IntentFilter();
            mIntentFilter.addDataScheme("package");
            mIntentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
            mIntentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
            mIntentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
            context.registerReceiver(mReceiver, mIntentFilter);
        }

    卸载应用

    需要系统级权限

        <!--  卸载应用权限 系统级权限-->
        <uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
        <uses-permission android:name="android.permission.DELETE_PACKAGES" />

    代码

    不要吃惊,没错卸载是依靠一个系统activity实现的

        /**
         * 卸载应用
         */
        fun uninstallApp(packageName: String) {
            try {
                val i: Intent = Intent.parseUri("#Intent;action=android.intent.action.DELETE;launchFlags=0x10800000;end", 0)
                    .setData(Uri.fromParts("package", packageName, null))
                    .putExtra(Intent.EXTRA_USER, Process.myUserHandle())
                this.startActivity(i)
            } catch (e: URISyntaxException) {
                Log.e("lwlx", "Failed to parse intent to start uninstall activity for item=$e")
            }
        }

    上面卸载的来源,luancher3源码

        /**
         * Performs the drop action and returns the target component for the dragObject or null if
         * the action was not performed.
         */
        protected ComponentName performDropAction(View view, ItemInfo info) {
            if (mCurrentAccessibilityAction == RECONFIGURE) {
                int widgetId = getReconfigurableWidgetId(view);
                if (widgetId != INVALID_APPWIDGET_ID) {
                    mLauncher.getAppWidgetHost().startConfigActivity(mLauncher, widgetId, -1);
                }
                return null;
            }
            // else: mCurrentAccessibilityAction == UNINSTALL
    
            ComponentName cn = getUninstallTarget(info);
            if (cn == null) {
                // System applications cannot be installed. For now, show a toast explaining that.
                // We may give them the option of disabling apps this way.
                Toast.makeText(mLauncher, R.string.uninstall_system_app_text, Toast.LENGTH_SHORT).show();
                return null;
            }
            try {
                Intent i = Intent.parseUri(mLauncher.getString(R.string.delete_package_intent), 0)
                        .setData(Uri.fromParts("package", cn.getPackageName(), cn.getClassName()))
                        .putExtra(Intent.EXTRA_USER, info.user);
                mLauncher.startActivity(i);
                return cn;
            } catch (URISyntaxException e) {
                Log.e(TAG, "Failed to parse intent to start uninstall activity for item=" + info);
                return null;
            }
        }

    其他设置

    /**
     * 系统设置工具类
     * 需要的系统级权限
     *
     * <uses-permission android:name="android.permission.SET_TIME"/>
     * <uses-permission android:name="android.permission.SET_TIME_ZONE"/>
     * <uses-permission android:name="android.permission.WRITE_SETTINGS"/>
     * <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/>
     */
    class SystemSettingsUtil {
    
        companion object {
    
            /**
             * 设置时间
             */
            fun setTime(context: Context, millis: Long) {
                val am: AlarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
                am.setTime(millis)
            }
    
            /**
             * 是否是24小时格式
             * @return true=24小时 false=12小时
             */
            fun is24HourMode(context: Context): Boolean {
                return Settings.System.getString(context.contentResolver, Settings.System.TIME_12_24) == "24"
            }
    
            /**
             * 设置时间格式
             * [is24HourMode] true=24小时 false=12小时
             */
            fun setHourMode(context: Context, is24HourMode: Boolean) {
                Settings.System.putString(context.contentResolver, Settings.System.TIME_12_24, if (is24HourMode) "24" else "12")
            }
    
            /**
             * 是否是自动校时
             */
            fun isAutoTime(context: Context) =
                Settings.Global.getInt(context.contentResolver, Settings.Global.AUTO_TIME, 0) == 1
    
            /**
             * 设置自动校时
             * [enable] 1=启用 0=禁用
             */
            fun setAutoTime(context: Context, enable: Int) {
                Settings.Global.putInt(context.contentResolver, Settings.Global.AUTO_TIME, enable)
            }
    
            /**
             * 设置亮度
             */
            fun setBrightness(context: Context, brightness: Int) {
                Settings.System.putInt(context.contentResolver, Settings.System.SCREEN_BRIGHTNESS_MODE, Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL)
                Settings.System.putInt(context.contentResolver, Settings.System.SCREEN_BRIGHTNESS, brightness)
            }
    
            /**
             * 获取亮度
             */
            fun getBrightness(context: Context) =
                Settings.System.getInt(context.contentResolver, Settings.System.SCREEN_BRIGHTNESS)
    
            /**
             * 获取多媒体的声音音量
             *
             * STREAM_VOICE_CALL 通话
             * STREAM_SYSTEM 系统
             * STREAM_RING 铃声
             * STREAM_MUSIC 媒体音量
             * STREAM_ALARM 闹钟
             * STREAM_NOTIFICATION 通知
             */
            fun getMusicSound(context: Context) =
                (context.getSystemService(Context.AUDIO_SERVICE) as AudioManager).getStreamVolume(AudioManager.STREAM_MUSIC)
    
            /**
             * 获取多媒体的最大声音音量
             *
             * STREAM_VOICE_CALL 通话
             * STREAM_SYSTEM 系统
             * STREAM_RING 铃声
             * STREAM_MUSIC 媒体音量
             * STREAM_ALARM 闹钟
             * STREAM_NOTIFICATION 通知
             */
            fun getMaxMusicSound(context: Context) =
                (context.getSystemService(Context.AUDIO_SERVICE) as AudioManager).getStreamMaxVolume(AudioManager.STREAM_MUSIC)
    
            /**
             * 设置多媒体的声音音量
             */
            fun setMusicSound(context: Context, sound:Int) {
                //AudioManager.FLAG_SHOW_UI 调整音量时显示系统音量进度条 , 0 则不显示
                //AudioManager.FLAG_ALLOW_RINGER_MODES 是否铃声模式
                //AudioManager.FLAG_VIBRATE 是否震动模式
                //AudioManager.FLAG_SHOW_VIBRATE_HINT 震动提示
                //AudioManager.FLAG_SHOW_SILENT_HINT 静音提示
                //AudioManager.FLAG_PLAY_SOUND 调整音量时播放声音
                (context.getSystemService(Context.AUDIO_SERVICE) as AudioManager).setStreamVolume(AudioManager.STREAM_MUSIC, sound, AudioManager.FLAG_PLAY_SOUND)
            }
        }
    
    }

    End

  • 相关阅读:
    PHP文件下载
    win7的IE11降到IE8
    京东电话面试——PHP开发
    PHP异常处理
    php错误处理
    php练习7——类的运用(四则运算or面积计算[javascript小技巧——根据需求显示不同界面])
    php练习6——面向对象编程(打印乘法表)
    SICP阅读笔记(一)
    随笔(2015-18-19)
    MIT scheme入门使用
  • 原文地址:https://www.cnblogs.com/guanxinjing/p/16093264.html
Copyright © 2020-2023  润新知