obsidian/笔记文件/2.笔记/安卓和Unity通信.md
2025-03-26 00:02:56 +08:00

23 KiB

#安卓/代码缓存

AndroidManifest.xml

<?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.cgbu.activity">
    <uses-permission android:name="android.permission.BATTERY_STATS"
        tools:ignore="ProtectedPermissions" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
    <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE"
        tools:ignore="ProtectedPermissions" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Activity"
        tools:ignore="ExtraText">
        <activity android:name=".FirstActivity"
            android:label="这是第一个活动"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>>


    </application>

</manifest>

first_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/Button_1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Button 1"
        tools:ignore="MissingConstraints" />

</androidx.constraintlayout.widget.ConstraintLayout>

FirstActivity.java

package com.cgbu.activity;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;

import android.Manifest;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.BatteryManager;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.Toast;
import android.content.Context;
import android.view.Choreographer;

import java.lang.reflect.Method;

public class FirstActivity extends Activity implements Choreographer.FrameCallback {

    private Choreographer mChoreographer;
    private long mLastFrameTime;

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

        mChoreographer = Choreographer.getInstance();

        Button button1 = (Button) findViewById(R.id.Button_1);

        button1.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {

                //跳转设置界面
//                Intent intent =  new Intent(Settings.ACTION_SETTINGS);
//                FirstActivity.this.startActivity(intent);

                //电池信息
//                BatteryManager manager = (BatteryManager) FirstActivity.this.peekAvailableContext().getSystemService(Context.BATTERY_SERVICE);
//                int currentLevel = manager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
//                Toast.makeText(FirstActivity.this.peekAvailableContext(),String.valueOf(currentLevel),Toast.LENGTH_LONG).show();

//                //定位开启
//                if (ContextCompat.checkSelfPermission(FirstActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
//                    ActivityCompat.requestPermissions(FirstActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 0);
//                }

                //通知发送
//                Toast.makeText(FirstActivity.this,String.valueOf("权限:"+ContextCompat.checkSelfPermission(FirstActivity.this, Manifest.permission.POST_NOTIFICATIONS)),Toast.LENGTH_SHORT).show();
                createNotificationChannel("my_channel_ID","my_channel_name",NotificationManager.IMPORTANCE_HIGH,FirstActivity.this);

                //系统分享
//                Intent sharingIntent = new Intent(Intent.ACTION_SEND);
//                sharingIntent.setType("text/plain");
//                String shareBody = "这是要分享的内容";
//                sharingIntent.putExtra(Intent.EXTRA_SUBJECT,"分享主题");
//                sharingIntent.putExtra(Intent.EXTRA_TEXT,shareBody);
//                startActivity(Intent.createChooser(sharingIntent,"分享到"));

                //应用列表
//                Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS);
//                startActivity(intent);

                //设备号
//                String serial = null;
//                serial = DeviceIdUtil.getDeviceId(FirstActivity.this);
//                Toast.makeText(FirstActivity.this, String.valueOf("设备号:"+serial), Toast.LENGTH_SHORT).show();

            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();

        mChoreographer.postFrameCallback(FirstActivity.this);
        mLastFrameTime = System.nanoTime();
    }

    @Override
    protected void onPause() {
        super.onPause();

        mChoreographer.removeFrameCallback(FirstActivity.this);
    }

    //定位开启
//    @Override
//    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
////        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
//        switch (requestCode) {
//            case 0: {
//
//                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//
//                    LocationListener locationListener = new LocationListener() {
//                        @Override
//                        public void onLocationChanged(Location location) {
//                            double latitude = location.getLatitude();
//                            double logitude = location.getLongitude();
//                            Toast.makeText(FirstActivity.this, String.valueOf(latitude), Toast.LENGTH_SHORT).show();
//                        }
//                    };
//
//                    //定位权限被授予
////                    Toast.makeText(FirstActivity.this, String.valueOf("通过"), Toast.LENGTH_SHORT).show();
//                    LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
//                    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
//                        // TODO: Consider calling
//                        //    ActivityCompat#requestPermissions
//                        // here to request the missing permissions, and then overriding
//                        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
//                        //                                          int[] grantResults)
//                        // to handle the case where the user grants the permission. See the documentation
//                        // for ActivityCompat#requestPermissions for more details.
//                        return;
//                    }
//                    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
//                }
//                else
//                {
//                    //定位权限被拒绝
//                    Toast.makeText(FirstActivity.this,String.valueOf("拒绝"),Toast.LENGTH_SHORT).show();
//                }
//
//                return;
//            }
//
//        }
//    }

