2026/03/16

오늘의 이야기

어느덧 우리 집 둘째 아들 녀석이 고등학교에 입학하게 되었다. 중학교 때까지만 해도 그냥저냥 공부 좀 하는 아이였는데, 고등학교에 진학하니 다른 세상인 듯하다. 학원에서도 상위권 학생들이 많이 다니는 곳이라 그런지 성적차이가 너무 크게 느껴진다. 그래서 이번 기회에 조금이나마 도움이 될까 싶어 몇 가지 조언을 해주고 싶다.




 1. 학교 수업시간에 집중하기

고등학교에서는 내신성적과 수능시험 두 마리 토끼를 모두 잡아야 한다. 그러기 위해서는 우선 학교 수업시간에 최대한 집중해야한다. 선생님께서 말씀하시는 내용 하나하나가 시험문제라고 생각하고 열심히 들어야 하며, 특히나 수학 같은 경우엔 공식암기와 문제풀이 연습 등 혼자서 해결해야 될 부분이 많기 때문에 더더욱 그렇다. 


 


2. 플래너 활용하기

플래너를 이용하면 시간관리 뿐만 아니라 자신의 학습량을 체크하는데 큰 도움이 된다. 매일매일 해야 할 일들을 적어놓고 실천하다 보면 성취감도 생기고 자기주도학습 습관 형성에도 좋다. 또한 하루하루 계획을 달성하면서 뿌듯함도 느낄 수 있다. 


 


3. 체력관리하기

체력관리는 모든 과목공부에 있어서 필수다. 아무리 머리가 좋아도 체력이 뒷받침되지 않으면 좋은 성과를 낼 수 없다. 고3 수험생처럼 장시간 앉아서 공부하려면 체력이 좋아야 하므로 운동을 꾸준히 하면서 체력을 길러야 한다. 


 


4. 예습보다는 복습 위주로 공부하기

수업시간에 배운 내용을 완벽하게 이해했다면 굳이 다시 한 번 반복해서 공부할 필요는 없다. 하지만 대부분의 학생들은 그렇지 못하기 때문에 복습위주로 공부하며 부족한 부분을 채워나가야 한다. 


 


5. 자투리 시간 활용하기

쉬는 시간이나 점심시간 같이 짧은 시간이라도 허투루 보내지 말고 단어장을 들고 다니면서 암기하거나 영어 듣기 평가 대비용으로 MP3 파일을 듣는 등 효율적으로 보내야 한다. 


 


6. 오답노트 만들기

틀린 문제는 반드시 짚고 넘어가야 한다. 그래야 다음번에 비슷한 유형의 문제가 나왔을 때 틀리지 않는다. 틀린 문제 중 헷갈렸던 문제나 찍어서 맞춘 문제 또는 아예 모르는 문제 등등 여러 종류의 문제를 노트에 정리해 두면 나중에 많은 도움이 된다. 


 


7. 친구관계 유지하기

친구와의 관계유지는 매우 중요하다. 서로 의지하기도 하고 선의의 경쟁자가 되기도 하는데, 만약 사이가 멀어지면 여러모로 손해 보는 게 많다. 


 


8. 스마트폰 멀리하기

스마트폰은 일상생활에 편리함을 주지만 반대로 학업에 방해가 되기도 한다. 게임이나 SNS등 유혹거리가 너무나 많고 중독성이 강하기 때문이다. 


 


9. 긍정적인 마인드 갖기

아무리 노력해도 안 되는 건 어쩔 수 없지만 항상 긍정적인 마음을 가지고 생활한다면 어려운 상황 속에서도 이겨낼 수 있는 힘이 생긴다. 


 


10. 건강 챙기기

건강만큼 중요한 것도 없다. 몸이 아프면 만사가 귀찮고 짜증나기 마련이다. 그러므로 식사 거르지 말고 규칙적인 생활을 해서 아프지 않도록 하자.




이 글은 작성자가 누구일까요?  이 글은 자동 글쓰기를 시키기는 했으나, 제법 사람의 마음과 같은 생각을 하는 것 같습니다.  사랑한다. 아들~


 


https://wrtn.ai/app/tool/63b2b5587b66829fa8483b89



 


뤼튼 - AI 콘텐츠 생성 플랫폼


뤼튼 - AI 콘텐츠 생성 플랫폼 | 고객의 반응을 얻고 매출을 늘리는 경쟁력 있는 카피, 강력한 AI와 함께 10배 빠르게 완성하세요.


wrtn.ai




 





오늘의 이야기

