Unity与Android交互(三):Android App调用Unity打包的AAR文件

开发环境:Android Studio 2.3.3 , Unity 2017.1.2

我们打开在第一篇文章中建立的 Android App 项目,新建一个模块,并导入第二篇文章中打包的 AAR 文件:File > New Module > Import .JAR/.ARR Package ,选择第二篇文章中打包的 testunity-debug.aar 文件。

之后右键点击 Project 面板中的 app 文件夹,选择 Open Module Settings 的 Dependencies 选项卡,添加 :testunity-debug 模块,如果会发生错误,我们先确保修改 build.gradle (Module: app) 文件中的 minSdkVersion 为与 Unity 中一致的 API 版本。

添加Unity的AAR后报错

添加Unity的AAR后报错

修改minSdkVersion与Unity中一致

修改minSdkVersion与Unity中一致

API 版本修改完成后,这里还有一个 Icon 和 Theme 相关的报错:

Icon和Theme的报错

Icon和Theme的报错

我们打开 App 的 AndroidManifest.xml 文件,告诉 merge 合并程序使用哪一个 Icon 和 Theme ,分别在  manifest 标签和 application 标签下添加代码:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.test.androidapp">
    <application
        tools:replace="android:icon,android:theme"
        ...
        android:theme="@style/AppTheme">
        ...
    </application>
</manifest>
manifest和application标签下添加代码

manifest和application标签下添加代码

保存,点击: Sync Project with Gradle Files ,Gradle 会对当前程序进行编译,这个时候就会成功编译了。

接下来我们像第一篇文章一样,开始调用 Unity 的 Activity ,我们在 MainActicity 中先引用导出的 AAR 包的 Unity 的 Activity:

import com.test.testunity.UnityPlayerActivity;

在 Button 的 click 事件中调用显示 Unity 的 Activity :

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent intent = new Intent(MainActivity.this, UnityPlayerActivity.class);
        startActivity(intent);
    }
});

到这里,我们就完成了在 Android App 中调用并显示 Unity 程序的所有步骤。

注意:我们这里并没有在 Unity 中添加返回键事件,所以你点击手机的返回键时不会有任何反应,如果你使用 Application.Quit(); 你会发现会把整个 Android App 也关掉,这一部分的处理可以参考网上的其他文章。

如果在文中发现了 BUG ,或发现某些地方写的不够清楚,欢迎在评论中告诉我,我会完善。

项目Git地址:https://gitee.com/trlanfeng/UnityAndroid/

Unity与Android交互(二):Unity项目打包为AAR供Android App调用

开发环境:Android Studio 2.3.3 , Unity 2017.1.2

这一篇我们讲如何将 Unity 程序打包为 AAR 文件,使 Android App 可以调用。

在 Unity 5.x 时, Unity 的 Build System 中就加入了使用 Gradle 方式输出项目。

Unity中使用Gradle输出

Unity中使用Gradle输出

当使用 Gradle 方式时,就只有 Export 按钮了,而不是 Build 和 Build And Run 了。

导出之前,要记得更改 Bundle Identifier , Export 项目之后,使用 Android Studio 打开这个项目,File > New > Import project > 选择你刚才导出的目录,并点击 OK 。之后会提示你 Gradle 尚未配置,是否自动配置,点击 OK 会自动配置,点击 Cancel 需要你之后手动配置。

Unity导出Gradle打开后的提示

Unity导出Gradle打开后的提示

我们这里使用自动配置,之后 Android Studio 会运行 Gradle 进行编译,这里可能会报错:

Gradle自动配置时的报错信息

Gradle自动配置时的报错信息

我们打开 Project 面板,双击打开 Gradle Scripts 中的 build.gradle ,修改 Gradle 插件版本到 2.3.3 ,和 Android Studio 版本保持一致。

修改Gradle插件版本

修改Gradle插件版本

修改之后,点击工具栏中的 Sync Project with Gradle Files , Gradle 会重新编译,并且编译通过,不会再遇到问题。

Sync Project with Gradle Files

Sync Project with Gradle Files

打开 Project 面板中的 manifests 文件夹中的 AndroidManifest.xml 文件,注释掉 intent-filter 标签:

注释intent-filter

注释intent-filter

现在,我们继续修改 build.gradle 文件中的内容:

修改Gradle编译方式

修改Gradle编译方式

将编译方式改为 com.android.library ,并注释掉 applicationId ,项目才能被打包成 AAR 。点击菜单栏 Build > Make Project ,Android Studio 会将项目打包成 AAR 文件,并放入 build/outputs/aar 文件夹中。

至此,我们就完成了 Unity 工程打包为 AAR 的所有步骤。

注意,这里 Android Studio 和 Gradle 插件必须是 2.3.3 版本,最新的 Android Studio 3.0.1 使用时会遇到错误,包括导入 AAR 时会提示 AAR 文件过大等错误。由于我不是 Android 开发人员,不知如何解决。

如果在文中发现了 BUG ,或发现某些地方写的不够清楚,欢迎在评论中告诉我,我会完善。

项目Git地址:https://gitee.com/trlanfeng/UnityAndroid/

Unity与Android交互(一):在Android App中加载Android Library中的Activity

开发环境:Android Studio 2.3.3

