반응형

[.NET MAUI] 안드로이드에서 구글 광고 연결하기 (Admob 달기)

 

.NET MAUI는 안드로이드 어플 개발이 가능하다.

따라서 많은 안드로이드 어플에 추가되어있는 Admob 광고도 추가가 가능하다.

 

 


1. Nuget에서 Plugin.MauiMTAdmob를 설치한다.

 

.net maui Admob 연결하기, 애드센스 연결하기

 

MauiMTAdmob을 설치한다.

 

 

** 에러 발생시

.net maui Admob 연결하기, 애드센스 연결하기

 

 

위와 같은 에러가 발생하면 'Nuget-설치됨' 에서 각각의 패키지를 찾아 업데이트 해준다.

 

.net maui Admob 연결하기, 애드센스 연결하기

 

 

 


2. MauiProgram.cs 파일 수정

 

위의 두곳에 내용을 추가한다.

 

using Microsoft.Extensions.Logging;

using Plugin.MauiMTAdmob;  // 추가

namespace Admob_Test
{
    public static class MauiProgram
    {
        public static MauiApp CreateMauiApp()
        {
            var builder = MauiApp.CreateBuilder();
            builder
                .UseMauiApp<App>()
                
                .UseMauiMTAdmob()  // 추가

                .ConfigureFonts(fonts =>
                {
                    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                    fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
                });
                
#if DEBUG
    		builder.Logging.AddDebug();
#endif

            return builder.Build();
        }
    }
}

 

 

 


3. Platforms - Android - MainActivity.cs에 내용 추가

using Android.App;
using Android.Content.PM;
using Android.OS;

using Plugin.MauiMTAdmob;  // 추가

namespace Admob_Test
{
    [Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, LaunchMode = LaunchMode.SingleTop, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
    public class MainActivity : MauiAppCompatActivity
    {
    	// 추가
        protected override void OnCreate(Bundle? savedInstanceState)
        {
            string appId = "AppID"; // Admob에서 AppID 입력하기
            CrossMauiMTAdmob.Current.Init(this, appId);

            base.OnCreate(savedInstanceState);
        }

        // 추가
        protected override void OnResume()
        {
            base.OnResume();
            CrossMauiMTAdmob.Current.OnResume();
        }
    }
}

 

네가지를 추가해줘야 한다.

1) using Plugin.MauiMTAdmob;

2) Oncreate Override 추가

3) OnResume Override 추가

4) Admob에서 받은 AppID를 추가해야 한다.

 


4. Banner 광고 추가 하기

4-1. MainPage.Xaml에 AdMMTAdView 컨트롤 추가

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             
             xmlns:admob="clr-namespace:Plugin.MauiMTAdmob.Controls;assembly=Plugin.MauiMtAdmob"
             
             x:Class="Admob_Test.MainPage">

    <ScrollView>
        <VerticalStackLayout
            Padding="30,0"
            Spacing="25">

            <admob:AdMMTAdView HeightRequest="50" 
                               x:Name="adViewTT"
                               AdSize="Banner" 
                               VerticalOptions="EndAndExpand" 
                               HorizontalOptions="CenterAndExpand" />

        </VerticalStackLayout>
    </ScrollView>

</ContentPage>

 

1) xmlns:admob="clr-namespace:Plugin.MauiMTAdmob.Controls;assembly=Plugin.MauiMtAdmob" 를 추가한다.

2) <admob:AdMMTAdView /> 컨트롤을 추가한다.

 

 

4-2. MainPage.cs 비하인드 코드에서 연결

namespace Admob_Test
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();


			// Admob 배너 광고 ID
            if (DeviceInfo.Platform.Equals(DevicePlatform.Android))
            {
                // 테스트 광고 ID
                adViewTT.AdsId = "ca-app-pub-3940256099942544/6300978111";
            }

        }
    }

}

 

Admob 광고 ID를 컨트롤에 추가해준다.

 

 


5. 전면 광고 추가하기

5-1. MainPage.xaml에서 Button 생성, Click Event 추가

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             
             xmlns:admob="clr-namespace:Plugin.MauiMTAdmob.Controls;assembly=Plugin.MauiMtAdmob"
             
             x:Class="Admob_Test.MainPage">

    <ScrollView>
        <VerticalStackLayout
            Padding="30,0"
            Spacing="25">
            
            <!--전면 광고 버튼 추가-->
            <Button x:Name="btn_Ads"
                    Clicked="btn_Ads_Clicked" />
            
        </VerticalStackLayout>
    </ScrollView>