겨울이 가고 봄이 오는 소리가 들려옵니다. 여러분은 어떤 계절을 좋아하시나요? 저는 사계절 중에서도 특히나 가을과 겨울을 좋아하는데요. 올해는 유난히 눈이 많이 와서 그런지 이번 겨울은 유독 길게 느껴지네요. 그래서 이 글에서는 제가 좋아하는 겨울이야기를 해볼까 합니다.

여러분에게 겨울이란 어떤 의미인가요?
저에게 겨울은 한 해를 마무리하며 새로운 마음으로 새해를 준비하는 시기입니다. 그래서인지 연말연시 분위기 속에서 지난 1년을 되돌아보고 다가올 새해도 계획하게 되는데요. 올 초 세웠던 목표들을 얼마나 이루었는지 점검하면서 스스로를 칭찬하기도 하고 반성하기도 하면서 앞으로의 방향성을 다시 설정하곤 합니다. 그리고 추운 날씨 탓에 몸과 마음이 움츠러들기 쉬운 만큼 건강관리에도 신경 쓰게 됩니다. 따뜻한 이불속에서 귤 까먹으며 책 읽는 재미 또한 쏠쏠하고요.

눈 내리는 날엔 뭐하시나요?
제가 사는 곳은 서울이지만 산자락에 위치해서인지 눈이 오면 참 아름다운 풍경을 만날 수 있답니다. 물론 교통체증 등 불편함도 있지만 하얀 눈이 소복이 쌓인 모습을 보고 있으면 왠지 모르게 기분이 좋아지는데요. 이럴 때면 아이처럼 밖으로 나가 눈사람도 만들고 눈싸움도 하며 신나게 놀곤 합니다. 하지만 이렇게 놀다 보면 어느새 옷이며 신발 모두 흠뻑 젖어버리는데요. 그럴 땐 근처 목욕탕에 가서 개운하게 씻고 나면 추위 따위는 금세 잊어버리게 된답니다.

겨울철 별미는 뭘까요?
추운 겨울이면 뜨끈한 국물 요리가 절로 생각나는데요. 개인적으로는 '어묵탕'을 즐겨 먹는답니다. 어묵탕은 만들기도 쉽고 맛도 좋아서 겨울철 단골 메뉴이기도 한데요. 멸치 육수에 무랑 양파 넣고 끓이다가 어묵이랑 파 송송 썰어 넣으면 완성이랍니다. 거기에 취향에 따라 청양고추 한두 개 넣어주면 칼칼한 맛이 더해져 더욱 맛있게 즐길 수 있지요. 따끈한 어묵탕 먹고 난 후 남은 국물에 가락국수사리 넣어서 끓여 먹으면 그야말로 금상첨화랍니다.

어느덧 3월 이네요. 이제 곧 꽃 피는 봄이 오겠죠? 우리 조금만 더 힘내서 이시국을 벗어나 보아요~~~


 




이 이야기는 제가 썼나요?


 


https://wrtn.ai/app/tool/63 b2 b5587 b66829 fa8483 b89



 


뤼튼 - AI 콘텐츠 생성 플랫폼


뤼튼 - AI 콘텐츠 생성 플랫폼 | 고객의 반응을 얻고 매출을 늘리는 경쟁력 있는 카피, 강력한 AI와 함께 10배 빠르게 완성하세요.


wrtn.ai




 





오늘의 이야기



#스치니1000프로젝트 #재미 #행운기원 #Compose #Firebase

🎯 야 너 토요일마다 로또 확인하냐?
나도 맨날 "혹시나~" 하면서 봤거든 ㅋㅋ

근데 이제는 그냥 안 해
AI한테 맡겼어 🤖✨

그것도 구글 Gemini로다가!

그래서 앱 하나 만들었지
👉 "로또 예상번호 by Gemini" 🎱

AI가 분석해서 번호 딱! 뽑아줌
그냥 보고 참고만 하면 됨

재미로 해도 좋고…
혹시 모르는 거잖아? 😏


https://play.google.com/store/apps/details?id=com.billcorea.gptlotto1127




오늘의 이야기

봄 하면 벚꽃이죠~ 코로나19로 인해 사람들이 많이 모이는 장소는 피하게 되는데요 그래서 저는 한적한 공원 위주로 소개하려고 해요. 서울 내에서도 유명한 여의도 윤중로 등 다양한 명소가 있지만 제가 사는 지역인 인천에서는 조금 멀리 떨어진 강화도나 경기도 양평 두물머리 같은 곳들을 주로 다녔어요. 특히 이번 포스팅에선 그동안 다녔던 곳 중 베스트 오브 베스트라고 생각되는 곳 10곳을 선정해서 알려드리려고 합니다.

