调用第三方打印apk Epson iPrint解决思路,目前仅有一个apk,爱普生打印,如何调用起来这个第三方apk?
1.使用反编译工具反编译爱普生打印APK,查看AndroidManifest.xml文件找到包名和爱普生打印预览Activity。
包名:package="epson.print"
打印预览界面Activity在AndroidManifest.xml的配置如下:
<activity android:configChanges="keyboard|keyboardHidden|orientation|screenSize" android:name="epson.print.ActivityDocsPrintPreview" android:screenOrientation="unspecified">
<intent-filter>
<span style="color:#ff0000;"><action android:name="android.intent.action.SEND"/></span>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<span style="color:#ff0000;"><data android:mimeType="application/pdf"/></span>
<data android:mimeType="application/msword"/>
<data android:mimeType="application/vnd.ms-excel"/>
<data android:mimeType="application/vnd.ms-powerpoint"/>
<data android:mimeType="application/vnd.openxmlformats-officedocument.wordprocessingml.document"/>
<data android:mimeType="application/vnd.openxmlformats-officedocument.presentationml.presentation"/>
<data android:mimeType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"/>
<data android:mimeType="text/csv"/>
<data android:mimeType="application/rtf"/>
<data android:mimeType="text/rtf"/>
<data android:mimeType="text/comma-separated-values"/>
</intent-filter>
</activity>
上面加红的可以看出掉起来这个Activity需要 actionandroid:name="android.intent.action.SEND" 和 <data android:mimeType="application/pdf"/>
2.在自己的代码中开始调用,出现“文件无法打开”;
3. 分析可以知道,打印预览是从文件浏览中打开的。查看反编译后的源代码。
<activity android:configChanges="keyboard|keyboardHidden|orientation|screenSize" android:name="epson.print.fileBrower" android:screenOrientation="unspecified"/>
这个activity一定是文件浏览Activity,这个Activity源代码中会包含startActivity函数,并让intent携带对应的参数传递给ActivityDocsPrintPreview。具体可以使用软件就会发现这个逻辑。
查看反编译后的源代码确实找到对应的代码片段如下,红色部分正是线索,intent使用STREAM携带了Uri参数:
const-string v3, "<span style="color:#ff0000;">android.intent.action.SEND</span>"
invoke-virtual {v2, v3}, Landroid/content/Intent;->setAction(Ljava/lang/String;)Landroid/content/Intent;
.line 536
const-string v3, "<span style="color:#ff0000;">android.intent.extra.STREAM</span>"
invoke-virtual {p1}, Ljava/io/File;->getAbsolutePath()Ljava/lang/String;
move-result-object v4
invoke-static {v4}, <span style="color:#ff0000;">Landroid/net/Uri;->parse(Ljava/lang/String;)Landroid/net/Uri;</span>
move-result-object v4
invoke-virtual {v2, v3, v4}, Landroid/content/Intent;-><span style="color:#ff0000;">putExtra(Ljava/lang/String;Landroid/os/Parcelable;)Landroid/content/Intent;</span>
goto :goto_1
.line 543
.end local v2 # "myIntent":Landroid/content/Intent;
:cond_2
invoke-virtual {p1}, Ljava/io/File;->getAbsolutePath()Ljava/lang/String;
move-result-object v3
invoke-direct {p0, v3}, Lepson/print/fileBrower;->isFilePdf(Ljava/lang/String;)Z
move-result v3
if-nez v3, :cond_3
invoke-virtual {p1}, Ljava/io/File;->getAbsolutePath()Ljava/lang/String;
move-result-object v3
invoke-static {v3}, Lepson/common/Utils;->isGConvertFile(Ljava/lang/String;)Z
move-result v3
if-eqz v3, :cond_5
.line 545
:cond_3
invoke-virtual {p1}, Ljava/io/File;->getAbsolutePath()Ljava/lang/String;
move-result-object v3
invoke-direct {p0, v3}, Lepson/print/fileBrower;->getFileSize(Ljava/lang/String;)Z
move-result v3
if-eqz v3, :cond_4
.line 546
new-instance v2, Landroid/content/Intent;
const-class v3, Lepson/print/ActivityDocsPrintPreview;
invoke-direct {v2, p0, v3}, Landroid/content/Intent;-><init>(Landroid/content/Context;Ljava/lang/Class;)V
.line 548
.restart local v2 # "myIntent":Landroid/content/Intent;
const-string v3, "from"
const/4 v4, 0x3
invoke-virtual {v2, v3, v4}, Landroid/content/Intent;->putExtra(Ljava/lang/String;I)Landroid/content/Intent;
.line 550
const-string v3, "send document"
invoke-virtual {p1}, Ljava/io/File;->getAbsolutePath()Ljava/lang/String;
move-result-object v4
invoke-virtual {v2, v3, v4}, Landroid/content/Intent;->putExtra(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;
.line 552
invoke-virtual {p0, v2}, Lepson/print/fileBrower;->startActivity(Landroid/content/Intent;)V
4.将上面的代码转化为调用爱普生打印apk的代码:
String epsonPrintApkPackageName = "epson.print";
Intent intent = new Intent();
intent.setAction("android.intent.action.SEND");
intent.setPackage(epsonPrintApkPackageName);
intent.setClassName(epsonPrintApkPackageName,"epson.print.ActivityDocsPrintPreview");
Uri uri = Uri.fromFile(new File(path));
intent.putExtra("android.intent.extra.STREAM", uri);
intent.setType("application/pdf");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addCategory(Intent.CATEGORY_DEFAULT);
getBaseContext().startActivity(intent);
代码已经可以成功运行了,在调用第三方apk使用的时候,如果不确定传入的参数,可以从反编译后的源代码中找到一些线索,这确实是一种方法。