第12章 车载安全与隐私:数据加密、用户隐私保护、安全驾驶模式、权限管理

各位好,我是老张。在车载系统里摸爬滚打了这么多年,我越来越觉得,安全这东西,就像汽车的刹车——平时你可能感觉不到它的存在,但一旦出问题,那就是大事。

这一章,我们来聊聊Android Automotive里的安全与隐私。说白了,就是怎么让你的车机系统,既好用,又让人放心。我见过不少开发者,功能做得花里胡哨,结果安全一塌糊涂。嗯,咱们今天就把这块硬骨头啃下来。

核心要点: 车载安全不是单一的技术点,而是从数据存储、用户授权、驾驶状态到系统权限的完整闭环。

12.1 数据加密:给数据穿上防弹衣

先说说数据加密。你想想看,车机里存着你的导航历史、通话记录、甚至家门地址。这些数据要是裸奔,那还得了?

Android Automotive 默认启用了 文件级加密(File-Based Encryption, FBE)。这意味着,不同用户的数据,甚至同一个用户的不同数据,都可以用不同的密钥加密。

我个人习惯,在开发涉及敏感信息的App时,除了系统级的加密,还会额外做一层应用层加密。比如,存储用户令牌时,我会用 EncryptedSharedPreferences

// 使用 EncryptedSharedPreferences 存储敏感数据
MasterKey masterKey = new MasterKey.Builder(context)
        .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
        .build();

SharedPreferences sharedPreferences = EncryptedSharedPreferences.create(
        context,
        "secure_prefs",
        masterKey,
        EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
        EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
);

sharedPreferences.edit().putString("user_token", "your_token_here").apply();
小提示: 我在项目中遇到过,有些开发者为了省事,直接把API密钥硬编码在代码里。千万别这么干!用 EncryptedSharedPreferences 或者 Android Keystore 才是正道。

12.2 用户隐私保护:别让你的App变成“间谍”

隐私保护,说白了就是尊重用户。车机上的隐私问题,比手机更敏感。因为车是共享的,今天你开,明天你家人开。

Android Automotive 引入了 用户配置文件(User Profiles) 的概念。每个驾驶员可以有自己的账号,数据完全隔离。

我曾经见过一个App,不管谁开车,都读取同一个位置数据。这其实很危险。正确的做法是,根据当前用户ID,加载对应的数据。

// 获取当前用户
UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
UserHandle currentUser = Process.myUserHandle();

// 根据用户加载隐私数据
if (userManager.isUserUnlocked(currentUser)) {
    // 安全地读取该用户的数据
    loadUserSpecificData(currentUser);
}
注意: 不要跨用户访问数据!Android Automotive 的隔离机制很严格,强行访问会抛出 SecurityException。我刚开始做的时候,就踩过这个坑。

12.3 安全驾驶模式:该停手时就停手

安全驾驶模式,这是车载系统独有的。它的核心逻辑很简单:车在动,就别让驾驶员分心。

Android Automotive 提供了 驾驶模式(Driving Mode) 的API。当车辆行驶时,系统会限制某些App的显示和交互。

举个例子,视频播放App在行驶中必须被禁用。但导航App可以继续显示,只是不能输入文字。

// 检查当前驾驶状态
CarDrivingStateManager manager = (CarDrivingStateManager) getSystemService(Context.CAR_DRIVING_STATE_SERVICE);
CarDrivingStateEvent event = manager.getCurrentCarDrivingState();

if (event != null && event.getStatus() == CarDrivingStateEvent.DRIVING_STATUS_MOVING) {
    // 车辆行驶中,限制交互
    disableVideoPlayback();
    showSimplifiedUI();
} else {
    // 停车状态,恢复完整功能
    enableFullUI();
}
避坑指南: 我曾经在测试时发现,有些模拟器无法正确模拟驾驶状态。所以,真机测试是必须的。另外,别忘了处理 CarDrivingStateEvent 的监听回调,状态变化时要及时响应。

12.4 权限管理:别让App“越界”

权限管理,是Android的老话题了。但在车上,它有一些特殊之处。

比如,一个音乐App,它需要访问网络,但不需要访问你的通讯录。在手机上,你可能随手就授权了。但在车上,权限滥用会带来更大的隐私风险。

Android Automotive 使用了 运行时权限(Runtime Permissions) 模型。而且,车载系统对 位置权限麦克风权限 的管理更加严格。

我建议,在请求权限时,一定要向用户解释清楚为什么需要这个权限。比如,导航App请求位置权限,可以说“用于实时导航”。

// 请求位置权限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
        != PackageManager.PERMISSION_GRANTED) {
    // 解释为什么需要这个权限
    showPermissionRationale("我们需要访问您的位置,以便提供导航服务。");
    ActivityCompat.requestPermissions(this,
            new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
            LOCATION_PERMISSION_REQUEST_CODE);
}
个人经验: 我在项目中遇到过,有些OEM厂商会自定义权限策略。比如,某些车型会默认禁止所有App在行驶中获取精确位置。所以,你的App一定要做好降级处理,比如从精确位置降级到粗略位置。

知识体系总览

下面这张图,是我自己梳理的本章知识结构。你可以把它当作一个思维导图,快速回顾。

车载安全与隐私 数据加密 用户隐私保护 安全驾驶模式 权限管理 FBE加密 EncryptedSharedPrefs 用户配置文件 数据隔离 DrivingState API UI限制 运行时权限 位置/麦克风特殊管理

好了,这一章的内容就到这里。安全与隐私,说白了就是一场攻防战。你做得越细致,用户就越放心。希望这些经验,能帮你少走一些弯路。

公众号:蓝海资料掘金营,微信deep3321