인천과 가까운 여행지로는 어디가 있을까요?
인천공항이 위치한 영종도 주변으로는 을왕리 해수욕장, 왕산 해수욕장, 마시안 해변 등 많은 관광지가 자리 잡고 있어요. 이 밖에도 송도 센트럴파크, 월미도, 차이나타운 등등 볼거리 먹거리가 가득한 도시랍니다.

서울 근교 드라이브 코스는요?
제가 살고 있는 인천지역 말고도 서울근교로도 갈만한 곳이 많아요. 대표적으로 가평 아침고요수목원, 파주 헤이리마을, 남양주 물의 정원, 양평 두물머리, 하남 스타필드 등 주말에 가족끼리 연인끼리 다녀오기 좋은 곳이랍니다.

경기도 광주시 화담숲은요?
화담숲은 곤지암 리조트 안에 조성된 수목원이에요. 4월 중순부터는 철쭉축제가 열리는데 올해는 아쉽게도 코로나19로 인해 취소되었다고 하네요. 하지만 산책하기 좋고 모노레일 타고 정상까지 올라갈 수 있어서 아이들과 함께 가기 좋아요. 입장료는 성인기준 1만 원이고 인터넷 예매 시 천 원 할인됩니다.

양평 두물머리는 어떤가요?
두물머리는 북한강과 남한강이 만나는 지점이라 붙여진 이름이래요. 이곳은 사계절 내내 멋진 풍경을 자랑하는데 개인적으론 가을 단풍철에 가면 제일 멋있다고 생각해요. 근처에 카페랑 맛집도 많아서 데이트 코스로도 좋답니다.

강화도는 어떤가요?
강화도는 섬 전체가 유적지라 해도 과언이 아닐 만큼 역사유적지가 많은데요 고인돌공원, 고려궁지, 전등사, 광성보, 초지진 등 교과서에서만 보던 문화재들을 직접 눈으로 볼 수 있답니다. 또한 동막해변, 석모도 보문사, 마니산 등 자연경관도 빼어나고 일몰명소이기도 해서 사진 찍기 좋아하시는 분들에게 강추입니다.

파주 프로방스 마을은요?
프로방스 마을은 프랑스 남부지방의 전원마을을 재현한 테마형 마을이에요. 알록달록 예쁜 건물들과 아기자기한 소품샵 그리고 맛있는 음식점들이 모여있어 나들이 겸 쇼핑하러 가기 딱 좋습니다. 무료주차장이 있긴 한데 워낙 인기가 좋아서 주차공간이 부족하니 일찍 가시는 걸 추천드려요.

하남 스타필드는 어떤가요?
스타필드는 신세계그룹에서 운영하는 복합쇼핑몰이에요. 쇼핑몰 규모가 어마어마한데 실내외 모두 구경거리가 많고 하루종일 있어도 지루하지 않아요. 아쿠아필드라는 워터파크 시설도 있고 메가박스 영화관도 있으니 참고하세요.


 




이글은 제가 썼을까요? GPT가 써 주었을까요?


 


https://wrtn.ai/app/tool/63 b2 b5587 b66829 fa8483 b89



 


뤼튼 - AI 콘텐츠 생성 플랫폼


뤼튼 - AI 콘텐츠 생성 플랫폼 | 고객의 반응을 얻고 매출을 늘리는 경쟁력 있는 카피, 강력한 AI와 함께 10배 빠르게 완성하세요.


wrtn.ai




 





오늘의 이야기


#스하리1000명프로젝트

스치니들!
내가 만든 이 앱은, 내 폰에 오는 알림 중에서 중요한 키워드가 있는 경우
등록해둔 친구에게 자동으로 전달해주는 앱이야 📲

예를 들어, 카드 결제 알림을 와이프나 자녀에게 보내주거나
이번 달 지출을 달력처럼 확인할 수도 있어!

앱을 함께 쓰려면 친구도 설치 & 로그인해줘야 해.
그래야 친구 목록에서 서로 선택할 수 있으니까~
서로 써보고 불편한 점 있으면 알려줘 🙏

👉 https://play.google.com/store/apps/details?id=com.nari.notify2kakao





오늘의 이야기

