Xamarin.Forsm for Android 系统功能

Xamarin.Forsm for Android 系统功能

  • 前述
    • pm 命令
    • Context
  • 命令执行
  • 检查应用是否安装
  • 设置自动开关机
  • 开机自启动

前述

初次涉猎Android程序,使用 Xamarin 编写,这里不讨论 Xamarin 的好坏,重点是解决我们的问题。调用系统功能必不可少的便是 adb 命令 和 Android 共享库,来浅试下。

pm 命令

pm工具为包管理(package manager)的简称。
可以使用 pm 工具来执行应用的安装和查询应用包的信息、系统权限、控制应用。
pm 工具是 Android 开发与测试过程中必不可少的工具。
命令格式:pm

  • 命令行下输入 adb shell pm 即可获得关于 pm 的用法帮助
usage: pm list packages [-f] [-d] [-e] [-s] [-3] [-i] [-u] [--user USER_ID] [FILTER]
       pm list permission-groups
       pm list permissions [-g] [-f] [-d] [-u] [GROUP]
       pm list instrumentation [-f] [TARGET-PACKAGE]
       pm list features
       pm list libraries
       pm list users
       pm path PACKAGE
       pm dump PACKAGE
       pm install [-lrtsfd] [-i PACKAGE] [PATH]
       pm install-create [-lrtsfdp] [-i PACKAGE] [-S BYTES]
       pm install-write [-S BYTES] SESSION_ID SPLIT_NAME [PATH]
       pm install-commit SESSION_ID
       pm install-abandon SESSION_ID
       pm uninstall [-k] [--user USER_ID] PACKAGE
       pm set-installer PACKAGE INSTALLER
       pm clear [--user USER_ID] PACKAGE
       pm enable [--user USER_ID] PACKAGE_OR_COMPONENT
       pm disable [--user USER_ID] PACKAGE_OR_COMPONENT
       pm disable-user [--user USER_ID] PACKAGE_OR_COMPONENT
       pm disable-until-used [--user USER_ID] PACKAGE_OR_COMPONENT
       pm hide [--user USER_ID] PACKAGE_OR_COMPONENT
       pm unhide [--user USER_ID] PACKAGE_OR_COMPONENT
       pm grant PACKAGE PERMISSION
       pm revoke PACKAGE PERMISSION
       pm set-install-location [0/auto] [1/internal] [2/external]
       pm get-install-location
       pm set-permission-enforced PERMISSION [true|false]
       pm trim-caches DESIRED_FREE_SPACE
       pm create-user [--profileOf USER_ID] [--managed] USER_NAME
       pm remove-user USER_ID
       pm get-max-users

pm list packages: prints all packages, optionally only
  those whose package name contains the text in FILTER.  Options:
    -f: see their associated file.
    -d: filter to only show disbled packages.
    -e: filter to only show enabled packages.
    -s: filter to only show system packages.
    -3: filter to only show third party packages.
    -i: see the installer for the packages.
    -u: also include uninstalled packages.

pm list permission-groups: prints all known permission groups.

pm list permissions: prints all known permissions, optionally only
  those in GROUP.  Options:
    -g: organize by group.
    -f: print all information.
    -s: short summary.
    -d: only list dangerous permissions.
    -u: list only the permissions users will see.

pm list instrumentation: use to list all test packages; optionally
  supply  to list the test packages for a particular
  application.  Options:
    -f: list the .apk file for the test package.

pm list features: prints all features of the system.

pm list users: prints all users on the system.

pm path: print the path to the .apk of the given PACKAGE.

pm dump: print system state associated with the given PACKAGE.

pm install: install a single legacy package
pm install-create: create an install session
    -l: forward lock application
    -r: replace existing application
    -t: allow test packages
    -i: specify the installer package name
    -s: install application on sdcard
    -f: install application on internal flash
    -d: allow version code downgrade
    -p: partial application install
    -S: size in bytes of entire session

pm install-write: write a package into existing session; path may
  be '-' to read from stdin
    -S: size in bytes of package, required for stdin

pm install-commit: perform install of fully staged session
pm install-abandon: abandon session

pm set-installer: set installer package name

pm uninstall: removes a package from the system. Options:
    -k: keep the data and cache directories around after package removal.

pm clear: deletes all data associated with a package.

pm enable, disable, disable-user, disable-until-used: these commands
  change the enabled state of a given package or component (written
  as "package/class").

pm grant, revoke: these commands either grant or revoke permissions
  to applications.  Only optional permissions the application has
  declared can be granted or revoked.

pm get-install-location: returns the current install location.
    0 [auto]: Let system decide the best location
    1 [internal]: Install on internal device storage
    2 [external]: Install on external media

pm set-install-location: changes the default install location.
  NOTE: this is only intended for debugging; using this can cause
  applications to break and other undersireable behavior.
    0 [auto]: Let system decide the best location
    1 [internal]: Install on internal device storage
    2 [external]: Install on external media

pm trim-caches: trim cache files to reach the given free space.

pm create-user: create a new user with the given USER_NAME,
  printing the new user identifier of the user.

pm remove-user: remove the user with the given USER_IDENTIFIER,
  deleting all data associated with that user

Context

Context 提供了关于应用环境全局信息的接口。它是一个抽象类,它的执行被Android系统所提供。它允许获取以应用为特征的资源和类型,是一个统领一些资源(应用程序环境变量等)的上下文。

也就是说Context描述一个应用程序环境的信息(即上下文);是一个抽象类,Android提供了该抽象类的具体实现类;通过它我们可以获取应用程序的资源和类。

下面的代码中使用到了 _context 对象这里交代下

public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
	internal static MainActivity Instance { get; private set; }
}

