Android Studio 编写无限查看QQ闪照APP
原理
QQ闪照在查看了之后就会立即删除,但是在查看之前,它会保存在你的手机里,它在你手机里的路径是:
“内部储存/tencent/MobileQQ/diskcache”
如果你直接在这个路径里查看QQ闪照也是可以的,而且你可以把文件复制出去,这样就可以永久查看了。
直接手动查看闪照
你的好友给你发了一张闪照:
记住,成功的关键在于:点开了闪照(不要点那5秒),然后到文件夹里按时间降序查看文件。这样第一个文件就一定会是闪照的图片(闪照图片结尾是:_fp)。点开闪照后腾讯的算法会自己把闪照文件解密,然后保存到那个文件夹里,所以它按时间降序查看文件时第一个文件一定会是那个刚刚点开的闪照图片。
代码实现
用刚刚的方法可以这么轻松地破解闪照,你是不是对用代码实现很失望呢?一开始我也是这么觉得的,但是弄了一段时间后发现手动操作非常不方便,每次都要自己打开文件夹,还有设置按时间降序查看,还要选择打开方式,非常麻烦。
1、开权限
和windows不一样,android文件操作都是要开启储存权限的,否则文件操作时会抛出异常。
开启权限对初学者来说不是很简单,网上有很多方法,但是有很多方法都太复杂,像我这样的小白根本不会弄。
下面是一个非常简单的开启权限的方法(以储存权限为例):
首先在 AndroidManifest.xml 文件里的 </application> 和 </manifest> 之间添加如下代码:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
这个表示在应用信息里会显示该应用会需要储存权限。但是 Android 6.0 以及之后的版本中,单单这样是不能够开启储存权限的,还需要再写一个能够弹出一个消息框,告诉使用者需要开启储存权限的代码,只有使用者点击同意后储存权限才真正的开启了。
废话不多说,直接说方法:首先在 build.gradle (Module: app) 的 dependencies 里添加一行代码:
compile 'com.github.dfqin:grantor:2.1.0'
添加了之后建议先 Rebuild Project 一下(菜单栏/Build/Rebuild/Project)
然后在 MainActivity 里添加一个方法:
private void requestStore(){
if(!PermissionsUtil.hasPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)){
PermissionsUtil.requestPermission(this, new PermissionListener() {
@Override
public void permissionGranted(@NonNull String[] permission) {
init(); //要自己定义的一个方法init(),用于初始化
}
@Override
public void permissionDenied(@NonNull String[] permission) {
}
},new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE});
}else{
init(); //要自己定义的一个方法init(),用于初始化
}
}
调用后这个方法如果应用未拥有储存权限就会弹出一个消息框,提示使用者是否给应用开启储存权限,使用者给了应用储存权限后就调用方法 init();如果应用已拥有储存权限,就直接调用方法 init()。
要写一 init() 方法,初始化就不写在 onCreate 里了。onCreate 里只需要写:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
requestStore();
}
这样应用申请完储存权限后就会开始初始化,初始化里可以绑定按钮、图片框等。
2、按照时间降序查看文件
你没有被一个简单的开启权限难倒吧?我们开启权限的目的是要读取文件中的闪照。首先要写一个可以按照时间降序查看文件的方法:
public static List<File> getFileSort(String path) {
List<File> list = getFiles(path, new ArrayList<File>());
if (list != null && list.size() > 0) {
Collections.sort(list, new Comparator<File>() {
public int compare(File file, File newFile) {
if (file.lastModified() < newFile.lastModified()) {
return 1;
} else if (file.lastModified() == newFile.lastModified()) {
return 0;
} else {
return -1;
}
}
});
}
return list;
}
public static List<File> getFiles(String realpath, List<File> files) {
File realFile = new File(realpath);
if (realFile.isDirectory()) {
File[] subfiles = realFile.listFiles();
for (File file : subfiles) {
if (file.isDirectory()) {
getFiles(file.getAbsolutePath(), files);
} else {
files.add(file);
}
}
}
return files;
}
这个代码是用 Java 的 File 读入所有文件信息,再用 Collections 给这些文件按照时间降序排序。写好这个代码后调用方法 getFileSort(路径) 就可以获得 路径 里的所有文件并且是按时间降序得到排列的。
则获取闪照图片的关键代码是:
String folderPath = Environment.getExternalStorageDirectory() + File.separator; //获取 内部储存 路径
String path = folderPath+"tencent/MobileQQ/diskcache"; //QQ闪照保存路径
files = getFileSort(path); //一个 List<File> 类型的全局变量
if(files.size() > 0) { //防止无文件导致 ffiles.get(0) 异常
String pathName = files.get(0).getPath();
Bitmap bitmap = BitmapFactory.decodeFile(pathName);
imageView.setImageBitmap(bitmap); //imageView是布局里的图片框
}
当然使用方法和之前手动查看的方法一样,必须要先点开闪照(不要点那5秒),然后再获取。
3、把获取到的闪照发回给好友
能无限查看闪照已经够秀的了,但是还可以更秀,就是查看了闪照之后直接分享给刚刚发给你闪照的好友。
先上代码:
private void shareImageQq() {
new Thread(new Runnable() {
@Override
public void run() {
try {
Intent intent = new Intent();
ComponentName comp;
comp = new ComponentName("com.tencent.mobileqq", "com.tencent.mobileqq.activity.JumpActivity");
intent.setComponent(comp);
intent.setAction(Intent.ACTION_SEND);
intent.setType("image/*");
Uri uri = Uri.fromFile(files.get(0)); //files.get(0) 就是刚刚的图片文件
intent.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(intent);
}catch (Exception e){
e.printStackTrace();
}
}
}).start();
}
直接用系统调用QQ的分享功能,把刚刚的图片分享给好友。“com.tencent.mobileqq” 是手机QQ的包名,“com.tencent.mobileqq.activity.JumpActivity” 是手机QQ分享功能类的类名。
4、可以用来耍了
先看看效果:
大概就这样了吧。