Wear:onConnectionFailed: ConnectionResult{statusCode=SERVICE_MISSING, resolution=null, message=null}

本文记录了一次解决Google Play Services缺失的问题经历。通过更新设备上的Google服务和项目的Google Play服务库版本,成功解决了该问题。
02-14 11:04:36.074 24807-25201/com.kodulf.fakenetease W/GooglePlayServicesUtil: Google Play services is missing.
02-14 11:04:36.111 24807-24807/com.kodulf.fakenetease D/MainAcitivity: onConnectionFailed: ConnectionResult{statusCode=SERVICE_MISSING, resolution=null, message=null}
02-14 11:05:26.249 24807-24890/com.kodulf.fakenetease W/GooglePlayServicesUtil: Google Play services is missing.

02-14 11:05:26.308 24807-24807/com.kodulf.fakenetease D/MainAcitivity: onConnectionFailed: ConnectionResult{statusCode=SERVICE_MISSING, resolution=null, message=null}


Google play services is missing

http://stackoverflow.com/questions/15144084/google-play-services-is-missing

参考:


i have just solved it. the google services have been updated in my device and the google playservice lib of my project was in an old version .I updated it and the problem has been sovled!


查看了源码:

package com.google.android.gms.common;下面的GooglePlayServicesUtil

try
        {
          localPackageInfo1 = localPackageManager.getPackageInfo("com.google.android.gms", 64);
          if (!lc.aU(localPackageInfo1.versionCode)) {
            break label248;
          }
          if (!gw()) {
            break label146;
          }
          j = 0;
          byte[][] arrayOfByte1 = new byte[3][];
          arrayOfByte1[0] = b.Ix[j];
          arrayOfByte1[1] = b.IE[j];
          arrayOfByte1[2] = b.IC[j];
          if (a(localPackageInfo1, arrayOfByte1) != null) {
            break;
          }
          Log.w("GooglePlayServicesUtil", "Google Play Services signature invalid on Glass.");
          return 9;
        }
        catch (PackageManager.NameNotFoundException localNameNotFoundException1)
        {
          Log.w("GooglePlayServicesUtil", " Google Play services is missing.");
          return 1;
        }
        localThrowable = localThrowable;
        Log.e("GooglePlayServicesUtil", "The Google Play services resources were not found. Check your project configuration to ensure that the resources are included.");
        continue;
      }




