Android手机信息采集

 1> 建立/断开设备连接

图像采集 和 dump采集 都需要与设备连接后使用,我们通过adb提供的连接了实现,取得Device。

在通过adb与手机建立连接的过程中,我们使用以下的接口:
Device my_getDevice() ;    

boolean my_startViewServer(Device device) ;   

boolean my_stopViewServer(Device device) ;    

其中,端口映射 建立/取消 也在 开启/关闭 的 接口中进行了封装,不再需要手工干预。

package yafeng.test;


import com.android.ddmlib.AndroidDebugBridge;
import com.android.ddmlib.Device;
import com.android.hierarchyviewer.device.DeviceBridge;

public class device_deal {
    
    public static boolean viewServer_started = false ;

   
    public static Device my_getDevice(){    
        
        AndroidDebugBridge.terminate();    
        
        Device device = null ;
        
        Device[] devices = null;
        
        while(null==devices || 0==devices.length){    
            
            System.out.println("rebuilt DeviceBridge connect......");
            
            DeviceBridge.initDebugBridge() ;    
            
            devices = DeviceBridge.getDevices() ;
            
            System.out.println("rebuilt DeviceBridge result is : "+devices);
           

            
        device = devices[0] ;
        
        return device ;
        
    }
    
    
    
    public static boolean my_startViewServer(Device device){
        
        int port = 0 ;
        
        while(4939!=port){
            
            System.out.println("start forward port to 4939......");
            
            DeviceBridge.setupDeviceForward(device) ;
            
            port = DeviceBridge.getDeviceLocalPort(device) ;
            
            System.out.println("forward result is port : "+port);
        }
        
        while(!viewServer_started){
            
            System.out.println("start view server ......") ;
            
            viewServer_started = DeviceBridge.startViewServer(device) ;
            
            System.out.println("start view server result is "+viewServer_started) ;
        }
        
        return viewServer_started ;
        
    }
    
    
    
    public static boolean my_stopViewServer(Device device){
        
        boolean result ;
        
        result = DeviceBridge.stopViewServer(device) ;
        
       
       if(false==result){
            
            DeviceBridge.removeDeviceForward(device) ;
        }
        
        return result ;
        
    }
   
}

2> 图像采集

    ImageData getDeviceImage(Device mDevice) ;    

    ImageData 类型封装了我们需要的所有图像信息。其中我们使用其

    public byte data[];

    属性涵盖了图像的像素矩阵信息。
    (320*480像素的图像,其data数组的大小是320*480*3+480  byte),
      每个像素由3个色素(红值,绿值和蓝值)构成,且每行行首有1个行标识字节。

    我们操作的图像对比就是操作这个data数组,具体的各种对比策略(如何操作这个data)是在详细设计中细化。

    
    public ImageData getDeviceImage(Device mDevice){

        RawImage rawImage;
        try
        {
            rawImage = mDevice.getScreenshot();
        }
        catch(Exception ioe)
        {
            System.out.println(ioe.getMessage());
            return null;
        }
        if(rawImage == null)
        {
            return null;
        } else
        {      
            PaletteData palette = new PaletteData(65280, 16711680, -16777216);
            ImageData imageData = new ImageData(rawImage.width, rawImage.height, rawImage.bpp, palette, 1, rawImage.data);

            return imageData ;
          
        }
        
    }

    由于图像采集不是很稳定(经常采集到null),所以得重复采集,如果一定次数(20次)后还是采集不到,那么就断开此次设备连接,重新建立连接,再做上述的采集。(当然,如果连接也不是100%成功,也得判断/重复 连接)。

    例如:
   
    while(null==imageData ){
            
            imageData = getDeviceImage(device) ;
            
            i++ ;
            
            if(i>=20){    
                
                device = device_deal.my_getDevice() ;
                
                i = 0 ;
            }
        }
 
3> dump信息采集

      ViewNode get_rootView(Device device,Window window) ;   

      void absolute_compute(ViewNode node) ;   


      
      import com.android.hierarchyviewer.device.Window;
      import com.android.hierarchyviewer.scene.ViewHierarchyLoader;
      import com.android.hierarchyviewer.scene.ViewHierarchyScene;
      import com.android.hierarchyviewer.scene.ViewNode;

      public ViewNode get_rootView(Device device,Window window){

            ViewNode vn = null ;
            ViewHierarchyScene vhs = null ;

            vhs = ViewHierarchyLoader.loadScene(device,window) ;

            if(null!=vhs){

                vn = vhs.getRoot() ;
            }

            return vn ;
      }

然后就可以从root组件开始,遍历整个布局/组件信息。以下的例子是一个解析的示例:
    
