Android开发 UsageStatsManager应用使用情况管理

Posted 观心静

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android开发 UsageStatsManager应用使用情况管理相关的知识,希望对你有一定的参考价值。

前言

  UsageStatsManager是用来知晓设备中应用的使用情况。它能给我们提供应用的进入前台动作与时间戳、进入后台的动作与时间戳、上次的使用时间、使用总时长等等信息。此功能在原生的设置-应用-使用统计中有所展示。在一般的场景下,我们可以用此管理开发一些应用使用时长统计、连续使用时长提醒、统计应用被前台化的次数/时间段从而分析应用的使用率。

所需权限

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

查询当前应用的使用事件

这里使用的是queryEventsForSelf方法,在这个方法返回的数据里包含相同应用每一次进入前后台的时间点。

代码

fun query(context: Context) 
    //查询的开始时间
    val startCalendar = Calendar.getInstance()
    startCalendar.set(Calendar.HOUR_OF_DAY, 0)
    startCalendar.set(Calendar.MINUTE, 0)
    startCalendar.set(Calendar.SECOND, 0)
    //查询的结束时间
    val endCalendar = Calendar.getInstance()
    endCalendar.set(Calendar.HOUR_OF_DAY, 23)
    endCalendar.set(Calendar.MINUTE, 59)
    endCalendar.set(Calendar.SECOND, 59)
    val simpleDateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")

    var usageStatsManager: UsageStatsManager = context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager

    /**
     * 查询当前应用的使用事件
     */
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) 
        val usageEvents = usageStatsManager.queryEventsForSelf(startCalendar.timeInMillis, endCalendar.timeInMillis)
        while (usageEvents.hasNextEvent()) 
            val event = UsageEvents.Event()
            usageEvents.getNextEvent(event)
            when (event.eventType) 
                MOVE_TO_FOREGROUND -> Log.e("zh", "进入前台 $event.packageName $simpleDateFormat.format(event.timeStamp)")
                MOVE_TO_BACKGROUND -> Log.e("zh", "退出后台 $event.packageName $simpleDateFormat.format(event.timeStamp)")
                else -> Log.e("zh", "其他事件 $event.eventType $event.packageName $simpleDateFormat.format(event.timeStamp)")
            
        
    

结果:

2023-05-23 11:25:37.934 14013-14013 zh                      com.xx.dev                         E  进入前台 com.xx.dev 2023-05-23 11:24:56
2023-05-23 11:25:37.935 14013-14013 zh                      com.xx.dev                         E  退出后台 com.xx.dev 2023-05-23 11:25:33
2023-05-23 11:25:37.935 14013-14013 zh                      com.xx.dev                         E  进入前台 com.xx.dev 2023-05-23 11:25:33
2023-05-23 11:25:37.935 14013-14013 zh                      com.xx.dev                         E  退出后台 com.xx.dev 2023-05-23 11:25:34
2023-05-23 11:25:37.935 14013-14013 zh                      com.xx.dev                         E  进入前台 com.xx.dev 2023-05-23 11:25:34
2023-05-23 11:25:37.935 14013-14013 zh                      com.xx.dev                         E  退出后台 com.xx.dev 2023-05-23 11:25:35
2023-05-23 11:25:37.935 14013-14013 zh                      com.xx.dev                         E  进入前台 com.xx.dev 2023-05-23 11:25:35
2023-05-23 11:25:37.935 14013-14013 zh                      com.xx.dev                         E  退出后台 com.xx.dev 2023-05-23 11:25:37
2023-05-23 11:25:37.935 14013-14013 zh                      com.xx.dev                         E  进入前台 com.xx.dev 2023-05-23 11:25:37

查询设备全局应用的使用事件

这里使用的是queryEvents方法

代码

fun query(context: Context) 
    //查询的开始时间
    val startCalendar = Calendar.getInstance()
    startCalendar.set(Calendar.HOUR_OF_DAY, 0)
    startCalendar.set(Calendar.MINUTE, 0)
    startCalendar.set(Calendar.SECOND, 0)
    //查询的结束时间
    val endCalendar = Calendar.getInstance()
    endCalendar.set(Calendar.HOUR_OF_DAY, 23)
    endCalendar.set(Calendar.MINUTE, 59)
    endCalendar.set(Calendar.SECOND, 59)
    val simpleDateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")

    var usageStatsManager: UsageStatsManager = context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager


    /**
     * 查询设备全局应用的使用事件
     */
    val usageEvents = usageStatsManager.queryEvents(startCalendar.timeInMillis, endCalendar.timeInMillis)
    while (usageEvents.hasNextEvent()) 
        val event = UsageEvents.Event()
        usageEvents.getNextEvent(event)
        when (event.eventType) 
            MOVE_TO_FOREGROUND -> Log.e("zh", "进入前台 $event.packageName $simpleDateFormat.format(event.timeStamp)")
            MOVE_TO_BACKGROUND -> Log.e("zh", "退出后台 $event.packageName $simpleDateFormat.format(event.timeStamp)")
        
    