요즘 뉴스나 신문기사를 보면 한숨밖에 안 나오는 기사들이 많아요. 특히 최근엔 조국 법무부장관 후보자 관련해서 여러 가지 의혹들이 제기되고 있고, 이에 대해 검찰 수사가 진행 중인 상황입니다. 그리고 자유한국당에서는 청문회 일정 합의를 거부하며 장외투쟁을 하고 있죠. 이렇게 여야 간의 갈등이 심화되는 가운데, 어제(9월 2일) 문재인 대통령과 5당 대표와의 회동이 있었습니다. 하지만 이번 회동에서도 서로 간의 입장차이만 확인했을 뿐 별다른 성과 없이 끝나게 되었습니다.

 현재 우리나라의 정치상황 어떻게 보시나요?
현재 우리나라의 정치상황은 한마디로 엉망진창이라 표현할 수 있겠네요. 여당 야당 모두 국민들을 위한 정치를 하겠다고 말하지만 정작 하는 행동은 자기 밥그릇 챙기기에만 급급한 모습이네요. 저는 개인적으로 지금처럼 진영논리로만 싸우는 정치는 이제 그만해야한다고 생각해요. 물론 보수진영에선 현 정부 정책 중 마음에 들지 않는 부분이 많을 거고, 진보진영에선 반대입장이겠죠. 그렇지만 그런 것들을 다 떠나서 국가발전을 위해 머리를 맞대고 논의해도 모자랄 판에 무조건 상대방 잘못이라며 헐뜯고 비난하기 바쁜 건 너무 소모적이고 비생산적인 일 같아요.

 왜 그렇게 싸우나요?
저는 크게 두가지 이유라고 생각해요. 첫 번째는 '국민'보다는 '자기 자신'만을 생각한다는 점이에요. 당장 내년 총선 때 자신에게 유리한 구도를 만들기 위해서죠. 국회의원이라는 자리는 지역구민들의 지지를 받아 당선되기 때문에 다음 선거 때 공천권을 받기 위해선 최대한 많은 표를 얻어야겠죠. 그래서 당대표라는 사람들이 앞장서서 막말을 하며 싸움을 부추기고 있다고 생각해요. 또한 언론플레이를 통해서 여론을 조작하려는 시도도 많이 보여요. 예를 들면 나경원 원내대표가 미국 측에 지소미아 파기 철회를 요구했다는 발언 같은 경우 거짓임이 드러났죠. 이러한 행위들은 결국 유권자들의 판단을 흐리게 만들고 민주주의 발전을 저해하게 됩니다.
두 번째는 정당정치의 한계점이죠. 대의민주주의 하에서 각 정당은 정권획득을 목표로 경쟁관계에 놓이게 되는데, 이때 필연적으로 발생하는 문제가 당내 계파갈등 및 분열문제입니다. 민주화 이후 한국정치는 양당체제하에서 전개되어 왔는데, 이를 두고 학자들은 '정당국가'라 부르기도 합니다. 즉, 모든 권력이 정당으로부터 나온다는 뜻이죠. 따라서 정당 내에서의 세력다툼은 자연스러운 현상이지만, 이것이 지나치게 과열될 경우 오히려 국정운영에 방해가 될 수 있다는 단점이 존재합니다.

 해결방안은 없을까요?
해결방안은 딱 하나로 정의하긴 어려울 것 같아요. 다만 제가 생각하는 방안은 첫째, 시민의식 개선입니다. 앞서 말했듯이 일부 정치인들의 극단적인 언행 등은 사회분열을 조장하고 국론을 분열시키는 결과를 초래합니다. 그렇기 때문에 성숙한 시민의식을 가지고 잘못된 관행을 비판함으로써 올바른 방향으로 나아갈 수 있도록 해야 합니다. 둘째, 제도개선입니다. 아무리 좋은 취지라도 법과 제도가 뒷받침되지 않으면 제대로 실현되기 어렵습니다. 공정한 규칙 속에서 선의의 경쟁을 펼칠 수 있도록 시스템을 정비한다면 보다 나은 미래를 기대할 수 있을 것입니다. 셋째, 대화와 타협 문화 정착입니다. 마지막으로 넷째, 초당적 협력체계 구축입니다. 특정 사안에 대하여 대립하더라도 궁극적으로는 민생안정과 경제회복을 최우선 과제로 삼아야 한다는 인식을 공유하여야 합니다.


 




이 글은 제가 썼을까요?  AI 가 썼을까요?


 


블로그 글쓰기



 


https://wrtn.ai/



 


뤼튼 - AI 콘텐츠 생성 플랫폼


뤼튼 - AI 콘텐츠 생성 플랫폼 | 고객의 반응을 얻고 매출을 늘리는 경쟁력 있는 카피, 강력한 AI와 함께 10배 빠르게 완성하세요.


