android ICS横竖屏定制及利用G-Sensor转屏的代码兼容
我们在使用android机器的时候,常常遇到有些应用固定是横屏的,有些应用又固定是竖屏的,有些应用横竖屏都支持。对于一个应用来说,我们也知道可以设置一个android:screenOrientation属性值来实现。网上也有不少文章是让在apk的manifest里面设置screenOrientation这个属性的,不过这种做法对于一个应用来说当然是可行的,常见的也就是横屏、竖屏、sensor自动这几种。在平板电脑及大尺寸的机器中,大多使用的横屏,手机这些小尺寸的机器一般使用的是竖屏。
/*****************************************************************************************************/
声明:本博内容均由http://blog.csdn.net/sundesheng125原创,转载请注明出处,谢谢!
/*****************************************************************************************************/
像在手机中带G-SENSOR几乎是一种标配,找一个不带的机器还难一点。笔者最近的项目时在车载方面的平板,由于结构的变化,使用球头式挂件,这样车载电脑也就可以旋转了,也就可以玩一下3D motor为代表的需要G-SENSOR数据的游戏。笔者以前使用的BMA250,目前这个项目使用的BMA250E,这两颗芯片都是bosch的。需要注意的是,BMA250E有多个iic地址。数据手册描述如下:
The default I²C address of the device is 0011000b (0x18). It is used if the SDO pin is pulled to´GND´. The alternative address 0011001b (0x19) is selected by pulling the SDO pin to´VDDIO´.
也就是说SDO这个脚接地时,IIC地址就是0X18,接高电平的时候IIC地址就是0x19。当然这个硬件设计一般硬件工程师都会把原理图给软件同事看的。但是由于有些项目时这种接法,有些项目有时另外一种接法,我们也可以使用一种盲扫的方法,就是把可能的IIC地址做成一个数组来。具体参考代码如下:
static const unsigned short i2c_address[4] = {0x19,0x08,0x38,0x18}; for(i2c_num = 0; i2c_num < (sizeof(i2c_address)/sizeof(i2c_address[0]));i2c_num++) { client->addr = i2c_address[i2c_num]; pr_info("%s:addr= 0x%x,i2c_num:%d\n",__func__,client->addr,i2c_num); ret = i2c_smbus_read_byte_data(client,BMA250_CHIP_ID_REG); pr_info("Read ID value is :0x%x\n",ret); if ((ret &0x00FF) == BMA250_CHIP_ID){ pr_info("Bosch Sensortec Device detected!\n" ); strlcpy(info->type, SENSOR_NAME, I2C_NAME_SIZE); return 0; }else if((ret &0x00FF) == BMA150_CHIP_ID){ pr_info("Bosch Sensortec Device detected!\n" \ "BMA150 registered I2C driver!\n"); strlcpy(info->type, SENSOR_NAME, I2C_NAME_SIZE); return 0; } else if((ret &0x00FF) == BMA250E_CHIP_ID) { strlcpy(info->type, SENSOR_NAME, I2C_NAME_SIZE); return 0; }
有sensor了,我们就可以利用sensor的数据来设置屏幕的方向。如果没有呢?我们怎么办?笔者使用的方法就是在windowmanagerservice里面下功夫。又为了兼容有sensor的项目,笔者做了一个改进,设置了一个系统属性ro.product.screenoritention,自定义了它的值,具体代码如下:
int computeForcedAppOrientationLocked() { int req = 0; /*mscreenOrientation 0: not init, 1: sensor, 2: portrait, 3: landscape*/ if(0 == mscreenOrientation) { mscreenOrientation = SystemProperties.getInt("ro.product.screenoritention", 3); } if(1 == mscreenOrientation) { req = getOrientationFromWindowsLocked(); } else if(2 == mscreenOrientation) { req = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;//getOrientationFromWindowsLocked(); } else if(3 == mscreenOrientation){ req = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;//getOrientationFromWindowsLocked(); } if (req == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) { req = getOrientationFromAppTokensLocked(); } return req; }
这样设置ro.product.screenoritention这个属性为1时,就会call到G-SENSOR的处理getOrientationFromWindowsLocked,如果不是,就使用指定的值,可以设置为横屏,也可以设置为竖屏,这样代码的兼容性、扩展性会更好一些,免得用项目名称来if--else好。