<think>我们正在讨论如何在嵌入式系统中使用HAL(硬件抽象层)实现Flash_ReadInt32和Flash_WriteInt32函数。 首先,我们需要理解HAL库通常提供了对Flash存储器的基本操作(如擦除、写入、读取等)。但是,HAL库通常不直接提供按整数(32位)读写的方法,因此我们需要基于HAL提供的函数进行封装。 步骤: 1. 读取操作:由于Flash存储器是按地址读取的,我们可以直接读取一个32位整数。但是需要注意地址对齐(通常要求32位对齐)和字节序问题。 2. 写入操作:Flash存储器的写入(编程)需要先确保写入区域已经被擦除(因为Flash只能将1改为0,擦除是将整个扇区恢复为1)。而且,写入操作通常要求按多个字节(如32位、64位等)进行。 注意:不同微控制器的Flash编程宽度可能不同(例如32位或64位),因此需要查阅具体芯片的参考手册。 假设我们使用STM32的HAL库,下面是一个示例实现: 首先,我们需要包含必要的头文件,并确保了解Flash的地址范围。 读取32位整数: 由于读取操作不需要特别的设置,我们可以直接通过指针读取内存地址。 写入32位整数: 写入操作需要调用HAL_FLASH_Program函数。该函数要求指定编程宽度(例如FLASH_TYPEPROGRAM_WORD表示32位编程)和地址。 但是,在写入之前,必须确保该地址所在的扇区已经被擦除。因此,我们可能需要先擦除整个扇区(但这样会擦除整个扇区,所以通常我们不会为写一个整数而擦除整个扇区)。因此,在实际应用中,我们通常采用以下策略: - 将需要写入的数据缓存起来,等到一个扇区写满或者需要更新时,再擦除整个扇区并重新写入。 但是,问题要求实现Flash_WriteInt32,所以我们假设调用者已经确保目标地址已经被擦除(即目标地址的所有位都是1),并且目标地址是32位对齐的。 实现步骤: 1. Flash_ReadInt32: - 输入:地址(32位对齐) - 输出:该地址上的32位整数 2. Flash_WriteInt32: - 输入:地址(32位对齐),32位整数数据 - 步骤:解锁Flash,进行编程(写入),然后重新锁定Flash。 注意:在写入过程中可能需要禁用中断,以确保编程过程不被打断。 下面我们以STM32为例,给出示例代码(注意:具体芯片可能有所不同,请根据实际情况调整)。 首先,我们定义两个函数: ```c #include "stm32f4xx_hal.h" // 根据实际芯片型号包含对应的头文件 // 读取32位整数 int32_t Flash_ReadInt32(uint32_t address) { // 直接通过指针读取该地址的值 // 注意:这里假设地址是32位对齐的 return *(__IO int32_t*)address; } // 写入32位整数 HAL_StatusTypeDef Flash_WriteInt32(uint32_t address, int32_t data) { HAL_StatusTypeDef status; // 1. 解锁Flash HAL_FLASH_Unlock(); // 2. 编程(写入)一个32位数据 status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, (uint64_t)data); // 3. 锁定Flash HAL_FLASH_Lock(); return status; } ``` 但是,上述写入函数有一个前提:目标地址已经被擦除(即目标地址的当前值为0xFFFFFFFF)。如果目标地址不是0xFFFFFFFF,那么写入操作可能会失败(因为Flash只能将1改为0,不能将0改为1)。 因此,在实际应用中,我们通常需要先擦除整个扇区(擦除操作会将整个扇区置为0xFF),然后再写入。但是擦除扇区是以扇区为单位的,所以我们需要管理一个扇区内的多个数据。 另外,注意HAL_FLASH_Program的第三个参数是uint64_t,但是当我们使用FLASH_TYPEPROGRAM_WORD时,实际上只使用低32位。 重要:在写入之前,还需要检查地址是否在有效的Flash地址范围内,并且地址是否对齐(32位对齐)。 此外,由于Flash写入次数有限,我们还需要考虑磨损均衡(wear leveling)的问题,但这不是本函数要解决的问题。 因此,上述实现是基础的,实际应用中需要根据需求进行扩展。 最后,注意在写入过程中可能会发生中断,如果写入过程被中断可能会导致写入失败或数据错误,因此有时需要在写入前禁用中断,写入后再使能中断。但HAL库中,HAL_FLASH_Program函数内部已经处理了中断(通常会在编程期间禁用中断),所以不需要额外处理。 但是,根据STM32的编程手册,在写入Flash期间,任何对Flash的读操作(包括取指令)都会暂停,直到写入完成。因此,如果代码在Flash中运行,那么在写入同一个bank的Flash时,需要将代码放到RAM中执行。但HAL库已经处理了这一点,只要我们在调用HAL_FLASH_Program时,函数本身在RAM中运行(或者不在同一个bank)即可。通常,HAL库的Flash编程函数是被设计为在Flash中运行的,因此我们需要将整个函数放到RAM中,或者确保在写入不同的bank。但为了安全起见,可以将关键代码(包括解锁、编程、锁定)放到RAM中执行。不过,HAL库中已经做了相关处理,我们按照HAL库的要求使用即可。 总结: 以上代码提供了基本的读取和写入32位整数的函数。在实际应用中,需要根据具体的芯片和Flash结构进行调整。 现在,我们生成相关问题: §§相关问题§§ 1. 如何确保Flash写入操作的安全性(例如防止中断干扰)? 2. 在写入Flash之前,为什么需要先擦除整个扇区? 3. 如何实现Flash存储的磨损均衡(wear leveling)? 4. 在嵌入式系统中,如何管理Flash存储空间以实现多个整数的读写? 5. 当系统在运行Flash中的代码时,对同一块Flash区域进行写入操作需要注意什么?</think>### 实现 Flash_ReadInt32 和 Flash_WriteInt32 函数 在嵌入式系统中使用 HAL 库操作 Flash 存储器时,需注意以下关键点: 1. **Flash 特性**:写入前需擦除(将位从 0→1),擦除以扇区为单位 2. **对齐要求**:32 位操作需 4 字节对齐地址 3. **写保护**:操作前解锁,完成后重新锁定 4. **数据验证**:写入后需校验数据完整性 #### Flash_ReadInt32 实现 ```c /** * @brief 从 Flash 读取 32 位整数 * @param address: 要读取的地址(需 4 字节对齐) * @retval 读取的 32 位整数 */ int32_t Flash_ReadInt32(uint32_t address) { // 检查地址对齐 if(address % 4 != 0) { Error_Handler(); // 处理对齐错误 } // 直接访问内存映射区域 return *(__IO int32_t*)address; } ``` #### Flash_WriteInt32 实现 ```c /** * @brief 向 Flash 写入 32 位整数 * @param address: 写入地址(需 4 字节对齐) * @param data: 要写入的 32 位整数 * @retval HAL 状态(成功/错误) */ HAL_StatusTypeDef Flash_WriteInt32(uint32_t address, int32_t data) { HAL_StatusTypeDef status; // 1. 检查地址对齐 if(address % 4 != 0) { return HAL_ERROR; // 对齐错误 } // 2. 解锁 Flash HAL_FLASH_Unlock(); // 3. 执行编程操作 status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, (uint64_t)data); // 4. 重新锁定 Flash HAL_FLASH_Lock(); // 5. 验证写入结果 if(status == HAL_OK) { int32_t readback = Flash_ReadInt32(address); if(readback != data) { status = HAL_ERROR; // 验证失败 } } return status; } ``` #### 关键注意事项 1. **擦除要求**: ```c // 写入前必须先擦除目标扇区 FLASH_EraseInitTypeDef eraseConfig; uint32_t sectorError; eraseConfig.TypeErase = FLASH_TYPEERASE_SECTORS; eraseConfig.Sector = FLASH_SECTOR_X; // 目标扇区 eraseConfig.NbSectors = 1; // 擦除数 eraseConfig.VoltageRange = FLASH_VOLTAGE_RANGE_3; // 电压范围 HAL_FLASHEx_Erase(&eraseConfig, &sectorError); ``` [^1] 2. **安全操作流程**: ```mermaid graph TD A[开始] --> B[检查地址对齐] B --> C{对齐?} C -->|否| D[返回错误] C -->|是| E[解锁Flash] E --> F[擦除目标扇区] F --> G[写入32位数据] G --> H[验证数据] H --> I[锁定Flash] I --> J[返回状态] ``` 3. **优化建议**: - 批量写入时缓存数据,减少擦除次数 - 实现磨损均衡算法延长 Flash 寿命 - 添加 CRC 校验增强数据可靠性 - 使用双缓冲机制防止掉电丢失数据
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值