wrtn.ai




 





오늘의 이야기

이 앱은...

가입유도 링크



이 앱은 최초에 마트에서 제공해 주는 할인쿠폰을 모아 보기 위해서 기획 의도 되고 개발된 앱 이었습니다.  
어느 날  요청자 께서 말씀하시길 회원이 보여주는 영수증도 모아볼 수 있는 가에 대한 의견을 제시해 주셨고, 그분의 의견을 들어 앱을 개선해 보기로 했습니다.    그러다가 ...  다시 원래의 모습으로 복원 하기로 하였습니다.


 


1. 이제 Ver 0.5.0  이 되면서  다시 원래의 모습으로 돌아갑니다. 사유는 앱의 기능을 분리하여 사용하고자 합니다. 원래의 앱은 당초 기획 했던 앱의 기능과 같이  회원앱으로 기능을 제한하게 됩니다.   마켓에 다른앱이 하나 게시 됩니다. 그 앱을 이용하여 중간에 구현 되었던 관리자 기능은 해당 앱으로 이전합니다. 이전된 앱 다음 링크에서 확인해 보실 수 있습니다.   관리자 앱의 기능은 아래 Ver 0.4.0 의 앱 기능 설명으로 대신 하고자 합니다.  정리가 되면 기능 설명은 분리할 예정 이기는 합니다.

https://play.google.com/store/apps/details?id=com.billcorea.barcodemanager0606



 


바코드 할인쿠폰 (관리자) - Google Play 앱


이 앱은 바코드 할인쿠폰 앱과 연동 하여 회원관리를 지원 하기 위한 관리자 전용 입니다.


play.google.com




관리자 버전의 사용자 설명서는 다음 링크를 참조해 주세요.


https://billcorea.tistory.com/362



 


바코드 할인쿠폰 (관리자용) 앱 사용자 설명서


이 글은 앱을 이용하여 회원관리를 할 수 있도록 구성하기 위한 방편으로 관리자용 업무 기능 지원하는 앱 사용자를 위한 사용자 설명서 페이지입니다. 회원관리를 위한 앱은 바코드 할인쿠폰


billcorea.tistory.com






2. Ver 0.5.0  이 기준으로 해서 앱의 기능은 각각 관리자용, 회원용 이렇게 분리 되어 운영될 예정 입니다.  



변경된 메인 화면 모습




3. 변경된 앱 기능 버튼은  
   3.1 추가버튼 (+ 표시) :  Barcode 쿠폰 등록을 할 수 있도록 지원 됩니다.
   3.2 회원버튼 (사람표시) : 회원 관리 기능으로 넘어갑니다.



근처에 관리자 / 회원 앱이 있을 때 접속이 되면서 버전 표식 옆에 나타나는 버튼 이미지




4. 위 그림과 같이 근처 인식 (Nearby) 기능이 활성화 되면, 접속 되었다는 알림(6자리 숫자 표시) 과 함께 상단에 표시가 나타납니다.  이 떄 해당 표시를 클릭 하게 되면, 관리자 앱의  방문자 리스트에 방문 등록이 추가 됩니다.  관리자는 방문자 리스트 을 확인 하여 업무 처리를 지원할 수 있습니다.
 


처음 작성 되었던 Ver 0.0.3 버전 이야기는 아래에 있습니다.

 
마트에 갔을 때  제공 되는 각종 할인 쿠폰을 이미지로 담아 두었다가 다음 방문 시에 활용할 수 있도록 지원하는 것을 목적으로 합니다. 


메인화면



화면이 비어 있다면 아직 자료가 1도 없다는 이야기가 될 듯합니다. 


메인화면 버튼

메인 화면에는 뒤로 가기, 추가하기( 플러스 버튼) 이 존재합니다. 추가하기 버튼을 클릭해 보겠습니다. 


입력화면



자료를 입력할 부분은 다음과 같습니다.



  • 바코드 : 바코드 아이콘을 클릭하면 바코드 스캐너가 실행되어 바코드 정보를 스캔할 수 있습니다.

  • 바코드 이미지 : 카메라 버튼으로 직접 촬영을 하거나, 이미 저장된 이미지를 불러올 수 있습니다.

  • 할인쿠폰 이름 : 할인 쿠폰 이름은 기억하기 쉬운 내용으로 입력을 하시면 됩니다.

  • 유효기간 선택 : 유효기간은 달력에서 선택하시면 됩니다.

  • 할인해 주는 금액 입력 : 할인해 주는 금액은 필요에 따라 숫자로 입력하시면 됩니다.


 
