<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>yjh의 클라우드 기반 인공지능 개발과 Devops</title>
    <link>https://yjh0922.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Thu, 28 May 2026 07:07:03 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>yjh0922</managingEditor>
    <image>
      <title>yjh의 클라우드 기반 인공지능 개발과 Devops</title>
      <url>https://tistory1.daumcdn.net/tistory/5347019/attach/a457c3b7e43f447ba279ca0677ccf081</url>
      <link>https://yjh0922.tistory.com</link>
    </image>
    <item>
      <title>안드로이드 스튜디오 : SHA 인증서 지문 찾기</title>
      <link>https://yjh0922.tistory.com/287</link>
      <description>&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;span&gt;fingerprint(&lt;/span&gt;핑거프린트) 번호라던지 SHA 번호라더던지 뭘 입력하라고 한다.&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;SHA 인증서 번호를 입력 하는 곳은 프로젝트 개요 -&amp;gt; 톱니 바퀴 -&amp;gt; 프로젝트 설정 을 들어가면 됩다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;714&quot; data-origin-height=&quot;736&quot; data-filename=&quot;안드로이드 스튜디오 - 파이어 베이스 SHA 인증 번호 입력하기.JPG&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/clZMxE/btq53Q6BJFI/KUQ2M2W7qPpPdTgCXMBwd0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FclZMxE%2Fbtq53Q6BJFI%2FKUQ2M2W7qPpPdTgCXMBwd0%2Fimg.jpg&quot; data-origin-width=&quot;714&quot; data-origin-height=&quot;736&quot; data-filename=&quot;안드로이드 스튜디오 - 파이어 베이스 SHA 인증 번호 입력하기.JPG&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; /&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;우측의 gradle 쪽을 이용하여 task -&amp;gt; android 어쩌고 폴더를 찾으러 가라고 하는데&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 alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;636&quot; data-origin-height=&quot;907&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b7gkYn/btrMfNOQrJe/yRj9kKEswEGABsMyeUw0fk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b7gkYn/btrMfNOQrJe/yRj9kKEswEGABsMyeUw0fk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b7gkYn/btrMfNOQrJe/yRj9kKEswEGABsMyeUw0fk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb7gkYn%2FbtrMfNOQrJe%2FyRj9kKEswEGABsMyeUw0fk%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;636&quot; height=&quot;907&quot; data-origin-width=&quot;636&quot; data-origin-height=&quot;907&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;&lt;a href=&quot;https://developers.google.com/android/guides/client-auth&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developers.google.com/android/guides/client-auth&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1663309654423&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;Authenticating Your Client &amp;nbsp;|&amp;nbsp; Google Play services &amp;nbsp;|&amp;nbsp; Google Developers&quot; data-og-description=&quot;Authenticating Your Client Stay organized with collections Save and categorize content based on your preferences. Certain Google Play services (such as Google Sign-in and App Invites) require you to provide the SHA-1 of your signing certificate so we can c&quot; data-og-host=&quot;developers.google.com&quot; data-og-source-url=&quot;https://developers.google.com/android/guides/client-auth&quot; data-og-url=&quot;https://developers.google.com/android/guides/client-auth&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bxRaa8/hyPOJMTfHv/MgCvyPSKRjCEEuoKT60KgK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://developers.google.com/android/guides/client-auth&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developers.google.com/android/guides/client-auth&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bxRaa8/hyPOJMTfHv/MgCvyPSKRjCEEuoKT60KgK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&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;Authenticating Your Client &amp;nbsp;|&amp;nbsp; Google Play services &amp;nbsp;|&amp;nbsp; Google Developers&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Authenticating Your Client Stay organized with collections Save and categorize content based on your preferences. Certain Google Play services (such as Google Sign-in and App Invites) require you to provide the SHA-1 of your signing certificate so we can c&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developers.google.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;구글 정식 서비스 센터에서&lt;span style=&quot;color: #555555;&quot;&gt;&amp;nbsp;2가지 방법을 알려주고 있다&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;size18&quot;&gt;1번 key tool을 사용&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;imageblock alignCenter&quot; data-origin-width=&quot;782&quot; data-origin-height=&quot;571&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XQIvn/btq54mRMflj/KhUXV2qC7AXRqmtpIzkaW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXQIvn%2Fbtq54mRMflj%2FKhUXV2qC7AXRqmtpIzkaW1%2Fimg.png&quot; data-origin-width=&quot;782&quot; data-origin-height=&quot;571&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; /&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;『디버그 인증서』 내용을 cmd에 복사 붙여넣기를 하면 된다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;keytool&amp;nbsp;-list&amp;nbsp;-v&amp;nbsp;-alias&amp;nbsp;androiddebugkey&amp;nbsp;-keystore&amp;nbsp;%USERPROFILE%\.android\debug.keystore&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내용을 cmd 를 이용해서 복사 붙여 넣기를 하면 비밀 번호를 입력하고 하는데&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;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;972&quot; data-origin-height=&quot;419&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnTqLf/btq57HU9PTo/ZxhJQJaoyAbQ2yOrN6k9HK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnTqLf%2Fbtq57HU9PTo%2FZxhJQJaoyAbQ2yOrN6k9HK%2Fimg.png&quot; data-origin-width=&quot;972&quot; data-origin-height=&quot;419&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; /&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;『무결성을 확인하려면 비밀번호를 제공해야 한다』면서 아무것도 뜨지 않는다...&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번째 방법을 사용해봤다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2번 &lt;span&gt;Gradle의 서명 보고서 사용&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;799&quot; data-origin-height=&quot;497&quot; data-filename=&quot;안드로이드 스튜디오 - 파이어 베이스 SHA 인증 번호 얻기 gradle 서명 보고서 이용.JPG&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bueYSF/btq56eeQ9lH/LwpVBoxmzyhvKAunkHWQcK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbueYSF%2Fbtq56eeQ9lH%2FLwpVBoxmzyhvKAunkHWQcK%2Fimg.jpg&quot; data-origin-width=&quot;799&quot; data-origin-height=&quot;497&quot; data-filename=&quot;안드로이드 스튜디오 - 파이어 베이스 SHA 인증 번호 얻기 gradle 서명 보고서 이용.JPG&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; /&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;이것을 하기 위해서는 굳이 'cmd'를 열지 말고&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;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;gradlew signingReport&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;841&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qTt16/btrMiOMQGsw/QPdB8UwA1SAa72GE0Ua7g0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qTt16/btrMiOMQGsw/QPdB8UwA1SAa72GE0Ua7g0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qTt16/btrMiOMQGsw/QPdB8UwA1SAa72GE0Ua7g0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqTt16%2FbtrMiOMQGsw%2FQPdB8UwA1SAa72GE0Ua7g0%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;1280&quot; height=&quot;841&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;841&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;저기서 SHA1 : ~~~ 에 적힌 코드를 firebase에 해당 프로젝트에 넣어준다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1647&quot; data-origin-height=&quot;930&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yWCPF/btrMjlQGCUj/tr9Px1Qij3daLwsrOAj6ZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yWCPF/btrMjlQGCUj/tr9Px1Qij3daLwsrOAj6ZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yWCPF/btrMjlQGCUj/tr9Px1Qij3daLwsrOAj6ZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyWCPF%2FbtrMjlQGCUj%2Ftr9Px1Qij3daLwsrOAj6ZK%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;1647&quot; height=&quot;930&quot; data-origin-width=&quot;1647&quot; data-origin-height=&quot;930&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Android</category>
      <author>yjh0922</author>
      <guid isPermaLink="true">https://yjh0922.tistory.com/287</guid>
      <comments>https://yjh0922.tistory.com/287#entry287comment</comments>
      <pubDate>Fri, 16 Sep 2022 15:36:51 +0900</pubDate>
    </item>
    <item>
      <title>Android - 구글맵 API 키 사용하는 방법</title>
      <link>https://yjh0922.tistory.com/286</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developers.google.com/maps/documentation/android-sdk/get-api-key?hl=ko&quot;&gt;https://developers.google.com/maps/documentation/android-sdk/get-api-key?hl=ko&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1659063758316&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;API 키 사용 &amp;nbsp;|&amp;nbsp; Android용 Maps SDK &amp;nbsp;|&amp;nbsp; Google Developers&quot; data-og-description=&quot;의견 보내기 API 키 사용 플랫폼 선택: Android iOS의 경우 자바스크립트 여기에서는 Android용 Maps SDK에 사용할 API 키를 만들어 앱에 추가하고 키를 제한하여 앱을 보호하는 방법을 설명합니다. SDK를 &quot; data-og-host=&quot;developers.google.com&quot; data-og-source-url=&quot;https://developers.google.com/maps/documentation/android-sdk/get-api-key?hl=ko&quot; data-og-url=&quot;https://developers.google.com/maps/documentation/android-sdk/get-api-key?hl=ko&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dXVB62/hyPf20zr2A/iF4OQC9q39lkgWQ8tgOvBk/img.png?width=1200&amp;amp;height=675&amp;amp;face=0_0_1200_675&quot;&gt;&lt;a href=&quot;https://developers.google.com/maps/documentation/android-sdk/get-api-key?hl=ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developers.google.com/maps/documentation/android-sdk/get-api-key?hl=ko&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dXVB62/hyPf20zr2A/iF4OQC9q39lkgWQ8tgOvBk/img.png?width=1200&amp;amp;height=675&amp;amp;face=0_0_1200_675');&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;API 키 사용 &amp;nbsp;|&amp;nbsp; Android용 Maps SDK &amp;nbsp;|&amp;nbsp; Google Developers&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;의견 보내기 API 키 사용 플랫폼 선택: Android iOS의 경우 자바스크립트 여기에서는 Android용 Maps SDK에 사용할 API 키를 만들어 앱에 추가하고 키를 제한하여 앱을 보호하는 방법을 설명합니다. SDK를&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developers.google.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;해당 API키를 눌러서 Maps SDK for Android를 추가해주면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1449&quot; data-origin-height=&quot;76&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cmJxtM/btrIpHxnuoG/dXSX2CBtDeY7oqbQ2RCmC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cmJxtM/btrIpHxnuoG/dXSX2CBtDeY7oqbQ2RCmC0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cmJxtM/btrIpHxnuoG/dXSX2CBtDeY7oqbQ2RCmC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcmJxtM%2FbtrIpHxnuoG%2FdXSX2CBtDeY7oqbQ2RCmC0%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;1449&quot; height=&quot;76&quot; data-origin-width=&quot;1449&quot; data-origin-height=&quot;76&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약, Maps가 없다면 아래와 같은 작업을 진행해 주면 된다.&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 alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;599&quot; data-origin-height=&quot;636&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/befhsp/btrIpuSZG8n/vhaTUGoeQIA3H3AKubTIsk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/befhsp/btrIpuSZG8n/vhaTUGoeQIA3H3AKubTIsk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/befhsp/btrIpuSZG8n/vhaTUGoeQIA3H3AKubTIsk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbefhsp%2FbtrIpuSZG8n%2FvhaTUGoeQIA3H3AKubTIsk%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;599&quot; height=&quot;636&quot; data-origin-width=&quot;599&quot; data-origin-height=&quot;636&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&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;303&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dRMgAE/btrIq6K3Nh8/ESXe0cJhuIReCRq3Wjw5F1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dRMgAE/btrIq6K3Nh8/ESXe0cJhuIReCRq3Wjw5F1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dRMgAE/btrIq6K3Nh8/ESXe0cJhuIReCRq3Wjw5F1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdRMgAE%2FbtrIq6K3Nh8%2FESXe0cJhuIReCRq3Wjw5F1%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;500&quot; height=&quot;303&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;303&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;&lt;a href=&quot;https://developers.google.com/maps/documentation/android-sdk/config?hl=ko&quot;&gt;https://developers.google.com/maps/documentation/android-sdk/config?hl=ko&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1659064231092&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;Android 스튜디오 프로젝트 설정 &amp;nbsp;|&amp;nbsp; Android용 Maps SDK &amp;nbsp;|&amp;nbsp; Google Developers&quot; data-og-description=&quot;의견 보내기 Android 스튜디오 프로젝트 설정 이 페이지에서는 빠른 시작에 자세히 설명되어 있는 Google 지도 템플릿을 사용하지 않고 Android용 Maps SDK를 사용하도록 Android 스튜디오 프로젝트를 구&quot; data-og-host=&quot;developers.google.com&quot; data-og-source-url=&quot;https://developers.google.com/maps/documentation/android-sdk/config?hl=ko&quot; data-og-url=&quot;https://developers.google.com/maps/documentation/android-sdk/config?hl=ko&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Bhdvz/hyPf71SaGo/qFGaxF8QyLPL4eFZPuDh8K/img.png?width=1200&amp;amp;height=675&amp;amp;face=0_0_1200_675&quot;&gt;&lt;a href=&quot;https://developers.google.com/maps/documentation/android-sdk/config?hl=ko&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developers.google.com/maps/documentation/android-sdk/config?hl=ko&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Bhdvz/hyPf71SaGo/qFGaxF8QyLPL4eFZPuDh8K/img.png?width=1200&amp;amp;height=675&amp;amp;face=0_0_1200_675');&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;Android 스튜디오 프로젝트 설정 &amp;nbsp;|&amp;nbsp; Android용 Maps SDK &amp;nbsp;|&amp;nbsp; Google Developers&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;의견 보내기 Android 스튜디오 프로젝트 설정 이 페이지에서는 빠른 시작에 자세히 설명되어 있는 Google 지도 템플릿을 사용하지 않고 Android용 Maps SDK를 사용하도록 Android 스튜디오 프로젝트를 구&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developers.google.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;</description>
      <category>Android</category>
      <author>yjh0922</author>
      <guid isPermaLink="true">https://yjh0922.tistory.com/286</guid>
      <comments>https://yjh0922.tistory.com/286#entry286comment</comments>
      <pubDate>Fri, 29 Jul 2022 12:48:31 +0900</pubDate>
    </item>
    <item>
      <title>Android - 위치기반 API</title>
      <link>https://yjh0922.tistory.com/285</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;AndroidManifest 파일&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1659060008941&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; &amp;lt;uses-permission android:name=&quot;android.permission.ACCESS_FINE_LOCATION&quot;/&amp;gt;
 &amp;lt;uses-permission android:name=&quot;android.permission.ACCESS_COARSE_LOCATION&quot;/&amp;gt;
    
 // 코드 추가해준다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MainActivity 파일&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1659060225979&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class MainActivity extends AppCompatActivity implements OnMapReadyCallback, GoogleMap.OnMarkerClickListener {

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

        // 구글맵 사용하겠다는 코드작성.
        SupportMapFragment mapFragment =
                (SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }

    @Override
    public void onMapReady(@NonNull GoogleMap googleMap) {
        //내 위치가 지도의 중심이 되도록
        LatLng myLocation = new LatLng(37.5428428, 126.6772096);

//        googleMap.moveCamera(CameraUpdateFactory.newLatLng( myLocation ));
        googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(myLocation, 17));

        googleMap.addMarker(new MarkerOptions().position(myLocation).title(&quot;연희직업전문학교&quot;)).setTag(0);
        googleMap.addMarker(new MarkerOptions().position(new LatLng(37.5436428,126.5432)).title(&quot;마커2&quot;)).
                setTag(1);
        googleMap.addMarker(new MarkerOptions().position(new LatLng(37.5428428,126.6762096)).title(&quot;마커3&quot;)).
                setTag(2);

        googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);

        googleMap.setOnMarkerClickListener(this);



    }

    @Override
    public boolean onMarkerClick(@NonNull Marker marker) {

        int index = (int) marker.getTag();

        if(index == 0){
            Toast.makeText(this, &quot;GOOD~~&quot;, Toast.LENGTH_SHORT).show();
        }else{
            Toast.makeText(this, &quot;Hello~~&quot;, Toast.LENGTH_SHORT).show();
        }

        return false;
    }
}&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를 구현하면됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.android.com/reference/android/location/LocationManager#requestLocationUpdates(java.lang.String,%20long,%20float,%20android.location.LocationListener)&quot;&gt;https://developer.android.com/reference/android/location/LocationManager#requestLocationUpdates(java.lang.String,%20long,%20float,%20android.location.LocationListener)&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1659060307721&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;LocationManager &amp;nbsp;|&amp;nbsp; Android Developers&quot; data-og-description=&quot;android.net.wifi.hotspot2.omadm&quot; data-og-host=&quot;developer.android.com&quot; data-og-source-url=&quot;https://developer.android.com/reference/android/location/LocationManager#requestLocationUpdates(java.lang.String,%20long,%20float,%20android.location.LocationListener)&quot; data-og-url=&quot;https://developer.android.com/reference/android/location/LocationManager&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cD04KJ/hyPeE74UuL/oLcFevFIculCfQzN3vme90/img.png?width=1201&amp;amp;height=676&amp;amp;face=0_0_1201_676&quot;&gt;&lt;a href=&quot;https://developer.android.com/reference/android/location/LocationManager#requestLocationUpdates(java.lang.String,%20long,%20float,%20android.location.LocationListener)&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.android.com/reference/android/location/LocationManager#requestLocationUpdates(java.lang.String,%20long,%20float,%20android.location.LocationListener)&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cD04KJ/hyPeE74UuL/oLcFevFIculCfQzN3vme90/img.png?width=1201&amp;amp;height=676&amp;amp;face=0_0_1201_676');&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;LocationManager &amp;nbsp;|&amp;nbsp; Android Developers&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;android.net.wifi.hotspot2.omadm&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer.android.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;구글맵 서비스이용하는 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://webnautes.tistory.com/647&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://webnautes.tistory.com/647&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1659060445957&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;Google Maps Android API 사용 방법 및 예제&quot; data-og-description=&quot;Google Maps Android API를 사용하는 기본적인 방법과 사용시 발생할 수 있는 문제점에 대해 다룹니다. 1. 간단한 안드로이드 구글맵 예제 동작시키기 2. Google Maps Android API 예제 코드 설명 3. 관련 포스&quot; data-og-host=&quot;webnautes.tistory.com&quot; data-og-source-url=&quot;https://webnautes.tistory.com/647&quot; data-og-url=&quot;https://webnautes.tistory.com/647&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bzbZDk/hyPf5bUbO0/azv30XH2SWfcNuU2XlI94k/img.png?width=424&amp;amp;height=825&amp;amp;face=0_0_424_825,https://scrap.kakaocdn.net/dn/blwnB3/hyPeIo5rSh/gEkTJDZStkSyxLHHDGzmbk/img.png?width=424&amp;amp;height=825&amp;amp;face=0_0_424_825,https://scrap.kakaocdn.net/dn/8Mxky/hyPeR0E6pZ/7Lsok9oxm3YSdj6eQ7r0GK/img.png?width=823&amp;amp;height=632&amp;amp;face=0_0_823_632&quot;&gt;&lt;a href=&quot;https://webnautes.tistory.com/647&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://webnautes.tistory.com/647&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bzbZDk/hyPf5bUbO0/azv30XH2SWfcNuU2XlI94k/img.png?width=424&amp;amp;height=825&amp;amp;face=0_0_424_825,https://scrap.kakaocdn.net/dn/blwnB3/hyPeIo5rSh/gEkTJDZStkSyxLHHDGzmbk/img.png?width=424&amp;amp;height=825&amp;amp;face=0_0_424_825,https://scrap.kakaocdn.net/dn/8Mxky/hyPeR0E6pZ/7Lsok9oxm3YSdj6eQ7r0GK/img.png?width=823&amp;amp;height=632&amp;amp;face=0_0_823_632');&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;Google Maps Android API 사용 방법 및 예제&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Google Maps Android API를 사용하는 기본적인 방법과 사용시 발생할 수 있는 문제점에 대해 다룹니다. 1. 간단한 안드로이드 구글맵 예제 동작시키기 2. Google Maps Android API 예제 코드 설명 3. 관련 포스&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;webnautes.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;</description>
      <category>Android</category>
      <author>yjh0922</author>
      <guid isPermaLink="true">https://yjh0922.tistory.com/285</guid>
      <comments>https://yjh0922.tistory.com/285#entry285comment</comments>
      <pubDate>Fri, 29 Jul 2022 11:05:29 +0900</pubDate>
    </item>
    <item>
      <title>Android - Bottom Navigation</title>
      <link>https://yjh0922.tistory.com/284</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;1. Manger를 눌러서 Navigation을 선택해준다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;506&quot; data-origin-height=&quot;280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KYirk/btrIiZLp3mM/VL1QdfJxRfnVuw2u3dn22k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KYirk/btrIiZLp3mM/VL1QdfJxRfnVuw2u3dn22k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KYirk/btrIiZLp3mM/VL1QdfJxRfnVuw2u3dn22k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKYirk%2FbtrIiZLp3mM%2FVL1QdfJxRfnVuw2u3dn22k%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;506&quot; height=&quot;280&quot; data-origin-width=&quot;506&quot; data-origin-height=&quot;280&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 새로운 Resource를 만들어준다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1028&quot; data-origin-height=&quot;593&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2feTX/btrIi6xdrPd/c8DFSazJIRMT0n3Bv2PSb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2feTX/btrIi6xdrPd/c8DFSazJIRMT0n3Bv2PSb1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2feTX/btrIi6xdrPd/c8DFSazJIRMT0n3Bv2PSb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2feTX%2FbtrIi6xdrPd%2Fc8DFSazJIRMT0n3Bv2PSb1%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;1028&quot; height=&quot;593&quot; data-origin-width=&quot;1028&quot; data-origin-height=&quot;593&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 필요한 프레그먼트화면을 만들어준다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;356&quot; data-origin-height=&quot;518&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eq6nbW/btrIjMrKV4B/sLSndFl7NmWsIEEXiH0gLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eq6nbW/btrIjMrKV4B/sLSndFl7NmWsIEEXiH0gLk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eq6nbW/btrIjMrKV4B/sLSndFl7NmWsIEEXiH0gLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Feq6nbW%2FbtrIjMrKV4B%2FsLSndFl7NmWsIEEXiH0gLk%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;356&quot; height=&quot;518&quot; data-origin-width=&quot;356&quot; data-origin-height=&quot;518&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;pre id=&quot;code_1658895561988&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;fragment
        android:id=&quot;@+id/firstFragment&quot;
        android:name=&quot;com.ygh547.tab.FirstFragment&quot;
        android:label=&quot;첫번째&quot;
        tools:layout=&quot;@layout/fragment_first&quot; /&amp;gt;
    &amp;lt;fragment
        android:id=&quot;@+id/secondFragment&quot;
        android:name=&quot;com.ygh547.tab.SecondFragment&quot;
        android:label=&quot;두번째&quot;
        tools:layout=&quot;@layout/fragment_second&quot; /&amp;gt;
    &amp;lt;fragment
        android:id=&quot;@+id/thirdFragment&quot;
        android:name=&quot;com.ygh547.tab.ThirdFragment&quot;
        android:label=&quot;세번째&quot;
        tools:layout=&quot;@layout/fragment_third&quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Android</category>
      <author>yjh0922</author>
      <guid isPermaLink="true">https://yjh0922.tistory.com/284</guid>
      <comments>https://yjh0922.tistory.com/284#entry284comment</comments>
      <pubDate>Wed, 27 Jul 2022 14:10:41 +0900</pubDate>
    </item>
    <item>
      <title>Android - 친구 포스팅 가져오기</title>
      <link>https://yjh0922.tistory.com/283</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;FollowPostingAdapter 파일&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1658825694175&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package com.ygh547.posting.adapter;

