Android 获取最近应用的缩略图

最近有项需求是获取应用的缩略,用于在动画时显示。因此就对此块知识简要了解了一下。


在android中获取视频文件的缩略图有三种方法:

1.从媒体库中查询
新视频增加后需要SDCard重新扫描才能给新增加的文件添加缩略图,灵活性差,而且不是很稳定,适合简单应用
2. android 2.2以后使用ThumbnailUtils类获取
实现简单,但2.2以前的版本不支持
3.调用jni文件,实现MediaMetadataRetriever类

实现复杂,但比较灵活,推荐使用


那么Android 中如何获取最近应用的缩略图,这块也有现成的函数,不过都被 @hide 掉了,所以需要利用java reflect 反射才能使用


核心代码如下:

[javascript] view plain copy print ?
  1. <span style="font-size:14px">package com.example.testondraw;  
  2.   
  3. import java.lang.reflect.Constructor;  
  4. import java.lang.reflect.Field;  
  5. import java.lang.reflect.Method;  
  6.   
  7. import android.app.ActivityManager;  
  8. import android.graphics.Bitmap;  
  9. import android.util.Log;  
  10.   
  11. </span>  
[javascript] view plain copy print ?
  1. <span style="font-size:14px">/** 
  2.  * 调用隐藏方法的助手类 
  3.  */</span>  
[javascript] view plain copy print ?
  1. <span style="font-size:14px">public class HideExploder {  
  2.     static final String TAG = "HideExploder";  
  3.     private final static Object refLock = new Object();  
  4.   
  5.     private static Method getTaskThumbnails = null;  
  6.     private static Field taskThumbnailsBitmap = null;  
  7.   
  8.     @SuppressWarnings("rawtypes")  
  9.     public static void listAllObject(String classFullName) {  
  10.         try {  
  11.             Log.i(TAG, "listAllObject classFullName: " + classFullName);  
  12.             Class<?> clazz = Class.forName(classFullName);  
  13.   
  14.             // 反射属性字段  
  15.             Field[] fields = clazz.getDeclaredFields();  
  16.   
  17.             // 反射方法字段  
  18.             Method[] methods = clazz.getDeclaredMethods();  
  19.   
  20.             // 反射构造器  
  21.             Constructor[] constuctors = clazz.getDeclaredConstructors();  
  22.   
  23.             Log.i(TAG, "FIELD========");  
  24.             for (Field f : fields) {  
  25.                 Log.i(TAG, "TYPE: " + f.getType() + " NAME: " + f.getName());  
  26.             }  
  27.   
  28.             Log.i(TAG, "METHOD========");  
  29.             for (Method m : methods) {  
  30.                 Log.i(TAG, "METHOD NAME: " + m.getName());  
  31.             }  
  32.   
  33.             Log.i(TAG, "CONSTUCTOR========");  
  34.             for (Constructor c : constuctors) {  
  35.                 Log.i(TAG, "NAME:" + c.getName());  
  36.   
  37.                 Class[] clss = c.getParameterTypes();  
  38.                 Object o = null;  
  39.   
  40.                 // 产生实例  
  41.                 try {  
  42.                     if (clss.length == 0)  
  43.                         o = c.newInstance();  
  44.                     else if (clss.length > 0) {  
  45.                         // TODO  
  46.                     }  
  47.                     Log.i(TAG, "object: " + o);  
  48.                 } catch (Exception e) {  
  49.                     e.printStackTrace();  
  50.                 }  
  51.             }  
  52.         } catch (Exception e) {  
  53.             e.printStackTrace();  
  54.         }  
  55.     }  
  56.   
  57. </span>  
[javascript] view plain copy print ?
  1. <span style="font-size:14px"><span style="white-space:pre"> </span>/** 
  2. <span style="white-space:pre">  </span> * 调用逻辑 
  3. <span style="white-space:pre">  </span> *  
  4. <span style="white-space:pre">  </span> * TaskThumbnails o = am.getTaskThumbnails(id) 
  5. <span style="white-space:pre">  </span> * Bitmap b = o.mainThumbnail; 
  6. <span style="white-space:pre">  </span> *  
  7. <span style="white-space:pre">  </span> * @param am ActivityManager 类实例 
  8. <span style="white-space:pre">  </span> * @param id 标识值 
  9. <span style="white-space:pre">  </span> * @return 
  10. <span style="white-space:pre">  </span> */</span>  
[javascript] view plain copy print ?
  1. <span style="font-size:14px">  
  2.     public static Bitmap getTaskThumbnailsBitmap(ActivityManager am, int id) {  
  3.         synchronized (refLock) {  
  4.             try {  
  5.                 if (getTaskThumbnails == null) {  
  6.                     getTaskThumbnails = am.getClass().getDeclaredMethod(  
  7.                             "getTaskThumbnails"int.class);  
  8.                 }  
  9.                 if (getTaskThumbnails != null) {  
  10.                     Object thumbnails = getTaskThumbnails.invoke(am,  
  11.                             Integer.valueOf(id));  
  12.                     if (thumbnails != null) {  
  13.                         if (taskThumbnailsBitmap == null)  
  14.                             taskThumbnailsBitmap = thumbnails.getClass()  
  15.                                     .getField("mainThumbnail");  
  16.                         if (taskThumbnailsBitmap != null) {  
  17.                             return (Bitmap) taskThumbnailsBitmap  
  18.                                     .get(thumbnails);  
  19.                         }  
  20.                     }  
  21.                 }  
  22.             } catch (Exception e) {  
  23.                 Log.w(TAG, "getTaskThumbnailsBitmap error:" + e);  
  24.                 e.printStackTrace();  
  25.             }  
  26.         }  
  27.         return null;  
  28.     }  
  29. }  
  30. </span>  