    //通知发送
    private void createNotificationChannel(String channelID, String channelNAME, int level,Context context) {
        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        Notification notification;

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(channelID, channelNAME, level);
            manager.createNotificationChannel(channel);
            notification = new NotificationCompat.Builder(context,channelID)
                    .setContentTitle("This is content title")
                    .setContentText("This is content text")
                    .setWhen(System.currentTimeMillis())
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .build();

        }
        else
        {
            notification = new NotificationCompat.Builder(this,"leo")
                    .setContentTitle("This is content title old")
                    .setContentText("This is content text old")
                    .setSmallIcon(R.drawable.ic_launcher_background)
                    .build();
        }

        manager.notify(1,notification);
    }

    @Override
    public void doFrame(long frameTimeNanos) {
        long frameIntervalNanos = frameTimeNanos - mLastFrameTime;
        double frameRate = 1/(frameIntervalNanos/1000000000.0);

        System.out.println("Frame rate:" + frameRate + "fps");
        mChoreographer.postFrameCallback(FirstActivity.this);
        mLastFrameTime = frameTimeNanos;
    }
}

DeviceIdUtil.java

package com.cgbu.activity;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Build;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.text.TextUtils;

import java.nio.charset.StandardCharsets;
import java.util.UUID;

public class DeviceIdUtil {

    public static String getDeviceId(Context context) {
        final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion;
        if (targetSdkVersion > Build.VERSION_CODES.P && Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
            return getUniqueID(context);
        } else {
            return getTelId(context);
        }
    }

    @SuppressLint("HardwareIds")
    private static String getTelId(Context context) {
        final TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
        return manager.getDeviceId();
    }

    private static String getUniqueID(Context context) {
        String id = null;
        @SuppressLint("HardwareIds") final String androidId = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
        if (!TextUtils.isEmpty(androidId) && !"9774d56d682e549c".equals(androidId)) {
            UUID uuid = UUID.nameUUIDFromBytes(androidId.getBytes(StandardCharsets.UTF_8));
            id = uuid.toString();
        }

        if (TextUtils.isEmpty(id)) {
            id = getUUID();
        }

        return TextUtils.isEmpty(id) ? UUID.randomUUID().toString() : id;
    }

    @SuppressLint("HardwareIds")
    private static String getUUID() {
        String serial = null;

        String m_szDevIDShort = "35" +
                Build.BOARD.length() % 10 + Build.BRAND.length() % 10 +

                ((null != Build.SUPPORTED_ABIS) ? Build.SUPPORTED_ABIS.length : 0) % 10 +

                Build.DEVICE.length() % 10 + Build.DISPLAY.length() % 10 +

                Build.HOST.length() % 10 + Build.ID.length() % 10 +

                Build.MANUFACTURER.length() % 10 + Build.MODEL.length() % 10 +

                Build.PRODUCT.length() % 10 + Build.TAGS.length() % 10 +

                Build.TYPE.length() % 10 + Build.USER.length() % 10; //13 位

        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
            try {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    serial = android.os.Build.getSerial();
                } else {
                    serial = Build.SERIAL;
                }
                //API>=9 使用serial号
                return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
            } catch (Exception exception) {
                serial = "serial" + UUID.randomUUID().toString(); // 随便一个初始化
            }
        } else {
            serial = android.os.Build.UNKNOWN + UUID.randomUUID().toString(); // 随便一个初始化
        }

        //使用硬件信息拼凑出来的15位号码
        return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
    }
}

UnityActivity.java

package com.cgbu.api;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;

public class UnityActivity {

    // 设置一个 Activity 参数

    private static Activity _unityActivity;

    // 通过反射获取 Unity 的 Activity 的上下文

