目录
一.保护 Android应用
1.Android 平台的安全模型
- 为防止应用 访问用户数据 或 属于其他应用的数据,Android 平台实现了 内核级安全
- Android 实现了应用签名,实现了在安装期间,自动将唯一 Linux用户ID 和 组ID 分配给所有应用的概念
- Android的安全机制:
- Android内核级安全性
- 每个程序分配一个用户ID
- 要求对应用进行签名
- 通过共享实现程序间数据访问
1.1 实现内核级安全性
- Android操作系统基于Linux内核,Linux 内核通过 将应用相互隔离以及与系统隔离,确保设备安全性
- Android安全架构包括: Linux 内核(Kernel) + 沙盒(Sandbox)技术
- 每个应用在安装时唯一分配一个用户ID,用于标志该应用,只有该应用可访问程序内的私有数据
- 程序包安装后,用户ID不变,同一程序包在不同设备上ID可能不同,不同程序包在同一设备上用户ID肯定不同
- Android 安全性模型的优势有: 保护组件、保护API、访问控制策略、访问限制、唯一签名
- Android 安全性模型的限制有: 可能无法自定义权限,没有相应机制使用户能够只授予应用特定权限
1.2 应用签名
- 首先对应用 签名,然后才能 发布 给全世界 Android用户 使用
- 所有 Android应用(.apk 文件)都需要:使用证书进行数字签名
- 证书可:识别应用作者,并帮助应用间建立信任关系
- 证书的基本要求:区分应用作者,这允许 Android系统授予 或 拒绝授予应用签名级权限
1.3 共享用户访问
- <manifest>元素的 android:sharedUserId 属性:使两个应用在同一进程中运行,A应用可以访问B应用数据
<manifest xmlns:android=http://schemas.android.com/apk/res/android package="com.sampleapackage.myapp" android:sharedUserId="com.sampleapackage.myapp.share" android:versionName="1.0">
2.权限
- 权限是:应用级别的安全机制,它允许用户限制对应用组件的访问
2.1 系统权限
- 如果应用需要访问受限制的资源/组件,它必须在清单文件中使用 <uses-permission> 声明所需权限,如:
- <uses-permission android:name="android.permission.INTERNET"> </uses-permission>
- 查看设备当前定义的权限:adb shell pm list permissions -s
- android.Manifest包 的 Manifest.permission类 提供的一些 系统权限:
- ACCESS_NETWORK_STATE:访问网络信息状态
- ACCESS_WIFI_STATE:访问 WIFI状态
- BLUETOOTH:蓝牙
- BROADCAST_SMS:发送信息广播接收器
- CALL_PHONE:拨打电话
- CAMERA:相机
- CHANGE_WIFI_STATE:改变 WIFI状态
- INSTALL_PACKAGES
- READ_SMS/RECEIVE_SMS/SEND_SMS
- SET_ALARM:设置闹铃
- WRITE_CONTACTS
- WRITE_EXTERNAL_STORAGE
- WRITE_SMS
2.2 自定义权限
- A.针对整个应用的权限:
- 应用定义自己的权限,在清单文件中用: <permission>
- 应用使用别的应用自己定义的权限,在清单文件中用:<uses-permission>,name属性应和别的应用一致
- <permission> 标记属性:
属性
描述
android:name
权限名称,任意且唯一,必须写
android:protectionLevel
应用面临的风险级别,通常是 dangerous
android:label
向用户显示的权限名称
android:description
向用户显示的权限描述
// APP1 系统配置文件:设置权限 <!-- 自定义一个权限,用于保护想保护的组件,如活动,服务,内容提供者等 --> <!-- 必须给权限的name属性,其他属性可选,描述在strings.xml中定义引用--> <permission android:name="com.andy.permission.START_MAIN_ACTIVITY" android:label="启动主活动" android:logo="@string/hello_world" android:description="@string/desc" android:protectionLevel="dangerous" android:icon="@drawable/ic_launcher"> </permission> // APP2 系统配置文件:设置权限 名字必须和 APP1 一致 <uses-permission android:name="com.andy.permission.START_MAIN_ACTIVITY"/>
- B.针对单个组件的权限:
- 考虑 Android 清单文件中的 <activity>标记 / <service>标记:
- <activity> /<service> 标记中的 android:permission属性 限制其他应用 启动此 活动 / 服务 的能力
- 调用这些方法:startActivity() 和 startActivityForResult() ,期间将检查该权限
- 调用这些方法:startService()、stopService() 和 bindService(),期间将检查该权限
- 调用者没有所需的权限,将抛出 SecurityException异常
- ==============================================================================
- 考虑 Android 清单文件中的 <receiver>标记:
- <receiver> 标记中的 android:permission属性 限制其他应用发送广播的能力
- 调用 sendBroadcast(),试图发送广播时,会检查此权限
- 调用者没有所需的权限,不会引发任何异常
- 想要控制哪些广播接收器应能够接收此广播: sendBroadcast(myIntent, REQUIRED_PERMISSION);
- ==============================================================================
- 考虑 Android 清单文件中的 <provider>标记:
- <provider> 标记中的 android:permission属性 限制其他应用发送广播的能力
- android:readPermission:控制从提供者进行读取
- android:writePermission:控制向提供者进行写入
2.3 URI权限
- 在启动活动 或 将结果返回给活动时,发出调用的组件可以设置:
- Intent.FLAG_GRANT_READ_URI_PERMISSION
- Intent.FLAG_GRANT_WRITE_URI_PERMISSION
- 上面两个权限,允许接收组件访问特定于此 URI 的数据,即使它没有访问内容提供者的权限
二.测试 Android应用
- 测试对于确定以下事项至关重要:
- 应用是否满足最终用户的需求
- 应用是否准备好供最终用户使用
- 是否存在导航问题
- 音频和视频质量是否符合要求
- 考虑和测试以下因素:
- 方向改变(横屏、竖屏)
- 设备配置变化(语言设置)
- 电池寿命
- 对外部资源的依赖(是否需要网络、地图、联系人信息等)
- 使用Junit 测试应用:
- 测试应用时,会创建 Test 应用,通过 AndroidManifest.xml文件的<instrumentation> 元素,链接到原始应用
- Test 应用包括每个测试用例的单独类,通过扩展 JUnit 的 TestCase类 创建测试用例类
- 最后,通过调用 Assert类 执行断言
- 测试分类:
- 初始化测试:onCreate() 内执行的代码
- UI 测试
- 状态管理测试:应用中的代码是否正确保存状态
- 创建测试项目:
- setUp() 方法:构建测试用例时 调用,执行所有初始化任务
- tearDown() 方法:测试后 销毁测试用例,释放所有获取的资源
- 为应用实现的每个测试用例,都要单独创建方法,方法名以 test开头
- 创建测试项目后:
- 添加测试用例构造函数
- 添加 Setup() 方法
- 添加初始化测试
- 添加单元测试
三.部署 Android应用
- 在真正的 Android设备上安装应用,称为部署 Android应用
- Android设备具有不同的 Android版本和硬件配置
- 部署时,应重点关注兼容性,记住硬件和软件限制,多种屏幕大小
- 发布应用之前,Android 要求对应用进行 数字签名
- 准备发布应用,必须:
- 在实际设备上全面测试创建的应用
- 添加最终用户许可证协议 (EULA)
- 添加许可证支持
- 在清单文件中指定图标和标签
- 关闭日志记录/调试并移除数据文件
- 在编译应用之前,必须:
- 指定应用版本,获取加密密钥
- 如果应用使用 MapView,请注册 Map API 密钥
- 在编译应用之后,必须:
- 通过使用加密密钥为应用签名
- 全面测试应用,以检查它是否按预期运行
- 将应用发布给移动设备用户
- 对应用正确签名,需要使用 私钥
- 为应用签名之后,使用 zipalign工具 对齐应用,与 Android SDK 一起存放在 tools 目录
- 确保所有未压缩的数据:从特定的字节对齐方式开始
- 对齐已签名的应用:zipalign -v 4 yourprojectname-unaligned.apk yourprojectname.apk
- 将应用发布到 Android市场,使用 Google 账号注册服务
- 注册并发布应用:http://market.android.com/publish
- 更新应用:必须确保 android:versionCode 和 android:versionName 属性 已经在清单文件中更新
- 确保 包的名称 和 密钥,与现有版本所用的一致
- 包名称与签名证书不匹配,那么会被当作新应用,不会通知用户更新
- 每个 APK 针对 不同配置的设备,被视作独立的应用版本,可发布不同的 APK
- Android 设备通用尺寸:大 (640dp x 480dp)