本文使用的工具有:
如何在在AS导出Unity可用的aar库文件,我参考了这篇文章:
unity2020以后aar方式调用android。
下面介绍我前后使用的三种打印实现方案 。如果想要跳过AS开发部分,直接使用,请下载我打包好的插件
下载地址
放在你Unity项目中的Plugins文件夹下即可调用。
创建好库文件的工程后,就可以在类中编写安卓的代码了。在安卓8.0及以上版本中,都提供了系统打印服务,可以轻松解决打印问题。调用系统打印服务的代码如下:
public void Printer(String path) {
if (PrintHelper.systemSupportsPrint()) {
//创建一个PrintHelper帮助类
PrintHelper ph = new PrintHelper(getActivity());
//读取图片文件
Bitmap bitmap = BitmapFactory.decodeFile(path);
//调整缩放模式
ph.setScaleMode(PrintHelper.SCALE_MODE_FILL);
//调用系统打印功能
ph.printBitmap("bitmap", bitmap);
}
else {
Log.i("PrintError", "system Not SupportsPrint");
}
}
其中PrintHelper类是在androidx.print包里的,所在类中需要添加
import androidx.print.PrintHelper;
在类所在模块中的build.gradle文件中需要添加androidx.print的依赖。(如下图)
然后在项目的gradle.properties文件中启用androidX(如下图)
经过以上设置,就可以使用AS顺利导出aar文件了。而在Unity中使用PrintHelper类,还需要将androidx.print.PrintHelper依赖添加到Unity的自定义gradle配置文件中的。首先需要在PlayerSettings/Publishing Settings中勾选Custom Main Gradle Template和Custom Gradle propertiesTemplate(如下图)。
在生成的mainTemplate.gradle文件中的dependencies项中,添加一行
implementation ‘androidx.print:print:1.0.0’
(如下图)
在生成的
gradleTemplate.properties文件中添加一行
android.useAndroidX=true
如下图
这样操作以后。运行时就不会报java.lang.ClassNotFoundException,说Landroidx.print.PrinterHelper没找到。
使用Native Share插件,github仓库地址。下载并导入Unity后,只需要两行就可以实现分享功能:
NativeShare share = new NativeShare();
share.AddFile(allFiles[0].FullName).Share();
用户可以在分享界面选择分享到系统打印服务,就可以完成打印。
如果你的安卓系统是经过阉割(比如我手上的这台oculus quest 2),无法调用系统打印服务,也无法打开分享界面,那么则需要通过调用第三方的打印服务来进行打印了。首先上核心代码,该代码所在类需要继承ContentProvider,该类是实现安卓跨应用传输文件消息的载体。学习ContentProvider的使用,我参考了这篇文章:FileProvider使用方法。
我的AndroidManifest.xml如下:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
tools:targetApi="31">
<provider
android:authorities="com.mycompanyname.appname.ContentProvider"
android:name="androidx.core.content.FileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
provider>
application>
manifest>
而在Unity中Application.persistentDataPath对应安卓的Context#getExternalFilesDir(String)/Context.getExternalFilesDir(null) 。例如我在Unity中将文件保存在Application.persistentDataPath的Pics文件夹下,则在设置FileProvider的文件访问路径的配置文件(xml/file_paths.xml)中如下配置即可
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files-path name="ext_files_images" path="Pics/" />
paths>
Java代码:
public void ShareToHpPrinterService(String imgPath) {
//使用其他APP打开文件
PackageManager packageManager = getActivity().getPackageManager();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
//com.mycompanyname.appname.ContentProvider 这个是在AndroidManifest.xml中定义的
Uri uri = FileProvider.getUriForFile(getActivity(), "com.mycompanyname.appname.ContentProvider", new File(imgPath));
intent.setDataAndType(uri, "image/*");
//这个是惠普打印机连接服务的打印方法
ComponentName cn = new ComponentName("com.hp.android.printservice", "com.hp.android.printservice.core.SingleFileReceiver");
intent.setComponent(cn);
getActivity().startActivity(intent);
}
在Unity的C#代码中调用ShareToHpPrinterService,带上文件目录,即可打开惠普打印机连接服务。
此篇文章我并没有将解决问题的过程全部写在这里,因为已经有写得很好的文章,我也是从中学习了很多。我使用到的惠普打印连接服务方法,是通过ES文件管理器打开打印功能,查看logcat中的log获取到方法名的,感觉还是蛮有趣的,这也体现了写代码时加log的重要性。
这是我第一次制作Oculus应用,遇到了很多的问题,Oculus开发的问题也可以问我哦!