    static Activity getActivity(){

        if(null == _unityActivity){

            try{

                Class<?> classtype = Class.forName("com.unity3d.player.UnityPlayer");

                Activity activity = (Activity) classtype.getDeclaredField("currentActivity").get(classtype);

                _unityActivity = activity;

            }catch (ClassNotFoundException e){

                e.printStackTrace();

            }catch (IllegalAccessException e){

                e.printStackTrace();

            }catch (NoSuchFieldException e){

                e.printStackTrace();

            }

        }

        return _unityActivity;

    }
}

Sys.java

package com.cgbu.api;
import android.Manifest;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.BatteryManager;
import android.provider.Settings;
import android.widget.Toast;

import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;

public class Sys  {

    //重启应用
    public void restartApplication()
    {
        Activity activity = UnityActivity.getActivity();
        Context context = activity.getApplicationContext();
        // 方法1
        Intent intent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
        Intent restartIntent = Intent.makeRestartActivityTask(intent.getComponent());
        context.startActivity(restartIntent);
        System.exit(0);
    }

    //跳转设置
    public void ACTION_SETTINGS()
    {
        Activity activity = UnityActivity.getActivity();
        Intent intent =  new Intent(Settings.ACTION_SETTINGS);
        activity.startActivity(intent);

    }

    //电池信息
    public void Battery()
    {
        Activity activity = UnityActivity.getActivity();
        BatteryManager manager = (BatteryManager) activity.getSystemService(Context.BATTERY_SERVICE);
        int currentLevel = manager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
        Toast.makeText(activity,String.valueOf(currentLevel),Toast.LENGTH_SHORT).show();
    }

    //定位开启
    public void Location()
    {
//        Activity activity = UnityActivity.getActivity();
//        if (ContextCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
//            ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 0);
//        }
    }

    //通知发送
    public void NotificationChannelTest()
    {
        String channelID = "my_channel_ID";
        String channelNAME = "my_channel_name";
        int level = NotificationManager.IMPORTANCE_HIGH;
        Activity activity = UnityActivity.getActivity();
        Context context = activity;
        NotificationManager manager = (NotificationManager) activity.getSystemService(Context.NOTIFICATION_SERVICE);
        Notification notification;

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(channelID, channelNAME, level);
            manager.createNotificationChannel(channel);
            notification = new NotificationCompat.Builder(context,channelID)
                    .setContentTitle("This is content title")
                    .setContentText("This is content text")
                    .setWhen(System.currentTimeMillis())
//                    .setSmallIcon(R.drawable.ic_launcher_background)
                    .build();

            manager.notify(1,notification);
        }

    }

}

AppTool.cs

using System.Collections.Generic;
using UnityEngine;
using Firebase;
using Firebase.Extensions;
using AnyThinkAds.Api;


public class AppTool : MonoBehaviour
{


    #region 私有变量
    
    private FirebaseApp app;
    
    AndroidJavaObject javaObject;
 
    public AndroidJavaObject MJavaObject { get {
 
            if (javaObject == null)
            {
                javaObject = new AndroidJavaObject("com.cgbu.api.Sys");
            }
 
            return javaObject;
        }
    }


    #endregion
    
    /// <summary>
    /// 重启应用
    /// </summary>
    public void ResartApp() 
    {
        
        MJavaObject.Call("restartApplication");
        // MJavaObject.Dispose();
    }

    /// <summary>
    /// 跳转设置
    /// </summary>
    public void ACTION_SETTINGS()
    {
        MJavaObject.Call("ACTION_SETTINGS");
        // MJavaObject.Dispose();
    }

    /// <summary>
    /// 电池信息
    /// </summary>
    public void Battery()
    {
        MJavaObject.Call("Battery");
        // MJavaObject.Dispose();
    }


    /// <summary>
    /// 定位开启
    /// </summary>
    public void Location()
    {
        MJavaObject.Call("Location");
        // MJavaObject.Dispose();
        
    }
    
    /// <summary>
    /// 通知发送
    /// </summary>
    public void NotificationChannel()
    {
        MJavaObject.Call("createNotificationChannel");
        // MJavaObject.Dispose();
    }

    /// <summary>
    /// 系统分享
    /// </summary>
    public void shareSDK()
    {
        MJavaObject.Call("shareSDK");
    }
    
    /// <summary>
    /// 应用列表
    /// </summary>
    public void appInfo()
    {
        MJavaObject.Call("appInfo");
    }
    
    /// <summary>
    /// 设备ID
    /// </summary>
    public void deviceID()
    {
        MJavaObject.Call("deviceID");
    }