结果

2023-05-23 14:09:23.051  6144-6144  zh                      com.xx.dev                         E  进入前台 com.android.launcher3 2023-05-23 14:08:57
2023-05-23 14:09:23.051  6144-6144  zh                      com.xx.dev                         E  退出后台 com.android.launcher3 2023-05-23 14:09:05
2023-05-23 14:09:23.051  6144-6144  zh                      com.xx.dev                         E  进入前台 com.xx.dev 2023-05-23 14:09:05
2023-05-23 14:09:23.051  6144-6144  zh                      com.xx.dev                         E  退出后台 com.xx.dev 2023-05-23 14:09:08

查询设备的应用使用统计情况

请注意下面的输入了时间间隔类型UsageStatsManager.INTERVAL_BEST,但是不代表返回的数值就是准确的,比如如果我查询中午12点至下午六点的使用统计,实际上它依然会返回今天应用的全部使用情况

代码

fun query(context: Context) 
    //查询的开始时间
    val startCalendar = Calendar.getInstance()
    startCalendar.set(Calendar.HOUR_OF_DAY, 0)
    startCalendar.set(Calendar.MINUTE, 0)
    startCalendar.set(Calendar.SECOND, 0)
    //查询的结束时间
    val endCalendar = Calendar.getInstance()
    endCalendar.set(Calendar.HOUR_OF_DAY, 23)
    endCalendar.set(Calendar.MINUTE, 59)
    endCalendar.set(Calendar.SECOND, 59)
    val simpleDateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")

    var usageStatsManager: UsageStatsManager = context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager

    /**
     * 查询设备的应用使用统计情况
     */
    val list = usageStatsManager.queryUsageStats(UsageStatsManager.INTERVAL_BEST, startCalendar.timeInMillis, endCalendar.timeInMillis)
    for (item in list) 
        Log.e("zh", "包名:$item.packageName")
        Log.e("zh", "开始时间:$simpleDateFormat.format(item.firstTimeStamp)")
        Log.e("zh", "上次时间戳:$simpleDateFormat.format(item.lastTimeStamp)")
        Log.e("zh", "最后使用时间:$simpleDateFormat.format(item.lastTimeUsed)")
        Log.e("zh", "前台总的时间:$item.totalTimeInForeground")
    

结果

2023-05-23 14:28:04.162  9020-9020  zh     com.xx.dev     E  包名:com.android.server.telecom
2023-05-23 14:28:04.162  9020-9020  zh     com.xx.dev     E  开始时间:2023-05-23 09:44:08
2023-05-23 14:28:04.162  9020-9020  zh     com.xx.dev     E  上次时间戳:2023-05-23 14:23:13
2023-05-23 14:28:04.162  9020-9020  zh     com.xx.dev     E  最后使用时间:1970-01-01 08:00:00
2023-05-23 14:28:04.162  9020-9020  zh     com.xx.dev     E  前台总的时间:0
2023-05-23 14:28:04.162  9020-9020  zh     com.xx.dev     E  包名:android.ext.services
2023-05-23 14:28:04.162  9020-9020  zh     com.xx.dev     E  开始时间:2023-05-23 09:44:08
2023-05-23 14:28:04.162  9020-9020  zh     com.xx.dev     E  上次时间戳:2023-05-23 14:23:13
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  最后使用时间:1970-01-01 08:00:00
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  前台总的时间:0
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  包名:com.mediatek.capctrl.service
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  开始时间:2023-05-23 09:44:08
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  上次时间戳:2023-05-23 14:23:13
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  最后使用时间:1970-01-01 08:00:00
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  前台总的时间:0
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  包名:net.huanci.hsj
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  开始时间:2023-05-23 09:44:08
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  上次时间戳:2023-05-23 14:23:13
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  最后使用时间:2023-05-23 11:10:10
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  前台总的时间:11449
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  包名:com.android.smspush
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  开始时间:2023-05-23 09:44:08
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  上次时间戳:2023-05-23 14:23:13
2023-05-23 14:28:04.163  9020-9020  zh     com.xx.dev     E  最后使用时间:1970-01-01 08:00:00

查询给定范围内的所有统计数据(使用该范围的最佳间隔)

这里使用的是queryAndAggregateUsageStats方法,这个方法里不需要传入时间间隔参数,并且返回的是map集合。

代码