这篇文章是作为Unity与Android交互系列的第一篇,只讲解如何在Android App中加载一个Android Library中的Activity,并传递参数。在这之前,你需要了解Android Application开发基础。网上有很多入门的Android开发教程。

我们先新建一个Android App工程,命名为AndroidApp,使用Empty Activity作为主Activity。

在菜单栏中点击 File > New > New Module ,在弹出的对话框中选择 Android Library,并命名为AndroidLib,在 Android Studio 左侧的 Project 面板中,右键点击 androidlib ,并选择 New > Activity > Empty Activity ,将新建的 Activity 命名为 LibActivity 以作区分。

我们将 LibActivity 中的 TextView 的 id 改为 lib_textview , text 改为“这是Android Library的Activity”并添加一个 id 为 lib_button 的按钮, text 改为“关闭并传回参数:456”。

在 Project 面板中,右键点击 app ,打开 Open Module Settings ,并在 Dependencies 选项卡中,点击右边的加号,选择 :androidlib ,之后点击 OK 。这时便可以从 App 中调用 Library 中的 Activity 了。

在 MainActivity 添加按钮的 click 事件,用于打开 Android Library 中的 Activity ,在 OnCreate 中加入如下代码:

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent intent = new Intent(MainActivity.this,com.test.androidlib.LibActivity.class);
        String message = "123";
        intent.putExtra("com.test.androidapp.message",message);
        startActivityForResult(intent,1);
    }
});

上面的代码用于启动 Android Library 中的 LibActivity 并传递了参数 123 ,参数名为 com.test.androidapp.message (官方推荐参数名前加包名以示区分),值为 123 。

我们需要在 MainActivity 中接收由 LibActivity 返回的数据,在类中加入如下代码:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    TextView main_textview = (TextView) findViewById(R.id.main_textview);
    main_textview.setText(data.getStringExtra("com.test.androidlib.message"));
}

之后在 LibActivity 中接收传递的参数并显示在 TextView 中,并为关闭按钮添加事件并回传参数 456 :

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_lib);

    Intent intent = getIntent();
    String message = intent.getStringExtra("com.test.androidapp.message");
    TextView lib_textview = (TextView) findViewById(R.id.lib_textview);
    lib_textview.setText(message);

    Button button = (Button) findViewById(R.id.lib_button);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent();
            String message = "456";
            intent.putExtra("com.test.androidlib.message",message);
            setResult(1,intent);
            finish();
        }
    });
}

至此我们就完成在 Android App 中加载一个 Android Library 中的 Activity ,并进行参数传递。目前我们是在 App 项目中新建了一个 Android Library ,我们也可以将 Android Library 导出为 aar 包,并通过 New Module > Import .JAR/.AAR Package 来加入到项目中。

如果在文中发现了 BUG ,或发现某些地方写的不够清楚,欢迎在评论中告诉我,我会完善。

项目Git地址:https://gitee.com/trlanfeng/UnityAndroid/

axios使用x-www-form-urlencoded方式传递参数无法接收的问题

之前的项目中,一直使用的jQuery来请求ajax数据。直到使用Vue框架,才开始使用axios这个库,作为一个官方推荐的库,觉得它应该有过人之处。

可是在刚开始使用中就遇到了一个问题:axios提交的数据,后台接收不到。

之前使用jQuery时,并没有问题,也从没有注意过Request Headers里的内容,这次遇到这个问题时,才开始注意到Request Headers里面的内容。

这个问题在于,jQuery请求数据时,传入JSON对象类型的参数,jQuery会自动转成querystring形式的,但axios并不会转成querystring类型,而是序列化成json字符串进行传递,所以axios请求时使用默认方式传递参数的话,服务端不做处理的话取不到数据。

JSON对象转为querystring有三种方法:

1.浏览器中

var params = new URLSearchParams();
params.append('param1', 'value1');
params.append('param2', 'value2');
axios.post('/foo', params);
2.浏览器中
var qs = require('qs');
axios.post('/foo', qs.stringify({ 'bar': 123 }));
3.nodejs中
var querystring = require('querystring');
axios.post('http://something.com/', querystring.stringify({ foo: 'bar' }));

【PHP】将数据导出为可以用Excel打开的一个CSV文件

在一些小型项目中,后台页面或许并不会有太多的功能。但是统计基本是所有客户必不可少的需求之一,虽然我们可以通过各种JS来实现图标效果,但个人觉得导出Excel是更加合适的方式,而最方便导出的格式莫过于CSV了。

CSV是很简单的文本格式,通过逗号 ,换行 \r\n 进行分隔,而且可以通过Excel打开,也可以很方便的转换为Excel格式。

$csv = fopen('user.csv','w');
$text = "昵称,性别,年龄\n";
foreach ($data['user'] as $row) {
    $nt = $row['name'].','.$row['sex'].','.$row['age']."\n";
    $text .= $nt;
}
//$text = utf8_encode($text);
$text = iconv('UTF-8','GBK',$text);
//echo $text;
fwrite($csv,$text);
fclose($csv);

在最开始导出CSV文件时,发现Excel打开后显示乱码,后得知必须转成GBK才能正常显示中文,所以就有了iconv转换编码类型的一行。之后保存在本地后,供用户下载。