测试用例如下:


  1. <span style="font-size:14px">// 应用缩略图测试  
  2.     static final int MAX_RECENT_TASKS = 64;  
  3.   
  4.     Bitmap loadThumbnail(int index) {  
  5.         ActivityManager am = (ActivityManager) this  
  6.                 .getSystemService(Context.ACTIVITY_SERVICE);  
  7.         List<ActivityManager.RecentTaskInfo> recentTasks = am.getRecentTasks(  
  8.                 MAX_RECENT_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE);  
  9.         int numTasks = recentTasks.size();  
  10.   
  11.         if (index < numTasks) {  
  12.             final ActivityManager.RecentTaskInfo info = recentTasks.get(index);  
  13.             if (info != null) {  
  14.                 Bitmap b = HideExploderX.getTaskThumbnailsBitmap(am,  
  15.                         info.persistentId);  
  16.                 return b;  
  17.             }  
  18.         }  
  19.         return null;  
  20.     }</span>  

调用 loadThumbnail(X) 【索引值为0就是上一次的缩略图】拿到Bitmap对象,利用 SurfaceView 方法画出来即可:

 

  1. <span style="font-size:14px">public void drawBitmap() {  
  2.         // 锁定画布,得到canvas  
  3.         if (mSurfaceHolder == null || this.mBitmap == null)  
  4.             return;  
  5.   
  6.         Canvas canvas = mSurfaceHolder.lockCanvas();  
  7.         if (canvas == null) {  
  8.             return;  
  9.         }  
  10.   
  11.         // 绘图  
  12.         Paint paint = new Paint();  
  13.         paint.setAntiAlias(true);  
  14.         paint.setColor(Color.BLUE);  
  15.   
  16.         canvas.drawBitmap(this.mBitmap, 00, paint);  
  17.   
  18.         // 绘制后解锁,绘制后必须解锁才能显示  
  19.         mSurfaceHolder.unlockCanvasAndPost(canvas);  
  20.     }</span>  


注意点:

1、添加应用权限

    <uses-permission android:name="android.permission.GET_TASKS"/>
    <uses-permission android:name="android.permission.READ_FRAME_BUFFER"/>

   否则会报:

W/System.err( 3314): Caused by: java.lang.SecurityException: Permission Denial: getTaskThumbnails() from pid=3314, uid=10040 requires android.permission.READ_FRAME_BUFFER


2、有 eclipse 上调试运行时,即使加上权限了也还是会报上述错误,有两个方法解决,要么进行系统签名,要不放到linux上编译,利用platform 签名,Android.mk 如下:

  1. LOCAL_PATH:= $(call my-dir)  
  2. include $(CLEAR_VARS)  
  3.   
  4. LOCAL_MODULE_TAGS :optional  
  5.   
  6. # Only compile source java files in this apk.  
  7. LOCAL_SRC_FILES := $(call all-java-files-under, src)  
  8.   
  9. $(warning build apk)  
  10.   
  11. LOCAL_PACKAGE_NAME :test  
  12.   
  13. LOCAL_CERTIFICATE :platform  
  14.   
  15. include $(BUILD_PACKAGE)  
  16.   
  17. include $(call all-makefiles-under,$(LOCAL_PATH))  


下一篇文章将针对其系统代码及原理分析清楚,用于新需求开发使用。


5
0
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值