이제 입력된 자료를 저장하기 위해서 저장하기 버튼을 클릭하면 자료가 저장되고 메인화면으로 돌아갑니다.
입력된 자료는 메인 화면에서 바로 조회가 되므로  메인 화면에서 보시면 됩니다.  
 


단위 아이템



메인화면에서 보이는 개별 아이템의 버튼은 앞에서부터



  • 자세히 보기

  • 수정하기

  • 삭제하기


버튼이 달려 있어서  실제 마트에서 바코드를 보여 주어야 하는 경우가 있다면 자세히 보기 버튼을 클릭해서 개별 화면으로 보여주는 것이 마트에 있는 POS 장비에게 도움이 될 듯합니다. 
 
이 앱은 사용하다가 궁금하거나, 추가 요청을 하시고 싶은 내용이 있다면 help@billcorea.com으로 메일 보내 주시면 적극 수용해 드립니다.
 
https://play.google.com/store/apps/details?id=com.billcorea.barcodevoucher0225 



 


할인 쿠폰 모아보기 (종이영수증 버리기) - Google Play 앱


마트에서 주는 할인 쿠폰을 모아서 쉽게 관리 하세요.


play.google.com




playstore에서 만나보세요.





오늘의 이야기


#스하리1000명프로젝트,
Bazen yabancı işçilerle konuşmak zor oluyor, değil mi?
Yardımcı olacak basit bir uygulama yaptım! Siz kendi dilinizde yazarsınız ve başkaları da bunu kendi dillerinde görür.
Ayarlara göre otomatik çeviri yapar.
Kolay sohbetler için son derece kullanışlı. Fırsat bulduğunda bir göz at!
https://play.google.com/store/apps/details?id=com.billcoreatech.multichat416




오늘의 이야기

할인쿠폰 모아 보기

오늘도 1일 1 앱 만들기에 도전해 보았어요.  오늘 만들고 싶었던 건...
언제부터 인가 우리 동네 마트에서 영수증에 할인 쿠폰을 찍어 주더라고요.  다음에 사용하면 3000원 할인해 준다거나...
맥주캔 묶음을 사면 할인을 해주는 쿠폰을 준다거나 하는 일이 있더라고요.
그런 쿠폰들이 일회성 종일로 나오기 때문에 버려지는 것이지요.  그래서 일단 모이 보기로 했어요.


 




 


zxing

이전 포스팅에서 사용했던 barcode 스캔을 위한 라이브러리를 활용했습니다.  그때는 바코드 스캔을 위한 기능만을 활용하기 위해 썼다면 이번에는 스캔도 하고 바코드를 만들어 내는 기능으로 활용을 했습니다. 


https://github.com/zxing/zxing



 


GitHub - zxing/zxing: ZXing ("Zebra Crossing") barcode scanning library for Java, Android


ZXing ("Zebra Crossing") barcode scanning library for Java, Android - GitHub - zxing/zxing: ZXing ("Zebra Crossing") barcode scanning library for Java, Android


github.com




 


언제쯤 이면 이런 라이브러리를 활용만 하는 게 아니라, 만들어 제공을 할 수 있을까는 궁금하기는 합니다.   아무튼...


덕분에 수월하게 바코드 활용과 관련된 앱을 만들어 볼 수 있었습니다. 


 


최근 버전은 아래와 같습니다. 이걸 gradle 파일에 추가하면 사용을 시작해 볼 수 있습니다.


// barcode scan
implementation 'com.journeyapps:zxing-android-embedded:4.3.0'
implementation 'com.google.zxing:core:3.4.1'

 


Camera 권한 얻기 

사용에 필요한 권한은 아시는 것처럼 camera 권한이 필요합니다. manifest 파일도 추가하고, source  code에서도 체크하는 기능을 추가합니다. 


<uses-permission android:name="android.permission.CAMERA" />

jetpack compose에서 아래처럼 카메라 권한을 획득하는 composable 함수를 만들어 사용하면 비슷한 기능을 구현할 때 코드 작업을 덜 해도 되는 도움이 되기는 하더라고요. 


