If you want to make the SDK developed for Android compatible with Unity apps, you need to create a plug-in to bridge the SDK and Unity apps. There are multiple ways to implement native plugins for Android, but this article will introduce a method that inherits UnityPlayerActivity. Please refer to Common for the implementation of common parts with the iOS plug-in.
BaseNativeActivity BaseNativeActivity is a class that inherits UnityPlayerActivity. It plays the role of Wrapper by calling the method of the class defined in SDK such as Sample and SampleLifecycle on behalf of it.
BaseNativeActivity
public class BaseNativeActivity extends UnityPlayerActivity {
public static final void setCallbackGameObjectName(String name) {
SampleUnityListener.getInstance().setCallbackGameObjectName(name);
}
@Override
protected void onStart() {
super.onStart();
SampleLifecycle.onStart(this);
}
@Override
protected void onResume() {
super.onResume();
SampleLifecycle.onResume(this);
}
@Override
protected void onPause() {
super.onPause();
SampleLifecycle.onPause(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
SampleLifecycle.onDestroy();
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
return super.onPrepareOptionsMenu(menu);
}
public void start(String sampleCode) {
Sample.getInstance().start(this);
}
public void doSomething() {
runOnUiThread(new Runnable() {
@Override
public void run() {
Sample.getInstance().doSomething()
}
});
}
public int getScore() {
return Sample.getInstance().getScore();
}
public String getSomeText() {
return Sample.getInstance().getSomeText();
}
public boolean isAvailable() {
return Sample.getInstance().isAvailable();
}
}
SampleUnityListener SampleUnityListener is a class to convey the callback on the SDK side to Unity side. It implements SampleListener, a listener class defined on the SDK side.
SampleUnityListener
public class SampleUnityListener implements SampleListener {
private static final Sample sample = Sample.getInstance();
private static SampleUnityListener instance;
private String callbackGameObjectName;
public synchronized static SampleUnityListener getInstance() {
if (instance == null) {
instance = new SampleUnityListener();
sample.setListener(instance);
}
return instance;
}
public final void setCallbackGameObjectName(String name) {
callbackGameObjectName = name;
}
@Override
public void onStatusChanged(SampleStatus status) {
if (callbackGameObjectName != null) {
String statusIndex = String.valueOf(status.ordinal());
UnityPlayer.UnitySendMessage(callbackGameObjectName, "_Sample_didStatusChange", statusIndex);
}
}
}
build.grade This is an example of build.gradle. In addition to the SDK itself (SampleSDK-*. Jar), classes.jar is included in the libs directory to import classes such as UnityPlayerActivity, but it is excluded because it is unnecessary at build time. Also, since it is necessary to resolve the name from the Unity side, minify is also set to false.
build.gradle
apply plugin: 'com.android.library'
android {
compileSdkVersion 26
buildToolsVersion "25.0.3"
defaultConfig {
minSdkVersion 14
targetSdkVersion 26
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:26.+'
}
android.libraryVariants.all { variant ->
variant.outputs.each { output ->
output.packageLibrary.exclude('libs/classes.jar')
output.packageLibrary.exclude('libs/SampleSDK-*.jar')
}
}
For Android Studio, you can create aar from Build-> Make Module. It's a good idea to put the built aar under Assets / Plugins / Android of the Unity project. Also, please refer to here for how to get the classes.jar used at compile time.
Sample_Android.cs Sample_Android.cs is a class that implements ISample, and by accessing the class (BaseNativeActivity) implemented on the plugin side, the Unity app and SDK We will bridge.
Sample_Android.cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
public class Sample_Android : ISample {
private Sample sampleGameObject;
private SampleEventListener listener;
private static AndroidJavaObject androidInstance;
public Sample_Android(Sample sampleParent) {
sampleGameObject = sampleParent;
InitAndroidInstance();
CreateListenerObject();
if (sampleParent.androidSampleCode != null) {
Start(null);
}
}
private void CreateListenerObject() {
listener = sampleGameObject.gameObject.AddComponent<SampleEventListener>();
using (AndroidJavaObject activityObject = GetCurrentActivity()) {
activityObject.CallStatic("setCallbackGameObjectName", sampleGameObject.gameObject.name);
}
listener.SetNativeParent(this);
}
public void Start(string sampleCode) {
using (AndroidJavaObject activityObject = GetCurrentActivity()) {
if (sampleGameObject.androidSampleCode != null) {
activityObject.Call("start", sampleGameObject.androidSampleCode);
} else if (sampleCode != null) {
activityObject.Call("start", sampleCode);
}
}
}
public void DoSomething() {
using (AndroidJavaObject activityObject = GetCurrentActivity()) {
activityObject.Call("doSomething");
}
}
public int GetScore() {
using (AndroidJavaObject activityObject = GetCurrentActivity()) {
return activityObject.Call<int>("getScore");
}
}
public SampleStatus GetStatus() {
SampleStatus status = SampleStatus.Unavailable;
using (AndroidJavaObject statusObject = androidInstance.Call<AndroidJavaObject>("getStatus")) {
string statusName = statusObject.Call<string>("name");
if (statusName.Equals("Unavailable")) {
status = SampleStatus.Unavailable;
} else if(statusName.Equals("Available")) {
status = SampleStatus.Available;
}
}
return status;
}
public string GetSomeText() {
return androidInstance.Call<string>("getSomeText");
}
public bool IsAvailable() {
using (AndroidJavaObject activityObject = GetCurrentActivity()) {
return activityObject.Call<bool>("isAvailable");
}
}
public AndroidJavaObject GetCurrentActivity() {
using (AndroidJavaClass playerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer")) {
return playerClass.GetStatic<AndroidJavaObject>("currentActivity");
}
}
protected static void InitAndroidInstance() {
using (AndroidJavaClass sampleClass = new AndroidJavaClass("com.sdk.Sample")) {
androidInstance = sampleClass.CallStatic<AndroidJavaObject>("getInstance");
}
}
}
AndroidManifest.xml This is an example of Android Manifest placed under Assets / Plugins / Android of Unity project. The above-mentioned Base Native Activity is described.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.unity3d.player"
android:installLocation="preferExternal"
android:theme="@android:style/Theme.NoTitleBar"
android:versionCode="1" android:versionName="1.0">
<supports-screens android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:xlargeScreens="true"
android:anyDensity="true" />
<application android:label="@string/app_name" android:debuggable="false">
<activity android:name="com.sample.plugin.BaseNativeActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="true" />
</activity>
</application>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>
Proguard If you want to make settings such as avoiding Minification for some classes, create proguard-user.txt and place it under Assets / Plugins / Android of Unity project, and it will be automatically exported as an Android project. It will be reflected.
proguard-user.txt (example)
-keepattributes *Annotation*
-keepattributes Signature
-keep class com.sample.sdk.** {
public <fields>;
public <methods>;
}
-keep class com.sample.plugin.** {
public <fields>;
public <methods>;
}
-dontwarn com.sample.sdk.**
Place the following under Assets / Plugins / Android of the Unity project as needed. --SDK body (jar / aar) --Plugins (jar / aar)
https://docs.unity3d.com/ja/540/Manual/PluginsForAndroid.html
Recommended Posts