You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity 5.6 Android插件onActivityResult未触发及选图Gallery意外启动求助

解决Unity 5.6 Android插件图片选择onActivityResult未触发+意外打开Gallery问题

嘿,这个问题我之前适配Unity老版本插件时也踩过坑,主要是Unity的Activity上下文和系统跳转的适配逻辑没理清楚,咱们一步步来搞定:

问题根源分析

  1. 意外打开Gallery:大概率是你创建图片选择的Intent参数不对——要么没限定图片类型,要么Action选得不合适,导致系统直接唤起了Gallery而非通用图片选择器。
  2. onActivityResult未调用:默认的UnityPlayerActivity不会把Activity跳转的结果转发给你的插件类,必须自定义Activity接管这个逻辑,而且必须用Unity的宿主上下文启动跳转。

具体解决方案

1. 修正图片选择插件类(fotoSec.java)

确保用UnityPlayer.currentActivity作为上下文,同时配置正确的Intent参数:

package com.alptugrul.background;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.provider.MediaStore;
import android.widget.Toast;
import com.unity3d.player.UnityPlayer;

public class fotoSec {
    // 定义唯一的请求码,避免和其他插件冲突
    private static final int PICK_IMAGE_REQUEST = 1001;
    // 保存Unity端的回调信息
    private static String callbackGameObj;
    private static String callbackMethodName;

    // 供Unity调用的图片选择入口
    public static void openImagePicker(String gameObjectName, String methodName) {
        callbackGameObj = gameObjectName;
        callbackMethodName = methodName;
        Activity hostActivity = UnityPlayer.currentActivity;

        // 配置正确的图片选择Intent:用ACTION_PICK唤起系统图片选择器
        Intent pickIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        pickIntent.setType("image/*"); // 限定只选择图片类型

        // 必须通过Unity的宿主Activity启动跳转
        hostActivity.startActivityForResult(pickIntent, PICK_IMAGE_REQUEST);
    }

    // 处理Activity返回结果的方法,由自定义UnityActivity调用
    public static void handleResult(int requestCode, int resultCode, Intent data) {
        if (requestCode != PICK_IMAGE_REQUEST) return;

        if (resultCode == Activity.RESULT_OK && data != null) {
            Uri imageUri = data.getData();
            if (imageUri != null) {
                // 将图片Uri传递回Unity的回调方法
                UnityPlayer.UnitySendMessage(callbackGameObj, callbackMethodName, imageUri.toString());
            } else {
                Toast.makeText(UnityPlayer.currentActivity, "未选中有效图片", Toast.LENGTH_SHORT).show();
            }
        } else {
            Toast.makeText(UnityPlayer.currentActivity, "已取消选择", Toast.LENGTH_SHORT).show();
        }
    }
}

2. 自定义UnityPlayerActivity接管结果

默认的UnityPlayerActivity不会转发onActivityResult,所以要创建子类:

package com.alptugrul.background;

import android.content.Intent;
import com.unity3d.player.UnityPlayerActivity;

public class CustomUnityActivity extends UnityPlayerActivity {
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        // 将结果转发给插件类处理
        fotoSec.handleResult(requestCode, resultCode, data);
    }
}

3. 修改AndroidManifest.xml配置

把默认的启动Activity换成咱们自定义的:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.alptugrul.background">
    <application android:icon="@drawable/app_icon" android:label="@string/app_name">
        <activity android:name=".CustomUnityActivity"
                  android:label="@string/app_name"
                  android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen"
                  android:launchMode="singleTask">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
        </activity>
    </application>
    <!-- Android 6.0+需要动态申请权限,这里先声明 -->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
</manifest>

4. Unity端调用示例(C#)

在Unity里写个脚本调用插件,并接收回调:

using UnityEngine;

public class ImagePickerHandler : MonoBehaviour
{
    public void TriggerImagePicker()
    {
        // 调用Android插件的静态方法,传入当前GameObject和回调方法名
        AndroidJavaClass pickerClass = new AndroidJavaClass("com.alptugrul.background.fotoSec");
        pickerClass.CallStatic("openImagePicker", gameObject.name, "OnImagePicked");
    }

    // 接收插件返回的图片Uri
    public void OnImagePicked(string imageUri)
    {
        Debug.Log("选中图片的Uri:" + imageUri);
        // 这里可以添加图片加载逻辑,比如将Uri转为Texture2D
    }
}

额外注意事项

  • 权限问题:Android 6.0及以上需要动态申请READ_EXTERNAL_STORAGE权限,你可以在Unity里用Permission.RequestUserPermission方法申请,或者在插件里处理。
  • 请求码唯一性:确保PICK_IMAGE_REQUEST的数值和其他插件的请求码不重复,避免结果处理混乱。
  • 打包配置:把编译好的插件jar/aar和修改后的Manifest放到Unity项目的Plugins/Android目录下,确保Unity打包时能正确识别。

内容的提问来源于stack exchange,提问作者alp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:47:59