<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>blog</title>
    <link>https://jihunstudy.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Thu, 2 Jul 2026 08:26:07 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>녹색꼬맹이</managingEditor>
    <image>
      <title>blog</title>
      <url>https://tistory1.daumcdn.net/tistory/2815027/attach/b1f595043b3e4c99bd1d8bcf7e763c5d</url>
      <link>https://jihunstudy.tistory.com</link>
    </image>
    <item>
      <title>오브제 썬스틱</title>
      <link>https://jihunstudy.tistory.com/88</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;예전에 OBge 오일썬스틱 처음 샀을 땐 별 기대 없이 그냥 하나 써봤는데 생각보다 꽤 괜찮았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기름기도 잘 잡아주고 무겁지도 않고, 그때 한창 잘 쓰긴 했다만,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;썬스틱이란 걸 자주 바르진 않다 보니 다 쓰는 데 시간이 오래 걸렸음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러다 이번엔 초여름부터 햇볕이 너무 세서 부지런히 챙겨 바르다 보니 금방 다 써버렸고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부족해서 이번에 새로 하나 더 삼.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;898&quot; data-origin-height=&quot;942&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bp2qlX/btsOTPORq9j/pHkYLRxxTKoKNchFBHbzQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bp2qlX/btsOTPORq9j/pHkYLRxxTKoKNchFBHbzQK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bp2qlX/btsOTPORq9j/pHkYLRxxTKoKNchFBHbzQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbp2qlX%2FbtsOTPORq9j%2FpHkYLRxxTKoKNchFBHbzQK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; alt=&quot;오브제 썬스틱 과거와 현재&quot; loading=&quot;lazy&quot; width=&quot;592&quot; height=&quot;1051&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;898&quot; data-origin-height=&quot;942&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item adsense responsive&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;반응형&lt;/div&gt;
    &lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
    &lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-host=&quot;ca-host-pub-9691043933427338&quot; data-ad-client=&quot;ca-pub-8585691276129476&quot; data-ad-format=&quot;auto&quot;&gt;&lt;/ins&gt;
    &lt;script&gt;(adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;840&quot; data-origin-height=&quot;888&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXruPA/btsOTmzSxxk/dvxbJRZ6oICMLDn842wKd0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXruPA/btsOTmzSxxk/dvxbJRZ6oICMLDn842wKd0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXruPA/btsOTmzSxxk/dvxbJRZ6oICMLDn842wKd0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXruPA%2FbtsOTmzSxxk%2FdvxbJRZ6oICMLDn842wKd0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;840&quot; height=&quot;888&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;840&quot; data-origin-height=&quot;888&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;광고에는 업그레이드 됐다고 떠들길래 기대 좀 했는데 막상 받아보니 겉은 예전이랑 똑같다. 글자랑 색상만 바뀐 정도?&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;근데 뚜껑 열어보니 안에 내용물 색이 예전이랑 살짝 다른 느낌이긴 하더라. 바를 때 느낌도 살짝 더 부드럽긴 한데 아주 큰 차이는 모르겠다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그래도 여전히 기름기 잘 잡아주고 끈적이지도 않아서 쓰기 편한 건 맞음.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그래서 또 쓴다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;별 건 없는데 이상하게 손이 자주 가는 제품.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item tenping&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;SMALL&lt;/div&gt;
    &lt;tenping class=&quot;adsbytenping&quot; style=&quot;width: 100%; max-width: 768px; margin: 0 auto; display: block;&quot; mediaid=&quot;2815027&quot; tenping-ad-display-type=&quot;UD8Mia8gyIoT5Z2MT6VB3Q%3d%3d&quot;&gt;&lt;/tenping&gt;
    &lt;script src=&quot;//tads.tenping.kr/scripts/adsbytenping.min.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_Photo_2025-06-26-17-52-19 005.jpeg&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;1600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EbbC1/btsOTbLGQPl/5cXW8Kagz11LCNWIageE21/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EbbC1/btsOTbLGQPl/5cXW8Kagz11LCNWIageE21/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EbbC1/btsOTbLGQPl/5cXW8Kagz11LCNWIageE21/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEbbC1%2FbtsOTbLGQPl%2F5cXW8Kagz11LCNWIageE21%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;901&quot; height=&quot;1600&quot; data-filename=&quot;KakaoTalk_Photo_2025-06-26-17-52-19 005.jpeg&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;1600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>일상</category>
      <category>기름잡아주는</category>
      <category>썬스틱</category>
      <category>썬크림</category>
      <category>오브제</category>
      <category>오브제썬스틱</category>
      <author>녹색꼬맹이</author>
      <guid isPermaLink="true">https://jihunstudy.tistory.com/88</guid>
      <comments>https://jihunstudy.tistory.com/88#entry88comment</comments>
      <pubDate>Thu, 26 Jun 2025 17:57:44 +0900</pubDate>
    </item>
    <item>
      <title>[ CICD #4 ] Github Actions - local.properties</title>
      <link>https://jihunstudy.tistory.com/87</link>
      <description>&lt;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item adsense responsive&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;반응형&lt;/div&gt;
    &lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
    &lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-host=&quot;ca-host-pub-9691043933427338&quot; data-ad-client=&quot;ca-pub-8585691276129476&quot; data-ad-format=&quot;auto&quot;&gt;&lt;/ins&gt;
    &lt;script&gt;(adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item tenping&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;SMALL&lt;/div&gt;
    &lt;tenping class=&quot;adsbytenping&quot; style=&quot;width: 100%; max-width: 768px; margin: 0 auto; display: block;&quot; mediaid=&quot;2815027&quot; tenping-ad-display-type=&quot;UD8Mia8gyIoT5Z2MT6VB3Q%3d%3d&quot;&gt;&lt;/tenping&gt;
    &lt;script src=&quot;//tads.tenping.kr/scripts/adsbytenping.min.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 API Key는 외부에 노출되면 안 되기 때문에 local.properties 파일에만 저장하여 로컬에서만 관리한다. 해당 파일은 .gitignore에 등록해 GitHub 저장소에는 포함되지 않도록 처리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;310&quot; data-start=&quot;199&quot; data-ke-size=&quot;size16&quot;&gt;GitHub Actions에서 자동화가 실행될 때 local.properties 파일이 없기 때문에, 워크플로우 내에서 해당 파일을 새로 생성하고 필요한 API Key를 등록하는 과정이 필요하다.&lt;/p&gt;
&lt;p data-end=&quot;310&quot; data-start=&quot;199&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;420&quot; data-start=&quot;312&quot; data-ke-size=&quot;size16&quot;&gt;이 글에서는 local.properties 파일을 GitHub Actions에서 자동으로 생성하고, 필요한 API Key들을 삽입하여 빌드에 사용할 수 있도록 처리하는 워크플로우를 정리한다.&lt;/p&gt;
&lt;p data-end=&quot;420&quot; data-start=&quot;312&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;420&quot; data-start=&quot;312&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;420&quot; data-start=&quot;312&quot; data-ke-size=&quot;size16&quot;&gt;우선 내가 사용하는 api key 들을 Github Actions secrets 에 등록해 준다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jihunstudy.tistory.com/84&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2025.05.28 - [Android/CICD] - [ CICD #1 ] GitHub secrets 등록 -1&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1749629141271&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[ CICD #1 ] GitHub secrets 등록 -1&quot; data-og-description=&quot;예전부터 해보고 싶었던 빌드, 테스트, 배포 과정을 자동화에 대해서 시도해 보고 최종적으로 성공한 것에 대해 기록하고자 한다.CI/CD 도구로 여러가지가 있다는 건 알고만 있었다 1. Github Actions2&quot; data-og-host=&quot;jihunstudy.tistory.com&quot; data-og-source-url=&quot;https://jihunstudy.tistory.com/84&quot; data-og-url=&quot;https://jihunstudy.tistory.com/84&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bUNmhm/hyY7Y12QIy/YC1nCwSg9vcH3GjnykbKk0/img.png?width=800&amp;amp;height=497&amp;amp;face=0_0_800_497,https://scrap.kakaocdn.net/dn/GlUF1/hyY45BzcaP/bk1EkEcEYoyoqYcHdjGPE1/img.png?width=800&amp;amp;height=497&amp;amp;face=0_0_800_497,https://scrap.kakaocdn.net/dn/cwAM5S/hyY31MTCHM/Mn51arGhw1y30holKKxeT1/img.png?width=1588&amp;amp;height=988&amp;amp;face=0_0_1588_988&quot;&gt;&lt;a href=&quot;https://jihunstudy.tistory.com/84&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jihunstudy.tistory.com/84&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bUNmhm/hyY7Y12QIy/YC1nCwSg9vcH3GjnykbKk0/img.png?width=800&amp;amp;height=497&amp;amp;face=0_0_800_497,https://scrap.kakaocdn.net/dn/GlUF1/hyY45BzcaP/bk1EkEcEYoyoqYcHdjGPE1/img.png?width=800&amp;amp;height=497&amp;amp;face=0_0_800_497,https://scrap.kakaocdn.net/dn/cwAM5S/hyY31MTCHM/Mn51arGhw1y30holKKxeT1/img.png?width=1588&amp;amp;height=988&amp;amp;face=0_0_1588_988');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[ CICD #1 ] GitHub secrets 등록 -1&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;예전부터 해보고 싶었던 빌드, 테스트, 배포 과정을 자동화에 대해서 시도해 보고 최종적으로 성공한 것에 대해 기록하고자 한다.CI/CD 도구로 여러가지가 있다는 건 알고만 있었다 1. Github Actions2&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jihunstudy.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;local.properties 를 생성하고 secrets 에 저장된 api key를 불러와 저장하는 워크 플로우 코드를 작성한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1749629206457&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# local.properties 파일 생성 (AdMob API 키 포함)
      - name: Create local.properties
        run: |
          echo &quot;ADS_ID=${{ secrets.ADMOB_APP_ID }}&quot; &amp;gt;&amp;gt; ./local.properties
          echo &quot;ADS_FIXED_SIZE_BANNER_UNIT_ID=${{ secrets.ADMOB_UNIT_ID }}&quot; &amp;gt;&amp;gt; ./local.properties&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 내에서 사용하는 api key 이름은 ADS_ID 이며&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;secrets 에 저장된 이름은 ADMOB_APP_ID 로 저장했기 때문에 위와 같은 코드가 나오는 것으로 이해하면 된다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저건 단순히 구글 애드몹 api key를 가져오는 코드다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 local.properties 생성할 때 위치를 잘잡아줘야 하는데 root 폴더를 잘못 지정해줘서 에러가 난 적이 있다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 심플하게 ./ 이걸로 루트 위치를 잡아 주면 된다&lt;/p&gt;</description>
      <category>Android/CICD</category>
      <category>API</category>
      <category>api key 관리</category>
      <category>github</category>
      <category>github actions</category>
      <category>local.properties</category>
      <author>녹색꼬맹이</author>
      <guid isPermaLink="true">https://jihunstudy.tistory.com/87</guid>
      <comments>https://jihunstudy.tistory.com/87#entry87comment</comments>
      <pubDate>Wed, 11 Jun 2025 17:09:42 +0900</pubDate>
    </item>
    <item>
      <title>[ CICD #3 ] GitHub Actions Play Store Alpha UpLoad -3</title>
      <link>https://jihunstudy.tistory.com/86</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item adsense responsive&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;반응형&lt;/div&gt;
    &lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
    &lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-host=&quot;ca-host-pub-9691043933427338&quot; data-ad-client=&quot;ca-pub-8585691276129476&quot; data-ad-format=&quot;auto&quot;&gt;&lt;/ins&gt;
    &lt;script&gt;(adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item tenping&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;SMALL&lt;/div&gt;
    &lt;tenping class=&quot;adsbytenping&quot; style=&quot;width: 100%; max-width: 768px; margin: 0 auto; display: block;&quot; mediaid=&quot;2815027&quot; tenping-ad-display-type=&quot;UD8Mia8gyIoT5Z2MT6VB3Q%3d%3d&quot;&gt;&lt;/tenping&gt;
    &lt;script src=&quot;//tads.tenping.kr/scripts/adsbytenping.min.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jihunstudy.tistory.com/84&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2025.05.28 - [Android/CICD] - [ CICD #1 ] GitHub secrets 등록 -1&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1748407764370&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[ CICD #1 ] GitHub secrets 등록 -1&quot; data-og-description=&quot;예전부터 해보고 싶었던 빌드, 테스트, 배포 과정을 자동화에 대해서 시도해 보고 최종적으로 성공한 것에 대해 기록하고자 한다.CI/CD 도구로 여러가지가 있다는 건 알고만 있었다 1. Github Actions2&quot; data-og-host=&quot;jihunstudy.tistory.com&quot; data-og-source-url=&quot;https://jihunstudy.tistory.com/84&quot; data-og-url=&quot;https://jihunstudy.tistory.com/84&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Gm9ck/hyY0661u8w/7XH7wQPswJXDc94KeEk7a0/img.png?width=800&amp;amp;height=497&amp;amp;face=0_0_800_497,https://scrap.kakaocdn.net/dn/h3CiM/hyY1ejFnFI/HyMPtzYjXmzobjDhzangQk/img.png?width=800&amp;amp;height=497&amp;amp;face=0_0_800_497,https://scrap.kakaocdn.net/dn/rIkbH/hyY07SnVTt/yCUeaaeQwDP42ZjkXUEsQ0/img.png?width=1588&amp;amp;height=988&amp;amp;face=0_0_1588_988&quot;&gt;&lt;a href=&quot;https://jihunstudy.tistory.com/84&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jihunstudy.tistory.com/84&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Gm9ck/hyY0661u8w/7XH7wQPswJXDc94KeEk7a0/img.png?width=800&amp;amp;height=497&amp;amp;face=0_0_800_497,https://scrap.kakaocdn.net/dn/h3CiM/hyY1ejFnFI/HyMPtzYjXmzobjDhzangQk/img.png?width=800&amp;amp;height=497&amp;amp;face=0_0_800_497,https://scrap.kakaocdn.net/dn/rIkbH/hyY07SnVTt/yCUeaaeQwDP42ZjkXUEsQ0/img.png?width=1588&amp;amp;height=988&amp;amp;face=0_0_1588_988');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[ CICD #1 ] GitHub secrets 등록 -1&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;예전부터 해보고 싶었던 빌드, 테스트, 배포 과정을 자동화에 대해서 시도해 보고 최종적으로 성공한 것에 대해 기록하고자 한다.CI/CD 도구로 여러가지가 있다는 건 알고만 있었다 1. Github Actions2&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jihunstudy.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jihunstudy.tistory.com/85&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2025.05.28 - [Android/CICD] - [ CICD #2 ] GitHub Actions Firebase Distribution -2&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1748407773678&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[ CICD #2 ] GitHub Actions Firebase Distribution -2&quot; data-og-description=&quot;이전 글에서 Github Secrets 를 등록 하는 방법을 정리했다. 2025.05.28 - [Android/CICD] - [ CICD #1 ] GitHub secrets 등록 -1 [ CICD #1 ] GitHub secrets 등록 -1예전부터 해보고 싶었던 빌드, 테스트, 배포 과정을 자동화&quot; data-og-host=&quot;jihunstudy.tistory.com&quot; data-og-source-url=&quot;https://jihunstudy.tistory.com/85&quot; data-og-url=&quot;https://jihunstudy.tistory.com/85&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/WFOV7/hyY1fQq1G5/jApHwdoU4uKFI7W1zs9wnK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/F7Lp1/hyY0mChjZ5/CvrVhvHxivGlAKw0RkXRmK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800&quot;&gt;&lt;a href=&quot;https://jihunstudy.tistory.com/85&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jihunstudy.tistory.com/85&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/WFOV7/hyY1fQq1G5/jApHwdoU4uKFI7W1zs9wnK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/F7Lp1/hyY0mChjZ5/CvrVhvHxivGlAKw0RkXRmK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[ CICD #2 ] GitHub Actions Firebase Distribution -2&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;이전 글에서 Github Secrets 를 등록 하는 방법을 정리했다. 2025.05.28 - [Android/CICD] - [ CICD #1 ] GitHub secrets 등록 -1 [ CICD #1 ] GitHub secrets 등록 -1예전부터 해보고 싶었던 빌드, 테스트, 배포 과정을 자동화&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jihunstudy.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전에 Github secrets 등록과 Firebase 테스트 앱 배포를 해보고&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 조금만 수정 하면 Play Store 에 자동으로 앱을 출시 하는 컨트롤을 할 수 있겠구나 라는 생각이 든다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 아래 부분만 수정 해서&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플레이 스토어 비공개 테스트 Alpha 트랙에 업로드 하는 Github actions 워크 플로우를 적어 둔다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1748407881322&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;name: Android Release Build and Upload to Play Alpha

on:
  push:
    tags:
      - 'UPAv*' # 태그가 'UPAv'로 시작하는 경우에만 워크플로우 실행됨 (예: UPAv1.0.4)

jobs:
  build:
    name: Build Release AAB and Upload to Google Play Alpha
    runs-on: ubuntu-latest

    steps:
    # 리포지토리의 코드를 체크아웃 (다운로드)
      - name: Checkout code
        uses: actions/checkout@v3

    # JDK 17 설치 (Android 빌드 도구 사용을 위해 필요)
      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          distribution: 'zulu'
          java-version: '17'

    # keystore 파일 디코딩 (base64 &amp;rarr; 바이너리) 후 저장, 앱 서명에 사용됨
      - name: Decode keystore.jks
        run: |
          mkdir -p app/jks
          echo &quot;${{ secrets.RELEASE_KEYSTORE_BASE64 }}&quot; | base64 -d &amp;gt; app/jks/saveurlkey.jks

    # Firebase 연동을 위한 google-services.json 파일 디코딩 및 저장
      - name: Decode google-services.json
        run: |
          mkdir -p app
          echo &quot;${{ secrets.GOOGLE_SERVICES_JSON }}&quot; | base64 -d &amp;gt; app/google-services.json

    # gradlew 스크립트 실행 권한 부여 (gradle 빌드 도구 실행을 위함)
      - name: Grant execute permission to gradlew
        run: chmod +x ./gradlew

    # Release AAB 빌드 (앱 번들 생성), keystore 정보는 환경변수로 전달
      - name: Build Release AAB
        env:
          KEYSTORE_PASSWORD: ${{ secrets.RELEASE_KEYSTORE_PASSWORD }}
          KEY_ALIAS: ${{ secrets.RELEASE_KEYSTORE_ALIAS }}
          KEY_PASSWORD: ${{ secrets.RELEASE_KEY_PASSWORD }}
        run: ./gradlew clean bundleRelease

    # Play Console 배포를 위한 서비스 계정 JSON 파일 디코딩 및 저장
      - name: Decode Play Store Service Account
        run: |
          echo &quot;${{ secrets.PLAY_STORE_SERVICE_ACCOUNT_JSON }}&quot; | base64 -d &amp;gt; service-account.json

    # build.gradle에서 versionName 추출하여 GitHub Actions 변수로 저장 (예: v1.0.4)
      - name: Extract versionName from build.gradle
        id: version
        run: |
          VERSION_NAME=$(grep versionName app/build.gradle | head -n 1 | sed -E 's/.*&quot;([^&quot;]+)&quot;.*/\1/')
          echo &quot;name=v$VERSION_NAME&quot; &amp;gt;&amp;gt; &quot;$GITHUB_OUTPUT&quot;

    # Google Play 콘솔의 Alpha 트랙으로 AAB 업로드 (릴리스 노트 포함, draft 상태로 업로드됨)
      - name: Upload AAB to Google Play (Alpha Track)
        uses: r0adkll/upload-google-play@v1
        with:
          serviceAccountJson: service-account.json                         # 인증용 서비스 계정 JSON
          packageName: com.jinscompany.saveurl                             # 앱의 패키지 이름
          releaseFiles: app/build/outputs/bundle/release/app-release.aab   # 업로드할 AAB 파일 경로
          whatsNewDirectory: distribution/whatsnew                             # 릴리스 노트 경로
          releaseName: ${{ steps.version.outputs.name }}                   # versionName 기반 릴리스 이름 (예: v1.0.4)
          track: alpha                                                     # 배포 트랙 (alpha)
          status: completed                                                    # 배포 상태 (completed - 자동 배포,  draft - 임시 저장, 직접 승인 필요, inProgress - 점진적 배포 userFraction: 0.2  # 20% 사용자에게만 배포 )&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앱을 배포할 때 출시 노트도 같이 작성이 가능하다&amp;nbsp;&lt;br /&gt;whatsNewDirectory 이며 아래는 원칙적인 내용이란다. 각 언어별도 셋팅할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 출시 노트 언어별 경로이다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-05-28 오후 1.54.38.png&quot; data-origin-width=&quot;574&quot; data-origin-height=&quot;510&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/es32aa/btsOg9tltkT/nK0Ko9OojW11mFXk9gfZV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/es32aa/btsOg9tltkT/nK0Ko9OojW11mFXk9gfZV1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/es32aa/btsOg9tltkT/nK0Ko9OojW11mFXk9gfZV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fes32aa%2FbtsOg9tltkT%2FnK0Ko9OojW11mFXk9gfZV1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;574&quot; height=&quot;510&quot; data-filename=&quot;스크린샷 2025-05-28 오후 1.54.38.png&quot; data-origin-width=&quot;574&quot; data-origin-height=&quot;510&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 한국어만 지원하므로 whatsnew-ko-KR 이렇게 만들어서 저장했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;확장자는 없어야 하는게 원칙 !&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 출시 이름 ( 이건 유저에게 보이지 않고 오직 개발자만 볼 수 있음 )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제는 .. 저 코드는 코드넘버를 갖고오지 못하는 워크 플로우다 .. 왜 못가져오는지 몰겠지만.. 이건 쓰지 마시길 ..&amp;nbsp;&lt;/p&gt;</description>
      <category>Android/CICD</category>
      <author>녹색꼬맹이</author>
      <guid isPermaLink="true">https://jihunstudy.tistory.com/86</guid>
      <comments>https://jihunstudy.tistory.com/86#entry86comment</comments>
      <pubDate>Wed, 28 May 2025 13:59:26 +0900</pubDate>
    </item>
    <item>
      <title>[ CICD #2 ] GitHub Actions Firebase Distribution -2</title>
      <link>https://jihunstudy.tistory.com/85</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item adsense responsive&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;반응형&lt;/div&gt;
    &lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
    &lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-host=&quot;ca-host-pub-9691043933427338&quot; data-ad-client=&quot;ca-pub-8585691276129476&quot; data-ad-format=&quot;auto&quot;&gt;&lt;/ins&gt;
    &lt;script&gt;(adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item tenping&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;SMALL&lt;/div&gt;
    &lt;tenping class=&quot;adsbytenping&quot; style=&quot;width: 100%; max-width: 768px; margin: 0 auto; display: block;&quot; mediaid=&quot;2815027&quot; tenping-ad-display-type=&quot;UD8Mia8gyIoT5Z2MT6VB3Q%3d%3d&quot;&gt;&lt;/tenping&gt;
    &lt;script src=&quot;//tads.tenping.kr/scripts/adsbytenping.min.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 글에서 Github Secrets 를 등록 하는 방법을 정리했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jihunstudy.tistory.com/84&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2025.05.28 - [Android/CICD] - [ CICD #1 ] GitHub secrets 등록 -1&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1748406462635&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[ CICD #1 ] GitHub secrets 등록 -1&quot; data-og-description=&quot;예전부터 해보고 싶었던 빌드, 테스트, 배포 과정을 자동화에 대해서 시도해 보고 최종적으로 성공한 것에 대해 기록하고자 한다.CI/CD 도구로 여러가지가 있다는 건 알고만 있었다 1. Github Actions2&quot; data-og-host=&quot;jihunstudy.tistory.com&quot; data-og-source-url=&quot;https://jihunstudy.tistory.com/84&quot; data-og-url=&quot;https://jihunstudy.tistory.com/84&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Gm9ck/hyY0661u8w/7XH7wQPswJXDc94KeEk7a0/img.png?width=800&amp;amp;height=497&amp;amp;face=0_0_800_497,https://scrap.kakaocdn.net/dn/h3CiM/hyY1ejFnFI/HyMPtzYjXmzobjDhzangQk/img.png?width=800&amp;amp;height=497&amp;amp;face=0_0_800_497,https://scrap.kakaocdn.net/dn/rIkbH/hyY07SnVTt/yCUeaaeQwDP42ZjkXUEsQ0/img.png?width=1588&amp;amp;height=988&amp;amp;face=0_0_1588_988&quot;&gt;&lt;a href=&quot;https://jihunstudy.tistory.com/84&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jihunstudy.tistory.com/84&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Gm9ck/hyY0661u8w/7XH7wQPswJXDc94KeEk7a0/img.png?width=800&amp;amp;height=497&amp;amp;face=0_0_800_497,https://scrap.kakaocdn.net/dn/h3CiM/hyY1ejFnFI/HyMPtzYjXmzobjDhzangQk/img.png?width=800&amp;amp;height=497&amp;amp;face=0_0_800_497,https://scrap.kakaocdn.net/dn/rIkbH/hyY07SnVTt/yCUeaaeQwDP42ZjkXUEsQ0/img.png?width=1588&amp;amp;height=988&amp;amp;face=0_0_1588_988');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[ CICD #1 ] GitHub secrets 등록 -1&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;예전부터 해보고 싶었던 빌드, 테스트, 배포 과정을 자동화에 대해서 시도해 보고 최종적으로 성공한 것에 대해 기록하고자 한다.CI/CD 도구로 여러가지가 있다는 건 알고만 있었다 1. Github Actions2&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jihunstudy.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 Firebase Distribution 에 테스트 apk 를 등록 하는 워크 플로우를 정리해 보려고 한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개념은 이런거 같다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 원하는 브렌치안에 .github/workflows 파일을 만들어서 CI/CD를 진행 하는것,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에 내가 default 로 설정되어 있는 Main Branch 에 워크 플로우를 만들어서 CI/CD를 아무리 트리거를 해도 실행이 되지 않아 이게 뭔가 하고 계속 찾았던 적이 있다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 옵션으로 branch 를 적을 수도 있지만,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;찾아보니 기본적으로 해당 branch 워크 플로우를 만들어 놓는 것이 덜 햇갈릴 수 있을거 같다고 생각 했다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 우선 main branch 에는 init Code 만 Commit 되어 있기에 개발중인 develop branch 에 워크 플로우를 작성해서 트리거 하게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1748406740838&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;name: Android Release Build and Firebase App Distribution

on:
  push:
    tags:
      - 'FBv*' # FBv로 시작하는 태그가 푸시될 때만 워크플로우 실행 (예: FBv1.0.4)

jobs:
  build:
    name: Build Release APK and Upload to Firebase App Distribution
    runs-on: ubuntu-latest

    steps:
    # GitHub 리포지토리에서 코드 가져오기
      - name: Checkout code
        uses: actions/checkout@v3

    # JDK 17 설치 (Android 빌드 도구 사용을 위해 필요)
      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          distribution: 'zulu'
          java-version: '17'
          
    # keystore 파일 base64 디코딩 후 저장 (앱 서명에 사용)
      - name: Decode keystore.jks
        run: |
          mkdir -p app/jks
          echo &quot;${{ secrets.RELEASE_KEYSTORE_BASE64 }}&quot; | base64 -d &amp;gt; app/jks/saveurlkey.jks
          
    # google-services.json 파일 base64 디코딩 후 저장 (Firebase 연동에 필요)
      - name: Decode google-services.json
        run: |
          mkdir -p app
          echo &quot;${{ secrets.GOOGLE_SERVICES_JSON }}&quot; | base64 -d &amp;gt; app/google-services.json

    # gradlew 실행 권한 부여
      - name: Grant execute permission to gradlew
        run: chmod +x ./gradlew

    # 릴리즈 APK 빌드 (keystore 정보 환경변수로 전달)
      - name: Build Release APK
        env:
          KEYSTORE_PASSWORD: ${{ secrets.RELEASE_KEYSTORE_PASSWORD }}
          KEY_ALIAS: ${{ secrets.RELEASE_KEYSTORE_ALIAS }}
          KEY_PASSWORD: ${{ secrets.RELEASE_KEY_PASSWORD }}
        run: ./gradlew clean assembleRelease

    # Firebase CLI 설치 (배포를 위해 필요)
      - name: Install Firebase CLI
        run: npm install -g firebase-tools

    # Firebase 서비스 계정 JSON을 파일로 저장
      - name: Save Firebase Service Account JSON
        env:
          FIREBASE_SERVICE_ACCOUNT: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }}
        run: |
          echo &quot;$FIREBASE_SERVICE_ACCOUNT&quot; &amp;gt; ${{ github.workspace }}/service-account.json

    # Firebase App Distribution에 APK 업로드
      - name: Upload APK to Firebase App Distribution
        env:
          GOOGLE_APPLICATION_CREDENTIALS: ${{ github.workspace }}/service-account.json
        run: |
          firebase appdistribution:distribute app/build/outputs/apk/release/app-release.apk \
            --app ${{ secrets.FIREBASE_APP_ID }}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트리거는 모든 코드를 커밋하고 푸시한 후에 원하는 태그를 푸시 했을 때에만 트기거가 되도록 했다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떤 방법이던 상관 없겠지만, 나는 태그를 사용한것 뿐이다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 흐름상 느낀점은&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 로컬에서 필요한 파일들을&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;github repository 에는 당연히 없기 때문에&amp;nbsp;&lt;br /&gt;필요한 파일들을 가져오는 코드들이 대부분이며,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막에는 upLoad 하는 코드다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1748407249676&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;signingConfigs {
        create(&quot;release&quot;) {
            storeFile = file(&quot;jks/saveurlkey.jks&quot;)
            storePassword = System.getenv(&quot;KEYSTORE_PASSWORD&quot;)
            keyAlias = System.getenv(&quot;KEY_ALIAS&quot;)
            keyPassword = System.getenv(&quot;KEY_PASSWORD&quot;)
        }
    }
    
buildTypes {
        release {
            signingConfig = signingConfigs.getByName(&quot;release&quot;)
            ..
            ..
        }
    }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내 Repository 에 들어 있는 build.gradle 에 코드를 이렇게 수정해서 반영 해 줘야 한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;storeFile 는 당연히 로컬에서 jks 가 들어 있는 파일 위치를 지정해 줘야 하고,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;워크 플로우가 실행되면서 Github Secrets 에서 해당 위치에 keystore 파일을 넣어 주고 처리 하기 때문에 build.gradle 에 저렇게 처리해야 하는거 같다 ..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1748407525896&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# keystore 파일 base64 디코딩 후 저장 (앱 서명에 사용)
      - name: Decode keystore.jks
        run: |
          mkdir -p app/jks
          echo &quot;${{ secrets.RELEASE_KEYSTORE_BASE64 }}&quot; | base64 -d &amp;gt; app/jks/saveurlkey.jks&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;step 중에 하나 예를 들자면&amp;nbsp;&lt;br /&gt;keystore.jks 파일을 가져와서 repository 에 저장 할꺼야&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 app/jks 라는 폴더를 만들고 Github secrets 안에 있는 RELEASE_KEYSTORE_BASE64 를 가져와서 디코딩 해서 app/jks/saveurlkey.jks 라고 만들어서 넣어 둘꺼야&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라는 내용&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보다보면 내용들이 이해가 갈 것으로 보인다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Android/CICD</category>
      <category>apk</category>
      <category>firebase distribution</category>
      <category>github</category>
      <category>github actions</category>
      <category>Workflows</category>
      <category>워크플로우</category>
      <category>테스트 배포</category>
      <author>녹색꼬맹이</author>
      <guid isPermaLink="true">https://jihunstudy.tistory.com/85</guid>
      <comments>https://jihunstudy.tistory.com/85#entry85comment</comments>
      <pubDate>Wed, 28 May 2025 13:47:54 +0900</pubDate>
    </item>
    <item>
      <title>[ CICD #1 ] GitHub secrets 등록 -1</title>
      <link>https://jihunstudy.tistory.com/84</link>
      <description>&lt;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item adsense responsive&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;반응형&lt;/div&gt;
    &lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
    &lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-host=&quot;ca-host-pub-9691043933427338&quot; data-ad-client=&quot;ca-pub-8585691276129476&quot; data-ad-format=&quot;auto&quot;&gt;&lt;/ins&gt;
    &lt;script&gt;(adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item tenping&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;SMALL&lt;/div&gt;
    &lt;tenping class=&quot;adsbytenping&quot; style=&quot;width: 100%; max-width: 768px; margin: 0 auto; display: block;&quot; mediaid=&quot;2815027&quot; tenping-ad-display-type=&quot;UD8Mia8gyIoT5Z2MT6VB3Q%3d%3d&quot;&gt;&lt;/tenping&gt;
    &lt;script src=&quot;//tads.tenping.kr/scripts/adsbytenping.min.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예전부터 해보고 싶었던 빌드, 테스트, 배포 과정을 자동화에 대해서 시도해 보고 최종적으로 성공한 것에 대해 기록하고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CI/CD 도구로 여러가지가 있다는 건 알고만 있었다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Github Actions&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. GitLab CI/CD&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. Bitrise&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. Jenkins 등등..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Bitrise는 예전에 부장님께서 프로젝트 진행 중 무료 버전으로만 사용할 수 있게 설정해서 사용해 봤었는데 아직 개념이 없었어서 그런지 와닿지가 않았다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 개발중인 앱이 Github Repository로 관리 중이어서 이번엔 Github Actions를 이용해 보기로 하고 시작해 봤다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 Github Actions 에서 자동화를 진행할 코드를 워크 플로우 ( workflow )라고 하는 거 같다. 이 워크 플로우의 확장자는 xxx.yml으로 저장된다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원래 목표는 Play Store 에 배포까지 하는 거였지만.. 워크 플로우 프로레스를 제대로 이해하지 못하고 덤볐다가 엄청나게 실패만 한 경험이 있어서.. 아 우선 간단하게 앱이 빌드가 되는지부터 확인하고, 그다음에 파이어 베이스에 배포해보고.. 그다음에 플레이 스토어를 진행하자라는 생각으로 다시 처음부터 진행했었다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 해야 할 것은&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GitHub Secrets 를 등록해야 한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이건 외부에 노출 되면 안 되는 정보들을 여기에 올려 두고 워크 플로우에서 꺼내 사용하는 방식으로 진행되는 거 같다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기에 등록될 것들은 주로 keyStore.jks나 Google-service.json, Api Key 등등 Repository에 등록되지 않고 로컬에서 저장되어 사용되는 것들?이라고 이해하면 될 거 같다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-05-28 오전 11.12.34.png&quot; data-origin-width=&quot;1588&quot; data-origin-height=&quot;988&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pua6i/btsOdZ7rOi8/gDkoByJDQ44WOjt4AZ73kk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pua6i/btsOdZ7rOi8/gDkoByJDQ44WOjt4AZ73kk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pua6i/btsOdZ7rOi8/gDkoByJDQ44WOjt4AZ73kk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fpua6i%2FbtsOdZ7rOi8%2FgDkoByJDQ44WOjt4AZ73kk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1588&quot; height=&quot;988&quot; data-filename=&quot;스크린샷 2025-05-28 오전 11.12.34.png&quot; data-origin-width=&quot;1588&quot; data-origin-height=&quot;988&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 등록한 것들은 이렇다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 Secrets에 등록되어 있는 것들은 어떤건 파이어베이스 등록할 때 필요하여도, 어떤 건 플레이 스토어에 배포할 때 필요하고 하니 필요한 것들은 모두 등록해 놓는 것이다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 내가 Json 파일을 저장 하거나 Api 키를 저장할 때는 무조건 Base64 인코딩 한 값을 넣었다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모르겠다 Chat GPT가 그렇게 하라더라 ..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 다른 사람들은 그냥 넣었던데&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 넣으면 또 안되더라고 ?&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1748399287171&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;openssl base64 -in [keystore file path] | tr -d '\n' &amp;gt; [base64 file path]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Mac 터미널 기준 요렇게 하면 파일이 생성된다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 주로 xxx.txt 파일로 만들어서 사용했다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;줄 바꿈 없이 쭉 쓰여있어야 인식을 할 수 있어서 저런 옵션을 넣은 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Base64 인코딩해야 하는 것은 따로 적어 둘 테니 참고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;FIREBASE_APP_ID&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Firebase -&amp;gt; 프로젝트 설정 -&amp;gt; 일반 -&amp;gt; 내 앱 -&amp;gt; 앱 ID를 그대로 넣어줌&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;FIREBASE_SERVICE_ACCOUNT&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Firebase 서비스 계정의 Json 파일을 저장한 값 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;[Base64]&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/wzieba/Firebase-Distribution-Github-Action/wiki/FIREBASE_TOKEN-migration&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;생성 방법 URL참고&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1748398824424&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;FIREBASE_TOKEN migration&quot; data-og-description=&quot;This action uploads artifacts (.apk or .ipa) to Firebase App Distribution. - wzieba/Firebase-Distribution-Github-Action&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/wzieba/Firebase-Distribution-Github-Action/wiki/FIREBASE_TOKEN-migration&quot; data-og-url=&quot;https://github.com/wzieba/Firebase-Distribution-Github-Action/wiki/FIREBASE_TOKEN-migration&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/GIorJ/hyY1kRIFyR/jnSiUOBYFLCYkD3MMGu86k/img.png?width=1200&amp;amp;height=600&amp;amp;face=982_155_1032_209,https://scrap.kakaocdn.net/dn/7qnDY/hyY0lch1dW/1ju9jylZ9QdEclloGx8Vfk/img.png?width=1200&amp;amp;height=600&amp;amp;face=982_155_1032_209&quot;&gt;&lt;a href=&quot;https://github.com/wzieba/Firebase-Distribution-Github-Action/wiki/FIREBASE_TOKEN-migration&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/wzieba/Firebase-Distribution-Github-Action/wiki/FIREBASE_TOKEN-migration&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/GIorJ/hyY1kRIFyR/jnSiUOBYFLCYkD3MMGu86k/img.png?width=1200&amp;amp;height=600&amp;amp;face=982_155_1032_209,https://scrap.kakaocdn.net/dn/7qnDY/hyY0lch1dW/1ju9jylZ9QdEclloGx8Vfk/img.png?width=1200&amp;amp;height=600&amp;amp;face=982_155_1032_209');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;FIREBASE_TOKEN migration&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;This action uploads artifacts (.apk or .ipa) to Firebase App Distribution. - wzieba/Firebase-Distribution-Github-Action&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 만든 Json 파일 안에 있는 내용을 가져와서 저장하면 된다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;GOOGLE_SERVICE_JSON&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;google-service.json 저장한 값 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;[Base64]&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;PLAY_STORE_SERVICE_ACCOUNT_JSON&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Play Store 용 서비스 계정 Json &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;[Base64]&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;a href=&quot;https://support.pushpay.com/s/article/Setting-up-your-Google-Publishing-API#s1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;생성 방법 URL참고&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1748399009243&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;How to Set up your Google Publishing API&quot; data-og-description=&quot;Overview Setting up your Google Publishing API allows our team to improve your app over time, giving your community a world-class app experience. This article outlines the steps for setting up your Google Publishing API. Before You Start Ensure you have re&quot; data-og-host=&quot;support.pushpay.com&quot; data-og-source-url=&quot;https://support.pushpay.com/s/article/Setting-up-your-Google-Publishing-API#s1&quot; data-og-url=&quot;https://support.pushpay.com/s/article/Setting-up-your-Google-Publishing-API#s1&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bm588t/hyY1bN0Ucv/gkBktdFHHjYqAQMVPdYlS1/img.png?width=1528&amp;amp;height=374&amp;amp;face=0_0_1528_374,https://scrap.kakaocdn.net/dn/cTGDbp/hyYYwTOMlM/rrfpr6HxYkbkvbbQDZKJ20/img.png?width=550&amp;amp;height=448&amp;amp;face=0_0_550_448,https://scrap.kakaocdn.net/dn/bQRLXp/hyYYGWpgrP/fgZHz1O6BqG38FK8CcBpcK/img.png?width=540&amp;amp;height=347&amp;amp;face=0_0_540_347&quot;&gt;&lt;a href=&quot;https://support.pushpay.com/s/article/Setting-up-your-Google-Publishing-API#s1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://support.pushpay.com/s/article/Setting-up-your-Google-Publishing-API#s1&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bm588t/hyY1bN0Ucv/gkBktdFHHjYqAQMVPdYlS1/img.png?width=1528&amp;amp;height=374&amp;amp;face=0_0_1528_374,https://scrap.kakaocdn.net/dn/cTGDbp/hyYYwTOMlM/rrfpr6HxYkbkvbbQDZKJ20/img.png?width=550&amp;amp;height=448&amp;amp;face=0_0_550_448,https://scrap.kakaocdn.net/dn/bQRLXp/hyYYGWpgrP/fgZHz1O6BqG38FK8CcBpcK/img.png?width=540&amp;amp;height=347&amp;amp;face=0_0_540_347');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;How to Set up your Google Publishing API&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Overview Setting up your Google Publishing API allows our team to improve your app over time, giving your community a world-class app experience. This article outlines the steps for setting up your Google Publishing API. Before You Start Ensure you have re&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;support.pushpay.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것 때문에 정말 많이 고생했다.. 어디에도 이 내용이 없더라..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 못 찾은 건지.. firebase service account 만든 것처럼 뭔가를 만들고&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만들 때 권한 허용 하는 부분에서 서비스 계정 - 서비스 계정 유저 이걸 꼭 선택해야 되고&amp;nbsp;&lt;br /&gt;이걸 만든 다음에 만들어진 Email 부분을 Google Console에 협업에 추가를 해야 된다..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 만들어진 Json 파일을 여기에 가져와서 저장하면 된다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;RELEASE_KEYSTORE_BASE64&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;앱 apk 및 aab 추출할 때 만들었던 xxx.jks 파일 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;[Base64]&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;RELEASE_KEYSTORE_ALIAS&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;RELEASE_KEYSTORE_PASSWORD&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;RELEASE_KEY_PASSWORD&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Android/CICD</category>
      <category>CD</category>
      <category>CI</category>
      <category>CI/CD</category>
      <category>firebase</category>
      <category>firebase distribution</category>
      <category>github</category>
      <category>github actions</category>
      <category>github secrets</category>
      <category>테스트 앱 배포</category>
      <category>파이어베이스</category>
      <author>녹색꼬맹이</author>
      <guid isPermaLink="true">https://jihunstudy.tistory.com/84</guid>
      <comments>https://jihunstudy.tistory.com/84#entry84comment</comments>
      <pubDate>Wed, 28 May 2025 11:35:00 +0900</pubDate>
    </item>
    <item>
      <title>[ Flutter #1 ] 내가 만든 Flutter web 접속 할 수 있게 해보자 ( Github -  Pages &amp;amp; Actions )</title>
      <link>https://jihunstudy.tistory.com/83</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플러터는 Android, iOS, Web 하나의 소스코드를 이용해서 만들 수 있는 플렛폼 이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이중에서 내가 만든 Flutter 코드를 web에 배포 해서 언제 어디서든 접속 할 수 있는 환경을 만들어 보자.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 내가 사용한 방법은 GitHub 에 Pages 를 이용한 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 형상 관리를 통해 내가 Flutter 코드를 수정 해서 Github에 Commit 하게 되면 자동으로 빌드해서 Pages 에 배포 되는 형식인 CI/CD 또한 같이 적용 될 수 있도록 해보려고 한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아직 배우는 단계 이다 보니 용어가 맞지 않을 수 있다. 참고&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item adsense responsive&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;반응형&lt;/div&gt;
    &lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
    &lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-host=&quot;ca-host-pub-9691043933427338&quot; data-ad-client=&quot;ca-pub-8585691276129476&quot; data-ad-format=&quot;auto&quot;&gt;&lt;/ins&gt;
    &lt;script&gt;(adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item tenping&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;SMALL&lt;/div&gt;
    &lt;tenping class=&quot;adsbytenping&quot; style=&quot;width: 100%; max-width: 768px; margin: 0 auto; display: block;&quot; mediaid=&quot;2815027&quot; tenping-ad-display-type=&quot;UD8Mia8gyIoT5Z2MT6VB3Q%3d%3d&quot;&gt;&lt;/tenping&gt;
    &lt;script src=&quot;//tads.tenping.kr/scripts/adsbytenping.min.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 글로 간단하게 정리해서 올려보면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Github Repository 를 만든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 내가 앞으로 작업 환경에 맞는 경로에 내가 만든 Repository 를 클론 해 준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 클론 받은 경로에다가 Flutter 프로젝트를 만들어 준다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 그리고 커밋 해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기까지 간단하게 만들어 볼 수 있을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자신이 만든 프로젝트 최상위에 &lt;span style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot;&gt;.github/workflows/build-deploy.yml&lt;span&gt; 를 만들어 준다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot;&gt;&lt;span&gt;이게 아마 Actions 에서 담당하는 것들을 나열하는듯 하다.&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-11-06 오후 4.27.04.png&quot; data-origin-width=&quot;698&quot; data-origin-height=&quot;690&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bl3pQY/btsKw7nO2zX/uWcmSoSdnKtPRHHxlroknK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bl3pQY/btsKw7nO2zX/uWcmSoSdnKtPRHHxlroknK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bl3pQY/btsKw7nO2zX/uWcmSoSdnKtPRHHxlroknK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbl3pQY%2FbtsKw7nO2zX%2FuWcmSoSdnKtPRHHxlroknK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;698&quot; height=&quot;690&quot; data-filename=&quot;스크린샷 2024-11-06 오후 4.27.04.png&quot; data-origin-width=&quot;698&quot; data-origin-height=&quot;690&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1730878128383&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;name: Deploy Flutter Web App to GitHub Pages

on:
  push:
    branches:
      - main

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Flutter
        uses: subosito/flutter-action@v2
        with:
          flutter-version: '3.16.9' # 사용하는 Flutter 버전으로 변경

      - name: Install Dependencies
        run: flutter pub get

      - name: Build Web
        run: flutter build web --release

      - name: Add .nojekyll
        run: echo &amp;gt; build/web/.nojekyll

      - name: Deploy to GitHub Pages
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.MY_SECRET_KEY_NAME }} # repository에서 사용할 시크릿 키 이름
          publish_dir: build/web
          publish_branch: gh-pages&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot;&gt;build-deploy.yml 파일에 위와 같은 내용을 저장 하고 커밋.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot;&gt;그리고&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot;&gt;내 Repository 이름을 적어 줘야 하는 곳이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot;&gt;web/index.html 파일을 열어서&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1730878263555&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;base href = &quot;/&amp;lt;자신의 레파지토리 이름&amp;gt;/&quot;&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 부분에 넣어 준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1730878287510&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;flutter build web --release&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 빌드 하게 되면,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;build/web 부분이 생성된걸 확인하고, 커밋&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드적으로는 일단 끝,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 Github 를 셋팅 해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Github에 자신의 프로필 이미지를 눌러 settings/developer settings 에 들어가서 Token을 발급 받자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Personal access tokens (classic) 으로 발급 받았다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-11-06 오후 4.34.10.png&quot; data-origin-width=&quot;1796&quot; data-origin-height=&quot;540&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c5TWpj/btsKypuC2PN/cbd6V9izZ6N87TyZYGVcv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c5TWpj/btsKypuC2PN/cbd6V9izZ6N87TyZYGVcv1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c5TWpj/btsKypuC2PN/cbd6V9izZ6N87TyZYGVcv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc5TWpj%2FbtsKypuC2PN%2Fcbd6V9izZ6N87TyZYGVcv1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1796&quot; height=&quot;540&quot; data-filename=&quot;스크린샷 2024-11-06 오후 4.34.10.png&quot; data-origin-width=&quot;1796&quot; data-origin-height=&quot;540&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;repo 와 workflow 를 체크하고 만들어서 토큰발급 진행&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 토큰을 복사하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 만든 Repository - settings - secrets and variables - Actions 를 들어가서 New repository secret 선택&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이름은 내가 &lt;span style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot;&gt;build-deploy.yml 파일 안에 적어준&amp;nbsp; github_token 을 그대로 넣어 준다.&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #222222; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;background-color: #2b2b2b; color: #a9b7c6;&quot;&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;MY_SECRET_KEY_NAME&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 아래 Secret 은 아까 발급받은 토큰을 넣고 저장해 준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-11-06 오후 4.38.29.png&quot; data-origin-width=&quot;2010&quot; data-origin-height=&quot;524&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NWb0m/btsKzaKg23k/RCkMK2iajLBZ6x1L0nLTrK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NWb0m/btsKzaKg23k/RCkMK2iajLBZ6x1L0nLTrK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NWb0m/btsKzaKg23k/RCkMK2iajLBZ6x1L0nLTrK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNWb0m%2FbtsKzaKg23k%2FRCkMK2iajLBZ6x1L0nLTrK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2010&quot; height=&quot;524&quot; data-filename=&quot;스크린샷 2024-11-06 오후 4.38.29.png&quot; data-origin-width=&quot;2010&quot; data-origin-height=&quot;524&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 확인해 봐야 할게&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pages 에서 위 사진처럼 gh-pages 로 셋팅 되어 있는지 확인해야 한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 gh-pages 로 셋팅이 되어 있지 않은경우&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Actions 에서 진행 하고 있는 것들이 모두 완료 되지 않은것 이니 위에서부터 놓친것이 없는지 확인 해 보자&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-11-06 오후 4.39.49.png&quot; data-origin-width=&quot;3958&quot; data-origin-height=&quot;1380&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cI5VU5/btsKykfNCzk/viXohpMeAOqcAaRcR6wUwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cI5VU5/btsKykfNCzk/viXohpMeAOqcAaRcR6wUwK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cI5VU5/btsKykfNCzk/viXohpMeAOqcAaRcR6wUwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcI5VU5%2FbtsKykfNCzk%2FviXohpMeAOqcAaRcR6wUwK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3958&quot; height=&quot;1380&quot; data-filename=&quot;스크린샷 2024-11-06 오후 4.39.49.png&quot; data-origin-width=&quot;3958&quot; data-origin-height=&quot;1380&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커밋을 할 때마다 Actions 에서 알아서 빌드 배포 과정이 이루어 지고 있는 걸 확인 할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-11-06 오후 4.41.09.png&quot; data-origin-width=&quot;6012&quot; data-origin-height=&quot;2992&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mLVkN/btsKyh4rfAX/3ABAYJQzdpoi6smtXKheDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mLVkN/btsKyh4rfAX/3ABAYJQzdpoi6smtXKheDK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mLVkN/btsKyh4rfAX/3ABAYJQzdpoi6smtXKheDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmLVkN%2FbtsKyh4rfAX%2F3ABAYJQzdpoi6smtXKheDK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;6012&quot; height=&quot;2992&quot; data-filename=&quot;스크린샷 2024-11-06 오후 4.41.09.png&quot; data-origin-width=&quot;6012&quot; data-origin-height=&quot;2992&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요렇게 플러터 첫 화면을 웹 페이지에서 확인 가능&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 간단하게 타이틀을 수정해서 커밋 해봤는데&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;actions 에서 알아서 빌드 배포 과정이 이루어지면서 수정 된걸 확인 할 수 있었다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Flutter</category>
      <category>actions</category>
      <category>Flutter</category>
      <category>flutter web</category>
      <category>github</category>
      <category>Pages</category>
      <category>Web</category>
      <category>호스팅</category>
      <author>녹색꼬맹이</author>
      <guid isPermaLink="true">https://jihunstudy.tistory.com/83</guid>
      <comments>https://jihunstudy.tistory.com/83#entry83comment</comments>
      <pubDate>Wed, 6 Nov 2024 16:50:24 +0900</pubDate>
    </item>
    <item>
      <title>[Logitech] MX Keys for mac 키보드</title>
      <link>https://jihunstudy.tistory.com/82</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;약 1년전에 몬스타기어 닌자87 키보드를 사용하다가 쓰다보면서 기계식 키보드는 나한테 맞지 않는거 같다라는 생각을 자주 하게 되서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간간히 맥 전용으로 쓸수 있는 키보드를 찾던중&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로지텍에서 나온 맥 전용 키보드를 알게 되서 구매 하게 됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item adsense responsive&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;반응형&lt;/div&gt;
    &lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
    &lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-host=&quot;ca-host-pub-9691043933427338&quot; data-ad-client=&quot;ca-pub-8585691276129476&quot; data-ad-format=&quot;auto&quot;&gt;&lt;/ins&gt;
    &lt;script&gt;(adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jihunstudy.tistory.com/65&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2023.05.10 - [일상] - [기계식키보드] 몬스타기어 닌자87K5 RGB 개봉&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1720572844887&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[기계식키보드] 몬스타기어 닌자87K5 RGB 개봉&quot; data-og-description=&quot;IT를 시작하면서 키보드 타이핑을 많이(?) 치다 보니 키보드에 관심을 가지게 됐다. 하지만, 그저 블루투스 기능이 되는 키보드만 생각했지 기계식 키보드가 뭔지도 몰랐다.&amp;nbsp;동료 개발자로부터 &quot; data-og-host=&quot;jihunstudy.tistory.com&quot; data-og-source-url=&quot;https://jihunstudy.tistory.com/65&quot; data-og-url=&quot;https://jihunstudy.tistory.com/65&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bHBpJf/hyWzCmWbzx/dh2masqPwTkmdr6YKJMhj0/img.png?width=800&amp;amp;height=873&amp;amp;face=0_0_800_873,https://scrap.kakaocdn.net/dn/bEMUWk/hyWvRF3jEe/kfKztxxHO5ZWYkrKJ3sq00/img.png?width=800&amp;amp;height=873&amp;amp;face=0_0_800_873,https://scrap.kakaocdn.net/dn/9S5qr/hyWvQmSw4V/98k77EK3sELs8TRlKznhp1/img.png?width=1401&amp;amp;height=2457&amp;amp;face=0_0_1401_2457&quot;&gt;&lt;a href=&quot;https://jihunstudy.tistory.com/65&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jihunstudy.tistory.com/65&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bHBpJf/hyWzCmWbzx/dh2masqPwTkmdr6YKJMhj0/img.png?width=800&amp;amp;height=873&amp;amp;face=0_0_800_873,https://scrap.kakaocdn.net/dn/bEMUWk/hyWvRF3jEe/kfKztxxHO5ZWYkrKJ3sq00/img.png?width=800&amp;amp;height=873&amp;amp;face=0_0_800_873,https://scrap.kakaocdn.net/dn/9S5qr/hyWvQmSw4V/98k77EK3sELs8TRlKznhp1/img.png?width=1401&amp;amp;height=2457&amp;amp;face=0_0_1401_2457');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[기계식키보드] 몬스타기어 닌자87K5 RGB 개봉&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;IT를 시작하면서 키보드 타이핑을 많이(?) 치다 보니 키보드에 관심을 가지게 됐다. 하지만, 그저 블루투스 기능이 되는 키보드만 생각했지 기계식 키보드가 뭔지도 몰랐다.&amp;nbsp;동료 개발자로부터&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jihunstudy.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구매는 인터넷으로 로지텍 코리아 인증 ? 받은 사이트에서 구매 했는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저녁 11시에 주문을 했는데 다음날 오후 7시에 왔다 ..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배송 내역을 보니 구매 하자마자 바로 배송을 시작한게 기록되어 있어서 놀랐다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요즘 배송 시스템이란.. 보면 볼수록 놀랍다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;게다가 무료배송..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;금액은 119,000원에 구매했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_Photo_2024-07-10-09-53-27 001.jpeg&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;1600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SU9YC/btsIs6p9OzA/GWcZKkMa68RAaUyQ5OUVfk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SU9YC/btsIs6p9OzA/GWcZKkMa68RAaUyQ5OUVfk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SU9YC/btsIs6p9OzA/GWcZKkMa68RAaUyQ5OUVfk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSU9YC%2FbtsIs6p9OzA%2FGWcZKkMa68RAaUyQ5OUVfk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;901&quot; height=&quot;1600&quot; data-filename=&quot;KakaoTalk_Photo_2024-07-10-09-53-27 001.jpeg&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;1600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_Photo_2024-07-10-09-53-28 002.jpeg&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;1600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckZw3X/btsIt7O9v2O/S965fBwtcK0k8Kq8rZPBPk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckZw3X/btsIt7O9v2O/S965fBwtcK0k8Kq8rZPBPk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckZw3X/btsIt7O9v2O/S965fBwtcK0k8Kq8rZPBPk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FckZw3X%2FbtsIt7O9v2O%2FS965fBwtcK0k8Kq8rZPBPk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;901&quot; height=&quot;1600&quot; data-filename=&quot;KakaoTalk_Photo_2024-07-10-09-53-28 002.jpeg&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;1600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_Photo_2024-07-10-09-53-28 003.jpeg&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;1600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnZdan/btsItPBhHOy/0bx82ZgUK2nFRPfNNa36i0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnZdan/btsItPBhHOy/0bx82ZgUK2nFRPfNNa36i0/img.jpg&quot; data-alt=&quot;구성품은 박스 하나인데 겉 박스? 가 쓸데 없이 크다 ..&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnZdan/btsItPBhHOy/0bx82ZgUK2nFRPfNNa36i0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnZdan%2FbtsItPBhHOy%2F0bx82ZgUK2nFRPfNNa36i0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;901&quot; height=&quot;1600&quot; data-filename=&quot;KakaoTalk_Photo_2024-07-10-09-53-28 003.jpeg&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;1600&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;구성품은 박스 하나인데 겉 박스? 가 쓸데 없이 크다 ..&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_Photo_2024-07-10-09-53-28 004.jpeg&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;1600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/owFm6/btsIuvhXfTi/EtcklO5eGKBUOI2iNxJLmK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/owFm6/btsIuvhXfTi/EtcklO5eGKBUOI2iNxJLmK/img.jpg&quot; data-alt=&quot;구성품은 단순히 키보드, 유니파잉 USB, 전원 케이블&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/owFm6/btsIuvhXfTi/EtcklO5eGKBUOI2iNxJLmK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FowFm6%2FbtsIuvhXfTi%2FEtcklO5eGKBUOI2iNxJLmK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;901&quot; height=&quot;1600&quot; data-filename=&quot;KakaoTalk_Photo_2024-07-10-09-53-28 004.jpeg&quot; data-origin-width=&quot;901&quot; data-origin-height=&quot;1600&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;구성품은 단순히 키보드, 유니파잉 USB, 전원 케이블&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_Photo_2024-07-10-09-53-29 005.jpeg&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;901&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qajuF/btsIsfhc0j2/1RRE01A8JLhTdWkkV1BWa1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qajuF/btsIsfhc0j2/1RRE01A8JLhTdWkkV1BWa1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qajuF/btsIsfhc0j2/1RRE01A8JLhTdWkkV1BWa1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqajuF%2FbtsIsfhc0j2%2F1RRE01A8JLhTdWkkV1BWa1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1600&quot; height=&quot;901&quot; data-filename=&quot;KakaoTalk_Photo_2024-07-10-09-53-29 005.jpeg&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;901&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어느 글에서 맥 전용 키보드는 유니파잉이 없다고 들은거 같은데 이번에 바뀐건지 잘 모르겠지만, 있어서 다행이군&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_Photo_2024-07-10-09-53-29 006.jpeg&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;901&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dYUOdI/btsItDujo4Y/x4YaMAZSue0wDiylmUtejK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dYUOdI/btsItDujo4Y/x4YaMAZSue0wDiylmUtejK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dYUOdI/btsItDujo4Y/x4YaMAZSue0wDiylmUtejK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdYUOdI%2FbtsItDujo4Y%2Fx4YaMAZSue0wDiylmUtejK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1600&quot; height=&quot;901&quot; data-filename=&quot;KakaoTalk_Photo_2024-07-10-09-53-29 006.jpeg&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;901&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유니파잉 연결 하면 바로 키보드 설정 하는 화면이 뜨고 바로 사용가능&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 사람들은 한영 바꾸는게 잘 안된다고 하는데 나는 다행이 잘되는 거 같다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_Photo_2024-07-10-10-13-33.jpeg&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;901&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bve8aT/btsItTcDN62/KlMfMxypdQ8PEZfvMBlLJ0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bve8aT/btsItTcDN62/KlMfMxypdQ8PEZfvMBlLJ0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bve8aT/btsItTcDN62/KlMfMxypdQ8PEZfvMBlLJ0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbve8aT%2FbtsItTcDN62%2FKlMfMxypdQ8PEZfvMBlLJ0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1600&quot; height=&quot;901&quot; data-filename=&quot;KakaoTalk_Photo_2024-07-10-10-13-33.jpeg&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;901&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이게 텐키리스를 쓰다가 풀배열을 쓰게 되니 불편한 점이 몇가지 있는거 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 텐키리스 배열일때에는 내 두 손을 기준으로 키보드가 가운데에 위치해 보기도 편하고 잡기도 편했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 풀배열로 하니까 .. 음.. 키보드가 약간 왼쪽에 있는 느낌을 받아서 신경이 쓰이기도 하다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 텐키리스 쓰면 키보드가 작아서 그런지 마우스나 트랙패트로 손이 갈때 가깝다는 생각이 전혀 없었는데, 풀배열을 쓰다보니 와.. 멀다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트랙패드까지 손이 가야 되는 느낌이 생각보다 많이 느껴진다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 이 두가지 단점? 이건 이 키보드에 단점이 아니기에 ..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 잘 적응해 봐야지&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아 그리고 사람바이사람 케이스로써 기계식 키보드를 쓰다가 이 키보드로 와보니 .. 타이핑이 어색하다 ..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오타율이 적다는.. 말이 있는데 음.. 이건 정말 케바케 인듯&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 잘 적응 해봐야겠다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-07-10 오전 10.19.47.png&quot; data-origin-width=&quot;3004&quot; data-origin-height=&quot;1692&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l7GUM/btsIsy8ymN4/fCEYrJXkiekyXI1MQeHOBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l7GUM/btsIsy8ymN4/fCEYrJXkiekyXI1MQeHOBK/img.png&quot; data-alt=&quot;요거요거 물건일세&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l7GUM/btsIsy8ymN4/fCEYrJXkiekyXI1MQeHOBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl7GUM%2FbtsIsy8ymN4%2FfCEYrJXkiekyXI1MQeHOBK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3004&quot; height=&quot;1692&quot; data-filename=&quot;스크린샷 2024-07-10 오전 10.19.47.png&quot; data-origin-width=&quot;3004&quot; data-origin-height=&quot;1692&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;요거요거 물건일세&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-07-10 시간: 10.21.31.png&quot; data-origin-width=&quot;3012&quot; data-origin-height=&quot;1714&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUgpTV/btsIuI2v30r/PLKU5OxWjoqaEXgCS21nQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUgpTV/btsIuI2v30r/PLKU5OxWjoqaEXgCS21nQk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUgpTV/btsIuI2v30r/PLKU5OxWjoqaEXgCS21nQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUgpTV%2FbtsIuI2v30r%2FPLKU5OxWjoqaEXgCS21nQk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3012&quot; height=&quot;1714&quot; data-filename=&quot;스크린샷 2024-07-10 시간: 10.21.31.png&quot; data-origin-width=&quot;3012&quot; data-origin-height=&quot;1714&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커스터마이징 할수 있는 버튼을 수정 할 수 있는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 잘 쓰지 않는다고 생각하는 버튼을&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;카카오톡 열기랑 슬렉 열기로 바꿔봤다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이거 아주 물건이네 .. ㅋㅋㅋ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이걸로 자동화를 더 연결해서 편하게 쓸 수 있다는데 이건 좀더 공부를 해봐야겠다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;------------------------------------- 추가글 ------&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근접 센서가 달려 있어서 키보드가 사용되지 않을때는 백라이트가 꺼지고 손을 올리면 켜진다고 되어 있어서 봤는데 내껀 그냥 계속 켜져있네 ?? 라고 생각해서 이것저것 만저보다가&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;충전단자를 빼로 해보니까 되네.. ?&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;충전중일때에는 그냥 계속 켜져 있나보다 ..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 맥OS 랑 windows 랑 options + 소프트 웨어가 좀 다르단다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맥 OS 에서는 키보드 배터리 잔량이 숫자로 표기 되지 않고 양호, 보통, 부족 이 세가지로만 판단 해야 되고&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;키보드가 충전중일때에트 키보드 오른쪽 LED가 계속 점등이 되고, 완충되면 계속 켜져 있단다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주황색 불이 들어오면 10% 미만이라 충전이 필요 하다..라고 한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;음..................... 조금 불편할 수도 있겠구만&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>일상</category>
      <category>Mac</category>
      <category>MX Keys</category>
      <category>MX keys for mac</category>
      <category>로지텍</category>
      <category>맥 전용</category>
      <category>풀배열 키보드</category>
      <author>녹색꼬맹이</author>
      <guid isPermaLink="true">https://jihunstudy.tistory.com/82</guid>
      <comments>https://jihunstudy.tistory.com/82#entry82comment</comments>
      <pubDate>Wed, 10 Jul 2024 10:23:32 +0900</pubDate>
    </item>
    <item>
      <title>[ Etc #20 ] AOS Image Url Bitmap 가져오기</title>
      <link>https://jihunstudy.tistory.com/81</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item adsense responsive&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;반응형&lt;/div&gt;
    &lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
    &lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-host=&quot;ca-host-pub-9691043933427338&quot; data-ad-client=&quot;ca-pub-8585691276129476&quot; data-ad-format=&quot;auto&quot;&gt;&lt;/ins&gt;
    &lt;script&gt;(adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item tenping&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;SMALL&lt;/div&gt;
    &lt;tenping class=&quot;adsbytenping&quot; style=&quot;width: 100%; max-width: 768px; margin: 0 auto; display: block;&quot; mediaid=&quot;2815027&quot; tenping-ad-display-type=&quot;UD8Mia8gyIoT5Z2MT6VB3Q%3d%3d&quot;&gt;&lt;/tenping&gt;
    &lt;script src=&quot;//tads.tenping.kr/scripts/adsbytenping.min.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #2b2b2b; color: #a9b7c6;&quot;&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;fun getBitmapFromURL(src: String): Bitmap? {
    return try {
        val url = URL(src)
        val connection =
            url.openConnection() as HttpURLConnection
        connection.setDoInput(true)
        connection.connect()
        val input = connection.inputStream
        BitmapFactory.decodeStream(input)
    } catch (e: IOException) {
        e.printStackTrace()
        null
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;</description>
      <category>Android/Etc</category>
      <category>AOS</category>
      <category>aos img url bitmap</category>
      <category>Bitmap</category>
      <author>녹색꼬맹이</author>
      <guid isPermaLink="true">https://jihunstudy.tistory.com/81</guid>
      <comments>https://jihunstudy.tistory.com/81#entry81comment</comments>
      <pubDate>Thu, 30 May 2024 14:44:46 +0900</pubDate>
    </item>
    <item>
      <title>[ Widget #2 ] AOS Widget 에서 Glide 이미지 로딩</title>
      <link>https://jihunstudy.tistory.com/80</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item adsense responsive&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;반응형&lt;/div&gt;
    &lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
    &lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-host=&quot;ca-host-pub-9691043933427338&quot; data-ad-client=&quot;ca-pub-8585691276129476&quot; data-ad-format=&quot;auto&quot;&gt;&lt;/ins&gt;
    &lt;script&gt;(adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item tenping&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;SMALL&lt;/div&gt;
    &lt;tenping class=&quot;adsbytenping&quot; style=&quot;width: 100%; max-width: 768px; margin: 0 auto; display: block;&quot; mediaid=&quot;2815027&quot; tenping-ad-display-type=&quot;UD8Mia8gyIoT5Z2MT6VB3Q%3d%3d&quot;&gt;&lt;/tenping&gt;
    &lt;script src=&quot;//tads.tenping.kr/scripts/adsbytenping.min.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #2b2b2b; color: #a9b7c6;&quot;&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;implementation(&quot;com.github.bumptech.glide:glide:4.11.0&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #2b2b2b; color: #a9b7c6;&quot;&gt;
&lt;pre class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;val target = AppWidgetTarget(context, R.id.img, views, appWidgetId)
Glide.with(context)
    .asBitmap()
    .load(widgetImg)
    .override(160.toPx, 160.toPx)
    .placeholder(R.drawable.ic_launcher_foreground)
    .error(R.drawable.ic_launcher_foreground)
    .into(target)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Android/Widget</category>
      <category>Glide</category>
      <category>widget glide</category>
      <category>widget 이미지 로딩</category>
      <author>녹색꼬맹이</author>
      <guid isPermaLink="true">https://jihunstudy.tistory.com/80</guid>
      <comments>https://jihunstudy.tistory.com/80#entry80comment</comments>
      <pubDate>Thu, 30 May 2024 14:42:45 +0900</pubDate>
    </item>
    <item>
      <title>[ Widget #1 ] AOS Widget 만들기</title>
      <link>https://jihunstudy.tistory.com/79</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item adsense responsive&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;반응형&lt;/div&gt;
    &lt;script src=&quot;//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
    &lt;ins class=&quot;adsbygoogle&quot; style=&quot;display: block;&quot; data-ad-host=&quot;ca-host-pub-9691043933427338&quot; data-ad-client=&quot;ca-pub-8585691276129476&quot; data-ad-format=&quot;auto&quot;&gt;&lt;/ins&gt;
    &lt;script&gt;(adsbygoogle = window.adsbygoogle || []).push({});&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div class=&quot;revenue_unit_wrap&quot;&gt;
  &lt;div class=&quot;revenue_unit_item tenping&quot;&gt;
    &lt;div class=&quot;revenue_unit_info&quot;&gt;SMALL&lt;/div&gt;
    &lt;tenping class=&quot;adsbytenping&quot; style=&quot;width: 100%; max-width: 768px; margin: 0 auto; display: block;&quot; mediaid=&quot;2815027&quot; tenping-ad-display-type=&quot;UD8Mia8gyIoT5Z2MT6VB3Q%3d%3d&quot;&gt;&lt;/tenping&gt;
    &lt;script src=&quot;//tads.tenping.kr/scripts/adsbytenping.min.js&quot; async=&quot;async&quot;&gt;&lt;/script&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;안드로이드 위젯 관련해서 만들어볼 기회가 생겨서 해보다가&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;너무 이해를 못하고 삽질만 하다가 내가 원하는 기능에 도달되서 기록에 남겨 두려 한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 기초적으로 위젯을 만들기 위한 셋팅에 관련된 것부터 시작 한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-30 오후 2.12.07.png&quot; data-origin-width=&quot;1614&quot; data-origin-height=&quot;1558&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NI7Lz/btsHHgm1MhL/KBK7iMfP1ZwlHkuKH5HPr1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NI7Lz/btsHHgm1MhL/KBK7iMfP1ZwlHkuKH5HPr1/img.png&quot; data-alt=&quot;이렇게 쉽게 위젯을 셋탕 할 수 있음.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NI7Lz/btsHHgm1MhL/KBK7iMfP1ZwlHkuKH5HPr1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNI7Lz%2FbtsHHgm1MhL%2FKBK7iMfP1ZwlHkuKH5HPr1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;592&quot; height=&quot;571&quot; data-filename=&quot;스크린샷 2024-05-30 오후 2.12.07.png&quot; data-origin-width=&quot;1614&quot; data-origin-height=&quot;1558&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이렇게 쉽게 위젯을 셋탕 할 수 있음.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-05-30 오후 2.13.09.png&quot; data-origin-width=&quot;1800&quot; data-origin-height=&quot;1362&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqrgQi/btsHHIQP5hw/mQ0mhlko6KwQKjdl6ZsRXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqrgQi/btsHHIQP5hw/mQ0mhlko6KwQKjdl6ZsRXK/img.png&quot; data-alt=&quot;다른 옵션들은 모르겠고 그냥 만들었다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqrgQi/btsHHIQP5hw/mQ0mhlko6KwQKjdl6ZsRXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcqrgQi%2FbtsHHIQP5hw%2FmQ0mhlko6KwQKjdl6ZsRXK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;470&quot; height=&quot;356&quot; data-filename=&quot;스크린샷 2024-05-30 오후 2.13.09.png&quot; data-origin-width=&quot;1800&quot; data-origin-height=&quot;1362&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;다른 옵션들은 모르겠고 그냥 만들었다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;App Widget 으로 만들면 파일이 여러개 생성 되면서 Manifest 파일에 브로드캐스트 도 같이 생성되어 위젯이 알아서 셋팅되어 진다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 이건 Layout 은 고려되지 않은 상태로 어떻게 위젯을 업데이트 하는가에 대해서만 얘기할 예정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 아래 내용이 없으면 그냥 참고만 하길.. 완벽하게 이해 한게 아니라..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1717046466686&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;appwidget-provider xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    android:description=&quot;@string/app_widget_description&quot;
    android:initialKeyguardLayout=&quot;@layout/new_app_widget&quot;
    android:initialLayout=&quot;@layout/new_app_widget&quot;
    android:minWidth=&quot;160dp&quot;
    android:minHeight=&quot;200dp&quot;
    android:previewImage=&quot;@drawable/example_appwidget_preview&quot;
    android:previewLayout=&quot;@layout/new_app_widget&quot;
    android:resizeMode=&quot;horizontal|vertical&quot;
    android:targetCellWidth=&quot;1&quot;
    android:targetCellHeight=&quot;1&quot;
    android:updatePeriodMillis=&quot;86400000&quot;
    android:widgetCategory=&quot;home_screen&quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1717046363365&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class NewAppWidget : AppWidgetProvider() {

    companion object {
        const val ACTION_WIDGET_REFRESH = &quot;action_widget_refresh&quot;
    }

    private val job = SupervisorJob()
    private val coroutineScope = CoroutineScope(Dispatchers.Main + job)

    override fun onUpdate(
        context: Context,
        appWidgetManager: AppWidgetManager,
        appWidgetIds: IntArray
    ) {

        val widgetImg = ConfigModule(context).widgetImg
        if (widgetImg.isEmpty()) {
            Log.d(&quot;NewAppWidget&quot;, &quot;onUpdate &amp;gt; widgetImg is Empty&quot;)
            for (appWidgetId in appWidgetIds) loadingWidget(context, appWidgetManager, appWidgetId)
            enqueueWork(context)
        } else {
            Log.d(&quot;NewAppWidget&quot;, &quot;onUpdate &amp;gt; widgetImg Update&quot;)
            for (appWidgetId in appWidgetIds) {
                updateLoadImgWidget(context, appWidgetManager, appWidgetId, widgetImg)
            }
        }
    }
    override fun onEnabled(context: Context) {}
    override fun onDisabled(context: Context) {
        job.cancel()
    }

    override fun onReceive(context: Context, intent: Intent) {
        Log.d(&quot;NewAppWidget&quot;, &quot;onReceive &amp;gt; ${intent.action}&quot;)
        val appWidgetManager = AppWidgetManager.getInstance(context)
        val thisWidget = ComponentName(context, NewAppWidget::class.java)
        val appWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget)

        when (intent.action) {
            ACTION_WIDGET_REFRESH -&amp;gt; {
                ConfigModule(context).widgetImg = &quot;&quot;
                onUpdate(context, appWidgetManager, appWidgetIds)
            }
        }


        super.onReceive(context, intent)
    }

    private fun enqueueWork(context: Context) {
        /*val inputData = Data.Builder()
                .putInt(&quot;id&quot;, appWidgetId)
                .build()*/
        val workRequest = OneTimeWorkRequestBuilder&amp;lt;WidgetWork&amp;gt;()
            //.setInputData(inputData)
            .build()
        WorkManager.getInstance(context).enqueue(workRequest)
    }

    private fun loadingWidget(context: Context, appWidgetManager: AppWidgetManager, appWidgetId: Int,) {
        val views = RemoteViews(context.packageName, R.layout.new_app_widget)
        views.setViewVisibility(R.id.img, View.INVISIBLE)
        views.setViewVisibility(R.id.updateTime, View.INVISIBLE)
        views.setViewVisibility(R.id.loading, View.VISIBLE)
        appWidgetManager.updateAppWidget(appWidgetId, views)
    }

    private fun updateLoadImgWidget(
        context: Context,
        appWidgetManager: AppWidgetManager,
        appWidgetId: Int,
        widgetImg: String
    ) {
        Log.d(&quot;NewAppWidget&quot;, &quot;updateLoadImgWidget &amp;gt; imgURl: ${widgetImg}&quot;)
        val views = RemoteViews(context.packageName, R.layout.new_app_widget)

        views.setTextViewText(R.id.updateTime, getToday())

        val target = AppWidgetTarget(context, R.id.img, views, appWidgetId)
        if (widgetImg.isEmpty()) {
            views.setImageViewResource(R.id.img, R.drawable.ic_launcher_foreground)
        } else {
            Glide.with(context)
                .asBitmap()
                .load(widgetImg)
                .override(160.toPx, 160.toPx)
                .placeholder(R.drawable.ic_launcher_foreground)
                .error(R.drawable.ic_launcher_foreground)
                .into(target)
        }

        views.setOnClickPendingIntent(R.id.update, getPendingWorkSelfIntent(context, intArrayOf(appWidgetId)))
        views.setOnClickPendingIntent(R.id.appOpen, getPendingOpenIntent(context, appWidgetId))

        appWidgetManager.updateAppWidget(appWidgetId, views)
    }

    private fun getPendingWorkSelfIntent(context: Context, widgetIds: IntArray): PendingIntent {
        val intent = Intent(context, NewAppWidget::class.java).apply {
            action = ACTION_WIDGET_REFRESH
            putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, widgetIds)
        }
        return PendingIntent.getBroadcast(
            context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )
    }

    private fun getPendingOpenIntent(context: Context, targetId: Int): PendingIntent =
        PendingIntent.getActivity(
            context,
            targetId,
            Intent(context, MainActivity::class.java),
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 코드를 보면 핵심은 onUpdate 와 onRecevie 이 두가지다..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 여기서 햇갈렸던건&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;onRecevie 는 어떤 Actiond을 받아서 UI를 업데이트 하면 되겠구나 라고 생각했는데 그게 아니더라..&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;온전히 onUpdate 메소드 안에서만 UI를 업데이트 한다고 생각하고 접근 해야 한다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;onReceive는 event형태와 데이터를 다룬다고 생각하자.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;onReceive 에서 이벤트를 브로드 캐스트로 전달 받는다 ( getPendingWorkSelfIntent 메소드 부분 )&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 이 부분으로이 ACTION_WIDGET_REFRESH 를 onReceive로 들어온다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 여기서 데이터를 처리하자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 이미지를 바꿀 예정이기 때문에&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로컬 저장소에 저장해둔 이미지를 지워서 update를 던진다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 onUpdate에서 이미지가 없으니 통신을 시작하고 loading 이미지로 바꿔둔다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;통신이 끝난 후에 다시 브로드캐스트로 (workManager -&amp;gt; newAppWidget ) 던진다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 사용한 Action은&lt;/p&gt;
&lt;div style=&quot;background-color: #2b2b2b; color: #a9b7c6;&quot;&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;AppWidgetManager.ACTION_APPWIDGET_UPDATE&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OnReveive에서 해당 ACtion 이 들어오면 자동으로 onUpdate를 태우게 된다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 통신 후에 로컬 저장소에 이미지를 저장해 뒀으니, 이미지를 로드 하기 시작한다 ..&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 삽질만 3일걸렸다 .. 도무지 이해가 안됬는데 갑자기 이해가 되기 시작하면서 기록하게 된다 ( 무서운 코딩 )&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;onReceive 에서는 UI 업테이트 금지다.......&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위젯 생성됨 -&amp;gt; onReceive -&amp;gt; ACTION_APPWIDGET_UPDATE 들어옴 -&amp;gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음엔 저장소에 이미지가 없으므로 통신 시작 및 로닝 이미지그림 -&amp;gt; 통신끝 이미지 로컬저장소에 저장 후 브로드캐스트로 전달 ( ACTION_APPWIDGET_UPDATE )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;gt; onUpdate -&amp;gt; 저장소에 이미지가 있으니 이미지 로드&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1717046388126&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class WidgetWork(private val context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
    override suspend fun doWork(): Result {

        val randomIndex = getRandomIndex()

        val imgList = listOf(
            &quot;https://picsum.photos/id/60/160/160&quot;,
            &quot;https://picsum.photos/id/61/160/160&quot;,
            &quot;https://picsum.photos/id/69/160/160&quot;,
            &quot;https://picsum.photos/id/71/160/160&quot;,
            &quot;https://picsum.photos/id/74/160/160&quot;,
            &quot;https://picsum.photos/id/77/160/160&quot;,
            &quot;https://picsum.photos/id/81/160/160&quot;,
            &quot;https://picsum.photos/id/84/160/160&quot;,
            &quot;https://picsum.photos/id/90/160/160&quot;,
            &quot;https://picsum.photos/id/101/160/160&quot;,
            &quot;https://picsum.photos/id/102/160/160&quot;,
            &quot;https://picsum.photos/id/103/160/160&quot;,
            &quot;https://picsum.photos/id/104/160/160&quot;,
        )

        val imgUrl = imgList.getRandomItem()
        Log.d(&quot;WidgetWork&quot;, &quot;imgURL &amp;gt; ${imgUrl}&quot;)
        delay(1000L)

        val appWidgetManager = AppWidgetManager.getInstance(context)
        val thisWidget = ComponentName(context, NewAppWidget::class.java)
        val appWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget)

        ConfigModule(context).widgetImg = imgUrl

        context.sendBroadcast(Intent(context, NewAppWidget::class.java).apply {
            action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
            putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds)
        })

        return Result.success()
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1717046412202&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;manifest xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:tools=&quot;http://schemas.android.com/tools&quot;&amp;gt;

    &amp;lt;uses-permission android:name=&quot;android.permission.INTERNET&quot; /&amp;gt;

    &amp;lt;application
        android:allowBackup=&quot;true&quot;
        android:dataExtractionRules=&quot;@xml/data_extraction_rules&quot;
        android:fullBackupContent=&quot;@xml/backup_rules&quot;
        android:icon=&quot;@mipmap/ic_launcher&quot;
        android:label=&quot;@string/app_name&quot;
        android:roundIcon=&quot;@mipmap/ic_launcher_round&quot;
        android:supportsRtl=&quot;true&quot;
        android:theme=&quot;@style/Theme.AppWidgetExample3&quot;
        tools:targetApi=&quot;31&quot;&amp;gt;
        &amp;lt;receiver
            android:name=&quot;.NewAppWidget&quot;
            android:exported=&quot;false&quot;&amp;gt;
            &amp;lt;intent-filter&amp;gt;
                &amp;lt;action android:name=&quot;android.appwidget.action.APPWIDGET_UPDATE&quot; /&amp;gt;
            &amp;lt;/intent-filter&amp;gt;

            &amp;lt;meta-data
                android:name=&quot;android.appwidget.provider&quot;
                android:resource=&quot;@xml/new_app_widget_info&quot; /&amp;gt;
        &amp;lt;/receiver&amp;gt;

        &amp;lt;activity
            android:name=&quot;.MainActivity&quot;
            android:exported=&quot;true&quot;&amp;gt;
            &amp;lt;intent-filter&amp;gt;
                &amp;lt;action android:name=&quot;android.intent.action.MAIN&quot; /&amp;gt;

                &amp;lt;category android:name=&quot;android.intent.category.LAUNCHER&quot; /&amp;gt;
            &amp;lt;/intent-filter&amp;gt;
        &amp;lt;/activity&amp;gt;
    &amp;lt;/application&amp;gt;

&amp;lt;/manifest&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1717046434792&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;RelativeLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:tools=&quot;http://schemas.android.com/tools&quot;
    style=&quot;@style/Widget.AppWidgetExample3.AppWidget.Container&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;
    android:theme=&quot;@style/Theme.AppWidgetExample3.AppWidgetContainer&quot;&amp;gt;

    &amp;lt;TextView
        android:id=&quot;@+id/updateTime&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:textSize=&quot;12dp&quot;
        android:layout_above=&quot;@id/img&quot;
        android:layout_centerHorizontal=&quot;true&quot;
        android:layout_marginBottom=&quot;12dp&quot;
        tools:text=&quot;24.05.30 13:50&quot;/&amp;gt;

    &amp;lt;ImageView
        android:id=&quot;@+id/img&quot;
        android:layout_width=&quot;160dp&quot;
        android:layout_height=&quot;160dp&quot;
        android:layout_centerInParent=&quot;true&quot;
        tools:src=&quot;@drawable/ic_launcher_foreground&quot;/&amp;gt;

    &amp;lt;ProgressBar
        android:id=&quot;@+id/loading&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:layout_centerInParent=&quot;true&quot;
        android:visibility=&quot;gone&quot;/&amp;gt;

    &amp;lt;Button
        android:id=&quot;@+id/update&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:layout_marginTop=&quot;12dp&quot;
        android:text=&quot;이미지 바꾸기&quot;
        android:layout_centerHorizontal=&quot;true&quot;
        android:layout_below=&quot;@id/img&quot;/&amp;gt;

    &amp;lt;Button
        android:id=&quot;@+id/appOpen&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:text=&quot;앱 열기&quot;
        android:layout_marginTop=&quot;12dp&quot;
        android:layout_centerHorizontal=&quot;true&quot;
        android:layout_below=&quot;@id/update&quot;/&amp;gt;
&amp;lt;/RelativeLayout&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;

            &lt;figure class=&quot;unsupported component-kakaotv&quot; contenteditable=&quot;false&quot; style=&quot;background:#000;margin:16px 0;min-height:72px;padding:10px 16px;display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box;width:100%;max-width:100%;&quot;&gt;
                &lt;p contenteditable=&quot;false&quot; style=&quot;margin:0;color:#8a8a8a;font-size:13px;line-height:1.6;user-select:none;pointer-events:none;&quot;&gt;동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.&lt;/p&gt;
            &lt;/figure&gt;
        
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;???&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Android/Widget</category>
      <category>Android</category>
      <category>android widget 만들기</category>
      <category>Widget</category>
      <category>widget onreceive</category>
      <category>widget onupdate</category>
      <category>widget 만들기</category>
      <category>위젯</category>
      <author>녹색꼬맹이</author>
      <guid isPermaLink="true">https://jihunstudy.tistory.com/79</guid>
      <comments>https://jihunstudy.tistory.com/79#entry79comment</comments>
      <pubDate>Thu, 30 May 2024 14:31:07 +0900</pubDate>
    </item>
  </channel>
</rss>