UE and Android call each other

Intermodulation between ue and android

Both methods are performed on top of the Android project packaged by UE.

1. First, UE packages Android, check the following item

If there are multiple scenes, you need to add scenes

The project file is in this path

Then you can open it through Android Studio and select gradle to open

Run it first to see if you can publish to an Android device before proceeding.

2. Create a new MainActivity to start UE

MainActivity should inherit Activity. The test.android package name is the package name when UE releases android.

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MainActivity.this, GameActivity.class);
                startActivity(intent);
            }
        });
    }
}

Then start the Activity in the Manifest and cancel the automatically generated GameActivity as the started Activity.

        <activity android:name="com.test.android.MainActivity"
>
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

There is only one button on this page, which is used to jump to UE.

<?xml version="1.0" encoding="utf-8"?>
<android.widget.RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.test.android.MainActivity">


    <Button
        android:id="@+id/button"
        android:layout_width="177dp"
        android:layout_height="155dp"
        android:text="Button"
        tools:layout_editor_absoluteX="172dp"
        tools:layout_editor_absoluteY="351dp" />
</android.widget.RelativeLayout>

Then you can test it. The startup project should be to start your new Activity. Click the button to jump to the UE interface.

3. Click the button of the custom widget in UE to open the Android page. The two on the right are useless and should not be ignored.

1. This is our new c++ class

head File

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "Components/Button.h"
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "DemoUserWidget.generated.h"

/**
 * 
 */
UCLASS()
class DEMOANDROID_API UDemoUserWidget : public UUserWidget
{
	GENERATED_BODY()


protected:
	virtual void NativeConstruct() override;
public:
	UPROPERTY(meta = (BindWidget))
	class UButton* ButtonUEJump;
	UPROPERTY(meta = (BindWidget))
	class UButton* ButtonHaerbin;
	UPROPERTY(meta =  (BindWidget))
	class UButton* ButtonBeijing;
	UFUNCTION()
	void ButtonUEJumpClick();
	UFUNCTION()
	void ButtonHaerbinClick();
	UFUNCTION()
	void ButtonBeijingClick();
};

 cpp file, ButtonHaerbinClick is the callback method when we click the widget button. toAndroidActivity is a java method defined in GameActivity, (Ljava/lang/String;) V. It should be noted that a semicolon must be added after the parameter. V means no return value. CallVoidMethod is to call a method with no return value in java, and str is the parameter to be passed.

void UDemoUserWidget::ButtonHaerbinClick()
{
	
	GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("haerbin")));

#if PLATFORM_ANDROID
    if (JNIEnv* Env = FAndroidApplication::GetJavaEnv())
    {
        bool bIsOptional = false;
        static jmethodID toAndroidActivity = FJavaWrapper::FindMethod(Env, FJavaWrapper::GameActivityClassID, "toAndroidActivity", "(Ljava/lang/String;)V", bIsOptional);


        char tt[30] = {"--------a--"};
        jstring str = Env->NewStringUTF((const char*)tt);
        FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, toAndroidActivity, str);
        UE_LOG(LogTemp, Warning, TEXT("jmethodID is vaild :AndroidThunkJava_GetMessage "));

    }
#endif//PALTFORM_ANDROOT
}

2. To create a Widget in UE, you need to inherit the c++ code we wrote before.

The name of the button must be consistent with the name of the c++ header file, because we are using binding.

 

3. Create two new methods in Android's GameActivty to open the Android interface in the form of a dialog box. 

public void toAndroidActivity(String placeName) {

		runOnUiThread(new Runnable() {
			@Override
			public void run() {
				showLimit(GameActivity.this);
			}
		});
	}
public  void showLimit(Context context) {
		final Dialog baseDialog = new Dialog(context);
		View view = LayoutInflater.from(context).inflate(R.layout.view_pop_custom, null);
		TextView tv_next = view.findViewById(R.id.tv_next);
		baseDialog.show();
		baseDialog.setCanceledOnTouchOutside(false);
		Window window = baseDialog.getWindow();
		WindowManager.LayoutParams attributes = window.getAttributes();
		attributes.width = 600;
		window.setAttributes(attributes);
		tv_next.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				Log.debug("tv_next.setOnClickListener");
				baseDialog.dismiss();
				toNewUEPlace();
			}
		});
		window.setContentView(view);
	}

4. Click the button on the pop-up Android interface to switch the scene in ue

1. Define a method public native void toNewUEPlace() in the GameActivity class;

2. In DemoUserWidget.cpp in UE

#include "Kismet/GameplayStatics.h"

#if PLATFORM_ANDROID
#include "Runtime/Launch/Public/Android/AndroidJNI.h"
#include "Runtime/ApplicationCore/Public/Android/AndroidApplication.h"
#include "Android/AndroidJavaEnv.h"
#endif//PLATFORM_ANDROID

#if PLATFORM_ANDROID
JNI_METHOD void Java_com_epicgames_unreal_GameActivity_toNewUEPlace(JNIEnv* jenv, jobject thiz)
{
    UE_LOG(LogTemp, Warning, TEXT("toNewUEPlace"));
    UGameplayStatics::OpenLevel(GWorld, FName("/Game/Maps/abc"), true);
}

#endif//PLATFORM_ANDROID

abc is a map created by yourself

Guess you like

Origin blog.csdn.net/zhuziying99/article/details/135179048