    /// <summary>
    /// FireBase初始化
    /// </summary>
    public void FireBaseInit()
    {
        FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task => {
            var dependencyStatus = task.Result;
            if (dependencyStatus == Firebase.DependencyStatus.Available) {
                // Create and hold a reference to your FirebaseApp,
                // where app is a Firebase.FirebaseApp property of your application class.
                
#if UNITY_ANDROID
                app = FirebaseApp.DefaultInstance;
#else
                    app = FirebaseApp.Create();
#endif

                // Set a flag here to indicate whether Firebase is ready to use by your app.
            } else {
                UnityEngine.Debug.LogError(System.String.Format(
                    "Could not resolve all Firebase dependencies: {0}", dependencyStatus));
                // Firebase Unity SDK is not safe to use here.
            }
        });
    }

    /// <summary>
    /// TopOn广告
    /// </summary>
    public void TopOn()
    {
        ATSDKAPI.setLogDebug(true);
        ATSDKAPI.initSDK("a62b40f5778f3d","c3d0d2a9a9d451b07e62b509659f7c97");
        ATRewardedVideo.Instance.client.onAdLoadEvent += (a, b) =>
        {
            ATRewardedVideo.Instance.showAd("b62b41c7f059aa");
        };
        ATRewardedVideo.Instance.client.onAdLoadFailureEvent += (a, b) => Debug.Log("加载失败");
        ATRewardedVideo.Instance.client.onAdVideoStartEvent += (a, b) => Debug.Log("播放开始");
        ATRewardedVideo.Instance.client.onAdVideoEndEvent += (a, b) => Debug.Log("播放结束");
        ATRewardedVideo.Instance.client.onAdVideoFailureEvent += (a, b) => Debug.Log("播放失败");
        ATRewardedVideo.Instance.client.onAdClickEvent += (a, b) => Debug.Log("被点击");
        ATRewardedVideo.Instance.client.onRewardEvent += (a, b) => Debug.Log("奖励");
        ATRewardedVideo.Instance.client.onAdVideoCloseEvent += (a, b) => Debug.Log("关闭");
        
        ATRewardedVideo.Instance.loadVideoAd("b62b41c7f059aa", null);
    }
    
    private List<string> buttonTexts = new List<string>
    {
        "重启应用",
        "跳转设置",
        "电池信息",
        "定位开启",
        "通知发送",
        "系统分享",
        "应用列表",
        "设备ID",
        "开启FireBase",
        "TopOn广告",
        "退出"
    };
    
    private void HandleButtonClick(int index)
    {
        switch (index)
        {
            case 0:
                ResartApp();
                break;
            case 1:
                ACTION_SETTINGS();
                break;
            case 2:
                Battery();
                break;
            case 3:
                Location();
                break;
            case 4:
                NotificationChannel();
                break;
            case 5:
                shareSDK();
                break;
            case 6:
                appInfo();
                break;
            case 7:
                deviceID();
                break;
            case 8:
                FireBaseInit();
                break;
            case 9:
                TopOn();
                break;
            case 10:
                Application.Quit();
                break;

        }
    }
    
    
    private float buttonHeight = 30f;
    private Vector2 scrollPosition = Vector2.zero;
 
    void OnGUI()
    {

        // GUI.skin.verticalScrollbar.fixedWidth = 20.0f; // 设置滚动条宽度
        // GUI.skin.verticalScrollbar.fixedHeight = 20.0f; // 设置滚动条高度
        // 计算ScrollView的位置和大小
        Rect scrollViewRect = new Rect((Screen.width / 2) - 200, (Screen.height / 2) - 200, 400, 600);
 
        // 绘制ScrollView
        scrollPosition = GUI.BeginScrollView(scrollViewRect, scrollPosition, new Rect(0, 0, 210, 1500));
        {
            for (int i = 0; i < buttonTexts.Count; i++) 
            {
                if (GUI.Button(new Rect(0, i * 120, 300, 100), buttonTexts[i])) {
                    // 按钮被点击时的处理逻辑
                    HandleButtonClick(i);
                }
            }
        }
        GUI.EndScrollView();
    }

    private void OnApplicationQuit()
    {
        MJavaObject.Dispose();
    }
}