      public void absolute_compute(ViewNode node){    
        
        if( 0!=node.children.size() ){
            
            for(int i=0;i<node.children.size();i++){
                
                absolute_compute( (ViewNode)(node.children.get(i)) ) ;   
               
        }
        
        
        int x = node.left;
        int y = node.top;
        
       
        ViewNode p = node.parent;
        while (p != null) {
            x += p.left - p.scrollX;
            y += p.top - p.scrollY;
            p = p.parent;
        }
        
        System.out.println("the "+node.name+" 's left_top absolute position x:"+x+" and y:"+y+" ,the size is: "+node.width+"*"+node.height+"\n") ;
        
        return ;
    }

----------------------------------------------------------------------------------------------------------

文章中讲到如下方法:

ImageData getDeviceImage(Device mDevice) ;

ImageData 类型封装了我们需要的所有图像信息。其中我们使用其

public byte data[];

属性涵盖了图像的像素矩阵信息。
(320*480像素的图像,其data数组的大小是320*480*3+480 byte),
每个像素由3个色素(红值,绿值和蓝值)构成,且每行行首有1个行标识字节。

在项目中,我们没采用这种方法,也未发现每行行首有什么标识字节。采用的方法是直接从/dev/graphics/fb0读取图像信息,在PC端,可以用adb pull /dev/graphics/fb0 D:\a 将Android手机上当前屏幕信息截回来存到PC中。对于320*480屏幕,该a文件大小为1024K 对于240*320的屏幕 ,a文件大小为620K

解析图像时,发现该a文件里面包含了几幅图的信息。不过我们只采用了第一幅图。每个像素占2字节RGB565的格式。这样我们就可以按像素解析成我们想要的图片格式。由于BMP效果较好,可以解析成BMP图像。

   解析成BMP时,关键代码如下:首先设置BMP文件头,修改大小以及图片分辨率,然后从a文件中按像素读取rgb值写入BMP像素中。

     sg_BHeader[0x02] = (UCHAR)(m_Width * m_Height * 3 + 0x36) & 0xff;
     sg_BHeader[0x03] = (UCHAR)((m_Width * m_Height * 3 + 0x36) >> 8) & 0xff;
     sg_BHeader[0x04] = (UCHAR)((m_Width * m_Height * 3 + 0x36) >> 16) & 0xff;
     sg_BHeader[0x05] = (UCHAR)((m_Width * m_Height * 3 + 0x36) >> 24) & 0xff;
     sg_BHeader[0x12] = (UCHAR)m_Width & 0xff;
     sg_BHeader[0x13] = (UCHAR)(m_Width >> 8) & 0xff;
     sg_BHeader[0x14] = (UCHAR)(m_Width >> 16) & 0xff;
     sg_BHeader[0x15] = (UCHAR)(m_Width >> 24) & 0xff;
     sg_BHeader[0x16] = (UCHAR)m_Height & 0xff;
     sg_BHeader[0x17] = (UCHAR)(m_Height >> 8) & 0xff;
     sg_BHeader[0x18] = (UCHAR)(m_Height >> 16) & 0xff;
     sg_BHeader[0x19] = (UCHAR)(m_Height >> 24) & 0xff;
// sg_BHeader[0x34] = (UCHAR)(m_Width * m_Height * 3 ) & 0xff;
// sg_BHeader[0x35] = (UCHAR)(m_Width * m_Height * 3 >>8) & 0xff;
// sg_BHeader[0x36] = (UCHAR)(m_Width * m_Height * 3 >>16) & 0xff;
// sg_BHeader[0x37] = (UCHAR)(m_Width * m_Height * 3 >>24) & 0xff;
     write(bmp, sg_BHeader, sizeof(sg_BHeader));

    for(i = 0; i < m_Height; i++)
     {
         unsigned char *c = p + (m_Height - 1 - i) * m_Width * 2;
         unsigned char cc;
         for(j = 0; j < m_Width * 2; j+=2)
         {
    value = c[j] & 0x00FF;
             value |= (c[j+1] << 8) & 0x0FF00;
    r = ((value >> 11) & 0x01F) << 3;
             g = ((value >> 5) & 0x03F) << 2;
    b = ((value >> 0) & 0x01F) << 3;
       outBuffer[index++] = (unsigned char)b;
    outBuffer[index++] = (unsigned char)g;
    outBuffer[index++] = (unsigned char)r;
            
         }
     }
write(bmp, outBuffer, sizeof(outBuffer));

建了一个简单的工程,里面包含了图片解析的主要代码,a,b,c是从手机截回来的图片,temp.bmp 是解析出来的图片 下载链接:http://download.csdn.net/source/2618563

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值