“适配”不仅仅是“能在系统上运行”,更关键的是要充分利用新特性、修复兼容性问题,并遵循新的设计规范,以提供更好的用户体验。

以下是适配工作的核心要点,我将从权限、多窗口、安全、文件存储、网络和设计规范几个方面展开。
权限处理:最重要的变化
Android 6.0(Marshmallow)引入了运行时权限,但Android 7.0进一步收紧了权限模型,特别是文件权限。
1 读写外部存储(READ_EXTERNAL_STORAGE / WRITE_EXTERNAL_STORAGE)
这是在Android 7.0上最常见的“坑”。
-
问题所在:从Android 7.0开始,应用无法直接通过
file://URI路径访问外部存储(如SD卡)中的其他应用私有文件,如果你的应用尝试打开由另一个应用创建的文件(通过文件选择器选择的图片),会抛出FileUriExposedException异常。
(图片来源网络,侵删) -
解决方案:使用FileProvider。
-
在Android项目中添加FileProvider:
- 在你的Android项目 (
YourProject.Droid) 的Resources目录下,创建一个xml文件夹。 - 在
xml文件夹中创建一个名为file_paths.xml的文件,这个文件用来定义你的应用可以共享哪些目录路径。
<!-- Resources/xml/file_paths.xml --> <?xml version="1.0" encoding="utf-8"?> <paths> <external-path name="my_images" path="Pictures/" /> <external-path name="my_documents" path="Documents/" /> <!-- 你可以添加更多路径 --> </paths> - 在你的Android项目 (
-
在AndroidManifest.xml中注册FileProvider: 在
AndroidManifest.xml的<application>标签内添加以下元数据:<application ...> ... <provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> ... </application> -
在代码中使用FileProvider生成URI: 当你需要分享或打开一个文件时(用户从相册选择的图片),不要使用原始的
file://路径,而是使用FileProvider将其转换为content://URI。
(图片来源网络,侵删)// 在Droid项目的特定Activity或Service中 using Android.Support.V4.Content; // 假设 filePath 是一个文件路径,"/storage/emulated/0/Pictures/my_image.jpg" var file = new Java.IO.File(filePath); // 生成一个 content:// URI var uri = FileProvider.GetUriForFile(this, $"{Application.Context.PackageName}.fileprovider", file); // 你可以安全地使用这个 uri 启动一个Intent,例如打开图片 var intent = new Intent(Intent.ActionView); intent.SetDataAndType(uri, "image/jpeg"); intent.AddFlags(ActivityFlags.GrantReadUriPermission); // 授予读取权限 StartActivity(intent);
-
2 其他运行时权限
对于位置、相机、麦克风等敏感权限,处理方式与Android 6.0一致,确保你的Xamarin.Forms项目使用了 Xamarin.Essentials 或 Xamarin.Permissions 库来简化权限请求流程。
多窗口模式
Android 7.0支持分屏和自由窗口模式。
-
适配建议:
-
测试:这是最重要的,在真机或模拟器上手动进入分屏模式,测试你的应用在窗口大小变化时的布局表现,Xamarin.Forms的布局引擎(如
Grid,StackLayout,FlexLayout)通常能很好地处理窗口尺寸变化,但复杂的自定义布局可能会出现问题。 -
处理
OnConfigurationChanged:如果你的应用需要根据屏幕方向或窗口大小变化执行特定逻辑,你可以在Android项目的MainActivity中重写OnConfigurationChanged方法。// YourProject.Droid > MainActivity.cs public override void OnConfigurationChanged(Configuration newConfig) { base.OnConfigurationChanged(newConfig); // 当屏幕变为横屏时 if (newConfig.Orientation == Orientation.Landscape) { // 执行你的逻辑 } } -
在AndroidManifest.xml中声明支持: 确保你的
MainActivity在AndroidManifest.xml中声明支持屏幕方向变化,否则系统可能不会通知你的应用。<activity ... android:configChanges="orientation|screenSize|keyboardHidden">
-
安全性增强
1 HTTPS默认强制
从Android 7.0开始,默认情况下,应用不允许使用未加密的HTTP网络连接,除非在AndroidManifest.xml中明确禁用该安全策略。
-
问题:如果你的应用尝试连接一个
http://网址,会抛出CleartextTrafficNotPermittedException。 -
解决方案:
- 最佳实践:强烈建议将所有网络请求升级到
https://。 - 临时禁用(不推荐):如果必须使用HTTP,可以在
AndroidManifest.xml的<application>标签中添加android:usesCleartextTraffic="true",但这会降低应用的安全性,应尽量避免。
<application android:usesCleartextTraffic="true" ...>
- 最佳实践:强烈建议将所有网络请求升级到
2 证书锁定
对于安全性要求高的应用,可以考虑实现证书锁定,只信任特定的服务器证书,防止中间人攻击。
文件存储访问
- Scoped Storage:虽然Android 10(API 29)才正式强制推行Scoped Storage,但Android 7.0已经开始引导开发者使用更安全的文件访问方式,尽量使用
Environment.GetExternalStoragePublicDirectory()来访问公共目录(如Pictures,Documents),并优先使用Application.Context.GetExternalFilesDir()来访问应用私有目录,后者不需要任何权限。
网络变化:省电模式
Android 7.0引入了Network Saver(省电模式)。
- 影响:当系统开启省电模式时,后台数据访问可能会被限制。
- 适配建议:
- 如果你的应用有后台数据同步需求,应监听网络状态的变化,并合理使用
ConnectivityManager来检查网络是否可用。 - 使用
Xamarin.Essentials.Connectivity可以轻松获取当前网络状态。
- 如果你的应用有后台数据同步需求,应监听网络状态的变化,并合理使用
设计规范和用户体验
- 通知图标:Android 7.0要求通知图标必须使用Alpha图层,如果你还在使用旧的、不透明的通知图标,它们在Android 7.0上可能会显示为白色方块。
- 解决方案:确保你的通知图标是
.png格式,并且背景是透明的,只保留需要显示的部分(通常是深色)。 - 在AndroidManifest.xml中设置通知图标:
<application ... android:icon="@mipmap/app_icon"> <!-- 设置通知图标 --> <meta-data android:name="com.android.systemui" android:resource="@mipmap/notification_icon" /> </application>
- 解决方案:确保你的通知图标是
- 快捷方式:Android 7.0引入了新的快捷方式API,允许用户将常用功能直接添加到桌面,如果你的应用有核心功能,可以考虑实现快捷方式以提升用户体验。
- Emoji支持:Android 7.0更新了字体,对Emoji的支持更好了,如果你的应用处理文本,这通常是一个正向的改进。
适配Android 7.0的检查清单
- [ ] 权限:
- 使用
Xamarin.Essentials或Xamarin.Permissions处理所有运行时权限。 - 对于文件分享,必须实现
FileProvider,并测试从其他应用(如相册)选择文件的流程。
- 使用
- [ ] 网络:
- 检查所有网络请求是否为
https,如果是http,了解风险并考虑是否需要usesCleartextTraffic。
- 检查所有网络请求是否为
- [ ] 多窗口:
在真机或模拟器上手动测试分屏模式,检查布局是否错乱或功能是否正常。
- [ ] 安全:
- 确保通知图标是Alpha图层(透明背景)。
- 审查应用的数据存储和网络通信安全性。
- [ ] 测试:
- 最重要的一步!在API 24的模拟器或真机上完整地测试你的应用所有功能,特别是那些涉及文件、网络和权限的部分。
遵循以上步骤,你的Xamarin.Forms应用就能顺利地适配Android 7.0,并利用其新特性为用户提供更现代、更安全的体验。
