이번에는 싱글턴 패턴을 활용하여 안드로이드의 많은 기능을 활용하는 코드를 간단하게 보여드리겠습니다!

참고로 밑의 유튜브는 제가 참고한 영상입니다.

 

이번 시간에는 권한 설정 + 권한이 필요한 기능 사용입니다.

 

https://www.youtube.com/watch?v=B7a6xpMXDYE&t=502s

저는 이번에 유니티 툴에서 안드로이드 스튜디오의 메서드 getAllCellInfo()를 사용하고 싶었습니다.

그를 위한 코드를 보여드리겠습니다.

 

package com.example.nrlibrary;

import android.annotation.SuppressLint;
import android.content.Context;
import android.telephony.CellIdentityCdma;
import android.telephony.CellIdentityGsm;
import android.telephony.CellIdentityLte;
import android.telephony.CellIdentityWcdma;
import android.telephony.CellInfo;
import android.telephony.CellInfoCdma;
import android.telephony.CellInfoGsm;
import android.telephony.CellInfoLte;
import android.telephony.CellInfoWcdma;
import android.telephony.TelephonyManager;
import android.widget.Toast;

import java.util.List;

public class cellnr {

    private static TelephonyManager telephonyManager;
    private static cellnr m_instance;
    private static Context context;

    // 싱글턴 메소드
    public static cellnr instance(Context ct) {
        if (m_instance == null) {
            context = ct;
            telephonyManager = (TelephonyManager) ct.getSystemService(ct.TELEPHONY_SERVICE);
            m_instance = new cellnr();
        }
        return m_instance;
    }

    private void ShowToast(String msg, int i) {
        // i는 짧게 아니면 길게 화면에 보여줄 것인지 체크한다.
        if (i == 0) // 짧은 경우
        {
            Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
        } else { // 길게 보이는 경우
            Toast.makeText(context, msg, Toast.LENGTH_LONG).show();

        }
    }
    
    @SuppressLint("MissingPermission")
    String easy_cell_info() {
        TelephonyManager tm = (TelephonyManager) context.getSystemService(context.TELEPHONY_SERVICE);
        return tm.getAllCellInfo().toString();
    }

위 코드를 설명하겠습니다.

우선 TelephonyManager와 Class 그리고 Context를  static을 활용하여 선언하였고

instance 싱글턴 메서드를 통해서만 접근할 수 있게 하였습니다.

 

telephonyManager 같은 경우 위치 정보의 권한이 필요로 합니다. 

따라서 easy_cell_info 메소드를 보면 위에 MissingPermission이라고 되어 있습니다.

이것은 간단하게 권한 사용을 거부당했는지 체크하는 함수를 사용하지 않겠다는 의미입니다.

기본적으로는 권한 사용 거부 여부를 체크하는 조건문을 달아야 합니다.

하지만 여기서 체크하게 되면 뭔가 오류가 생겨서 그냥 무시하고 유니티에서 체크하도록 하였습니다.

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Android;
using UnityEngine.UI;

public class check_5G : MonoBehaviour
{
    private AndroidJavaObject UnityInstance;
    private AndroidJavaObject UnityActivity;
    public Text text;

    void Start()
    {
        AndroidJavaClass ajc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        UnityActivity = ajc.GetStatic<AndroidJavaObject>("currentActivity");

        AndroidJavaClass ajc2 = new AndroidJavaClass("com.example.nrlibrary.cellnr");
        UnityInstance = ajc2.CallStatic<AndroidJavaObject>("instance", UnityActivity);


        StartCoroutine(DelayEffect());
    }
    private IEnumerator DelayEffect()

    {

        while (true)

        {
            ShowCell5();

            /** 1초 딜레이 **/

            yield return new WaitForSeconds(1f);
        }

    }

    public void ShowCell5()
    {
        text.text = UnityInstance.Call<string>("easy_cell_info");

    }