</ContentPage>

 

전면광고를 위한 Button 컨트롤을 추가하고 Clicked 이벤트를 추가한다.

 

 

5-2. MainPage.cs 비하인드 코드에서 이벤트 내용 추가

using Plugin.MauiMTAdmob;

namespace Admob_Test
{
    public partial class MainPage : ContentPage
    {
        int count = 0;

        public MainPage()
        {
            InitializeComponent();
        }

		// 추가
        private void btn_Ads_Clicked(object sender, EventArgs e)
        {
        	// 테스트 광고 ID
            string Id_Interstitial = "ca-app-pub-3940256099942544/1033173712";

            if (DeviceInfo.Platform.Equals(DevicePlatform.Android))
            {
                CrossMauiMTAdmob.Current.LoadInterstitial(Id_Interstitial);
                CrossMauiMTAdmob.Current.ShowInterstitial();

            }
        }
    }

}

 

Button Click 이벤트의 내용을 추가한다.

광고를 LoadInterstitial에 광고 ID로 로드하고

ShowInterstitial로 광고를 표시한다.

 


[TIP] Interstitial 로드 빠르게 하는 팁

위의 코드로 전면 광고를 호출하면 한박자 늦에 표시되는 것을 알 수 있다.

구글 Admob에 광고를 요청 - 수신 한 뒤 보여주는 로직이라 통신 시간이 소요된다.

이 문제는 간단하게 해결 가능하다.

using Plugin.MauiMTAdmob;

namespace Admob_Test
{
    public partial class MainPage : ContentPage
    {
        int count = 0;

        public MainPage()
        {
            InitializeComponent();
        }
		
        // 화면 로딩과 함께 광고 내용을 Load
        protected override void OnAppearing()
        {
            base.OnAppearing();

            string Id_Interstitial = "ca-app-pub-3940256099942544/1033173712";

            if (DeviceInfo.Platform.Equals(DevicePlatform.Android))
            {
                CrossMauiMTAdmob.Current.LoadInterstitial(Id_Interstitial);
            }
        }
		
        // 전면 광고가 필요한 상황에서 ShowInterstitial()로 광고를 표시한다.
        private void btn_Ads_Clicked(object sender, EventArgs e)
        {
            if (DeviceInfo.Platform.Equals(DevicePlatform.Android))
            {
                CrossMauiMTAdmob.Current.ShowInterstitial();
            }
        }
    }
}

 

위에서는 OnAppearing()에 LoadInterstitial()에 추가했지만 Task등을 이용해 비동기처리를 해도 무방하다.

반응형
반응형

LDF Viewer

 

차량 통신에서 사용되는 가장 흔한 통신 방식은 2가지가 있다.

LIN 통신과 CAN 통신이다.

 

이중 LIN 통신은 보통 LDF 파일을 생성한다.

LIN 통신에서 필요한 요소들에 대한 일종의 명세서다.

  • 통신 속도 등의 기본 통신 명세
  • Master/Slave 노드
  • 각 메시지들의 형식
  • 데이터의 형식
  • 주기적 스케줄에 대한 명세
  • 인코딩에 대한 명세

 

물론 메모장이나 기타 다른 프로그램으로 파일 내용 확인이 가능하다.

하지만 보기 불편하다.

그래서 만들었다.

 

 

https://play.google.com/store/apps/details?id=com.LFC.LinViewer&pli=1

 

Ldf 뷰어 - Google Play 앱

Lin Ldf viewer

play.google.com

 

 

사용법은 간단하다.

LDF파일을 선택하기만 하면 상세 내용이 나오게된다.

 

 

0123

 

 

안드로이드 태블릿에서도 사용 가능한 어플이다.

 

또한 번외로 PC에서 무설치로 사용 할 수 있도록 웹으로도 만들었다.

 

 

https://fasttool.co.kr/

 

Fast Tool

여러 CSV파일을 하나의 파일로 요약합니다.

fasttool.co.kr

 

 

