前言
项目要解决的问题:
unity访问安卓相册获取图片或视频,且该activity不能继承UnityPlayerActivity(避免与其他包起冲突)
解决方式:在C#中获取UnityPlayerActivity类,并且将其作为参数传入方法。
参考:Unity添加多个安卓SDK解决冲突(https://blog.csdn.net/weixin_30572613/article/details/96530111)若没有以上问题,完全可以参考一下两篇:
但是以下两篇还是略微麻烦,提到了很多不必要的操作,可以取其实现思想,总而言之,本篇所利用的思想既解决了unity中多个安卓sdk冲突的问题,又实现了标题中的功能。
参考:Unity调用android相册获取图片或视频
【Unity】调用安卓相机及相册
一、创建AndroidStudio工程
1、创建空工程
2、创建新模块Module
3、在该Module下创建Activity
4、导入unity class.jar
Unity jar包位置:
Unity\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes
参考:
Unity与百度语音丨(三)AndroidStudio aar包的编写
Unity 实战项目 ☀️| 接入科大讯飞语音SDK(二)在Android Studio该如何操作! 系列共两万多字超级新手教程!
5、编写Java调用代码
(1)CallAndroid.java 主类
package com.example.takevideos; //你的包名
import android.app.Activity;
import android.content.Intent;
import com.unity3d.player.UnityPlayer;
public class CallAndroid {
//Unity中会调用这个方法,用于打开本地相册
//str 为unity传过来的路径
public void TakePhoto(String str)//我们不需要unity传它的上下文 可以直接通过UnityPlayer.currentActivity获取Unity的界面(Activity)
{
System.out.println("路径:"+str);
Intent intent = new Intent(UnityPlayer.currentActivity,WebViewActivity.class);//WebViewActivity为需要跳转的界面(Activity) //记得回来修改这里WebViewActivity改为权限的Activity我这里是TestActivity
//intent.putExtra("path", str);//传给跳转的Activity 参数一是键 参数二是值
UnityPlayer.currentActivity.startActivity(intent);//跳转到另一个界面(Activity)
}
}
(2)WebViewActivity.java 访问相册里面的视频类
package com.example.takevideos; //你的包名
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import com.unity3d.player.UnityPlayer;
import java.io.IOException;
//import android.view.KeyEvent;
public class WebViewActivity extends Activity
{
public static final int NONE = 0;
public static final int PHOTORESOULT = 3;
public static final String IMAGE_UNSPECIFIED = "video/*";//image"*/;//划重点,这里指定视频或图片
private String LOG_TAG = "LOG_ZDQ";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = new Intent(Intent.ACTION_PICK, null);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, IMAGE_UNSPECIFIED);
startActivityForResult(intent, PHOTORESOULT);
Log.d(LOG_TAG, "打开相册!");
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
requestCode是我们在上方startActivityForResult的参数2(这里没起作用) resultCode是上一个Activity也就是选择图片的那个Activty(页面)的结果
Log.d(LOG_TAG, "resultCode :" + resultCode);
if (resultCode == NONE)
{
if (data == null)
{
this.finish();
UnityPlayer.UnitySendMessage("InputURL","GetPhoto","");
}else
{
if(this.isFinishing() == false)
{
this.finish();
}
UnityPlayer.UnitySendMessage("InputURL","GetPhoto","");
}
return;
}
if (data == null)
{
this.finish();
UnityPlayer.UnitySendMessage("InputURL","GetPhoto","");
}
ContentResolver resolver = getContentResolver();
Bitmap bm=null;
Uri originalUri = data.getData();
try {
bm = MediaStore.Images.Media.getBitmap(resolver, originalUri);
} catch (IOException e) {
e.printStackTrace();
}
String[] proj = {MediaStore.Images.Media.DATA};
Cursor cursor= getContentResolver().query(originalUri,proj,null,null,null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
String _path = cursor.getString(column_index);
UnityPlayer.UnitySendMessage("InputURL", "GetPhoto", _path);
super.onActivityResult(requestCode, resultCode, data);
this.finish();
}
}
(3)AndroidManifest.xml
//在原有的基础上添加
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application >
<activity android:name=".WebViewActivity" />
</application>
6、build生成arr包
(1)更新MainActivity.java
将该class下的方法删除
(2)导出arr包
(3)修改arr包
参考:Unity与百度语音丨(三)AndroidStudio aar包的编写
二、unity导入arr包
1、导入路径
Assets/Plugins/Android/
2、创建物体(消息传递的媒介,因为前面WebViewActivity.java我们安卓跟unity发信息指定的是名称的InputURL物体.)
UnityPlayer.UnitySendMessage("InputURL", "GetPhoto", _path);
3、InputURL物体上挂载的代码
//用Button事件监听该函数执行
public void OpenLibery()
{
Permission.RequestUserPermission(Permission.ExternalStorageRead);
Permission.RequestUserPermission(Permission.ExternalStorageWrite);
//AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
//AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
//jo.Call("TakePhoto", Application.persistentDataPath);
using (AndroidJavaObject javaobj = new AndroidJavaObject("com.example.takevideos.CallAndroid"))
{
javaobj.Call("TakePhoto", Application.persistentDataPath);
}
}
//Java获取path传递给unity
public void GetPhoto(string path)
{
debugtext.text += path;
Debug.Log("android give path ==> " + path);
//
}
4、此方法下的arr包的导入不用考虑unity中的AndroidManifest.xml文件activity合并问题。
三、此方法已在真机上测试并实用,若有其他问题,欢迎留言探讨,一起进步!!!
站在巨人的肩膀上!!!
ADB⭐️教你怎样测试 Unity App
【Unity】调用安卓相机及相册
Unity与安卓交互(打开安卓手机相册为例)
Android中Activity的启动模式(LaunchMode)和使用场景