fun query(context: Context) 
    //查询的开始时间
    val startCalendar = Calendar.getInstance()
    startCalendar.set(Calendar.HOUR_OF_DAY, 0)
    startCalendar.set(Calendar.MINUTE, 0)
    startCalendar.set(Calendar.SECOND, 0)
    //查询的结束时间
    val endCalendar = Calendar.getInstance()
    endCalendar.set(Calendar.HOUR_OF_DAY, 23)
    endCalendar.set(Calendar.MINUTE, 59)
    endCalendar.set(Calendar.SECOND, 59)
    val simpleDateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")

    var usageStatsManager: UsageStatsManager = context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager

    val map = usageStatsManager.queryAndAggregateUsageStats(startCalendar.timeInMillis, System.currentTimeMillis())
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) 
        map.forEach  key, value ->
            Log.e("zh", "包名:$key")
            Log.e("zh", "开始时间:$simpleDateFormat.format(value.firstTimeStamp)")
            Log.e("zh", "上次使用时间戳:$simpleDateFormat.format(value.lastTimeStamp)")
            Log.e("zh", "最后使用时间:$simpleDateFormat.format(value.lastTimeUsed)")
            Log.e("zh", "前台总的时间:$value.totalTimeInForeground")
        
    

结果

2023-05-23 14:38:09.392 11063-11063 zh   com.xx.dev   E  包名:net.huanci.hsj
2023-05-23 14:38:09.392 11063-11063 zh   com.xx.dev   E  开始时间:2023-05-23 09:44:08
2023-05-23 14:38:09.392 11063-11063 zh   com.xx.dev   E  上次使用时间戳:2023-05-23 14:23:13
2023-05-23 14:38:09.392 11063-11063 zh   com.xx.dev   E  最后使用时间:2023-05-23 11:10:10
2023-05-23 14:38:09.392 11063-11063 zh   com.xx.dev   E  前台总的时间:11449
2023-05-23 14:38:09.392 11063-11063 zh   com.xx.dev   E  包名:com.android.smspush
2023-05-23 14:38:09.392 11063-11063 zh   com.xx.dev   E  开始时间:2023-05-22 09:38:07
2023-05-23 14:38:09.392 11063-11063 zh   com.xx.dev   E  上次使用时间戳:2023-05-23 14:23:13
2023-05-23 14:38:09.392 11063-11063 zh   com.xx.dev   E  最后使用时间:1970-01-01 08:00:23
2023-05-23 14:38:09.392 11063-11063 zh   com.xx.dev   E  前台总的时间:0
2023-05-23 14:38:09.392 11063-11063 zh   com.xx.dev   E  包名:com.android.settings
2023-05-23 14:38:09.392 11063-11063 zh   com.xx.dev   E  开始时间:2023-05-22 09:38:07
2023-05-23 14:38:09.392 11063-11063 zh   com.xx.dev   E  上次使用时间戳:2023-05-23 09:38:07
2023-05-23 14:38:09.393 11063-11063 zh   com.xx.dev   E  最后使用时间:2023-05-23 09:33:18
2023-05-23 14:38:09.393 11063-11063 zh   com.xx.dev   E  前台总的时间:3328776

时间间隔类型

在上面的方法中,有要求输入查询时间的间隔类型,下面一共提供了4种间隔类型。

/**
 * 跨越一天的间隔类型。参见@link queryUsageStats(int, long, long)。
 */
public static final int INTERVAL_DAILY = 0;

/**
 * 跨越一周的间隔类型。参见@link queryUsageStats(int, long, long)。
 */
public static final int INTERVAL_WEEKLY = 1;

/**
 * 跨越一个月的间隔类型。参见@link queryUsageStats(int, long, long)。
 */
public static final int INTERVAL_MONTHLY = 2;

/**
 * 跨越一年的间隔类型。参见@link queryUsageStats(int, long, long)。
 */
public static final int INTERVAL_YEARLY = 3;

/**
 * 一种间隔类型,它将使用给定时间范围的最佳拟合间隔。参见@link queryUsageStats(int, long, long)。
 */
public static final int INTERVAL_BEST = 4;

查询当前应用是否活跃

代码

@RequiresApi(Build.VERSION_CODES.M)
fun isAppInactive(context: Context, packageName:String):Boolean 
    val usageStatsManager: UsageStatsManager = context.getSystemService(Context.USAGE_STATS_SERVICE) as UsageStatsManager
    return usageStatsManager.isAppInactive(packageName)

其他api

queryConfigurations(int intervalType, long beginTime, long endTime) 获取指定时间区间内硬件配置信息统计数据。

end

Android游戏开发大全的目录

参考技术A