 위 코드는 유니티 코드입니다.  start에서 하고 있는 작업은 간단하게 싱글턴 패턴 메서드 instance를 사용하기 위한

작업과 코 루틴 함수 getCellInfo() 통신 정보 획득 함수를 사용하고 있습니다.

ShowCell5에 있는 easay_cell_info를 사용하기 위해서는 미리 위치 정보를 확인할 수 있는 권한이 있어야 합니다.

 

유니티에서 권한 설정을 위해 AndroidManifest.xml 파일이 필요합니다. 파일의 위치는

저 같은 경우 아래와 같았습니다.

C:\Program Files\Unity\Hub\Editor\2019.2.17f1\Editor\Data\PlaybackEngines\AndroidPlayer\Apk

 

일반적인 경우로는

- Unity 설치 폴더/Editor/Data/PlaybackEngines/AndroidPlayer/Apk/AndroidManifest.xml

- 대상 경로 : {Project Root}/Assets/Plugins/Android/AndroidManifest.xml

에서  AndroidManifest.xml 파일이 있고  AndroidManifest.xml 파일을 가져와서

Plugins/Android폴더 안에 넣어서 사용할 수 있습니다.

저 같은 경우 위치 정보와 휴대폰 상태 정보가 필요하여 아래와 같이 퍼미션을 사용한다고 xml 파일에 명시하였습니다.

 

 

 

저는 위치 정보 권한을 시작하자마자 획득하기 위해서 아래의 코드를 사용하였습니다.

아래의 코드는 어느 블로거 님의 글을 통해 학습한 내용을 제가 필요한 코드로 바꿔 사용한 코드이며

설명은 블로거 님의 블로그를 통해 자세히 알아보실 수 있습니다.

https://mentum.tistory.com/150

 

유니티 퍼미션 체크 적용기. (Unity Permission Check) 2019.11.14 재작성.

2019.11.14 재작성. 유니티 안드로이드에서 스크린샷을 저장하기 위해 권한 부분을 다시 작성해야해서 하는 김에 이 글도 재작성 하였다. 2019/11/14 - [Unity/프로그래밍] - 유니티 안드로이드 스크린샷

mentum.tistory.com

 

using System;
using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.Android;

// 매니페스트 선언필요.  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
public class PermissionCheck : MonoBehaviour
{
    [SerializeField] private GameObject panel; 
    bool onCheck = false;

    private void Start()
    {
        if (onCheck == false)
        {
            StartCoroutine("PermissionCheckCoroutine");
            panel.SetActive(true);
        }
    }

    public void PressBtnCapture()
    {
        if (onCheck == false)
        {
            StartCoroutine("PermissionCheckCoroutine");
            panel.SetActive(true);
        }
    }

    IEnumerator PermissionCheckCoroutine()
    {
        onCheck = true;

        yield return new WaitForEndOfFrame();
        if (Permission.HasUserAuthorizedPermission(Permission.FineLocation) == false)
        {
            Permission.RequestUserPermission(Permission.FineLocation);

            yield return new WaitForSeconds(0.2f); // 0.2초의 딜레이 후 focus를 체크하자.
            yield return new WaitUntil(() => Application.isFocused == true);

            if (Permission.HasUserAuthorizedPermission(Permission.FineLocation) == false)
            {
                // 다이얼로그를 위해 별도의 플러그인을 사용했기 때문에 주석처리. 그냥 별도의 UI를 만들어주면 됨.
                //AGAlertDialog.ShowMessageDialog("권한 필요", "스크린샷을 저장하기 위해 저장소 권한이 필요합니다.",
                //"Ok", () => OpenAppSetting(),
                //"No!", () => AGUIMisc.ShowToast("저장소 요청 거절됨"));

                OpenAppSetting(); // 원래는 다이얼로그 선택에서 Yes를 누르면 호출됨.
                onCheck = false;
                yield break;

            }
        }

        // 권한을 사용해서 처리하는 부분. 스크린샷이나, 파일 저장 등등.

        onCheck = false;
    }





    // 해당 앱의 설정창을 호출한다.
    // https://forum.unity.com/threads/redirect-to-app-settings.461140/
    private void OpenAppSetting()
    {
        try
        {
#if UNITY_ANDROID
            using (var unityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
            using (AndroidJavaObject currentActivityObject = unityClass.GetStatic<AndroidJavaObject>("currentActivity"))
            {
                string packageName = currentActivityObject.Call<string>("getPackageName");

                using (var uriClass = new AndroidJavaClass("android.net.Uri"))
                using (AndroidJavaObject uriObject = uriClass.CallStatic<AndroidJavaObject>("fromParts", "package", packageName, null))
                using (var intentObject = new AndroidJavaObject("android.content.Intent", "android.settings.APPLICATION_DETAILS_SETTINGS", uriObject))
                {
                    intentObject.Call<AndroidJavaObject>("addCategory", "android.intent.category.DEFAULT");
                    intentObject.Call<AndroidJavaObject>("setFlags", 0x10000000);
                    currentActivityObject.Call("startActivity", intentObject);
                }
            }
#endif
        }
        catch (Exception ex)
        {
            Debug.LogException(ex);
        }
    }
}

+ Recent posts