精华内容
下载资源
问答
  • 怎么获得应用使用记录,比如在一个时间段里都在哪些时候使用了应用
  • 原标题:android如何获取系统里各个应用使用时间比如24pi和offtime这两个软件APP,它们都可以统计Android手机上所有应用使用时间,当然这个不是自己的而是那些厂商的。那么android如何获取系统里各个应用使用...

    原标题:android如何获取系统里各个应用的使用时间

    比如24pi和offtime这两个软件APP,它们都可以统计Android手机上所有应用的使用时间,当然这个不是自己的而是那些厂商的。那么android如何获取系统里各个应用的使用时间呢?华清创客学院讲师在这里解读一下android如何获取系统里各个应用的使用时间?

    3f9a7cbea8bdfb3be6ce66407c8ab92b.png

    android如何获取系统里各个应用的使用时间:

    应用使用情况统计信息

    您现在可以通过新的 android.app.usage API 访问 Android 设备上的应用使用情况历史记录。此 API 提供了比被弃用的getRecentTasks() 方法更详细的使用情况信息。要使用此 API,必须先在您的清单中声明"android.permission.PACKAGE_USAGE_STATS" 权限。用户还必须通过“设置”>“安全性”>“应用”使用“使用情况访问”启用对此应用的访问权限。

    系统将以每个应用为单位收集使用情况数据,并按每天、每周、每月和每年时间间隔对数据进行汇总。系统保留此数据的最大持续时间如下所述:

    每天数据:7 天每周数据:4 周每月数据:6 个月每年数据:2 年

    对于每个应用,系统将记录以下数据:

    上次使用应用的时间应用在该时间间隔内(按天、周、月或年)处于前台的总时间长度组件(由程序包和活动名称予以标识)在一天中移动到前台或后台时的时间戳捕获设备配置更改时(例如当设备配置因为旋转而更改时)的时间戳捕获。

    华清创客学院Android开发讲师:以上就是为读者整理的android如何获取系统里各个应用的使用时间具体操作步骤,华清创客学院整合时下最新最全的Android开发技术,形成了一套完整的Android开发学习路线体系,符合所有阶段Android技术人才的需求。返回搜狐,查看更多

    责任编辑:

    展开全文
  • 资源主要是结合博客文章:http://blog.csdn.net/eastmount/article/details/18474655主要讲述使用C# 系统应用获取Windows最近使用记录Recent,通过自定义类函数实现获取Recent快捷键的原始存放路径并显示在控件...
  • 该文章是“个人电脑历史记录清除软件”项目的系统应用系列文章. 前面已经讲述了如何清除...这篇文章首先主要讲述了通过注册表获取USB使用记录,希望对大家有所帮助. 一.注册表基本知识 注册表(registry)是Windo

    该文章是“个人电脑历史记录清除软件”项目的系统应用系列文章.
    前面已经讲述了如何清除IE浏览器的历史记录、获取Windows最近访问文件记录、清除回收站等功能.现在我需要完成的是删除USB设备上的U盘、手机、移动硬盘等记录,真心觉得这方面资料特别少.这篇文章首先主要讲述了通过注册表获取USB使用记录,希望对大家有所帮助.

    一.注册表基本知识

    注册表(registry)是Windows系统中一个重要的数据库,它用于存储有关应用程序、用户和系统信息.注册表的结构就像一颗树.树的顶级节点(hive)不能添加、修改和删除.如下图所示是Windows注册表的顶级节点:

    \

    (1).HKEY_CURRENT_USER:包含当前登录到Windows的用户配置信息
    (2).HKEY_USERS:包含计算机所有用户的配置信息
    (3).HKEY_LOCAL_MACHINE:包含与计算机相关的配置信息,不论用户是否登录
    (4).HKEY_CLASSES_ROOT:包含将文件类型同程序关联起来的信息及COM组件配置数据
    (5).HKEY_CURRENT_CONFIG:包含本地计算机启动时所使用的硬件描述文件.
    详见百度百科

    二.C#中注册表简单使用

    在前面"C# 系统应用之IE浏览器记录和地址栏输入网址"文章中我已经简单的使用了通过注册表获取地址栏的信息并显示.这里想讲讲注册表常使用的获取内容方法.主要代码如下:

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    //定义注册表顶级节点 其命名空间是using Microsoft.Win32; 
    RegistryKey historykey;; 
    //检索当前用户CurrentUser子项Software\\Microsoft\\Internet Explorer\\typedURLs
    historykey = Registry.CurrentUser.OpenSubKey( "Software\\Microsoft\\Internet Explorer\\typedURLs" , true ); 
    if (historykey != null
             //获取检索的所有值 
             String[] names = historykey.GetValueNames(); 
             foreach (String str in names) 
            
             listBox1.Items.Add(historykey.GetValue(str).ToString()); 
            
    }

    其中,RegistryKey类(MSDN)表示注册表中的顶级结点,此类是注册表封装.Registry类(MSDN)提供表示Windows注册表中的根项的RegistryKey对象,并提供访问项/值.常用值如下对应的是注册表顶级节点内容.

    \

    上面代码获取IE浏览器地址栏最近输入URL对应的注册表树形路径为:
    HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\TypedURLs
    通过Registry.CurrentUser(HKEY_CURRENT_USER)中的OpenSubKey函数检索指定的子项,并指定是否将写访问权限应用于该项.最后通过GetValueNames()获取检索的所有值.函数原型:

    ?
    1
    2
    3
    4
    public RegistryKey OpenSubKey(
         string name,     //要打开的子项名称或路径
         bool writable    //如果需要项的写访问权限=true
    )

    三.注册表如何存储USB信息

    此处查阅多处资料并主要引用《计算机信息获取系统的研究与实现》论文部分:
    https://cdmd.cnki.com.cn/Article/CDMD-10431-2010236667.htm
    在Windows系统中,当一个USB移动存储设备插入时,就会在注册表中留下痕迹.当移动设备插入计算机时,即插即用管理器PnP(Plug and Play)接受该事件,并且在USB设备的固件(Firewre information)中查询有关该设备的描述信息(厂商、型号、序列号等).当设备被识别后,在注册表中创建一个新的键值:
    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USBSTOR
    在这个键值下,会看到类似下面的结构子键:(该子键代表设备类标示符,用来标识设备的一个特定类)
    Disk&Ven_###&Prod_###&Rev_###
    其中子键中"###"代表区域由PnP管理器依据在USB设备描述符中获取的数据填写.如下图所示

    \

    Disk&Ven_aigo&Prod_Miniking&Rev_8.07是Device class ID
    Q0UKCH37&0是Unique instance ID(UID)
    如果使用UVCView工具可以看见USB设备描述内容,其中的信息都是相互对应的.设备类ID一旦建立,就需要建立一个特定唯一的UID.它可以把具有同一设备类标识的多个存储设备区分.

    四.程序实现获取USB使用信息

    具体代码如下所示,同时希望大家去下载wnt08的代码,很有帮助https://download.csdn.net/detail/lwnt08/3083499

    ?
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    //获取USB使用信息
    private void button1_Click(object sender, EventArgs e)
    {
    //定义注册表顶级节点 其命名空间是using Microsoft.Win32;
    RegistryKey USBKey;
    //检索子项   
    USBKey = Registry.LocalMachine.OpenSubKey(@ "SYSTEM\CurrentControlSet\Enum\USBSTOR" , false );
    //检索所有子项USBSTOR下的字符串数组
    foreach (string sub1 in USBKey.GetSubKeyNames())
    {
         RegistryKey sub1key = USBKey.OpenSubKey(sub1, false );
         foreach (string sub2 in sub1key.GetSubKeyNames())
         {
             try
             {
                 //打开sub1key的子项
                 RegistryKey sub2key = sub1key.OpenSubKey(sub2, false );
                 //检索Service=disk(磁盘)值的子项 cdrom(光盘)
                 if (sub2key.GetValue( "Service" , "" ).Equals( "disk" ))
                 {
                     String Path = "USBSTOR" + "\\" + sub1 + "\\" + sub2;
                     String Name = (string)sub2key.GetValue( "FriendlyName" , "" );
                     richTextBox1.AppendText( "USB名称  " + Name + "\r\n" );
                     richTextBox1.AppendText( "UID标记  " + sub2 + "\r\n" );
                     richTextBox1.AppendText( "路径信息 " + Path + "\r\n\r\n" );
                 }
             }
             catch (Exception msg) //异常处理
             {
                 MessageBox.Show(msg.Message);
             }
         }
    }

    运行结果如下图所示:

    \

    其中对应的注册表信息如下图所示:

    \

    其中对应的FriendlyName即是输出的“USB名称 aigo Miniking USB Device”,UID序号为"Q0UKCH37".搜索的Service(服务)为disk(磁盘)的选项.

    五.总结与展望

    首先个人感触,这方面的资料真心很少,文章博客也少,所以看起来操作似乎很简单,但真正实现起来还是令人深思的.然后就是其实存储USB记录的还有很多键值.如
    1.HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB
    该键值中能看到厂商号(VID_)、厂商产品号(PID_),还有LocationInformation(端口号) Port_#0001.Hub_#0005等.
    \
    2.HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceClasses
    该键值下有两个设备类:{53F56307-B6BF-11D0-94F2-00A0C91EFB8B}{53F5630d-B6BF-11D0-94F2-00A0C91EFB8B},可以通过他们获取USB最后接入系统时间.
    接下来我想要完成的就是如何把这些键值联系起来,似乎要通过Dictionary,同时怎样获取时间,怎样正确删除这些信息.最后希望文章对大家有所帮助,如果有错误或不足之处,还请海涵!最后感谢下面参考资料的一些文章博客和作者.这类资料真心不好找,都是相关的内容而且不错的,有的引用,有的没有,但都不错,也希望这些链接大家能用到.
    (By:Eastmount 2014-4-8 夜1点半 原创CSDN https://blog.csdn.net/eastmount/)
    参考资料及相似文章(值得一看):
    1.《计算机信息获取系统的研究与实现》论文讲诉了计算机取证学及USB原理
    https://cdmd.cnki.com.cn/Article/CDMD-10431-2010236667.htm
    2.Tracking USB storage: Analysis of windows artifacts generated by USB storage devices
    英文文章,如何获取USB使用记录的时间及信息
    https://www.sciencedirect.com/science/article/pii/S1742287605000320
    3.用C# 编写USB存储设备使用痕迹检测和删除工具 讲诉了如何删除获取分章节讲解
    https://blog.csdn.net/metaphysis/article/details/18504315
    4.C# 读取注册表获取U盘使用记录
    https://download.csdn.net/detail/lwnt08/3083499

    展开全文
  • aop的应用使用aop完成日志的记录

    千次阅读 2019-06-03 16:22:20
    前面已经介绍过aop的多种应用场景,今天研究了一下使用aop记录日志,使用的是后置通知。具体的实现如下: 自定义注解,用来记录用户的操作和一些基本信息 package com.soecode.lyf.log.annatation; import java....

     

    前面已经介绍过aop的多种应用场景,今天研究了一下使用aop记录日志,使用的是后置通知。具体的实现如下:

    自定义注解,用来记录用户的操作和一些基本信息

    package com.soecode.lyf.log.annatation;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * Create by wws on 2019/6/3
     */
    @Target({ ElementType.TYPE, ElementType.METHOD })
    @Retention(RetentionPolicy.RUNTIME)
    public @interface LogRequire {
    
        /**
         * 操作模块
         */
         String operationModel() default "";
        /**
         * 操作功能
         */
         String operationFunction()default "";
    
        /**
         * 操作说明
         */
         String operationExplain ()default "";
    
    
    }
    

    增加一个获取参数里面的用户信息注解,注意这个值一般是从session里面获取的,从controller里面传过来,这里为了简单从页面传来一个假的参数。

    package com.soecode.lyf.log.annatation;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * @Description
     * @Author DJZ-WWS
     * @Date 2019/6/4 8:36
     */
    @Target({ ElementType.TYPE, ElementType.PARAMETER })
    @Retention(RetentionPolicy.RUNTIME)
    public  @interface LogUser {
    
    }
    

    日志的切面实现

    package com.soecode.lyf.log.aspect;
    
    import com.mchange.v1.util.ArrayUtils;
    import com.soecode.lyf.datasource.DataSourceAspect;
    import com.soecode.lyf.log.annatation.LogRequire;
    import com.soecode.lyf.log.annatation.LogUser;
    import com.soecode.lyf.log.pojo.LogInfo;
    import com.soecode.lyf.log.service.LogService;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Pointcut;
    import org.aspectj.lang.reflect.MethodSignature;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.springframework.util.StringUtils;
    
    import java.lang.annotation.Annotation;
    import java.lang.reflect.Method;
    import java.lang.reflect.Parameter;
    import java.net.InetAddress;
    import java.net.NetworkInterface;
    import java.net.UnknownHostException;
    import java.text.MessageFormat;
    import java.util.Date;
    import java.util.Enumeration;
    
    
    /**
     * @Description 日志切面
     * @Author DJZ-WWS
     * @Date 2019/6/3 14:04
     */
    
    @Aspect
    @Component
    public class SysLogAspect {
        static Logger logger = LoggerFactory.getLogger(DataSourceAspect.class);
        @Autowired
        private LogService logService;
    
        @Pointcut("@annotation(com.soecode.lyf.log.annatation.LogRequire)")
        public void log() {
        }
    
        @After("log()")
        public void doAfter(JoinPoint joinPoint) throws UnknownHostException {
            System.out.println("=====SysLogAspect后置通知开始=====,开始记录日志信息");
            LogInfo logInfo = new LogInfo();
            //记录基本信息
            Class<?> target = joinPoint.getTarget().getClass();
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            Parameter[] parameters = method.getParameters();
            //记录用户信息  获取参数里面加LogUser注解的值,表示用户信息
            //获取参数上所有的注解
            Annotation[][] parameterAnnotations = method.getParameterAnnotations();
            //判断注解LogUser是否存在
    
            for (Annotation[] paraeterAnnotation : parameterAnnotations) {
                //获取注解的索引
                int paramIndex = ArrayUtils.indexOf(parameterAnnotations, paraeterAnnotation);
                //获取注解标记的值
    
                for (Annotation annotation : paraeterAnnotation) {
                    if (annotation instanceof LogUser) {
                        Object[] args = joinPoint.getArgs();
                        Object value = args[paramIndex];
                        logInfo.setAccountInfo(value.toString());
                    }
                }
            }
            //获取注解上的值
            LogRequire logRequire = null;
            logRequire = this.getLogRequire(target, method);
            //从接口初始化
            if (logRequire == null) {
                for (Class<?> clazz : target.getInterfaces()) {
                    logRequire = getLogRequire(clazz, method);
                    if (logRequire != null) {
                        break;//从某个接口中一旦发现注解,不再循环
                    }
                }
            }
    
            if (logRequire != null && (!StringUtils.isEmpty(logRequire.operationExplain())) && (!StringUtils.isEmpty(logRequire.operationFunction())) && (!StringUtils.isEmpty(logRequire.operationModel()))) {
                调用日志处理类去处理我们的日志
                logInfo.setOperationModel(logRequire.operationModel());
                logInfo.setOperationFunction(logRequire.operationFunction());
                logInfo.setOperationExplain(logRequire.operationExplain());
                logInfo.setIp(this.getIp());
                logInfo.setOperationTime(new Date());
                logService.saveLog(logInfo);
            }
    
    
        }
    
        /**
         * 获取方法或类的注解对象DataSource
         *
         * @param target
         * @param method
         * @return
         */
        private LogRequire getLogRequire(Class<?> target, Method method) {
            try {
                //1.优先方法注解
                Class<?>[] types = method.getParameterTypes();
                Method m = target.getMethod(method.getName(), types);
                if (m != null && m.isAnnotationPresent(LogRequire.class)) {
                    return m.getAnnotation(LogRequire.class);
                }
                //2.其次类注解
                if (target.isAnnotationPresent(LogRequire.class)) {
                    return target.getAnnotation(LogRequire.class);
                }
    
            } catch (Exception e) {
                e.printStackTrace();
                logger.error(MessageFormat.format("通过注解切换数据源时发生异常[class={0},method={1}]:"
                        , target.getName(), method.getName()), e);
            }
            return null;
        }
    
    
        private String getIp() throws UnknownHostException {
            try {
                InetAddress candidateAddress = null;
                // 遍历所有的网络接口
                for (Enumeration ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements(); ) {
                    NetworkInterface iface = (NetworkInterface) ifaces.nextElement();
                    // 在所有的接口下再遍历IP
                    for (Enumeration inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements(); ) {
                        InetAddress inetAddr = (InetAddress) inetAddrs.nextElement();
                        if (!inetAddr.isLoopbackAddress()) {// 排除loopback类型地址
                            if (inetAddr.isSiteLocalAddress()) {
                                // 如果是site-local地址,就是它了
                                return inetAddr.getHostAddress();
                            } else if (candidateAddress == null) {
                                // site-local类型的地址未被发现,先记录候选地址
                                candidateAddress = inetAddr;
                            }
                        }
                    }
                }
                if (candidateAddress != null) {
                    return candidateAddress.getHostAddress();
                }
                // 如果没有发现 non-loopback地址.只能用最次选的方案
                InetAddress jdkSuppliedAddress = InetAddress.getLocalHost();
                if (jdkSuppliedAddress == null) {
                    throw new UnknownHostException("The JDK InetAddress.getLocalHost() method unexpectedly returned null.");
                }
                return jdkSuppliedAddress.getHostAddress();
            } catch (Exception e) {
                UnknownHostException unknownHostException = new UnknownHostException(
                        "Failed to determine LAN address: " + e);
                unknownHostException.initCause(e);
                throw unknownHostException;
            }
        }
    
    }
    

    业务层的应用:

    package com.soecode.lyf.bookuserservice.service.impl;
    
    import com.soecode.lyf.bookuserservice.dao.BookDao;
    import com.soecode.lyf.bookuserservice.pojo.Book;
    import com.soecode.lyf.bookuserservice.service.BookService;
    import com.soecode.lyf.datasource.DataSource;
    import com.soecode.lyf.log.annatation.LogRequire;
    import com.soecode.lyf.log.annatation.LogUser;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import java.util.List;
    
    
    @Service
    public class BookServiceImpl implements BookService {
    
    	private Logger logger = LoggerFactory.getLogger(this.getClass());
    
    	// 注入Service依赖
    	@Autowired
    	private BookDao bookDao;
    
    
    
    	@Override
    	@DataSource("dataSource1")
    	@LogRequire(operationModel = "book",operationFunction = "根据书的id查询book",operationExplain = "查询操作")
    	public Book getById(long bookId,@LogUser String  userName) {
    		return bookDao.queryById(bookId);
    	}
    
    	@Override
    	@DataSource("dataSource1")
    	@LogRequire(operationModel = "books",operationFunction = "查询所有的书",operationExplain = "查询所有的书")
    	public List<Book> getList() {
    		return bookDao.queryAll(0, 1000);
    	}
    
    
    
    
    }
    

    日志基本信息bean

    package com.soecode.lyf.log.pojo;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    import java.util.Date;
    
    /**
     * @Description
     * @Author DJZ-WWS
     * @Date 2019/6/3 13:47
     */
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class LogInfo {
    
       
        /**
         * 操作模块
         */
        private String operationModel;
        /**
         * 操作功能
         */
        private String operationFunction;
    
        /**
         * 操作说明
         */
        private String operationExplain;
        /**
         * 账号信息
         */
    
        private String accountInfo;
        /**
         * ip归属地
         */
        private String ip;
    
        /**
         * 操作时间
         */
    
        private Date operationTime;
    
    }
    

    记录日志的服务

    package com.soecode.lyf.log.service.impl;
    
    import com.soecode.lyf.log.pojo.LogInfo;
    import com.soecode.lyf.log.service.LogService;
    import org.springframework.stereotype.Service;
    
    /**
     * @Description
     * @Author DJZ-WWS
     * @Date 2019/6/3 14:09
     */
    
    @Service
    public class LogServiceImpl  implements LogService {
        @Override
        public void saveLog(LogInfo logInfo) {
            System.out.println("执行保存操作,保存的日志信息为"+logInfo.toString());
        }
    }
    


    业务层注解的应用

    日志结构图

    这样就实现了aop对日志的操作。

    结果如下:

     

       这里的没用真正的实现保存,伪保存。

       日志一般我们不会记录在数据库,数据量大的时候数据库压力大,可以采用mongodb记录日志。

       另外记录日志可以采用异步的方式实现日志的记录。

    关于异步可以采用MQ或者使用线程的方式实现日志的记录。

    展开全文
  • 先上图,看看最终我们可以得到什么...应用内权限信息分为两个部分,我们先来看应用内权限使用情况。 PackageManager pm = context.getPackageManager(); PackageInfo packageInfo = pm.getPackageInfo(packageN...

    先上图,看看最终我们可以得到什么样子的结果:

    截图来自 android开发工具箱, 点我下载 android开发工具箱

     

    应用内权限信息分为两个部分,我们先来看应用内权限使用情况。

    PackageManager pm = context.getPackageManager();
    PackageInfo packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS);
    if (packageInfo.requestedPermissions != null) {
        for (String permission : packageInfo.requestedPermissions) {
            PermissionInfo permissionInfo = pm.getPermissionInfo(permission, 0);
            if ((permissionInfo.flags & PermissionInfo.FLAG_INSTALLED) == 0
                                || (permissionInfo.flags & FLAG_REMOVED) != 0) {
                continue;
            }
            boolean isHasPermission = PackageManager.PERMISSION_GRANTED == pm.checkPermission(permission, packageName);
            ...
        }
    }

    获取权限列表步骤大致为:

    1. 先从PackageInfo获取应用内使用权限的列表,得到一个String数组
    2. 遍历数组,使用PackageManager获取PermissionInfo对象
    3. 根据permissionInfo.flags对结果进行筛选
    4. 判断应用是否已经获得了此权限

    这样,我们的列表所需的数据就齐了。下面我们看看PermissionInfo里面都有些什么我们需要的信息

    public class PermissionInfo extends PackageItemInfo implements Parcelable {
        public int protectionLevel;
        public @Nullable String group;
        public @Flags int flags;
        //获取权限描述信息
        public @Nullable CharSequence loadDescription(@NonNull PackageManager pm) {
            ...
        }
    }

    我们使用上面的信息即可获取权限的level、group、权限的描述。flags是之前我们用到的属性。

    系统没有提供给我们把int类型的protectionLevel转换成String的方法,但是,PermissionInfo类中有个隐藏的方法:

    /** @hide */
    @UnsupportedAppUsage
    public static @NonNull String protectionToString(int level) {
        String protLevel = "????";
        switch (level & PROTECTION_MASK_BASE) {
            case PermissionInfo.PROTECTION_DANGEROUS:
                protLevel = "dangerous";
                break;
            case PermissionInfo.PROTECTION_NORMAL:
                protLevel = "normal";
                break;
            case PermissionInfo.PROTECTION_SIGNATURE:
                protLevel = "signature";
                break;
            case PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM:
                protLevel = "signatureOrSystem";
                break;
        }
        ...
    }

    这里不但隐藏了,还加了UnsupportedAppUsage注解,所以只能复制出来一份了。同时,这段代码也给出了判断一个权限是否是危险权限的方法:

    public static boolean isDangerous(int level) {
        return (level & PermissionInfo.PROTECTION_MASK_BASE) == PermissionInfo.PROTECTION_DANGEROUS;
    }

    系统没有直接提供获取权限描述的属性,但是提供了方法loadDescription,最后来看一下group。

    group的概念是android6引入运行时权限引入了,但是到了android10,应用无法在界面中查询权限的分组方式。所以我们在不同版本上获取group信息会有所不同。

    下面以`android.permission.ACCESS_FINE_LOCATION`权限为例。

    在android6-9上面,我们获取到的group内容为:

    android.permission-group.LOCATION

    在android10上面获取到的group内容为:

    > android.permission-group.UNDEFINED

    综上,显示应用内使用的权限的几个关键信息:权限名称、级别、分组以及权限描述就都有了。

    自定义权限要要更简单一点

    if (packageInfo.permissions != null) {
        for (PermissionInfo permissionInfo : packageInfo.permissions) {
            boolean isHasPermission = PackageManager.PERMISSION_GRANTED == pm.checkPermission(permissionInfo.name, packageName);
            ...
        }
    }

    packageInfo.permissions是PermissionInfo数组,所以少了使用PackageManager获取PermissionInfo对象这一步,其余逻辑与展示系统权限逻辑完全一致,至此,我们就能制作一个展示应用内权限的页面了。

     

    点我下载 android开发工具箱

    展开全文
  • Android 5.0 应用使用情况统计信息

    千次阅读 2017-09-14 17:49:20
    Android 5.0 应用使用情况统计信息概述在Android 5.0以前,我们使用ActivityManager.getRecentTasks()方法来获取最近使用过的应用程序信息集合,此方法不需要用户授权,任何应用都可以获取用户最近使用应用的信息,...
  • 本文就主要叙述通过C#实现获取Recent中使用的文件和文件夹.通过讲述Windows最近历史记录,ShortCut快捷追踪Recent中文件的原始路径,并结合学习Level Up的博主代码实现获取Windows最近浏览的文件和文件夹.希望文章对...
  • Android使用记录访问权限

    千次阅读 2017-03-27 08:00:04
    用于查看设备上其它应用使用情况的统计信息等。
  • 然后通过如下代码进而手动打开权限:当然只要我们在manifest中进行了权限配置,也可以通过 设置->安全->有权查看使用情况的应用 来打开权限:到此我们的应用就拥有了该权限。那么有了这个权限到底能做什么呢?继续往...
  • 该文章是“个人电脑历史记录清除软件”项目的系统应用系列文章. 前面已经讲述了如何清除IE浏览器的历史记录获取Windows最近访问文件记录、清除回收站等功能.现在我需要完成的是删除USB设备上的U盘、手机、移动硬盘...
  • android统计手机应用使用时长以及开启次数

    万次阅读 热门讨论 2018-12-27 17:36:32
    今天遇到一个需求,需要将手机里面的应用启动次数以及使用时长给统计出来。首先想到的就是需要开启“允许查看应用使用情况”这个权限。具体在“设置--安全--有权查看使用情况的应用”。废话不多说,开始撸码。 ...
  • Springboot获取应用的上下文(记录

    千次阅读 2019-02-10 23:20:02
    获取应用的上下文ApplicationContext实例非常有用,因为底层代码需要获取一些配置信息和Bean.这可以大大的增加底层的灵活性,下面代码是参照别人所写:   import org.springframework.beans.BeansException; ...
  • 前面"C# 系统应用之清除Cookies、IE临时文件、历史记录"中已经讲述了借助RunDll32.exe运行dll文件实现清除IE缓存操作,同时网上有很多方法讲述删除操作的,但怎样获取IE浏览器中最近浏览的网站历史记录和IE浏览器的...
  • RunningTracker:一个使用html,css和javascript构建的应用程序,用于记录每日,每天针对英里目标运行的英里数,并获取每周平均运行距离
  • Android 使用记录访问权限

    千次阅读 2017-03-28 13:50:27
    什么是使用记录访问权限呢?这是在Android5.0(Api level 21)新添加的,通过该权限我们可以查看设备上其它应用使用情况的统计信息等。 如何使用该权限呢? 首先在manifest中添加: android:name="android....
  • 关键字: 应用统计 &...最近在做有关于应用统计有关的工作,主要是统计系统中客户端应用(非系统自带的那些基础应用,比如DownLoadManager),在每一天的使用情况,统计内容包括:应用打开次数,应用合计
  • UsageStatsManager就是使用情况统计管理者,通过它可以获取应用使用情况。 它是Android 5.0 才有的API。 使用它之前需要在清单文件中配置 “android.permission.PACKAGE_USAGE_STATS”的权限 用户必须在 设置–...
  • 相反,我们想使用应用程序开发人员选择的任何日志记录框架。 anylogger让您做到这一点。 快速开始 图书馆 带应用 具有应用 带有应用 带有log4js的应用 安装 npm i -P anylogger 用 import anylogger from '...
  • 请问如何获取手机用户安装应用记录下,通知服务器这个用户安装了这个应用记录,卸载应用时也做同样的操作,谢谢
  • 很多安全卫士类软件都实现了网速监测功能,...static long getMobileRxBytes()//获取通过Mobile连接收到的字节总数,但不包含WiFi static long getMobileRxPackets()//获取Mobile连接收到的数据包总数 static long g
  • 钉钉微应用踩坑记录

    千次阅读 2020-12-22 06:32:01
    一、要解决的问题:钉钉微应用开发,应对未来可能的PC端使用场景:PC访问网页,工作台登陆后,通过钉钉服务端接口完成自身业务。二、开发前准备:根据官方文档,钉钉微应用PC端开发和移动端开发已经统一,方便我们...
  • Android获取栈顶的应用包名

    千次阅读 2017-08-15 11:51:14
    Android获取栈顶的应用包名,判断应用是否在栈顶有时候我们需要判断栈顶的应用是否是我们的应用,于是获取栈顶的应用包名的需求就出现了。在android5.0之前,系统提供了一套API可以实现这个功能。ActivityManager ...
  • 如果用户获得高分,则将其记录为新的高分。 目录 哲学 使用应用程序: 单击一个字符。 每次单击后,字符将重新洗牌。 不要单击同一角色两次,否则游戏结束。 单击所有12,您将赢得比赛。 每次点击都记录在顶部...
  • 记录手机app的使用时长

    千次阅读 2015-07-21 13:27:15
    时间记录App汇总 iOS平台 1.aTimeLogger 老牌时间记录器,可以自定义分类,统计和回顾也很清晰 iTunes App Store 的 iPhone,iPod touch和 iPadaTimeLoggeraTimeLogger出安卓版啦!(2013/12/3更新)2.Evertracker,...
  • 获取android设备已安装应用信息

    千次阅读 2015-04-01 16:25:04
    本文介绍了如何获取设备中已经安装的应用信息,包括:应用名称、包名、图标等。获得信息列表后,选择某一项记录还可以启动对应的应用
  • 一、背景 uniapp开发App端需要实现微信登录、分享等功能,需到微信开放平台申请移动应用。 填写申请信息需要填写Android的应用签名和应用包名。本文讲述如何获取应用签名和应用包名。
  • Android 获取手机中微信聊天记录

    万次阅读 多人点赞 2018-01-10 13:18:42
    首先我们要知道,微信的聊天记录一般是不提供给我们获取的,所以一般情况下我们手机没root的话就拿不到了。就算是root后的手机,想要获取微信的EnMicroMsg.db文件并且解密它、打开它也有点难度。 下面我们就来演示...
  • 4.1.5 消费者获取记录

    千次阅读 2021-04-15 22:55:04
    拉取器的获取记录集方法会使用414节“处理拉取响应”方法生成的全局成员变茧,作为数据源构成最终的拉取结果。既然数据已经在全局成员变量中了,那么要提供给客户端使用,就可以直接返回。但实际上拉取器在这一步还...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,095,207
精华内容 438,082
关键字:

获取应用使用记录