《android游戏开发大全》
第一篇 android游戏开发核心技术
第1章 android平台简介 2
1.1 android的来龙去脉 2
1.2 掀起android的盖头来 2
1.2.1 选择android的理由 2
1.2.2 android的应用程序框架 3
1.3 android开发环境的搭建 6
1.3.1 sdk的下载及安装 6
1.3.2 eclipse集成开发环境的搭建 6
1.3.3 虚拟设备的创建与模拟器的运行 9
1.3.4 第一个android程序 11
1.3.5 android程序的监控与调试 14
1.4 小结 15
第2章 android游戏开发之前台渲染 16
2.1 创建android用户界面 16
2.1.1 布局管理 16
2.1.2 常用控件及其事件处理 22
2.2 图形与动画在android中的实现 24
2.2.1 简单图形的绘制 24
.2.2.2 贴图的艺术 26
2.2.3 自定义动画的播放 27
2.3 android平台下的多媒体开发 30
2.3.1 音频的播放 30
2.3.2 视频的播放 33
2.3.3 camera图像采集 36
2.4 小结 38
第3章 android游戏开发之交互式通信 39
3.1 android应用程序的基本组件 39
3.1.1 activity组件 39
3.1.2 service组件 41
3.1.3 broadcast receiver组件 42
3.1.4 content provider组件 43
3.1.5 androidmanifest.xml文件简介 43
3.2 应用程序的内部通信 47
3.2.1 消息的处理者——handler类简介 47
3.2.2 使用handler进行内部通信 48
3.3 应用程序组件之间的通信 50
3.3.1 intent类简介 50
3.3.2 应用程序组件——intentfilter类简介 52
3.3.3 示例1:与android系统组件通信 53
3.3.4 示例2:应用程序组件间通信示例activity部分的开发 54
3.3.5 示例3:应用程序组件间通信示例service部分的开发 56
3.4 小结 59
第4章 android游戏开发之数据存储和传感器 60
4.1 在android平台上实现数据存储 60
4.1.1 私有文件夹文件的写入与读取 60
4.1.2 读取resources和assets中的文件 63
4.1.3 轻量级数据库sqlite简介 65
4.1.4 sqlite的使用示例 69
4.1.5 数据共享者——content provider的使用 72
4.1.6 简单的数据存储——preferences的使用 76
4.2 android平台下传感器应用的开发 78
4.2.1 传感器应用开发流程 78
4.2.2 常用传感器简介 79
4.2.3 传感器应用开发示例 81
4.2.4 使用sensorsimulator模拟传感器变化 83
4.2.5 使用新版本的api开发传感器应用 86
4.3 小结 88
第5章 android游戏开发之网络编程 89
5.1 基于socket套接字的网络编程 89
5.2 基于http协议的网络编程 93
5.2.1 通过url获取网络资源 93
5.2.2 在android中解析xml 95
5.3 android平台下的google map 95
5.3.1 定位类genpoint与显示地图类mapview的搭配使用 95
5.3.2 位置监听器——locationlistener的使用 99
5.4 其他网络通信方式 101
5.4.1 使用wifi进行开发 101
5.4.2 借助于蓝牙(bluetooth)技术进行开发 102
5.5 小结 102
第6章 不一样的游戏,一样的精彩 103
6.1 射击类游戏 103
6.1.1 游戏玩法 103
6.1.2 视觉效果 104
6.1.3 游戏内容设计 104
6.2 竞速类游戏 104
6.2.1 游戏玩法 105
6.2.2 视觉效果 105
6.2.3 游戏内容设计 106
6.3 益智类游戏 106
6.3.1 游戏玩法 106
6.3.2 视觉效果 107
6.3.3 游戏内容设计 107
6.4 角色扮演游戏 107
6.4.1 游戏玩法 108
6.4.2 视觉效果 108
6.4.3 游戏内容设计 109
6.5 闯关动作类游戏 109
6.5.1 游戏玩法 109
6.5.2 视觉效果 110
6.5.3 游戏内容设计 110
6.6 冒险游戏 110
6.6.1 游戏玩法 110
6.6.2 视觉效果 111
6.6.3 游戏内容设计 112
6.7 策略游戏 112
6.7.1 游戏玩法 112
6.7.2 视觉效果 113
6.7.3 游戏内容设计 113
6.8 养成类游戏 113
6.8.1 游戏玩法 114
6.8.2 视觉效果 114
6.8.3 游戏内容设计 114
6.9 经营类游戏 115
6.9.1 游戏玩法 115
6.9.2 视觉效果 115
6.9.3 游戏内容设计 116
6.10 体育类游戏 116
6.10.1 游戏玩法 116
6.10.2 视觉效果 117
6.10.3 游戏内容设计 117
6.11 小结 117
第7章 游戏背后的数学与物理 118
7.1 编程中经常用到的数理知识 118
7.1.1 数学方面 118
7.1.2 物理方面 120
7.2 物理小球在游戏中的应用 121
7.2.1 开发运动体movable类的代码 121
7.2.2 开发物理引擎ballthread类的代码 123
7.2.3 视图类——开发ballview类的代码 126
7.2.4 绘制线程——开发drawthread类的代码 129
7.2.5 开发activity部分的代码 131
7.3 粒子系统 132
7.3.1 粒子对象类——开发粒子对象particle类和粒子集合particleset类 132
7.3.2 开发焰火粒子系统的物理引擎particlethread类的代码 134
7.3.3 视图类——开发视图类particleview及其相关类 135
7.3.4 开发程序activity部分的代码 137
7.3.5 将焰火粒子系统改为瀑布粒子系统 138
7.4 碰撞检测技术 139
7.4.1 碰撞检测技术基础 139
7.4.2 游戏中实体对象之间的碰撞检测 140
7.4.3 游戏实体对象与环境之间的碰撞检测 143
7.5 小结 144
第8章 游戏中的人工智能 145
8.1 让怪物聪明起来——android中的路径搜索 145
8.1.1 路径搜索示例基本框架的搭建 145
8.1.2 路径搜索示例的控制面板实现 147
8.1.3 路径搜索示例gameview的实现 151
8.1.4 深度优先路径搜索dfs 154
8.1.5 广度优先路径搜索bfs 156
8.1.6 路径搜索算法——dijkstra 159
8.1.7 用a*算法优化搜索 162
8.2 有限状态机 164
8.2.1 何为有限状态机 164
8.2.2 有限状态机的简单实现 165
8.2.3 有限状态机的oo实现 170
8.3 小结 172
第9章 游戏开发小秘技 173
9.1 地图编辑器与关卡设计 173
9.1.1 关卡地图的重要性 173
9.1.2 图片分割界面的实现 175
9.1.3 地图设计界面的实现 179
9.2 游戏中的模糊逻辑 185
9.2.1 模糊的才是真实的 185
9.2.2 如何在android中将游戏模糊化 186
9.3 游戏的基本优化技巧 188
9.3.1 代码上的小艺术 188
9.3.2 android中的查找表技术 190
9.3.3 游戏的感觉和性能问题 192
9.4 小结 193
第10章 游戏的心脏——物理引擎 194
10.1 物理引擎很重要 194
10.1.1 什么是物理引擎 194
10.1.2 常见的物理引擎 194
10.2 2d的王者jbox2d 197
10.2.1 基本的物理学概念 197
10.2.2 jbox2d中常用类的介绍 199
10.3 球体撞击木块金字塔案例 203
10.3.1 案例运行效果 204
10.3.2 案例的基本框架结构 204
10.3.3 常量类——constant 205
10.3.4 抽象类——mybody 206
10.3.5 圆形刚体类——mycirclecolor 206
10.3.6 生成刚体形状的工具类——box2dutil 207
10.3.7 颜色工具类——colorutil 208
10.3.8 主控制类——mybox2dactivity 209
10.3.9 显示界面类——gameview 211
10.3.10 绘制线程类——drawthread 212
10.4 简易打砖块案例 213
10.4.1 一般碰撞版 213
10.4.2 碰撞后消失版 215
10.5 旋转关节跷跷板案例 220
10.5.1 旋转关节介绍 220
10.5.2 多边形刚体类mypolygoncolor的开发 220
10.5.3 生成刚体形状的工具类——box2dutil 221
10.5.4 将场景中的刚体摆放到位 222
10.5.5 增加旋转关节 223
10.6 旋转关节链条摆案例 225
10.6.1 案例运行效果 225
10.6.2 案例的机械结构 225
10.6.3 主控制类——mybox2dactivity 226
10.7 组合机械结构案例 227
10.7.1 案例的运行效果 227
10.7.2 整体场景的机械结构 228
10.7.3 案例的基本框架结构 229
10.7.4 圆形刚体类——mycirclecolor 229
10.7.5 生成刚体形状的工具类——box2dutil 230
10.7.6 主控制类——mybox2dactivity 230
10.7.7 游戏界面类——gameview 232
10.7.8 绘制线程类——drawthread 233
10.8 小结 233
第11章 opengl es应用开发基础 234
11.1 opengl es概述及3d基本图形绘制 234
11.1.1 opengl及opengl es简介 234
11.1.2 3d基本知识 235
11.1.3 使用索引的不同绘制方式 236
11.1.4 用索引法绘制三角形的案例 238
11.1.5 不使用索引数据绘制 244
11.2 正交投影和透视投影 245
11.2.1 正交投影 246
11.2.2 透视投影 246
11.2.3 两种投影方式的原理及视口 247
11.2.4 两种投影方式的案例 248
11.3 光照与材质 250
11.3.1 光照的3种组成元素 250
11.3.2 定向光与定位光 252
11.3.3 法向量 253
11.3.4 材质 254
11.3.5 两种光源的案例 255
11.4 纹理及纹理映射 257
11.4.1 纹理映射基本原理 257
11.4.2 使用纹理映射的案例 258
11.4.3 几种纹理拉伸方式 261
11.4.4 几种纹理过滤方式 262
11.5 摄像机和雾特效 263
11.5.1 摄像机的设置 264
11.5.2 设置合理的视角 264
11.5.3 雾特效的开发 266
11.6 典型几何体的开发 267
11.6.1 圆柱 268
11.6.2 圆锥 273
11.6.3 球 276
11.6.4 椭圆体 278
11.6.5 胶囊体 281
11.6.6 几何体大集合 284
11.7 小结 286
第二篇 android游戏开发实战综合案例
第12章 滚屏动作游戏——太空保卫战 288
12.1 游戏的背景及功能概述 288
12.1.1 背景概述 288
12.1.2 功能简介 288
12.2 游戏的策划及准备工作 290
12.2.1 游戏的策划 290
12.2.2 android平台下游戏的准备工作 291
12.3 游戏的架构 292
12.3.1 各个类的简要介绍 292
12.3.2 游戏的框架简介 293
12.4 辅助界面相关类的实现 294
12.4.1 主控制类——planeactivity的实现 294
12.4.2 欢迎界面welcomeview类 296
12.4.3 其他辅助界面的介绍 300
12.5 游戏界面的框架设计 303
12.6 游戏实体相关类的实现 306
12.6.1 飞机plane类的实现 306
12.6.2 敌方飞机enemyplane类的实现 309
12.6.3 子弹bullet类的实现 311
12.6.4 其他相关类的实现 312
12.7 游戏界面的完善 314
12.7.1 地图类maps的实现 314
12.7.2 背景滚动类gameviewback groundthread的实现 316
12.7.3 物体移动线程movethread的实现 317
12.7.4 键盘监听线程keythread的实现 319
12.7.5 图片初始化方法initbitmap的实现 320
12.7.6 绘制方法ondraw的实现 322
12.8 游戏的优化与改进 324
第13章 棋牌游戏——中国象棋人机对弈 325
13.1 游戏的背景及功能概述 325
13.1.1 背景概述 325
13.1.2 功能介绍 325
13.2 游戏的策划及准备工作 327
13.2.1 游戏的策划 327
13.2.2 android平台下游戏的准备工作 327
13.3 游戏的架构 329
13.3.1 各个类简要介绍 329
13.3.2 游戏框架简介 330
13.4 主控制类——chess_djb_activity 331
13.5 辅助界面相关类 334
13.6 游戏界面相关类 336
13.6.1 游戏界面绘制类gameview 336
13.6.2 游戏界面常量类viewconstant 353
13.7 走法引擎相关类 354
13.7.1 常量类constant 354
13.7.2 工具类chess_loadutil 359
13.7.3 走法引擎主类loadutil 360
13.7.4 走法的排序规则类mycomparator 371
13.7.5 记录走棋步骤类stackplaychess 371
13.8 游戏的优化与改进 371
第14章 物理传感器游戏——小球快跑(3d版) 372
14.1 游戏背景及功能概述 372
14.1.1 背景概述 372
14.1.2 功能简介 372
14.2 游戏的策划及准备工作 374
14.2.1 游戏的策划 374
14.2.2 小球快跑游戏开发的准备工作 375
14.3 游戏的架构 375
14.3.1 游戏的总体架构 376
14.3.2 游戏的类结构 376
14.4 主控制类——driftball类的开发 378
14.4.1 driftball类的代码框架 378
14.4.2 driftball类的主要成员方法的实现 379
14.5 游戏主菜单的开发 381
14.5.1 欢迎界面类——welcome view类的代码框架 381
14.5.2 welcomeview类主要成员方法 382
14.5.3 welcomethread类的开发 383
14.5.4 菜单界面的用户交互事件处理 384
14.6 游戏界面模块的开发 385
14.6.1 游戏界面类——gameview的成员变量 385
14.6.2 gameview的成员方法简介 387
14.6.3 游戏界面绘制线程——gamethread类的代码框架 387
14.6.4 gamemenuthread类的开发 388
14.6.5 用户交互事件处理 389
14.7 游戏中各个图层的开发 391
14.7.1 地图图层的开发 391
14.7.2 其他图层的开发与实现 392
14.8 游戏后台逻辑的开发 395
14.8.1 小球的运动控制 395
14.8.2 小球的碰撞检测 396
14.8.3 大炮相关类cannon和missile的开发 400
14.9 传感器计算模块的开发 403
14.9.1 手机姿态变化监听器——balllistener类的开发 403
14.9.2 工具类——rotateutil类的代码框架 404
14.9.3 工具类——rotateutil类的开发 406
14.10 游戏的优化与改进 408
第15章 塔防游戏——精灵塔防 410
15.1 游戏的背景及功能概述 410
15.1.1 背景概述 410
15.1.2 功能介绍 410
15.2 游戏的策划及准备工作 413
15.2.1 游戏的策划 413
15.2.2 android平台下游戏开发的准备工作 414
15.3 游戏的架构 415
15.3.1 各个类的简要介绍 416
15.3.2 游戏框架简介 417
15.4 主控制类tafanggameactivity和数据库类dbutil 418
15.4.1 主控制类——tafanggame activity主要框架 418
15.4.2 主控制类——tafanggame activity中部分数据库的实现 421
15.4.3 主控制类——tafanggame activity中对话框的开发 423
15.4.4 数据库类dbutil的开发 427
11.5 界面相关类 428
15.5.1 欢迎界面welcomeview类的介绍 428
15.5.2 主界面mainmenusurfaceview类的介绍 430
15.5.3 音效设置界面musicsurfaceview类的介绍 434
15.5.4 游戏结束界面gameoverview类和帮助界面helpview类的介绍 435
15.5.5 积分榜界面highjifensurfaceview类的介绍 435
15.6 游戏界面gameview及相关类 438
15.6.1 精灵怪物target类 439
15.6.2 箭塔singlejianta类 443
15.6.3 箭shell类 444
15.6.4 精灵怪物的出击现场——targetnumthread 447
15.6.5 箭塔控制发射线程——shellnumthread 449
15.6.6 游戏地图矩阵模拟化 451
15.6.7 摆放箭塔守护城池 452
15.6.8 游戏中的2.5d效果 455
15.6.9 弹指间怪物灰飞烟灭——游戏水晶 455
15.7 游戏的优化和改进 459
第16章 策略游戏——回到战国 460
16.1 游戏的背景及功能概述 460
16.1.1 背景概述 460
16.1.2 功能简介 460
16.2 游戏的策划及准备工作 465
16.2.1 游戏的策划 465
16.2.2 android平台下游戏的准备工作 465
16.3 游戏的架构 467
16.3.1 游戏的模块架构 467
16.3.2 游戏各个类的简要介绍 468
16.4 地图设计器的开发 470
16.4.1 底层地图设计器的开发 470
16.4.2 上层地图设计器的开发 474
16.5 activity和游戏工具类的开发 475
16.5.1 主控制类——hdzgactivity的介绍 475
16.5.2 公式封装类——gameformula的介绍 478
16.5.3 常量工具类constantutil的介绍 479
16.6 数据存取模块的开发 481
16.6.1 城池信息以及地图层信息的封装类 481
16.6.2 数据存取相关类的介绍 485
16.7 英雄角色模块的开发 488
16.7.1 hero类的代码框架 488
16.7.2 英雄运动线程——herogo thread类的开发 491
16.7.3 辅助线程——herobackdata thread类的开发 493
16.8 表示层界面模块的开发 493
16.8.1 滚屏类——screenrollview类的开发 494
16.8.2 滚屏线程——screenroll thread的开发 495
16.8.3 游戏界面gameview的框架介绍 496
16.8.4 游戏界面绘制方法ondraw的介绍 498
16.8.5 游戏界面屏幕监听方法ontouch的介绍 500
16.8.6 游戏界面后台线程game viewthread的介绍 502
16.9 管理面板模块的开发 503
16.9.1 人物属性面板类manpanel view的开发 503
16.9.2 城池管理面板类citymanage view的开发 508
16.10 地图中可遇实体模块的开发 511
16.10.1 绘制类——mydrawable的开发 511
16.10.2 抽象类——mymeetabledrawable的开发 513
16.10.3 森林类——forestdrawable的开发 514
16.10.4 可遇实体对象的调用流程 516
16.11 英雄技能模块的开发 518
16.11.1 技能抽象类——skill的开发 518
16.11.2 伐木技能类——lumber skill的开发 519
16.11.3 随心步技能类——suixinbuskill的开发 520
16.12 游戏提示模块的开发 520
16.12.1 提示模块抽象类——gamealert的开发 520
16.12.2 点击确定按钮显示的信息类——plainalert的开发 521
16.12.3 显示粮草危机信息类——foodalert的开发 522
16.12.4 辅助线程herobackdatathread中对foodalert的调用 524
16.13 游戏的优化与改进 525
第17章 体育游戏——2d迷你桌球 527
17.1 2d桌球的背景及功能概述 527
17.1.1 背景概述 527
17.1.2 功能简介 527
17.2 游戏的策划及准备工作 530
17.2.1 游戏的策划 530
17.2.2 android平台下游戏的准备工作 530
17.3 游戏的架构 531
17.3.1 游戏的框架简介 531
17.3.2 各个类的简要介绍 532
17.4 公共类的实现 534
17.4.1 主控制类——gameactivity的代码框架 534
17.4.2 gameactivity类主要成员变量及方法的实现 536
17.4.3 常量类——constant的实现 540
17.5 辅助界面相关类的实现 542
17.5.1 欢迎动画界面welcomeview类的实现 542
17.5.2 主菜单界面mainmenuview的代码框架 544
17.5.3 主界面类——mainmenu view部分成员方法的实现 545
17.5.4 主界面动画线程类view drawthread的实现 548
17.5.5 排行榜界面highscore view的代码框架 549
17.5.6 highscoreview类的部分方法的实现 550
17.6 游戏界面相关类的实现 552
17.6.1 游戏界面gameview类的代码框架 552
17.6.2 gameview类部分成员方法的实现 553
17.6.3 键盘监听线程keythread类的实现 557
17.6.4 球运动的线程ballgothread类的实现 558
17.7 情景相关类的实现 559
17.7.1 球台table类的实现 559
17.7.2 桌球ball类的代码框架 561
17.7.3 ball类部分成员方法的实现 563
17.7.4 球杆cue类的实现 566
17.8 自定义控件及工具类的实现 568
17.8.1 球与球碰撞检测的工具类collisionutil的实现 568
17.8.2 定时器timer类的实现 571
17.8.3 主菜单按钮mainmenu button类的实现 572
17.8.4 获取日期的工具dateutil 类的实现 573
17.9 游戏的优化与改进 574
第18章 益智游戏——3d版推箱子 575
18.1 3d版推箱子的背景及功能概述 575
18.1.1 背景概述 575
18.1.2 功能简介 575
18.2 游戏的策划及准备工作 579
18.2.1 游戏的策划 579
18.2.2 android平台下游戏开发的准备工作 579
18.3 游戏的架构 580
18.3.1 游戏的框架简介 580
18.3.2 各个类的简要介绍 581
18.4 公共类的实现 582
18.4.1 主控制类——myactivity的代码框架 582
18.4.2 myactivity类成员方法的实现 584
18.4.3 常量类constant的实现 585
18.5 辅助界面相关类的实现 587
18.5.1 欢迎动画界面welcomeview类的实现 587
18.5.2 主菜单界面mainview的实现 589
18.6 游戏界面相关类 590
18.6.1 游戏界面mysurfaceview类的设计与实现 590
18.6.2 键盘监听线程keythread 599
18.7 自定义控件及工具类 600
18.7.1 缩放图片的方法picloadutil 600
18.7.2 主菜单上的按钮类mainmenubutton 601
18.8 情景相关类的实现 602
18.8.1 机器人类的代码框架 602
18.8.2 机器人类成员方法的实现 603
18.8.3 机器人组类robotgroup类的实现 605
18.8.4 机器人组类成员方法的实现 606
18.8.5 圆面circle类的实现 607
18.8.6 矩形纹理类texturerect的实现 609
18.8.7 纹理矩形组类texturerect group的实现 610
18.8.8 墙类wall的实现 611
18.8.9 墙wall类成员方法的实现 612
18.8.10 箱子cube类的实现 616
18.8.11 箱子组cubegroup类的实现 618
18.8.12 箱子移动cubego类的代码框架 619
18.8.13 箱子移动cubego类的成员方法的实现 620
18.8.14 地板类floor的实现 621
18.9 推箱子地图设计器的开发 623
18.10 游戏的优化与改进 624
第19章 物理引擎游戏——盛怒的老鼠 625
19.1 游戏背景及功能概述 625
19.1.1 游戏开发背景 625
19.1.2 游戏功能概述 625
19.2 游戏策划及准备工作 628
19.2.1 游戏策划 628
19.2.2 游戏开发的准备工作 628
19.3 游戏的框架 630
19.3.1 游戏主要用到的技术 631
19.3.2 游戏各个类的介绍 631
19.3.3 游戏的基本框架 633
19.4 公共类 634
19.4.1 主控制类——mybox2dactivity 634
19.4.2 常量类constant 635
19.5 主界面的设计与实现 644
19.5.1 鼠头和猫头类taj 644
19.5.2 鼠头和猫头控制线程——tjthread 646
19.5.3 主界面mainmenuview 646
19.5.4 刷帧线程mainmenudrawthread 653
19.6 工具类 654
19.6.1 加载及缩放图片的工具类picloadutil 654
19.6.2 生成刚体工具类box2dutil 655
19.6.3 声音工具类soundutil 656
19.7 刚体相关类 657
19.7.1 多边形类mypolygonimg 657
19.7.2 猫头类bodycat 659
19.7.3 冰块类bodyice 660
19.7.4 木条类bodywood 661
19.7.5 刚体类型枚举类bodytype 661
19.7.6 刚体查询工具类bodysearchutil 662
19.8 游戏界面相关类 663
19.8.1 皮筋类pijin 663
19.8.2 记录分数类score 664
19.8.3 刷帧线程drawthread 665
19.8.4 游戏界面类gameview 668
19.9 游戏优化与改进 673

以上是关于Android开发 UsageStatsManager应用使用情况管理的主要内容,如果未能解决你的问题,请参考以下文章

android开发难学吗? Android开发学习方法

Android开发和JAVA开发有啥区别

Android开发工程师的android工程师简介

Android开发 学生求助了期末大作业

如何Golang开发Android应用

Android样式的开发