LDF뷰어 뿐만 아니라 평소 내가 자주 사용하는 단위 변환기도 있다.

 

 

모두 무료이니 비용 걱정은 없다.

편히 사용하면 된다.

반응형

'일지 > 앱 개발' 카테고리의 다른 글

언제까지 놀고만 있을 순 없다. (.NET Maui)  (0) 2025.03.18
반응형

코틀린에서는 특이한 점이 하나 있다. (물론 내가 c#개발을 했었어서일수도 있다.)

 

int a;
a = 1;
Console.WriteLine(a)

// 1

 

c#에서는 위와같이 int a를 변수명 선언만 한 뒤 a의 값을 나중에 할당해도 된다.

 

하지만 코틀린에서는 에러가 발생한다.

 

 

이를 해결하기 위해 사용하는 키워드가 바로 lateinit / lazy다.

 

 


1. lateinit (kotlin아! 값은 나중에 알려줄께..)

lateinit var name : String

name = "Kim"

println(name)


// Kim

 

위에서 언급한 C#과 파이썬등 여러 언어들과 동일한 방법이다.

lateinit이라는 키워드로 나중에 값을 할당할것이라고 kotlin에게 알려준 뒤,

필요할 때 값을 넣어주는 방법이다.

여기엔 몇가지 제한 조건이 있다.

  • var 변수에만 사용이 가능하다.
    • 당연하다. val 타입은 추후에 값을 못바꾸기 때문에 불가능하다.
  • nullable 자료형을 사용 할 수 없다.
  • 초기화하기 전에 변수를 호출하면 에러가 발생한다.
    • 값이 없는 상태이기에 반환 할 값도, 주소도 없다.
    • 변수명.isInitialized()로 초기화가 되었는지 확인 가능하다.
  • 원시 자료형에는 사용이 불가능하다.
    • Int, Double, Float, Bool 등..

2. lazy (미리 값은 알려주는데 내가 값을 넣으라 할때까지 기다려봐)

val lazyVar : String by lazy {
    println("초기화 되었습니다 1.")
    println("초기화 되었습니다 2.")
    "Lazy 키워드"
}


println(lazyVar)
println("------------")
println(lazyVar)


// 초기화 되었습니다 1.  // 초기화 동작으로 인한 출력
// 초기화 되었습니다 2.  // 초기화 동작으로 인한 출력
// Lazy 키워드          // 초기화 동작으로 인한 출력, "Lazy 키워드" 값이 lazyVar에 할당 / 반환
// ------------
// Lazy 키워드          // lazyVar에 할당된 값 반환

 

lazy는 val만 사용 가능하다.

다시말해 변경 불가한 값이다.

처음 변수를 선언할때 '나중에 호출하면 이런 값을 할당해줘' 라는 방법(혹은 레시피)를 미리 선언해 놓는다.

위의 코드처럼 println()등도 함께 호출 가능하다.

 

변수가 호출되는 시점에 초기화가 진행되면서 lazy블록 안에 있는 코드가 실행되고 "Lazy 키워드"라는 값이 lazyVar에 할당된다.

그리고 이후에 호출이 되면 "Lazy 키워드"만 반환된다.

(위의 출력값에 "초기화 되었습니다. 1", "초기화 되었습니다. 2", "Lazy 키워드"가 나오는 부분은 초기화 되면서 실행된 값들이다.)

(맨 마지막줄 "Lazy 키워드"는 초기화가 완료되었기에 다른 문구 없이 lazyVar에 할당된 값만 출력되게 된다.)  

 

용량이 큰 자료를 데이터값으로 사용해야 할때 프로그램 실행시부터 메모리에 올려놓게되면 메모리의 효율성이 떨어진다.

(10년뒤 사용할 휴지100묶음을 지금부터 방에 놔두는 꼴이 된다.)

그래서 필요시에 할당해 사용하기위해 주문서만 만들어놓고 필요할대 주문해 사용하는 방법인것이다.

반응형
반응형

코틀린에는 배열의 종류가 4가지가 있다.

array, list, set, map 네가지를 비교해보자

 

 

1. Array

// Array 선언
var arr = arrayOf("A", "B", "C", "D")

println(arr[0] + "  " + arr[1])
arr[0] = "AAA"
println(arr[0] + "  " + arr[1])

// A  B
// AAA  B
  • 특징 
    • Array 선언시 배열의 크기를 지정해야 한다.
      • 지정된 배열의 크기는 변경 불가하다.
        (python의 list.append(), C#의 list.ㅁdd() 사용 불가)
    • 배열 안의 값을 자유롭게 변경이 가능하다.
      • arr[0] = "AAA"처럼 인덱스값으로 내용 수정 가능
    • 순서를 저장한다.
    • 중복값을 허용한다.

 


2. List

// Immutable List

var imList = listOf<String>("mL-1", "mL-2", "mL-3")
for (a in imList) { println(a)}

// 읽기 전용(immutable)인 리스트의 값을 변경을 시도하기에 에러 발생
// imList[0] = "mL-4"

println("---------------")
for (a in imList) { println(a)}
println("---------------")

// error



// Mutable List

var mList = mutableListOf<String>("mL-1", "mL-2", "mL-3")
for (a in mList) { println(a)}

// mutable 리스트기에 값 변경 가능
mList[0] = "ML-4" // mList.set(0, "mL-4")도 같은 기능

// 리스트 값 추가
mList.add("mL-5")

println("---------------")
for (a in mList) { println(a)}
println("---------------")


// mL-1
// mL-2
// mL-3
// ---------------
// mL-4
// mL-2
// mL-3
// mL-5
// ---------------

 

  • 특징
    • List는 순서를 저장한다.
    • 중복값을 허용한다.
    • List는 두가지 mutable, immutable 두가지로 나뉜다.
      • immutable
        • 기본 값, 읽기전용 (수정 불가)
      • mutable
        • 값 수정 가능
        • 인덱스에 직접 접근하여 값 변경 가능
        • 배열 추가/삭제 가능 (add/remove)
    • List의 단점
      • 메모리에 순서대로 할당되지 않는다.
        • 검색기능 활용시 성능저하가 발생한다.
          (메모리 순서대로 검색이 아니라 각 데이터가 있는 메모리 주소를 찾아들어가 값을 확인하고 다음 주소로 이동해야 하기에 성능 저하가 발생한다)

 


3. Set

// immutable Set
var imSet = setOf(1, 2, 3, 1, 2, 3)
for (a in imSet) { println(a) }

// 1
// 2
// 3
// (중복값은 허용되지 않기에 1, 2, 3 한가지씩 저장된다)


// mutable Set
var mSet = mutableSetOf(1, 2, 3, 1, 2, 3)
for (a in imSet) { println(a) }
println("---------------")
mSet.add(4)
mSet.remove(1)
for (a in imSet) { println(a) }
println("---------------")

// 1
// 2
// 3
// ---------------
// 2
// 3
// 4
// ---------------
// (중복값이 허용되지 않아 1, 2, 3만 할당)
// (mutable이기에 내용 수정 가능 add/remove)
  • 특징
    • List와 같이 immutable / mutable로 나뉜다.
    • 순서를 저장하지 않는다.
    • 중복 값을 허용하지 않는다.

 


4. Map

// immutable Map
var imMap = mapOf("name" to "J", "age" to "13", "country" to "korea")
println(imMap)
println(imMap["name"])

// {name=J, age=13, country=korea}
// J


// mutable Map
var mMap = mutableMapOf("트와이스" to "TT", "아이유" to "내 손을 잡아", "NCT" to "영웅")
mMap.put("QWER", "고민중독")
println("-Put <mMap.put(\"QWER\", \"고민중독\")>")
println(mMap)
mMap.remove("NCT")
println("-Remove <mMap.remove(\"NCT\")>")
println(mMap)
mMap.remove("QWER", "내 이름 맑음")


// -Put <mMap.put("QWER", "고민중독")>
// {트와이스=TT, 아이유=내 손을 잡아, NCT=영웅, QWER=고민중독}
// 영웅
// -Remove <mMap.remove("NCT")>
// {트와이스=TT, 아이유=내 손을 잡아, QWER=고민중독}

 

  • 특징
    • key : value의 쌍으로 저장되는 자료 구조
      • 파이썬의 dictionary와 같은 형식
    • immutable / mutable로 분리됨
    • key값은 중복 불가
    • value값은 중복 가능

 

반응형

+ Recent posts