// 在各自的实现类中定义然后使用
private readonly Context _context = MainActivity.Instance;

命令执行

  • 执行命令前需要获取 su 权限
using Java.IO;

private bool ExecuteCommand(string commandStr)
{
    try
    {
        using Process p = Runtime.GetRuntime().Exec("su");

        BufferedReader ins = new BufferedReader(new InputStreamReader(p.InputStream));
        BufferedReader ie = new BufferedReader(new InputStreamReader(p.ErrorStream));
        BufferedWriter w = new BufferedWriter(new OutputStreamWriter(p.OutputStream));

        w.Write(commandStr);
        w.Flush();
        w.Close();

        ins.Close();
        ie.Close();

        int res = p.WaitFor();
        if (res is 0)
            return true;
    }
    catch (Throwable ex)
    {
        return false;
    }
    return false;
}

检查应用是否安装

检查 APP 是否安装,PackageManager 实例来获取当前系统安装的所有 APP 通过packageName 进行判断。

public bool CheckAppInstalled(string packageName)
{
    var packageInfo = _context.PackageManager.GetInstalledPackages(PackageInfoFlags.Activities).Where(pm => pm.PackageName == packageName).FirstOrDefault();

    if (packageInfo != null)
        return true;

    return false;
}

设置自动开关机

自动开关机,就属于 Android 共享库实现了 Android Intent,具体怎么用自己搜很多,这里把开关机时间的设定作为例子。

  • 需要指定共享库的操作函数,用常量存下
/// 
/// 开机 Intent
/// 
private static readonly string SETPOWERON = "android.intent.action.setpoweron";
/// 
/// 关机 Intent
/// 
private static readonly string SETPOWEROFF = "android.intent.action.setpoweroff";
  • 代码实现,需要注意的是时间,它是个 long 类型需要进行转换
private static readonly string SETPOWERON = "android.intent.action.setpoweron";
private static readonly string SETPOWEROFF = "android.intent.action.setpoweroff";
private static readonly string POWERON = "poweron";
private static readonly string POWEROFF = "poweroff";
private static readonly string ENABLE = "enable";

public bool PowerOffPlan(bool enable, long planTime)
{
    try
    {
        Intent intent = new Intent(SETPOWEROFF);
        intent.PutExtra(ENABLE, enable);
        if (enable && planTime > 0)
        {
            Date dateTime = new Date(planTime);
            Calendar calendar = Calendar.GetInstance(Locale.SimplifiedChinese);

            calendar.Time = dateTime;
            calendar.Set(CalendarField.Second, 0);
            int[] time = new int[]
            {
                calendar.Get(CalendarField.Year),
                calendar.Get(CalendarField.Month),
                calendar.Get(CalendarField.DayOfMonth),
                calendar.Get(CalendarField.HourOfDay),
                calendar.Get(CalendarField.Minute),
                calendar.Get(CalendarField.Second),
            };
            intent.PutExtra(POWEROFF, time);
        }
        _context.SendBroadcast(intent);
        return true;
    }
    catch (Throwable ex)
    {
        Toast.MakeText(_context, $"Exception:{ex.Message}", ToastLength.Short).Show();
    }
    return false;
}

public bool PowerOnPlan(bool enable, long planTime)
{
    try
    {
        Intent intent = new Intent(SETPOWERON);
        intent.PutExtra(ENABLE, enable);
        if (enable && planTime > 0)
        {
            Date dateTime = new Date(planTime);
            Calendar calendar = Calendar.GetInstance(Locale.SimplifiedChinese);

            calendar.Time = dateTime;
            calendar.Set(CalendarField.Second, 0);
            int[] time = new int[]
            {
                calendar.Get(CalendarField.Year),
                calendar.Get(CalendarField.Month),
                calendar.Get(CalendarField.DayOfMonth),
                calendar.Get(CalendarField.HourOfDay),
                calendar.Get(CalendarField.Minute),
                calendar.Get(CalendarField.Second),
            };
            intent.PutExtra(POWERON, time);
        }
        _context.SendBroadcast(intent);
        return true;
    }
    catch (Throwable ex)
    {
        Toast.MakeText(_context, $"Exception:{ex.Message}", ToastLength.Short).Show();
    }
    return false;
}

开机自启动

通过监听系统的开机广播来实现,拉起app。
首先,需要在清单文件AndroidManifest.xml申请监听开机广播权限
android.intent.action.BOOT_COMPLETED

然后在清单文件 AndroidManifest.xml 声明该广播接收者,也就是下面实现监听广播处理自己的业务逻辑(拉起自己app)的类 BootReceiver

<receiver android:name=".base.BootReceiver">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />

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

最后实现一个BroadcastReceiver,该广播接收者监听"android.intent.action.BOOT_COMPLETED"广播,当接收到该广播时,打开该应用的启动页面。

[BroadcastReceiver(Enabled = true)]
[IntentFilter(new[] { Intent.ActionBootCompleted, Intent.ActionReboot })]
public class BootReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        try
        {
            if (intent.Action != null && intent.Action is Intent.ActionBootCompleted)
            {
                Intent _intent = new Intent();
                _intent.SetClass(context, typeof(MainActivity));
                _intent.SetFlags(ActivityFlags.NewTask);
                context.StartService(_intent);
            }
        }
        catch (System.Exception ex)
        {
            Toast.MakeText(context, ex.Message, ToastLength.Short).Show();
        }
    }
}

这种开机自启的方式不好的地方在于,需要在安装之后手动启动一下,才能收听广播。如果有好的方案,请不吝赐教

你可能感兴趣的:(#,Xamarin,android,xamarin,adb,c#)