Android 资源保护问题——探索
apk文件使用解压工具就能看到drawable等资源,但是有些游戏中的图片资源却是无法看到的。
这个问题探索了许久……
【1】图片资源不放置在drawable文件下,放在assets中(但是解压apk,同样能看到图片资源),以下说说使用方法。
分析:Ⅰ)当图片资源放在drawable中的时候,能有相应的Id去解析: BitmapFactory.decodeResource(res, id)
如果放置在assets下,就需要根据文件的名字去解析(Android提供AssetManager)。
Ⅱ)可以自己建立多层目录,方便管理。
Ⅲ)这样的解析过程,耗费的时间要比根据Id解析要多(手机越来越智能,这点时间基本看不出来)。
代码:
/*** 从Assets中读取图片* @param fileName :assets根目录下 "a.png",有子文件夹的 "abc/a.png"* @return*/public static Bitmap getImageFromAssets(Context context, String fileName){Bitmap image = null;AssetManager am = context.getResources().getAssets();try{InputStream is = am.open(fileName);image = BitmapFactory.decodeStream(is);is.close();}catch (IOException e){e.printStackTrace();}return image;}
【2】图片资源打包在jar下,然后导入工程(但是解压apk,同样能看到图片资源)
分析:使用过一下第三方的jar包,在apk解压后是看不到的,尝试看看。最终发现jar包中的assets文件在apk中可见了。
Step1:打包jar
工程->右键->Export->Java/jar file->选择需要打包的src 和 assets(如下图)
Step2:解读assets中的图片,同【1】
Step3:打包apk,然后发现jar包中的assets和当前工程的assets合并了!
【3】图片资源加密,然后在assets文件下读取(可以实现资源保护,但是貌似比较耗时)
分析:通过某种方式对图片预先加密,然后在Android程序中解密,在转换成Bitmap。
可能别的应用程序就是这样做的吧,哪位大神有妙招,给介绍一下吧!(下面介绍一下简单方法)
Step1:加密,采用文件流方式,读取资源,然后修改,最后生成文件(随便格式都可以,就不能知道是图片了)
Ⅰ)每隔多少个字节添加一个指定的字节
Ⅱ)每隔多少个字节,交换字节(代码示例)
public class KMD1 {public static void encrypt(String filePath){byte[] tempbytes = new byte[5000];try {InputStream in = new FileInputStream(filePath);OutputStream out = new FileOutputStream(filePath.subSequence(0, filePath.lastIndexOf("."))+"2.jpg")while (in.read(tempbytes) != -1) {//简单的交换byte a = tempbytes[0];tempbytes[0] = tempbytes[1];tempbytes[1] = a;out.write(tempbytes);//写文件 }} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args){KMD1.encrypt("D:/a.jpg");} }
Step2:解密,与加密过程反向即可。
/** * 从Assets中读取图片 * @param fileName * @return */public static Bitmap getImageFromAssets(Context context, String fileName){Bitmap image = null;AssetManager am = context.getResources().getAssets();try{InputStream is = am.open(fileName);byte[] buffer = new byte[1000000];//足够大 is.read(buffer);for(int i=0; i<buffer.length; i+= 5000){//与加密相同byte temp = buffer[i];buffer[i] = buffer[i+1];buffer[i+1] = temp;}image = BitmapFactory.decodeByteArray(buffer, 0, buffer.length);is.close();}catch (IOException e){e.printStackTrace();}return image;}
【3】使用setPixel()和getPixel()对每个像素点进行加密,然后在使用的时候在还原
分析:通过Bitmap.getPixel(x, y)得到color值,对color的rgb值加密操作,然后setPixel(x,y,color)
Step1:懒得写了,直接贴代码:
注意:bitmap一定要copy一份,然后第二个值为true才能对其setPixel,不然会报错的;代码中的encrypt和decrypt就是你加密解密过程;
严重问题:对bitmap setPixel然后在getPixel,color值竟然不是set的值,有偏差,不知道为什么。有能解决这个问题的,请留言一下。
Bitmap temp_bitmap = image.copy(Bitmap.Config.ARGB_8888, true); int width = temp_bitmap.getWidth(); int height = temp_bitmap.getHeight(); int[] pixels = new int[width * height]; //temp_bitmap.getPixels(pixels, 0, width, 0, 0, width, height); for(int i = 0; i < height; i++) { for(int j = 0; j < width; j++) { int color = temp_bitmap.getPixel(i, j); int r = Color.red(color); int g = Color.green(color); int b = Color.blue(color); int alpha = Color.alpha(color); //if(alpha != 0) { r = encrptyRGB(r, 2*(i*j)); g = encrptyRGB(g, 4*(i*j)); b = encrptyRGB(b, 6*(i*j)); color = Color.argb(alpha, r, g, b); pixels[width * i + j] = color; //temp_bitmap.setPixel(i, j, color); } } } temp_bitmap.setPixels(pixels, 0, width, 0, 0, width, height); for(int i = 0; i < height; i++) { for(int j = 0; j < width; j++) { int color = temp_bitmap.getPixel(i, j); int r = Color.red(color); int g = Color.green(color); int b = Color.blue(color); int alpha = Color.alpha(color); //if(alpha != 0) { r = decryptRGB(r, 2*(i*j)); g = decryptRGB(g, 4*(i*j)); b = decryptRGB(b, 6*(i*j)); color = Color.argb(alpha, r, g, b); pixels[width * i + j] = color; //temp_bitmap.setPixel(i, j, color); } } } temp_bitmap.setPixels(pixels, 0, width, 0, 0, width, height); return temp_bitmap;
【?】继续探索中,忘大神指教!感激不尽!
转载于:https://www.cnblogs.com/DswCnblog/p/4499977.html
Android 资源保护问题——探索相关推荐
- 《Android开发艺术探索》读书笔记——Cha3.2.2使用动画实现View的滑动
章节来自<Android开发艺术探索> 第一种方式 3.2.2 使用动画 上一节介绍了采用scrollTo/scrollBy来实现View的滑动,本节介绍另外一种滑动方式,即使用动画,通过 ...
- 《Android开发艺术探索》自定义View中关于“HorizontalScrollViewEx”的改进
在<Android开发艺术探索>一书中自定义View一节中提到了关于一个类似横向滑动List的自定义ViewGroup:HorizontalScrollViewEx.如果你使用过的话就会发 ...
- 《android开发艺术探索》读书笔记(五)--RemoteViews
接上篇<android开发艺术探索>读书笔记(四)--View工作原理 No1: RemoteViews使用场景:通知栏和桌面小部件 No2: 通知栏主要通过NotificationMan ...
- 《Android开发艺术探索》图书勘误
第一章 在13页提到"系统只在Activity异常终止的时候才会调用onSaveInstanceState与onRestoreInstanceState来储存和恢复数据,其他情况不会触发这个 ...
- Android开发艺术探索——第七章:Android动画深入分析
Android开发艺术探索--第七章:Android动画深入分析 Android的动画可以分成三种,view动画,帧动画,还有属性动画,其实帧动画也是属于view动画的一种,,只不过他和传统的平移之类 ...
- Android开发艺术探索读书笔记(一)
首先向各位严重推荐主席这本书<Android开发艺术探索>. 再感谢主席邀请写这篇读书笔记 + 书评.书已经完整的翻完一遍了,但是还没有细致的品读并run代码,最近有时间正好系统的把整本书 ...
- Android开发艺术探索--第二章IPC机制(2)之Binder
最近在拜读任主席的Android开发艺术探索,现在看了一半,再回头看前面的,感觉跟没有看一样,所以还是把知识点总结一下吧,这一节咱们来讲一下IPC中的Binder 直观来说,Binder是Androi ...
- Android开发艺术探索完结篇——天道酬勤
这片文章发布,代表着我已经把本书和看完并且笔记也发布完成了,回忆了一下我看Android群英传,只用了两个月,但是看本书却花了2016年05月04日 - 2018年07月16日,整整两年多,真是惭愧 ...
- Android 开发艺术探索——第十章 Android的消息机制
Android 开发艺术探索--第十章 Android的消息机制读书笔记 Handler并不是专门用于更新UI的,只是常被用来更新UI 概述 Android的消息机制主要值得就是Handler的运行机 ...
最新文章
- JAVA基础6-函数
- windows上报错:Could not find a version that satisfies the requirement torch==0.4.1
- 继承的基本概念(1)
- 用最小二乘法拟合任意次函数曲线(C#)
- android老 电池,为什么安卓手机不会因为电池的老化而降频呢?
- 数据库-MySQL-搭建服务器
- 大变革!苹果设计团队三名核心元老离职
- 【算法】剑指 Offer 36. 二叉搜索树与双向链表
- 宝马无法gps定位_2.0T+后驱,豪华品牌论运动还得看它,带你看宝马3系
- Java数组3(2015-8-27)
- python的学习之路
- python urllib2详解及实例
- selenium之chrome driver版本选择
- sw4stm32开发stm32
- ISO9000 质量管理和质量保证系列国际标准
- telnet linux 退格键无法生效
- 多行文字内容溢出显示点点点(...)省略号
- ubuntu18.04 用LSD-SLAM跑通rgbd数据集以及地图重用
- 关于CAN报文中ACK应答错误的检测原理
- python做flash帧动画_[练习]利用CSS steps 实现逐帧动画
热门文章
- C#基础知识整理:基础知识(10) 静态
- latin1_swedish_ci gbk_chinese_ci
- 领课网络在线教育系统开源项目
- 玩转SpringCloud Spring Cloud 微服务
- SpringMVC通过注解方式读取properties文件中的值
- Android开发之dp转像素,像素转换为dp工具类,详细代码,带有源文件下载地址。...
- 带你走近AngularJS - 创建自定义指令
- AU3学习案例----------考勤机手工补卡
- 连麦互动直播方案全实践3:网易云信连麦互动的实现方案
- 你不知道的JavaScript·第一部分