@OptIn(ExperimentalPermissionsApi::class)
@Composable
fun FeatureThatRequiresCameraPermission(
doResult: (result : Boolean) -> Unit
) {
// Camera permission state
val cameraPermissionState = rememberPermissionState(
Manifest.permission.CAMERA
)

when (cameraPermissionState.status) {
// If the camera permission is granted, then show screen with the feature enabled
PermissionStatus.Granted -> {
doResult(true)
}
is PermissionStatus.Denied -> {
Column(
modifier = Modifier.padding(3.dp),
horizontalAlignment = Alignment.End
) {
val textToShow = if ((cameraPermissionState.status as PermissionStatus.Denied).shouldShowRationale) {
// If the user has denied the permission but the rationale can be shown,
// then gently explain why the app requires this permission
stringResource(id = R.string.msgGetPermissonCamera)
} else {
// If it's the first time the user lands on this feature, or the user
// doesn't want to be asked again for this permission, explain that the
// permission is required
stringResource(id = R.string.msgGetPermissonCamera)
}
IconButton(onClick = {

cameraPermissionState.launchPermissionRequest()
doResult(false)

}) {
Icon(
imageVector = Icons.Outlined.PermCameraMic,
contentDescription = "Grant a Camera",
tint = softBlue
)
}
Text(textToShow)
}
}
}
}

이런 함수 구현을 위해서는  아래와 같은 implementation 선언이 필요합니다.


 


// 권한 획득
implementation "com.google.accompanist:accompanist-permissions:0.28.0"

그러면 실제 코드에서는 그냥 함수를 호출하는 것만으로 권한 획득을 구현해 볼 수 있습니다.


 


바코드 스캔 하기

스캔하는 부분에 관한 이야기는 이전 포스팅을 봐주세요. 달라지는 부분이 별로 없는 것 같아요.


https://billcorea.tistory.com/128



 


안드로이드 앱 만들기 : qrscan , barcode 스캐너


예전에도 살펴본 적이 있기는 하지만, https://github.com/zxing/zxing/wiki/Getting-Started-Developing GitHub - zxing/zxing: ZXing ("Zebra Crossing") barcode scanning library for Java, Android ZXing ("Zebra Crossing") barcode scanning library fo


billcorea.tistory.com




 


 


바코드 만들어 보기

스캔이 되어 저장을 했다면 이제 그 걸 반대로 이미지로 만들어 보겠습니다. 


 


barcodeItem.barCode.let { itemImage ->
if (itemImage != "") {
val imageAsBytes: ByteArray =
Base64.decode(itemImage.toByteArray(), Base64.DEFAULT)
val bitMap =
BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.size)
Image(
bitmap = bitMap.asImageBitmap(),
contentDescription = "bitMap",
modifier = Modifier.fillMaxWidth()
)
}
}

composable 함수 내에서 구현을 하고 있기 때문에 위와 같은 코드 하나면 이미지로 전환을 해서 바로 화면에 보여줄 수 있습니다. barcode 정보는 byte string으로 전환해서 저장을 해 두었으니 그 반대로 byte string을 bitmap으로 전환해 Image에 넣어 보여 주는 것입니다. 


 


혹여나 composable 화면이 아닌 xml layout 을 활용하고 있다고 해도 그 원리는 유사하게 구현이 가능할 듯합니다.


아무튼 이렇게 해서 코드 구현에 대한 이야기는 정리가 될 것 같습니다. 


 


하루가 지났는 데도  playstore에서는 아직 승인이 나지 않았습니다.  금방 배포가 되겠지요...   배포가 되면 링크는 수정해서 게시해 보도록 하겠습니다.





오늘의 이야기

안드로이드가 파일을 download 해야 한다고?

이런 일이 있을까 싶기도 합니다.  안드로이드 앱에서 파일을 받아야 한다니? 


 


하지만 그것이 필요한 시점이 되었을 때,  기초가 미흡한 입장에서는 어디서 찾아야 하는 가 하는 고민을 하게 됩니다. 


오늘은  ktor을 활용해 파일 받기 구현을 해 보았습니다. 


 


gradle 구성하기

// ktor download
implementation "io.ktor:ktor-client-android:1.2.5"
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.3'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'

앱 수준의 grade 파일에는 위와 같은 implementation 이 필요합니다. 


 


manifest에서 필요 권한  선언 하기

<uses-permission android:name="android.permission.INTERNET" />

당연한 이야기 이겠지만, internet 접속을 위한 권한은 있어야 합니다. 그래야 통신으로 원격지에 있는 파일을 받아올 테니까요.


인터넷을 활용하는 앱을 구성할 때 챙겨서 가야  하는 부분들이 있더군요. 인터넷은 비동기 통신을 하기 때문에 꼭 들어가야 합니다. 


 


<application
...
android:usesCleartextTraffic="true"
android:networkSecurityConfig="@xml/network_security_config"
...
>

