1.最近项目有一个需求,Unity安卓端打开上传到服务器的word文档。 第一个想法是去商店找webview插件,但是将文档的Url路径放上去之后,几个webview插件无一例外都打不开这个文档
2.解决这个问题只能写安卓的ARR包来实现这个功能
思路有很多种
2.1 通过安卓引用WPS第三方的库,外部打开这个文档
2.2 通过安卓将doc文档转成其他格式(例如pdf,html),然后再通过unity的webview插件或者pdf插件打开。我这次是将doc文档下载到安卓路径,然后再写一个将doc转成pdf的Arr包,最后将文档转化成pdf,通过PDFRender插件打开这个文档。
我的Unity版本是2019.4 AS的版本是
第一步,打开Android Studio ,新建一个New project 输入项目名字和包名,选好API
左上角选中File-Project Structure
选中Modules,然后点击加号,弹出来的界面选择第二个Library,名字改不改无所谓,默认就好了
在左上角将试图换成Project,将Unity里面的res文件夹复制到mylibrary/src/main/res文件夹中,将UnityPlayerActivity文件复制到mylibrary/src/main/java/com.aabb.mylibrary中,将aspose包(下载地址最下面)和Unity的classes.jar包复制到mylibrary/libs文件夹中,并且两个包右键选择Add as library
Unity Res路径
然后在com.aabb.mylibrary的路径下右键新建两个java脚本,`
package com.aabb.mylibrary;
import android.widget.Toast;
import android.os.Bundle;
public class DemoActivity extends UnityPlayerActivity {@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Toast.makeText(this, "DemoActivity -> onCreate", Toast.LENGTH_SHORT).show();
}
}
package com.aabb.mylibrary;
import android.app.Activity;
import android.widget.Toast;
import com.aspose.words.Document;
import com.aspose.words.SaveFormat;
import com.unity3d.player.UnityPlayer;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
;
public abstract class AndroidUnityDemo {
/**
* unity项目启动时的的上下文
*/
private Activity _unityActivity;
/**
* 获取unity项目的上下文
* @return
*/
Activity getActivity(){
if(null == _unityActivity) {
try {
Class<?> classtype = Class.forName("com.unity3d.player.UnityPlayer");
Activity activity = (Activity) classtype.getDeclaredField("currentActivity").get(classtype);
_unityActivity = activity;
} catch (ClassNotFoundException e) {
} catch (IllegalAccessException e) {
} catch (NoSuchFieldException e) {
}
}
return _unityActivity;
}
/**
* 调用Unity的方法
* @param gameObjectName 调用的GameObject的名称
* @param functionName 方法名
* @param args 参数
* @return 调用是否成功
*/
boolean callUnity(String gameObjectName, String functionName, String args){
try {
Class<?> classtype = Class.forName("com.unity3d.player.UnityPlayer");
Method method =classtype.getMethod("UnitySendMessage", String.class, String.class, String.class);
method.invoke(classtype,gameObjectName,functionName,args);
return true;
} catch (ClassNotFoundException e) {
} catch (NoSuchMethodException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
return false;
}
/**
* Toast显示unity发送过来的内容
* @param content 消息的内容
* @return 调用是否成功
*/
public boolean showToast(String content){
Toast.makeText(getActivity(),content, Toast.LENGTH_SHORT).show();
//这里是主动调用Unity中的方法,该方法之后unity部分会讲到
callUnity("Main Camera","FromAndroid", "hello unity i'm android");
return true;
}
public void OpenWps(String str,String str2) {
try {
Document document=new Document(str);
File outputFile=new File(str2);
document.save(outputFile.getAbsolutePath(), SaveFormat.PDF);
} catch (Exception e) {
e.printStackTrace();
}
}
}
上面是测试Unity互通的方法,转PDF的方法是OpenWps,参数1是doc文档的路径,参数2是转换之后pdf的路径。
最后修改AndroidManifes.xml文件,点击上面的锤子图标打包,最终将Arr包和AndroidManifes.xml文件拷贝到Unity/Plugins/Android文件夹下
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.aabb.mylibrary">
<application>
<activity
android:name="com.aabb.mylibrary.DemoActivity"
android:theme="@style/UnityThemeSelector">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="unityplayer.UnityActivity"
android:value="true" />
</activity>
</application>
</manifest>
As那边就完工了,Unity这边准备好pdfrender插件,搭一个简单的UI,新建一个脚本叫SDKTest挂在main摄像机上
using Paroxe.PdfRenderer;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
public class SDKTest : MonoBehaviour
{
private string Downloadstr;
private AndroidJavaObject mJavaObj;
private string downPath;
private string PdfPath;
public Text showText;
public void OnClick()
{
Downloadstr = "doc下载路径,放你自己的Url下载路径";
StartCoroutine(Download(Downloadstr));
}
public void Show()
{
mJavaObj = new AndroidJavaObject("com.aabb.mylibrary.AndroidUnityDemo");
mJavaObj.Call("OpenWps", downPath, PdfPath);
}
public PDFViewer pDFViewr;
public GameObject View;
public void Check() {
if (File.Exists(PdfPath)) {
showText.text = "转换成功了";
View.gameObject.SetActive(true);
pDFViewr.LoadDocumentWithFile(PdfPath, "", 0);
}
}
public void FromAndroid(string str)
{
showText.text = str;
}
IEnumerator Download(string url)
{
string name = Path.GetFileName(Downloadstr );
string onlyname = Path.GetFileNameWithoutExtension(Downloadstr );
UnityWebRequest request = UnityWebRequest.Get(url);
request.SendWebRequest();
if (request.isHttpError || request.isNetworkError)
{
print("当前的下载发生错误" + request.error);
yield break;
}
while (!request.isDone)
{
print("当前的下载进度为:" + request.downloadProgress);
yield return 0;
}
if (request.isDone)
{
//将下载的文件写入
using (FileStream fs = new FileStream(Application.persistentDataPath + "/" + name, FileMode.Create))
{
byte[] data = request.downloadHandler.data;
fs.Write(data, 0, data.Length);
}
downPath = Application.persistentDataPath + "/" + name;
PdfPath = Application.persistentDataPath + "/" + onlyname + ".pdf";
showText.text = downPath;
}
}
}
拉一个PDFView预设进画布然后隐藏,虽然搭三个按钮和Text,分别挂载click show 和check方法,打包测试即可
先按下载按钮,然后点击转换按钮,最后点击check按钮 真机测试如图
aspose下载:https://download.csdn.net/download/pnzpb/18265820
注:如果打包报错,将arr包用winrar打开,删除libs里面的classes.jar文件即可