import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;

import com.bumptech.glide.Glide;
import com.ygh547.posting.PostingListActivity;
import com.ygh547.posting.R;
import com.ygh547.posting.config.Config;
import com.ygh547.posting.model.Posting;

import java.util.List;

public class FollowPostingAdapter extends RecyclerView.Adapter&amp;lt;FollowPostingAdapter.ViewHolder&amp;gt; {

    Context context;
    List&amp;lt;Posting&amp;gt; postingList;

    public FollowPostingAdapter(Context context, List&amp;lt;Posting&amp;gt; postingList) {
        this.context = context;
        this.postingList = postingList;
    }

    @NonNull
    @Override
    public FollowPostingAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.posting_row, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull FollowPostingAdapter.ViewHolder holder, int position) {
        Posting posting = postingList.get(position);
        holder.txtContent.setText(posting.getContent());
        holder.txtUserName.setText(posting.getUsername());
        holder.txtCreatedAt.setText(posting.getCreatedAt());
        holder.txtLikeCnt.setText(&quot;&quot;+posting.getLikeCnt());

        if(posting.getIsLike() == 1){
            holder.imgLike.setImageResource(R.drawable.ic_thumb);
        }else{
            holder.imgLike.setImageResource(R.drawable.ic_thumb_off);
        }

        Glide.with(context).load(Config.IMAGE_URL+posting.getImgURL() )
                .placeholder(R.drawable.ic_default_photo)
                .into(  holder.imgPhoto  );

    }

    @Override
    public int getItemCount() {
        return postingList.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        CardView cardView;
        TextView txtContent;
        TextView txtUserName;
        TextView txtCreatedAt;
        TextView txtLikeCnt;
        ImageView imgPhoto;
        ImageView imgLike;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);

            cardView = itemView.findViewById(R.id.cardView);
            txtContent = itemView.findViewById(R.id.txtContent);
            txtUserName = itemView.findViewById(R.id.txtUserName);
            txtCreatedAt = itemView.findViewById(R.id.txtCreatedAt);
            txtLikeCnt = itemView.findViewById(R.id.txtLikeCnt);
            imgPhoto = itemView.findViewById(R.id.imgPhoto);
            imgLike = itemView.findViewById(R.id.imgLike);

            imgLike.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // 메인액티비에 함수 만들어놓고 그 함수 호출하자.
                    int index = getAdapterPosition();
                    ((PostingListActivity)context).setLike(index);
                }
            });
        }
    }
}&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;b&gt;MainActivity 파일&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1658826025236&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class MainActivity extends AppCompatActivity {

    Button btnAdd;
    RecyclerView recyclerView;
    MyPostingAdapter adapter;
    ArrayList&amp;lt;Posting&amp;gt; postingList = new ArrayList&amp;lt;&amp;gt;();
    ProgressBar progressBar;

    private ProgressDialog dialog;

    // 페이징 처리를 위한 멤버변수
    int count = 0;
    int offset = 0;
    int limit = 10;
    
    protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            SharedPreferences sp = getApplication().getSharedPreferences(Config.PREFERENCES_NAME, MODE_PRIVATE);
            String accessToken = sp.getString(&quot;accessToken&quot;, &quot;&quot;);

            if(accessToken.isEmpty()){

                Intent intent = new Intent(MainActivity.this, RegisterActivity.class);
                startActivity(intent);

                finish();
                return;
            }

            btnAdd = findViewById(R.id.btnAdd);
            recyclerView = findViewById(R.id.recyclerView);
            recyclerView.setHasFixedSize(true);
            recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
            progressBar = findViewById(R.id.progressBar);

            recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
                    @Override
                    public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                        super.onScrolled(recyclerView, dx, dy);

                        int lastPosition = ((LinearLayoutManager)recyclerView.getLayoutManager()).findLastCompletelyVisibleItemPosition();
                        int totalCount = recyclerView.getAdapter().getItemCount();

                        if( lastPosition + 1 == totalCount){
                            if(limit == count){
                                // 네트워크 통해서 남아있는 데이터 추가로 가져와라.
                                addNetworkData();
                            }
                        }

                    }
                });

            btnAdd.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        Intent intent = new Intent(MainActivity.this, AddActivity.class);
                        startActivity(intent);
                    }
                });

            }

            private void addNetworkData() {


                progressBar.setVisibility(View.VISIBLE);

                Retrofit retrofit = NetworkClient.getRetrofitClient(MainActivity.this);
                PostingApi api = retrofit.create(PostingApi.class);

                SharedPreferences sp = getApplication().getSharedPreferences(Config.PREFERENCES_NAME, MODE_PRIVATE);
                String accessToken = sp.getString(&quot;accessToken&quot;, &quot;&quot;);

                Call&amp;lt;PostingList&amp;gt; call = api.getMyPosting(&quot;Bearer &quot;+accessToken,
                        offset,
                        limit);
                call.enqueue(new Callback&amp;lt;PostingList&amp;gt;() {
                    @Override
                    public void onResponse(Call&amp;lt;PostingList&amp;gt; call, Response&amp;lt;PostingList&amp;gt; response) {
                        progressBar.setVisibility(View.GONE);
                        if(response.isSuccessful()){

                            count = response.body().getCount();

                            postingList.addAll( response.body().getItems() );

                            offset = offset + count;

                            adapter.notifyDataSetChanged();

                        }else{

                        }
                    }

                    @Override
                    public void onFailure(Call&amp;lt;PostingList&amp;gt; call, Throwable t) {
                        progressBar.setVisibility(View.GONE);
                    }
                });

            }

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

            // 처음으로 데이터 가져올때
            void getNetworkData(){

                postingList.clear();
                count = 0;
                offset = 0;

                progressBar.setVisibility(View.VISIBLE);

                Retrofit retrofit = NetworkClient.getRetrofitClient(MainActivity.this);
                PostingApi api = retrofit.create(PostingApi.class);

                SharedPreferences sp = getApplication().getSharedPreferences(Config.PREFERENCES_NAME, MODE_PRIVATE);
                String accessToken = sp.getString(&quot;accessToken&quot;, &quot;&quot;);

                Call&amp;lt;PostingList&amp;gt; call = api.getMyPosting(&quot;Bearer &quot;+accessToken,
                        offset,
                        limit);
                call.enqueue(new Callback&amp;lt;PostingList&amp;gt;() {
                    @Override
                    public void onResponse(Call&amp;lt;PostingList&amp;gt; call, Response&amp;lt;PostingList&amp;gt; response) {
                        progressBar.setVisibility(View.GONE);
                        if(response.isSuccessful()){

                            count = response.body().getCount();

                            postingList.addAll( response.body().getItems() );

                            offset = offset + count;

                            adapter = new MyPostingAdapter(MainActivity.this, postingList);

                            recyclerView.setAdapter(adapter);

                        }else{

                        }
                    }

                    @Override
                    public void onFailure(Call&amp;lt;PostingList&amp;gt; call, Throwable t) {
                        progressBar.setVisibility(View.GONE);
                    }
                });
            }
}&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;해당 액티비티 디자인 화면&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1291&quot; data-origin-height=&quot;576&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bT05SB/btrIdXVmMGp/FKFFDY6uwgnCGjK9sU6Tf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bT05SB/btrIdXVmMGp/FKFFDY6uwgnCGjK9sU6Tf0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bT05SB/btrIdXVmMGp/FKFFDY6uwgnCGjK9sU6Tf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbT05SB%2FbtrIdXVmMGp%2FFKFFDY6uwgnCGjK9sU6Tf0%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;1291&quot; height=&quot;576&quot; data-origin-width=&quot;1291&quot; data-origin-height=&quot;576&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Android</category>
      <author>yjh0922</author>
      <guid isPermaLink="true">https://yjh0922.tistory.com/283</guid>
      <comments>https://yjh0922.tistory.com/283#entry283comment</comments>
      <pubDate>Tue, 26 Jul 2022 18:03:04 +0900</pubDate>
    </item>
    <item>
      <title>Android - Retrofit 에서 Multipart form 으로 데이터 보내는 방법</title>
      <link>https://yjh0922.tistory.com/282</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;1. 파일을 보내는 방법&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. 텍스트로 보내기 위한 방법&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1658798073226&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class AddActivity {
	private File photoFile;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add);


        btnSave.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {

                    if (photoFile == null) {
                        Toast.makeText(AddActivity.this, &quot;사진은 필수입니다.&quot;, Toast.LENGTH_SHORT).show();
                        return;
                    }

                    String content = editContent.getText().toString().trim();
                    if (content.isEmpty()) {
                        Toast.makeText(AddActivity.this, &quot;내용을 입력하세요.&quot;, Toast.LENGTH_SHORT).show();
                        return;
                    }
                    Retrofit retrofit = NetworkClient.getRetrofitClient(AddActivity.this);
                    PostingApi api = retrofit.create(PostingApi.class);

                    // 멀티파트로 파일을 보내는 경우, 파일 파라미터 만드는 방법
                    RequestBody fileBody = RequestBody.create(photoFile, MediaType.parse(&quot;image/*&quot;));
                    MultipartBody.Part photo = MultipartBody.Part.createFormData(&quot;photo&quot;, photoFile.getName(), fileBody);
                    // 멀티파트로 텍스트를 보내는 경우, 파라미터 만드는 방법
                    RequestBody contentBody = RequestBody.create(content, MediaType.parse(&quot;text/plain&quot;));

                    // 헤더에 들어갈 억세스토큰 가져온다.
                    SharedPreferences sp = getApplication().getSharedPreferences(Config.PREFERENCES_NAME, MODE_PRIVATE);
                    String accessToken = sp.getString(&quot;accessToken&quot;, &quot;&quot;);


                    Call&amp;lt;PostRes&amp;gt; call = api.addPosting(&quot;Bearer &quot; + accessToken,
                            photo, contentBody);

                    showProgress(&quot;포스팅 업로드중&quot;);

                    call.enqueue(new Callback&amp;lt;PostRes&amp;gt;() {
                        @Override
                        public void onResponse(Call&amp;lt;PostRes&amp;gt; call, Response&amp;lt;PostRes&amp;gt; response) {
                            dismissProgress();

                            Toast.makeText(AddActivity.this, &quot;업로드가 완료되었습니다.&quot;, Toast.LENGTH_SHORT).show();
                            finish();
                        }

                        @Override
                        public void onFailure(Call&amp;lt;PostRes&amp;gt; call, Throwable t) {
                            dismissProgress();
                        }
                    });
                }
            });
            
     }&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Android</category>
      <author>yjh0922</author>
      <guid isPermaLink="true">https://yjh0922.tistory.com/282</guid>
      <comments>https://yjh0922.tistory.com/282#entry282comment</comments>
      <pubDate>Tue, 26 Jul 2022 10:21:36 +0900</pubDate>
    </item>
    <item>
      <title>Android - retrofit2의 POST 사용하는 방법</title>
      <link>https://yjh0922.tistory.com/281</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://yjh0922.tistory.com/280?category=1108568&quot;&gt;https://yjh0922.tistory.com/280?category=1108568&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1658392593526&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;Android - Retrofit2 라이브러리 사용을 위한 설정 방법&quot; data-og-description=&quot;&quot; data-og-host=&quot;yjh0922.tistory.com&quot; data-og-source-url=&quot;https://yjh0922.tistory.com/280?category=1108568&quot; data-og-url=&quot;https://yjh0922.tistory.com/280?category=1108568&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://yjh0922.tistory.com/280?category=1108568&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yjh0922.tistory.com/280?category=1108568&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&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;Android - Retrofit2 라이브러리 사용을 위한 설정 방법&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yjh0922.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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;새로만든 api폴더 -&amp;gt; UserApi파일 부분&lt;/p&gt;
&lt;pre id=&quot;code_1658392661868&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package com.ygh547.memo.api;

import com.ygh547.memo.model.RegisterRes;
import com.ygh547.memo.model.User;

import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.POST;

// 함수랑 상수만 있는것을 interface
public interface UserApi
{
    @POST(&quot;/users/register&quot;)
    Call&amp;lt;RegisterRes&amp;gt; register(@Body User user);
}&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;RegisterActivity 파일&lt;/p&gt;
&lt;pre id=&quot;code_1658392712906&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package com.ygh547.memo;

import androidx.appcompat.app.AppCompatActivity;

import android.app.ProgressDialog;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Patterns;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.ygh547.memo.api.NetworkClient;
import com.ygh547.memo.api.UserApi;
import com.ygh547.memo.config.Config;
import com.ygh547.memo.model.RegisterRes;
import com.ygh547.memo.model.User;
import com.ygh547.memo.model.RegisterRes;

import java.util.regex.Pattern;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;

public class RegisterActivity extends AppCompatActivity {

    EditText editEmail;
    EditText editPassword;
    EditText editNickname;
    Button btnRegister;

    // 네트워크 처리 보여주는 프로그레스 다이얼로그
    ProgressDialog dialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register);
        editEmail = findViewById(R.id.editEmail);
        editPassword = findViewById(R.id.editPasssword);
        editNickname = findViewById(R.id.editNickname);
        btnRegister = findViewById(R.id.btnRegister);
        btnRegister.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                // 이메일 가져온다. 이메일 형식체크
                String email = editEmail.getText().toString().trim();
                Pattern pattern = Patterns.EMAIL_ADDRESS;
                if(pattern.matcher(email).matches() == false){
                    Toast.makeText(RegisterActivity.this, &quot;이메일 형식이 올바르지 않습니다.&quot;, Toast.LENGTH_SHORT).show();
                    return;
                }

                // 비밀번호 가져온다.
                String password = editPassword.getText().toString().trim();
                // 비번 길이 체크
                if(password.length() &amp;lt; 4 || password.length() &amp;gt; 12){
                    Toast.makeText(RegisterActivity.this, &quot;비번길이는 4자이상 12자이하로 만들어 주세요.&quot;, Toast.LENGTH_SHORT).show();
                    return;
                }

                // 닉네임을 가져와서, 빈 문자열인지만 체크
                String nickname = editNickname.getText().toString().trim();
                if(nickname.isEmpty()){
                    Toast.makeText(RegisterActivity.this, &quot;닉네임 입력하세요.&quot;, Toast.LENGTH_SHORT).show();
                    return;
                }

                // 이 데이터를 API로 호출!!
                // 네트워크 통해서 데이터를 보내고 있다는,
                // 프로그레스 다이얼로그를 먼저 띄운다.
                showProgress(getString(R.string.dialog_register));

                Retrofit retrofit =
                        NetworkClient.getRetrofitClient(RegisterActivity.this);

                UserApi api = retrofit.create(UserApi.class);

                User user = new User(email, password, nickname);

                Call&amp;lt;RegisterRes&amp;gt; call = api.register(user);
                call.enqueue(new Callback&amp;lt;RegisterRes&amp;gt;() {
                    @Override
                    public void onResponse(Call&amp;lt;RegisterRes&amp;gt; call, Response&amp;lt;RegisterRes&amp;gt; response) {
                        dismissProgress();

                        // 200 OK 일때,
                        if(response.isSuccessful()){

                            RegisterRes registerRes = response.body();

                            // 억세스토큰은, 이제 앱에서, api 호출할때마다 헤더에 넣어서 보내야한다.
                            // 따라서 억세스토큰은, 쉐어드프리퍼런스에 저장해 놓는다.
                            SharedPreferences sp =
                                    getApplication().getSharedPreferences(Config.PREFERENCES_NAME, MODE_PRIVATE);
                            SharedPreferences.Editor editor = sp.edit();
                            editor.putString(&quot;accessToken&quot;, registerRes.getAccess_token());
                            editor.apply();

                            finish();

                        } else if (response.code() == 400){

                        } else {
                            Toast.makeText(RegisterActivity.this, &quot;에러발생 : &quot;+response.code(), Toast.LENGTH_SHORT).show();
                        }
                    }

                    @Override
                    public void onFailure(Call&amp;lt;RegisterRes&amp;gt; call, Throwable t) {
                        // 네트워크 자체 문제로 실패!
                        dismissProgress();
                    }
                });

            }
        });

    }

    void showProgress(String message){
        dialog = new ProgressDialog(this);
        dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        dialog.setMessage(message);
        dialog.show();
    }

    void dismissProgress(){
        dialog.dismiss();
    }
}&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;MainActivity 파일&lt;/p&gt;
&lt;pre id=&quot;code_1658392757061&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package com.ygh547.memo;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;

import com.ygh547.memo.config.Config;

public class MainActivity extends AppCompatActivity {



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

        // 1. 쉐어드프리퍼런스에 억세스토큰을 가져온다.
        SharedPreferences sp =
                getApplication().getSharedPreferences(Config.PREFERENCES_NAME, MODE_PRIVATE);
        String accessToken = sp.getString(&quot;accessToken&quot;, &quot;&quot;);

        // 2. 만약 억세스토큰이 없으면, 회원가입 액티비티를 실행하고,
        //    그렇지 않으면, 메모가져오는 API 호출해서, 리사이클러뷰로 화면에 내 메모 보여준다.
        if(accessToken.isEmpty()){
            Intent intent =
                    new Intent(MainActivity.this, RegisterActivity.class);
            startActivity(intent);
        } else {
            // todo 내 메모 가져오는 api 호출
        }
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Android</category>
      <author>yjh0922</author>
      <guid isPermaLink="true">https://yjh0922.tistory.com/281</guid>
      <comments>https://yjh0922.tistory.com/281#entry281comment</comments>
      <pubDate>Thu, 21 Jul 2022 17:39:22 +0900</pubDate>
    </item>
    <item>
      <title>Android - Retrofit2 라이브러리 사용을 위한 설정 방법</title>
      <link>https://yjh0922.tistory.com/280</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;AndroidManifest.xml파일&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1658392032900&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;uses-permission android:name=&quot;android.permission.INTERNET&quot; /&amp;gt;

&amp;lt;application
        android:networkSecurityConfig=&quot;@xml/network_security_config&quot;
        android:usesCleartextTraffic=&quot;true&quot;/&amp;gt;
# 추가해준다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;gradle(Module:)파일&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1658392115901&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;dependencies 
{
	implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
    implementation(&quot;com.squareup.okhttp3:logging-interceptor:4.9.0&quot;)
}

# 추가해준다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;xml파일 &amp;lt;- 네트워크 연결을 위해서 만들어준다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1658392433819&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&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;network-security-config&amp;gt;
    &amp;lt;domain-config cleartextTrafficPermitted=&quot;false&quot;&amp;gt;
        &amp;lt;domain includeSubdomains=&quot;true&quot;&amp;gt;*.amazonaws.com&amp;lt;/domain&amp;gt;
    &amp;lt;/domain-config&amp;gt;
&amp;lt;/network-security-config&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;b&gt;config파일&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1658392263521&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Config
{
    public static final String BASE_URL = &quot;https://n01bfgt1eh.execute-api.us-east-1.amazonaws.com&quot;;
    public static final String TEST_URL = &quot;http://127.0.0.1:5000&quot;;
    public static final String PREFERENCES_NAME = &quot;memo_app&quot;;
}

# 자신이 사용할 URL을 넣어준다.&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;b&gt;RegisterRes파일&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1658392326407&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class RegisterRes implements Serializable
{
    private String result;
    private String access_token;

    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
    }

    public String getAccess_token() {
        return access_token;
    }

    public void setAccess_token(String access_token) {
        this.access_token = access_token;
    }
}&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;User파일 &amp;lt;-사용자가 가져올 데이터를 넣어둔곳&lt;/p&gt;
&lt;pre id=&quot;code_1658392383724&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package ~~~~~~~~~;

import java.io.Serializable;

public class User implements Serializable
{
    private String email;
    private String password;
    private String nickname;

    public User(String email, String password, String nickname)
    {
        this.email = email;
        this.password = password;
        this.nickname = nickname;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Android</category>
      <author>yjh0922</author>
      <guid isPermaLink="true">https://yjh0922.tistory.com/280</guid>
      <comments>https://yjh0922.tistory.com/280#entry280comment</comments>
      <pubDate>Thu, 21 Jul 2022 17:34:36 +0900</pubDate>
    </item>
    <item>
      <title>Android - 카메라 / 앨범 사용하는 방법</title>
      <link>https://yjh0922.tistory.com/279</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;안드로이드 매니페스트&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1658382281717&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;uses-permission android:name=&quot;android.permission.READ_EXTERNAL_STORAGE&quot;/&amp;gt;
    &amp;lt;uses-permission android:name=&quot;android.permission.WRITE_EXTERNAL_STORAGE&quot;/&amp;gt;
    &amp;lt;uses-permission android:name=&quot;android.permission.CAMERA&quot;/&amp;gt;
    
&amp;lt;application
        android:requestLegacyExternalStorage=&quot;true&quot;/&amp;gt;
        
&amp;lt;provider
            android:authorities=&quot;com.ygh547.camera.fileprovider&quot;
            android:name=&quot;androidx.core.content.FileProvider&quot;
            android:exported=&quot;false&quot;
            android:grantUriPermissions=&quot;true&quot;&amp;gt;
            &amp;lt;meta-data
                android:name=&quot;android.support.FILE_PROVIDER_PATHS&quot;
                android:resource=&quot;@xml/fileprovider&quot;/&amp;gt;
        &amp;lt;/provider&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;b&gt;xml파일&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1658382352630&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 파일 이름 : fileprovider.xml

&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;paths&amp;gt;
    &amp;lt;root-path
        name=&quot;root&quot;
        path=&quot;.&quot; /&amp;gt;

    &amp;lt;cache-path
        name=&quot;cache&quot;
        path=&quot;.&quot; /&amp;gt; &amp;lt;!--Context.getCacheDir() 내부 저장소--&amp;gt;
    &amp;lt;files-path
        name=&quot;files&quot;
        path=&quot;.&quot; /&amp;gt; &amp;lt;!--Context.getFilesDir() 내부 저장소--&amp;gt;

    &amp;lt;external-path
        name=&quot;external&quot;
        path=&quot;.&quot;/&amp;gt;  &amp;lt;!--  Environment.getExternalStorageDirectory() 외부 저장소--&amp;gt;
    &amp;lt;external-cache-path
        name=&quot;external-cache&quot;
        path=&quot;.&quot;/&amp;gt; &amp;lt;!--  Context.getExternalCacheDir() 외부 저장소--&amp;gt;
    &amp;lt;external-files-path
        name=&quot;images&quot;
        path=&quot;Pictures&quot; /&amp;gt; &amp;lt;!--  Context.getExternalFilesDir() 외부 저장소--&amp;gt;
&amp;lt;/paths&amp;gt;


# 해당 코드를 class로 새로 만들어서 작성해준다.&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;b&gt;라이브러리 설정&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1658382430433&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#gradle(Module:)파일

dependencies {
		implementation 'commons-io:commons-io:2.4'
        }

# 해당 코드를 추가해준다.&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;b&gt;메인엑티비티 파일&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1658382801740&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package ~~~~~~~~~~~~~~~~~;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.provider.MediaStore;
import android.provider.OpenableColumns;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import org.apache.commons.io.IOUtils;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

public class MainActivity extends AppCompatActivity
{
    Button button;
    ImageView imageView;
    // 사진관련된 변수들
    private File photoFile;


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

        button = findViewById(R.id.button);
        imageView = findViewById(R.id.imageView);

        button.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View view)
            {
                //버튼을 누르면, 카메라에서 선택인지 앨범에서 선택인지 고를 수 있게 알러트 다이얼로그를 띄운다.
                showDialog();
                //카메라를 선택하면, 사진찍는 것으로
                //앨범을 선택하면, 앨범에서 사진 선택할수 있도록 하고

                // 그 결과는 이미지뷰에 보여주도록 개발.
            }
        });
    }

    // 알러트 다이얼로그를 띄우는 함수
    void showDialog()
    {
        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
        builder.setTitle(R.string.alert_title);
        builder.setItems(R.array.alert_photo, new DialogInterface.OnClickListener()
        {
            @Override
            public void onClick(DialogInterface dialogInterface, int i)
            {
                if (i == 0)
                {
                    //todo : 사진찍는 코드 실행
                    camera();
                }
                else if(i == 1)
                {
                    //todo : 앨범에서 사진 가져오는 코드 실행
                    album();
                }
            }
        });
        AlertDialog alert = builder.create();
        alert.show();
    }

    private void camera()
    {
        int permissionCheck = ContextCompat.checkSelfPermission(
                MainActivity.this, Manifest.permission.CAMERA);

        if(permissionCheck != PackageManager.PERMISSION_GRANTED)
        {
            ActivityCompat.requestPermissions(MainActivity.this,
                    new String[]{Manifest.permission.CAMERA} ,
                    1000);
            Toast.makeText(MainActivity.this, &quot;카메라 권한 필요합니다.&quot;,
                    Toast.LENGTH_SHORT).show();
            return;
        } 
        else 
        {
            Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            if(i.resolveActivity(MainActivity.this.getPackageManager())  != null  ){

                // 사진의 파일명을 만들기
                String fileName = new SimpleDateFormat(&quot;yyyyMMdd_HHmmss&quot;).format(new Date());
                photoFile = getPhotoFile(fileName);

                Uri fileProvider = FileProvider.getUriForFile(MainActivity.this,
                        &quot;com.ygh547.camera.fileprovider&quot;, photoFile);
                i.putExtra(MediaStore.EXTRA_OUTPUT, fileProvider);
                startActivityForResult(i, 100);

            } 
            else
            {
                Toast.makeText(MainActivity.this, &quot;이폰에는 카메라 앱이 없습니다.&quot;,
                        Toast.LENGTH_SHORT).show();
            }
        }


    }
    private File getPhotoFile(String fileName) 
    {
        File storageDirectory = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        try{
            return File.createTempFile(fileName, &quot;.jpg&quot;, storageDirectory);
        }catch (IOException e){
            e.printStackTrace();
            return null;
        }
    }

    private void album()
    {
        if(checkPermission())
        {
            displayFileChoose();
        }
        else
        {
            requestPermission();
        }
    }
    private void requestPermission() 
    {
        if(ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE)){
            Toast.makeText(MainActivity.this, &quot;권한 수락이 필요합니다.&quot;,
                    Toast.LENGTH_SHORT).show();
        }
        else
        {
            ActivityCompat.requestPermissions(MainActivity.this,
                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 500);
        }
    }

    private boolean checkPermission()
    {
        int result = ContextCompat.checkSelfPermission(MainActivity.this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE);
        if(result == PackageManager.PERMISSION_DENIED)
        {
            return false;
        }
        else
        {
            return true;
        }
    }

    private void displayFileChoose() 
    {
        Intent i = new Intent();
        i.setType(&quot;image/*&quot;);
        i.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(i, &quot;SELECT IMAGE&quot;), 300);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) 
    {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) 
        {
            case 1000: 
            {
                if (grantResults.length &amp;gt; 0 &amp;amp;&amp;amp; grantResults[0] == PackageManager.PERMISSION_GRANTED) 
                {
                    Toast.makeText(MainActivity.this, &quot;권한 허가 되었음&quot;,
                            Toast.LENGTH_SHORT).show();
                } else 
                {
                    Toast.makeText(MainActivity.this, &quot;아직 승인하지 않았음&quot;,
                            Toast.LENGTH_SHORT).show();
                }
                break;
            }
            case 500: 
            {
                if (grantResults.length &amp;gt; 0 &amp;amp;&amp;amp; grantResults[0] == PackageManager.PERMISSION_GRANTED) 
                {
                    Toast.makeText(MainActivity.this, &quot;권한 허가 되었음&quot;,
                            Toast.LENGTH_SHORT).show();
                } 
                else 
                {
                    Toast.makeText(MainActivity.this, &quot;아직 승인하지 않았음&quot;,
                            Toast.LENGTH_SHORT).show();
                }

            }

        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) 
    {
        if(requestCode == 100 &amp;amp;&amp;amp; resultCode == RESULT_OK)
        {

            Bitmap photo = BitmapFactory.decodeFile(photoFile.getAbsolutePath());

            ExifInterface exif = null;
            try 
            {
                exif = new ExifInterface(photoFile.getAbsolutePath());
            } catch (IOException e) 
            {
                e.printStackTrace();
            }
            int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                    ExifInterface.ORIENTATION_UNDEFINED);
            photo = rotateBitmap(photo, orientation);

            // 압축시킨다. 해상도 낮춰서
            OutputStream os;
            try 
            {
                os = new FileOutputStream(photoFile);
                photo.compress(Bitmap.CompressFormat.JPEG, 50, os);
                os.flush();
                os.close();
            } 
            catch (Exception e) 
            {
                Log.e(getClass().getSimpleName(), &quot;Error writing bitmap&quot;, e);
            }

            photo = BitmapFactory.decodeFile(photoFile.getAbsolutePath());

            imageView.setImageBitmap(photo);
            imageView.setScaleType(ImageView.ScaleType.CENTER);

            // 네트워크로 데이터 보낸다.



        }
        else if(requestCode == 300 &amp;amp;&amp;amp; resultCode == RESULT_OK &amp;amp;&amp;amp; data != null &amp;amp;&amp;amp;
                data.getData() != null)
        {

            Uri albumUri = data.getData( );
            String fileName = getFileName( albumUri );
            try 
            {

                ParcelFileDescriptor parcelFileDescriptor = getContentResolver( ).openFileDescriptor( albumUri, &quot;r&quot; );
                if ( parcelFileDescriptor == null ) return;
                FileInputStream inputStream = new FileInputStream( parcelFileDescriptor.getFileDescriptor( ) );
                photoFile = new File( this.getCacheDir( ), fileName );
                FileOutputStream outputStream = new FileOutputStream( photoFile );
                IOUtils.copy( inputStream, outputStream );

//                //임시파일 생성
//                File file = createImgCacheFile( );
//                String cacheFilePath = file.getAbsolutePath( );


                // 압축시킨다. 해상도 낮춰서
                Bitmap photo = BitmapFactory.decodeFile(photoFile.getAbsolutePath());
                OutputStream os;
                try 
                {
                    os = new FileOutputStream(photoFile);
                    photo.compress(Bitmap.CompressFormat.JPEG, 60, os);
                    os.flush();
                    os.close();
                } catch (Exception e) 
                {
                    Log.e(getClass().getSimpleName(), &quot;Error writing bitmap&quot;, e);
                }

                imageView.setImageBitmap(photo);
                imageView.setScaleType(ImageView.ScaleType.CENTER);


//                imageView.setImageBitmap( getBitmapAlbum( imageView, albumUri ) );

            } 
            catch ( Exception e ) 
            {
                e.printStackTrace( );
            }

            //네트워크로 보낸다.
        }
        super.onActivityResult(requestCode, resultCode, data);
    }


    public static Bitmap rotateBitmap(Bitmap bitmap, int orientation) 
    {

        Matrix matrix = new Matrix();
        switch (orientation) {
            case ExifInterface.ORIENTATION_NORMAL:
                return bitmap;
            case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
                matrix.setScale(-1, 1);
                break;
            case ExifInterface.ORIENTATION_ROTATE_180:
                matrix.setRotate(180);
                break;
            case ExifInterface.ORIENTATION_FLIP_VERTICAL:
                matrix.setRotate(180);
                matrix.postScale(-1, 1);
                break;
            case ExifInterface.ORIENTATION_TRANSPOSE:
                matrix.setRotate(90);
                matrix.postScale(-1, 1);
                break;
            case ExifInterface.ORIENTATION_ROTATE_90:
                matrix.setRotate(90);
                break;
            case ExifInterface.ORIENTATION_TRANSVERSE:
                matrix.setRotate(-90);
                matrix.postScale(-1, 1);
                break;
            case ExifInterface.ORIENTATION_ROTATE_270:
                matrix.setRotate(-90);
                break;
            default:
                return bitmap;
        }
        try 
        {
            Bitmap bmRotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
            bitmap.recycle();
            return bmRotated;
        }
        catch (OutOfMemoryError e) 
        {
            e.printStackTrace();
            return null;
        }
    }

    //앨범에서 선택한 사진이름 가져오기
    public String getFileName( Uri uri ) 
    {
        Cursor cursor = getContentResolver( ).query( uri, null, null, null, null );
        try 
        {
            if ( cursor == null ) return null;
            cursor.moveToFirst( );
            @SuppressLint(&quot;Range&quot;) String fileName = cursor.getString( cursor.getColumnIndex( OpenableColumns.DISPLAY_NAME ) );
            cursor.close( );
            return fileName;

        } catch ( Exception e ) 
        {
            e.printStackTrace( );
            cursor.close( );
            return null;
        }
    }

    //이미지뷰에 뿌려질 앨범 비트맵 반환
    public Bitmap getBitmapAlbum( View targetView, Uri uri ) 
    {
        try 
        {
            ParcelFileDescriptor parcelFileDescriptor = getContentResolver( ).openFileDescriptor( uri, &quot;r&quot; );
            if ( parcelFileDescriptor == null ) return null;
            FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor( );
            if ( fileDescriptor == null ) return null;

            int targetW = targetView.getWidth( );
            int targetH = targetView.getHeight( );

            BitmapFactory.Options options = new BitmapFactory.Options( );
            options.inJustDecodeBounds = true;

            BitmapFactory.decodeFileDescriptor( fileDescriptor, null, options );

            int photoW = options.outWidth;
            int photoH = options.outHeight;

            int scaleFactor = Math.min( photoW / targetW, photoH / targetH );
            if ( scaleFactor &amp;gt;= 8 ) 
            {
                options.inSampleSize = 8;
            } 
            else if ( scaleFactor &amp;gt;= 4 ) 
            {
                options.inSampleSize = 4;
            } 
            else 
            {
                options.inSampleSize = 2;
            }
            options.inJustDecodeBounds = false;

            Bitmap reSizeBit = BitmapFactory.decodeFileDescriptor( fileDescriptor, null, options );

            ExifInterface exifInterface = null;
            try 
            {
                if ( Build.VERSION.SDK_INT &amp;gt;= Build.VERSION_CODES.N ) 
                {
                    exifInterface = new ExifInterface( fileDescriptor );
                }
            } 
            catch ( IOException e ) 
            {
                e.printStackTrace( );
            }

            int exifOrientation;
            int exifDegree = 0;

            //사진 회전값 구하기
            if ( exifInterface != null ) 
            {
                exifOrientation = exifInterface.getAttributeInt( ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL );

                if ( exifOrientation == ExifInterface.ORIENTATION_ROTATE_90 ) 
                {
                    exifDegree = 90;
                } 
                else if ( exifOrientation == ExifInterface.ORIENTATION_ROTATE_180 ) 
                {
                    exifDegree = 180;
                } 
                else if ( exifOrientation == ExifInterface.ORIENTATION_ROTATE_270 ) 
                {
                    exifDegree = 270;
                }
            }

            parcelFileDescriptor.close( );
            Matrix matrix = new Matrix( );
            matrix.postRotate( exifDegree );

            Bitmap reSizeExifBitmap = Bitmap.createBitmap( reSizeBit, 0, 0, reSizeBit.getWidth( ), reSizeBit.getHeight( ), matrix, true );
            return reSizeExifBitmap;

        } 
        catch ( Exception e ) 
        {
            e.printStackTrace( );
            return null;
        }


    }

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Android</category>
      <author>yjh0922</author>
      <guid isPermaLink="true">https://yjh0922.tistory.com/279</guid>
      <comments>https://yjh0922.tistory.com/279#entry279comment</comments>
      <pubDate>Thu, 21 Jul 2022 14:53:29 +0900</pubDate>
    </item>
    <item>
      <title>Android - 리사이클러뷰 페이징 처리하는 방법</title>
      <link>https://yjh0922.tistory.com/278</link>
      <description>&lt;pre id=&quot;code_1658307752774&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);

                int lastPosition = ((LinearLayoutManager)recyclerView.getLayoutManager()).findLastCompletelyVisibleItemPosition();
                int totalCount = recyclerView.getAdapter().getItemCount();
                // 스크롤을 맨 끝까지 한것!
                if(lastPosition + 1 == totalCount) {
                    //리스트 마지막(바닥) 도착!!!!! 다음 페이지 데이터 로드!!
                    //데이터 로드후의 사용할 코드는 밑의 부분에 작성해준다.
 
                }
            }
        })&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;b&gt;예시 코드&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1658308042319&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;			@Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);

                int lastPosition = ((LinearLayoutManager)recyclerView.getLayoutManager()).findLastCompletelyVisibleItemPosition();
                int totalCount = recyclerView.getAdapter().getItemCount();
                // 스크롤을 맨 끝까지 한것!
                if(lastPosition + 1 == totalCount){
//              if (pageToken == null)
//                    {
//                        return;
//                    }
//
//                    // 1. 프로그레스바를 돌린다.
//                    progressBar.setVisibility(View.VISIBLE);
//
//                    // 2. URL을 조합한다.
//                    // ?part=snippet&amp;amp;key=[자신의 API KEY]&amp;amp;q=축구&amp;amp;maxResults=20
//                    String url = Config.BASE_URL + &quot;?part=snippet&amp;amp;key=&quot;+
//                            Config.GOOGLE_API_KEY + &quot;&amp;amp;q=&quot;+keyword+&quot;&amp;amp;maxResults=20&amp;amp;pageToken=&quot;+pageToken;
//
//                    RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
//                    JsonObjectRequest request = new JsonObjectRequest(
//                            Request.Method.GET,
//                            url,
//                            null,
//                            new Response.Listener&amp;lt;JSONObject&amp;gt;()
//                            {
//                                @Override
//                                public void onResponse(JSONObject response)
//                                {
//                                    // 데이터를 받아오면, 프로그레스바를 안보이게 한다.
//                                    progressBar.setVisibility(View.INVISIBLE);
//
//                                    try {
//                                        if (response.has(&quot;nextPageToken&quot;)){
//                                            pageToken = response.getString(&quot;nextPageToken&quot;);
//                                        }
//                                        else
//                                        {
//                                            pageToken = null;
//                                        }
//
//                                        JSONArray dataList = response.getJSONArray(&quot;items&quot;);
//
//                                        for(int i = 0; i &amp;lt; dataList.length(); i++){
//                                            String title = dataList.getJSONObject(i)
//                                                    .getJSONObject(&quot;snippet&quot;).getString(&quot;title&quot;);
//                                            String description = dataList.getJSONObject(i)
//                                                    .getJSONObject(&quot;snippet&quot;).getString(&quot;description&quot;);
//
//                                            String imgUrl = dataList.getJSONObject(i)
//                                                    .getJSONObject(&quot;snippet&quot;).getJSONObject(&quot;thumbnails&quot;)
//                                                    .getJSONObject(&quot;medium&quot;).getString(&quot;url&quot;);
//
//                                            String videoId = dataList.getJSONObject(i)
//                                                    .getJSONObject(&quot;id&quot;).getString(&quot;videoId&quot;);
//
//                                            Video video = new Video(title, description, imgUrl, videoId);
//                                            videoList.add(video);
//                                        }
//
//                                    }
//                                    catch (JSONException e)
//                                    {
//                                        e.printStackTrace();
//                                    }
//
//                                    adapter.notifyDataSetChanged();
//
//                                }
//                            },
//                            new Response.ErrorListener()
//                            {
//                                @Override
//                                public void onErrorResponse(VolleyError error)
//                                {
//                                    // 데이터를 받아오면, 프로그레스바를 안보이게 한다.
//                                    progressBar.setVisibility(View.INVISIBLE);
//
//                                }
//                            }
//                    );
//                    queue.add(request);
//
//
//
//                }
//
//            }
//        });&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Android</category>
      <author>yjh0922</author>
      <guid isPermaLink="true">https://yjh0922.tistory.com/278</guid>
      <comments>https://yjh0922.tistory.com/278#entry278comment</comments>
      <pubDate>Wed, 20 Jul 2022 18:05:07 +0900</pubDate>
    </item>
  </channel>
</rss>