개발자 페이지 참조



요새는 다들 보안 때문에 HTTPS:// 으로 시작하는 대부분의 URL을 보게 되는 데, 예전 HTTP 통신보다는 인증서등을 활용해서 보안이 강화되어 기본적으로 안드로이드는 HTTPS 통신이 아닌 경우 처리가 되지 않습니다.  그래서 안드로이드에서는 http 통신을 해야 하는지에 대한 부분을 선언해 주어야 하거나,  아래와 같이 보안 구성을 해 주는 방식으로 처리를 해야 한다고 합니다.


 


network_security_config

이 파일은 res/xml 폴더에 network_security_config.xml로 작성 되어 있습니다. 저기에 기술되는 도메인이나, ip 등은 http로 접속을 해도 허용하도록 해 주는 것이지요.


<?xml version="1.0" encoding="utf-8"?>

<network-security-config>

<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">192.168.0.7</domain>
</domain-config>

</network-security-config>

https://developer.android.com/training/articles/security-config?hl=ko 



 


네트워크 보안 구성  |  Android 개발자  |  Android Developers


앱 개발자가 안전한 구성 파일에서 네트워크 보안 설정을 사용자설정할 수 있는 기능입니다.


developer.android.com




좀 더 자세한 부분은 개발가이드를 참조해 보세요.


 


activity에서 download 받아 보기.

이제 download을 구현해 보겠습니다.  봐야 하는 부분은 파일을 저장할 경로입니다.  예전에는 sdcard 등등 External Storage에 권한을 이용해서 저장을 많이 하고는 했지만, 안드로이드가 보안에 적극적이면 앱이 사용할 수 있는 경로가 한정적으로 변해 왔습니다.


 


그래서 기본적으로 사용이 가능한 경로는 앱마다 가지게 되는 경로를 이용해서 저장을 하게 됩니다.


/sdcard/Android/data/패키지이름/files/Download를 지칭하게 됩니다.


val folder = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)
val file = File(folder, tableOrder.pos_app_id)

val uri = FileProvider.getUriForFile(this@MainActivity, "${BuildConfig.APPLICATION_ID}.provider", file)

Log.e("","path= ${file.path} ${file.name}")

downloadFile(this@MainActivity, tableOrder.pos_file_link, uri)

 downloadFile  함수는 다음 코드처럼 구현을 할 수 있습니다.   이렇게 함수를 호출하는 것 만으로 파일을 내려받을 수 있습니다. 


private fun downloadFile(context: Context, url: String, file: Uri) {
val ktor = HttpClient(Android)

context.contentResolver.openOutputStream(file)?.let { outputStream ->
CoroutineScope(Dispatchers.IO).launch {
ktor.downloadFile(outputStream, url).collect {
withContext(Dispatchers.Main) {
when (it) {
is DownloadResult.Success -> {
... // 정상적으로 끝났을 때
}

is DownloadResult.Error -> {
... // 처리 하다가 오류가 발생한 경우
}

is DownloadResult.Progress -> {
// 프로그램바 표시를 위한 처리
dataViewModels.downloadProgress.value = it.progress
}
}
}
}
}
}
}

 


오늘은 이상으로 파일 내려받기를 구현해 보았습니다.   아직 정리가 될 되어 실행하는 모습은 보여 드릴 수가 없네요.


아무튼 오늘도 하나 기억으로 남겨 두고자 글을 적었습니다. 


 


이 부분이랑, 받은 파일을 이용해서 설치 하는 코드를 구현 하느라 2일이 지나갔습니다.  다음에 안 그래야 할 텐데 말입니다. 


 


 





오늘의 이야기


#billcorea #운동동아리관리앱
🏸 Schneedle, badminton kulüplerinin olmazsa olmaz uygulaması!
👉 Maç Oyunu – Skorları Kaydedin ve Rakipleri Bulun 🎉
Tek başınıza, arkadaşlarınızla veya bir kulüpte her yerde mükemmel! 🤝
Badmintonu seviyorsanız mutlaka deneyin

Uygulamaya git 👉 https://play.google.com/store/apps/details?id=com.billcorea.matchplay




오늘의 이야기

어느덧 우리 집 둘째 아들 녀석이 고등학교에 입학하게 되었다. 중학교 때까지만 해도 그냥저냥 공부 좀 하는 아이였는데, 고등학교에 진학하니 다른 세상인 듯하다. 학원에서도 상위권 학생들이 많이 다니는 곳이라 그런지 성적차이가 너무 크게 느껴진다. 그래...