AndroidStudio学习笔记

Tips:以下是为了给Unity用的

构建aar

过程

准备工作

首先创建一个AndroidStudio工程,再新建一个模块,模块的名字无所谓,遵循.com.xxx.xxx就可以 
以Unity2021.3.6自带的gradle插件版本4.0.1 gradle版本6.1.1举例子
AndroidStudio版本是2021.3.1
然后在AndroidStudio中File-->Project Structure-->Project中
修改Gradle Plugin Version 和Gradle Version
修改成和Unity中的一样  你也可以用别的Gradle版本(下面有插件版本和版本对应关系的官方链接)
如果你不想用Unity自己的Gradle版本  请到后面找修改方法
然后你就可以开始写代码了

点这里看AS官方Gradle版本对应关系

开始写代码

首先,如果你不需要UnityPlayer库(2021.3.6f1c1\Editor\Data\PlaybackEngines\AndroidPlayer
\Variations\il2cpp\Release\Classes\classes.jar),或者说你不需要通知Unity那就不用导入
如果需要那就把这个jar包复制粘贴到刚新建的模块的libs目录下,
然后点右键Add as library,这是为了添加依赖
让你的代码能够识别到这个库,然后就可以开始写代码了
这里举一个例子:打开图库选择图片并返回图片路径和剪切板
Tips:UnityPlayer.currentActivity是Unity当前的活动窗口,跳转活动窗口必须这样跳,还有Activity之间传参数
	  需要注意的是自己写的Activity千万不要继承UnityPlayerActivity
	  因为在调用finish的时候会直接调用到UnityPlayerActivity的OnDestroy,结果就是应用退出
	  单纯的继承Activity就可以了
	  Gradle其实是Groovy语言,不同版本的Gradle语法是不一样的,看着报错改就可以
	  重要的:自己写的Activity需要在Unity的AndroidManifest里面声明这个Activity
	         写法:在Application标签下添加一个Activity标签
	         <activity android:name="com.xxx.xxx.xxxActivity"></activity>
Intent intent = new Intent(context, xxxActivity.class);
context.startActivity(intent);

Activity之间传递参数参考这里

这个是MainActivity

// 这里改自己的包名
package com.xxx.xxx;

import com.unity3d.player.UnityPlayer;

public class MainActivity {
    public static void OpenPic(){
        WebViewActivity.launch(UnityPlayer.currentActivity);
    }
    public static void CopyTextToClipboard(String str) throws Exception {
        ClipboardHelper.copyTextToClipboard(UnityPlayer.currentActivity, str);
    }
}

这个是图库的Activity

// 这里改自己的包名
package com.xxx.xxx;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
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;


public class WebViewActivity extends Activity {
    public static final String IMAGE_UNSPECIFIED = "image/*";
    private static final int PICK_IMAGE_REQUEST_CODE = 1;

    @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, PICK_IMAGE_REQUEST_CODE);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == PICK_IMAGE_REQUEST_CODE) {
            if (resultCode == RESULT_OK) {
                Uri uri = data.getData();
                String path = getImagePath(uri);
                // 如果选择了图片  就返回图片路径
                // 第一个参数是接收消息的GameObject的name
                // 第二个参数是GameObject身上挂载的脚本里的方法
                // 第三个参数是方法的参数(只能是字符串)
                UnityPlayer.UnitySendMessage("SDKManager", "GetPhoto", path);
            } else if (resultCode == RESULT_CANCELED) {
            	// 没有选择直接退出就返回空字符串
                UnityPlayer.UnitySendMessage("SDKManager", "GetPhoto", "");
            }
        }
        finish();
    }

    private String getImagePath(Uri uri)
    {
        if(null == uri) return null;
        String path = null;
        final String scheme = uri.getScheme();
        if (null == scheme) {
            path = uri.getPath();
        } else if (ContentResolver.SCHEME_FILE.equals(scheme)) {
            path = uri.getPath();
        } else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) {
            String[] proj = { MediaStore.Images.Media.DATA };
            Cursor cursor = getContentResolver().query(uri, proj, null, null,
                    null);
            int nPhotoColumn = cursor
                    .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            if (null != cursor) {
                cursor.moveToFirst();
                path = cursor.getString(nPhotoColumn);
            }
            cursor.close();
        }
        return path;
    }

    public static void launch(Context context){
        Intent intent = new Intent(context, WebViewActivity.class);
        context.startActivity(intent);
    }
}

这个是调用剪切板

// 这里改自己的包名
package com.xxx.xxx;

import android.app.Activity;
import android.content.ClipData;
import android.content.ClipDescription;
import android.content.ClipboardManager;
import android.content.Context;
import android.util.Log;

public class ClipboardHelper {
    public static ClipboardManager clipboard = null;
    public static void copyTextToClipboard(Context activity, String str) throws Exception {
        clipboard = (ClipboardManager) activity.getSystemService(Activity.CLIPBOARD_SERVICE);
        ClipData clipData = ClipData.newPlainText("data", str);
        clipboard.setPrimaryClip(clipData);
    }

