最近在对接Android平台的SDK,由于工作保密原因,这里做一个Demo进行研发记录!
因为项目要求由Unity进行开发,所以需要将Android的东西做成插件导出给Unity调用,所以参考官方提供的文献:https://docs.unity3d.com/Manual/PluginsForAndroid.html ;
进行了进一步修改!
插件使用 Android Studio2.2 进行开发编写:Android Studio 有个好处,就是可以将res中的资源文件一起打包导出成aar包!
开发流程:
一、首先创建一个空项目:
二、在空工程中新建一个Module(Android Library):
三、在本地的Unity安装路径中找到classes.jar包:(可以通过搜索查找)
D:\Unity\Editor\Data\PlaybackEngines\androidplayer\Variations\mono\Development\Classes\classes.jar
四、将Unity的classes.jar包拷贝到刚才新建的 Android Library 模块下的 libs 文件夹中 : AndroidLibrary/libs/classes.jar
五、在AndroidLibrary中的build.gradle文件中添加几句代码,将Unity的classes.jar添加到依赖中,这样才可以正常使用Unity的Java类:
repositories{
flatDir{
dirs 'libs'
}
}
dependencies{
compile files(libs/classes.jar)
}
六、到这里开始就可以进行正常的Plugins插件编写了:
package com.wjt.plugins.customactivity;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Build.VERSION;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.Window;
import android.widget.Toast;
import com.unity3d.player.UnityPlayer;
public class CustomProxyActivity extends Activity
{
private final String TAG = getPackageName();
//权限申请码
private static final int READ_PHONE_STATE_REQUEST_CODE = 1;
//Android 6.0 需要动态申请某些权限 =====》下列权限还必须在AndroidManifest.xml文件中进行声明
private static final String[] DANGEROUS_PERMISSION = { "android.permission.READ_PHONE_STATE", "android.permission.READ_EXTERNAL_STORAGE", "android.permission.WRITE_EXTERNAL_STORAGE" };
protected UnityPlayer mUnityPlayer;
public void PermissionRequest()
{
Log.e(this.TAG, "申请权限!");
runOnUiThread(new Runnable()
{
public void run() {
if (Build.VERSION.SDK_INT >= 23)
if ((ActivityCompat.checkSelfPermission(CustomProxyActivity.this, "android.permission.READ_PHONE_STATE") != 0) ||
(ActivityCompat.checkSelfPermission(CustomProxyActivity.this, "android.permission.READ_EXTERNAL_STORAGE") != 0) ||
(ActivityCompat.checkSelfPermission(CustomProxyActivity.this, "android.permission.WRITE_EXTERNAL_STORAGE") != 0))
{
//申请权限
ActivityCompat.requestPermissions(CustomProxyActivity.this, CustomProxyActivity.DANGEROUS_PERMISSION, 1);
}
else {
//权限已经授予
Log.i(CustomProxyActivity.this.TAG, "权限已经授予");
Toast.makeText(CustomProxyActivity.this.getApplicationContext(), "权限已经授予!", 0).show();
}
}
});
}
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
{
if (requestCode == 1) {
if (grantResults[0] == 0)
{
//权限授予成功
Toast.makeText(getApplicationContext(), "成功获得授权!", 0).show();
Log.i(this.TAG, "成功获得授权");
} else {
Log.i(this.TAG, "未获得授权");
Toast.makeText(getApplicationContext(), "权限拒绝,准备退出,请处理后事!", 0).show();
}
}
else super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
Log.i(this.TAG, String.format("请求码 :%d , 结果码 :%d , Intent :%s", new Object[] { Integer.valueOf(requestCode), Integer.valueOf(resultCode), data.getDataString() }));
Toast.makeText(this, String.format("请求码 :%d , 结果码 :%d , Intent :%s", new Object[] { Integer.valueOf(requestCode), Integer.valueOf(resultCode), data.getDataString() }), 0).show();
}
protected void onCreate(Bundle savedInstanceState)
{
requestWindowFeature(1);
super.onCreate(savedInstanceState);
getWindow().takeSurface(null);
getWindow().setFormat(2);
this.mUnityPlayer = new UnityPlayer(this);
setContentView(this.mUnityPlayer);
this.mUnityPlayer.requestFocus();
}
protected void onDestroy()
{
this.mUnityPlayer.quit();
super.onDestroy();
}
protected void onPause()
{
super.onPause();
this.mUnityPlayer.pause();
}
protected void onResume()
{
super.onResume();
this.mUnityPlayer.resume();
}
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
this.mUnityPlayer.configurationChanged(newConfig);
}
public void onWindowFocusChanged(boolean hasFocus)
{
super.onWindowFocusChanged(hasFocus);
this.mUnityPlayer.windowFocusChanged(hasFocus);
}
public boolean dispatchKeyEvent(KeyEvent event)
{
if (event.getAction() == 2)
return this.mUnityPlayer.injectEvent(event);
return super.dispatchKeyEvent(event);
}
public boolean onKeyUp(int keyCode, KeyEvent event)
{
return this.mUnityPlayer.injectEvent(event);
}
public boolean onKeyDown(int keyCode, KeyEvent event)
{
return this.mUnityPlayer.injectEvent(event);
}
public boolean onTouchEvent(MotionEvent event)
{
return this.mUnityPlayer.injectEvent(event);
}
public boolean onGenericMotionEvent(MotionEvent event)
{
return this.mUnityPlayer.injectEvent(event);
}
}
//创建res资源
package com.wjt.plugins.customactivity;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;
import com.wjt.plugins.R.id;
import com.wjt.plugins.R.layout;
public class onStartActivity extends Activity
{
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main_onstartactivity);
findViewById(R.id.button).setOnClickListener(new View.OnClickListener()
{
public void onClick(View view) {
Toast.makeText(onStartActivity.this, "onStartActivity is ready start!", 0).show();
}
});
}
}
编写好AndroidPlugins后 Rebuilt Project ,完成后就可以在当前AndroidLibrary模块下的 build文件中找到导出的aar包了:AndroidLibrary\build\outputs\aar\***.aar
七、使用:将导出的*.aar包拷贝到Unity项目中的Assets\Plugins\Android\ 目录下,然后用zip压缩工具打开aar包,将libs\文件夹下的classes.jar包文件删除掉,否则在打包Unity项目的时候会报错!
八、为Unity项目配置AndroidManifest.xml文件:
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.wjt.plugins"
android:installLocation="preferExternal" android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:versionCode="1" android:versionName="1.0" >
android:minSdkVersion="15"
android:targetSdkVersion="24" />
android:name="android.permission.ACCESS_NETWORK_STATE"/>
android:name="android.permission.INTERNET"/>
android:name="android.permission.READ_PHONE_STATE"/>
android:name="android.permission.GET_TASKS"/>
android:name="android.permission.ACCESS_WIFI_STATE"/>
android:name="android.permission.GET_ACCOUNTS"/>
android:name="android.permission.CALL_PHONE"/>
android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
android:name="android.permission.WRITE_SETTINGS"/>
android:name="android.permission.READ_EXTERNAL_STORAGE"/>
android:name="android.permission.READ_LOGS"/>
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:xlargeScreens="true"
android:anyDensity="true"/>
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true">
android:name="com.wjt.plugins.customactivity.CustomProxyActivity">
android:name="android.intent.action.MAIN"/>
android:name="android.intent.category.LAUNCHER"/>
android:name="unityplayer.UnityActivity"
android:value="true" />
android:name="unityplayer.ForwardNativeEventsToDalvik"
android:value="false" />
android:name="com.wjt.plugins.customactivity.onStartActivity" android:screenOrientation="landscape"/>
九、在Unity中进行调用: