Unity在安卓系统打印功能的实现

1. 工具介绍

本文使用的工具有:

  1. Unity 2021.3.6f1 已安装安卓平台支持
  2. Android Studio(简称AS,下同)

2. 使用AS调用打印服务

如何在在AS导出Unity可用的aar库文件,我参考了这篇文章:
unity2020以后aar方式调用android。
下面介绍我前后使用的三种打印实现方案 。如果想要跳过AS开发部分,直接使用,请下载我打包好的插件
下载地址
放在你Unity项目中的Plugins文件夹下即可调用。

1. 直接调用系统打印服务

创建好库文件的工程后,就可以在类中编写安卓的代码了。在安卓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的依赖。(如下图)
Unity在安卓系统打印功能的实现_第1张图片
然后在项目的gradle.properties文件中启用androidX(如下图)
Unity在安卓系统打印功能的实现_第2张图片
经过以上设置,就可以使用AS顺利导出aar文件了。而在Unity中使用PrintHelper类,还需要将androidx.print.PrintHelper依赖添加到Unity的自定义gradle配置文件中的。首先需要在PlayerSettings/Publishing Settings中勾选Custom Main Gradle Template和Custom Gradle propertiesTemplate(如下图)。
Unity在安卓系统打印功能的实现_第3张图片
在生成的mainTemplate.gradle文件中的dependencies项中,添加一行

implementation ‘androidx.print:print:1.0.0’

(如下图)
Unity在安卓系统打印功能的实现_第4张图片
在生成的
gradleTemplate.properties文件中添加一行

android.useAndroidX=true

如下图
Unity在安卓系统打印功能的实现_第5张图片
这样操作以后。运行时就不会报java.lang.ClassNotFoundException,说Landroidx.print.PrinterHelper没找到。

2. 使用分享的方式打印

使用Native Share插件,github仓库地址。下载并导入Unity后,只需要两行就可以实现分享功能:

NativeShare share = new NativeShare();
share.AddFile(allFiles[0].FullName).Share();

用户可以在分享界面选择分享到系统打印服务,就可以完成打印。

3. 使用惠普打印机连接服务(第三方打印服务)打印

如果你的安卓系统是经过阉割(比如我手上的这台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,带上文件目录,即可打开惠普打印机连接服务。

3. 总结

此篇文章我并没有将解决问题的过程全部写在这里,因为已经有写得很好的文章,我也是从中学习了很多。我使用到的惠普打印连接服务方法,是通过ES文件管理器打开打印功能,查看logcat中的log获取到方法名的,感觉还是蛮有趣的,这也体现了写代码时加log的重要性。
这是我第一次制作Oculus应用,遇到了很多的问题,Oculus开发的问题也可以问我哦!

你可能感兴趣的:(Unity移动端交互,unity备忘,unity,android,vr,游戏引擎)