    public static String getTextFromClipboard() {
        if (clipboard != null && clipboard.hasPrimaryClip() && clipboard.getPrimaryClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {
            ClipData cdText = clipboard.getPrimaryClip();
            ClipData.Item item = cdText.getItemAt(0);
            return item.getText().toString();
        } else {
            return "";
        }
    }
}

这里贴上模块的AndroidManifest.xml和build.gradle

<?xml version="1.0" encoding="utf-8"?>
																	<!-- 改成自己的包名 -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.xxx.xxx">
    <!-- 读写权限 -->
    <uses-permission android:name="android.permission.READ_INTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <application>
    							<!-- 改成自己的包名 -->
        <activity android:name="com.xxx.xxx.WebViewActivity"/>
    </application>
</manifest>
plugins {
    // 这里一定是com.android.library
    id 'com.android.library'
}

android {
    compileSdkVersion 32

    defaultConfig {
        minSdkVersion 22
        targetSdkVersion 32

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        consumerProguardFiles "consumer-rules.pro"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {
    implementation 'androidx.appcompat:appcompat:1.4.1'
    implementation 'com.google.android.material:material:1.5.0'
    implementation files('libs\\unitylib.jar')
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}

这个是项目的build.gradle

buildscript {
    repositories {
        google()
        jcenter()
        mavenCentral()
    }
    dependencies {
        // 这里是修改gradle插件版本的地方
        classpath 'com.android.tools.build:gradle:4.0.1'
    }
}
allprojects {
    repositories {
        google()
        jcenter()

    }
}
task clean(type: Delete) {
    delete rootProject.buildDir
}

打aar包,这里很重要

可以打包了,先点击一下模块文件夹,再点工具栏的Build/Make Moudle '项目名称.模块名称'
打包出来之后到当前模块的目录下找到build/outputs/aar这里放着的就是打出来的aar包
接着我们需要对aar包进行处理,用压缩工具打开它,它里面有个libs文件夹,
把libs文件夹里的Unity里复制粘贴过来的jar包删掉(因为Unity打包的时候会自己带着这个jar包)
然后返回上级目录打开jar包,把BuildConfig.java文件删除掉(因为Unity打包的时候会自己生成)
然后应用修改,关闭,然后就可以把它放到Unity里面了,路径是Plugins/Android/
Tips:再说一遍AS的Gradle插件版本和Gradle版本和Unity的Gradle插件版本和Gradle版本一定要对应上

这里是Unity中修改Gradle插件版本和Gradle版本

Unity中
Edit-->Preferences-->External Tools可以修改Gradle版本
Edit-->Project Settings-->Player-->Publishing Settings-->Build 勾选Custom Base Gradle Template
勾选后会在Assets/Plugin/Android路径下生成baseProjectTemplate.gradle文件
这个相当于是AS项目的项目build.gradle可以修改Gradle插件版本
Custom Main Manifest会生成AndroidManifest文件,
在这里面可以声明权限,声明Activity
最后贴一个Unity打包生成的Gradle项目的路径UnityProject\Library\Bee\Android\Prj\IL2CPP\Gradle
如果说打包的时候有Gradle构建的报错,到这里看Gradle为什么报错

然后在Unity中调用这个aar包

private const string NoPath = "NoPath";
private AndroidJavaObject _mainActivity;
private string _path = NoPath;

/// <summary>
/// 获取图片地址调用这个
/// </summary>
/// <param name="onSelect"></param>
public void OpenPic(Action<PicPathResult, string> onSelect)
{
    try
    {
        if (_mainActivity == null)
        {
            _mainActivity = new AndroidJavaObject("com.xxx.xxx.MainActivity");
        }
        _mainActivity.CallStatic("OpenPic");
        StartCoroutine(WaitForPath(onSelect));
    }
    catch (System.Exception ex)
    {
        onSelect.Invoke(PicPathResult.Failed, string.Empty);
    }
}

public void CopyText(string format, params object[] args)
{
    string result = string.Format(format, args);
    _mainActivity.CallStatic("CopyTextToClipboard", result);
}

private IEnumerator WaitForPath(Action<PicPathResult, string> onSelect)
{
    while (string.Equals(_path, NoPath))
    {
        yield return null;
    }
    if (string.IsNullOrEmpty(_path))
    {
        onSelect?.Invoke(PicPathResult.Failed, string.Empty);
    }
    else
    {
        onSelect?.Invoke(PicPathResult.Success, _path);
    }
    _path = NoPath;
}
/// <summary>
/// 不许删
/// </summary>
/// <param name="path"></param>
public void GetPhoto(string path)
{
    _path = path;
}
public enum PicPathResult{
	Success, Failed
}

结束语:写完下班啦

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值