1. 오류상세

   -  java.lang.IllegalStateException: Room cannot verify the data integrity. 

      Looks like you've changed schema but forgot to update the version number.

      You can simply fix this by increasing the version number.

 

2. 사용 Libaray 및 기능

   - Room

 

3. 발생이유

   - 생성했던 database안에 테이블 및 컬럼들이 변경 되었는데 소스상에서 변경된 상황을 App에게 알려주지 않았기 때문이다.

    - 발생이유 상세예제

      아래 *1차버전 소스에서 보면 history table을 하나만 관리하다가

              *2차버전 소스에서 review table 을 하나 추가 했는데 이때 version을 증가시키지 않았기 때문에 오류가 발생한다.

9. 해결방법 - 1

    - database version을 올려주고, Migration( ) 작업을 해준다.

    - script (AppDatabase.kt)

Posted by 농부지기
,

1. 오류상세

   - E/part3.chapter0: Unknown bits set in runtime_flags: 0x8000
     E/RecyclerView: No adapter attached; skipping layout

 

2. 사용 Libaray 및 기능

   - RecyclerView

   - binding

 

3. 발생이유

   - RecyclerView 사용기능 확인

   - binding 기법 확인 

9. 해결방법 - 1

   - getItemCount() 함수에서 return 시 size 확인

       Log를 이용해서 size가 정확히 return 되는지 확인 한다.

   - Adapter를 ListAdapter로 상속받아서 개발하면 getItemCount( ) 메서드를 생성하지 않아도 된다.

    - script

    public int getItemCount() {

        Log.d("size", data.size())
        return data.size();
    }

 

9. 해결방법 - 2

     - Adapter class는 정상적이라고 생각 하고...  

       Adapter class와 RecyclerView를 연결하는 부분을 확인한다.

     - 거의 layoutManager를 생성하지 않았을 경우에 위와 같은 오류가 발생한다.

     - 참고, layoutManager는 kotlin소스 내부에서도 할 수 있자만 View속성에서도 지정할 수 있다.

        <androidx.recyclerview.widget.RecyclerView

                 android:id="@+id/rv_list"

                 app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />

     - script

    private lateinit var adapter: BookAdapter
    private fun initBookRecyclerView() {
        adapter = BookAdapter()
        binding.bookRecyclerView.layoutManager = LinearLayoutManager(this)
        binding.bookRecyclerView.adapter = adapter
    }

 

9. 해결방법 - 3

    - binding 방식으로 개발 했으면서 setContentView에 binding방식으로 변경하지 않은 경우

    - default MainActivity.kt는 setContentView(R.id.activity_main) 으로 되어 있는데

      이것을 binding방식으로 개발할 때는 setContentView(binding.root)로 변경해야 된다.

    - RecyclerView를 사용하면서 binding.root로 변경하지 않으면 위와 같은 오류가 발생한다.

    - script

       private lateinit var binding: ActivityMainBinding
       binding = ActivityMainBinding.inflate(layoutInflater)
       setContentView(binding.root)

 

 

Posted by 농부지기
,

network security policy

 

1. 오류상세

   - java.net.UnknownServiceException: CLEARTEXT communication to book.interpark.com not permitted by network security policy

 

2. 사용 Libaray

   - retrofit

 

3. 발생이유

   - URL 호출시 "http" 로 호출 했기때문이다.

   - 예, http://book.interpark.com 

 

4. 해결방법 - 1

   - http를 https 로 변경

       https://book.interpark.com

 

4. 해결방안 - 2

   - 보안 연결인 TLS(Transport Layer Security)연결을 사용 해야 한다.

   - 관련 Link.

   - 방안1: 장점 : 모든 ip 가능

             : Manifest.xml 파일의 Application내에

              android:userClearTextTraffic="true" 를 추가하면

              http 연결을 허용하게 된다.

   - 방안2: 단점 - 저장한 ip만 가능

             : 파일생성 - res>xml>network_security_config.xml
             : 파일내용 -

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">192.168.000.000</domain>
    </domain-config>
</network-security-config>

            :  Manifest.xml 파일의 Application내에

               android:networkSecurityConfig="@xml/network_security_config"

5. 비슷한 오류
    - https://farmerkyh.tistory.com/1152

   

        

 

Posted by 농부지기
,

NoConnectionError. ClearTextHTTP traffic

 

1. 오류상세

   - No type arguments expected for class Call

 

2. 사용 Libaray

   - retrofit

 

3. 발생이유

   - return : Call<Dto> 을 기술하면 자동 import가  "android.telecom.Call" 이 된다.

4. 해결방안

   - import retrofit2.Call     로 해주면 정상수행 된다.

Posted by 농부지기
,

NoConnectionError. ClearTextHTTP traffic

 

1. 오류상세

   - com.android.volley.NoConnectonError: java.io.IOException:

     ClearText HTTP traffic to192.168.000.000 not permitted

 

2. 사용 Libaray

   - volley

 

3. 발생이유

   - 예전에는 http호출로 인터넷이 접속 되었지만 google정책변경으로

     http접속을 차단하고 https만 가능하도록 했다.

   - SDK 28버전 부터 https를 통한 연결만 가능하도록 했다.

 

4. 해결방안

   - 보안 연결인 TLS(Transport Layer Security)연결을 사용 해야 한다.

   - 관련 Link.

   - 방안1: 장점 : 모든 ip 가능

             : Manifest.xml 파일의 Application내에

              android:userClearTextTraffic="true" 를 추가하면

              http 연결을 허용하게 된다.

   - 방안2: 단점 - 저장한 ip만 가능

             : 파일생성 - res>xml>network_security_config.xml
             : 파일내용 -

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">192.168.000.000</domain>
    </domain-config>
</network-security-config>

            :  Manifest.xml 파일의 Application내에

               android:networkSecurityConfig="@xml/network_security_config"

 

..

 

Posted by 농부지기
,

1. Camera Process


2. 카메라 사용 Process 2가지 방법
    첫번째. 개발한 앱에서 카메라 API를 이용해서 직접 사진을 찍고 사진을 얻어 오는 방법
            정점, 사진찍기 속도가 빠르다.
            단점, 폰 기종마다 카메라 성능등이 달라 어려움이 많다.
    두번째-(thumbnail방식). 카메라 APP을 이용하는 방법 
            a. 진행 과정
               1. 개발한 앱 <-> 카메라 APP <-> 카메라
            b. 진행 과정 상세
               1. 개발한 앱에서 카메라 APP에 사진찍어달라 요청
               2. 카메라 APP은 카메라를 통해 사진을 찍고, 사진을 받아온다.
               3. 카메라 APP은 전달받은 사진을 다시 개발한 앱으로 전송한다.
            c. 특징
               1. 위와 진행과정 같은 Process방식은 INTENT를 이용해야 된다.
               2. INTENT의 용량은 제한적이다. 그래서 thumbnail방식으로만(작은size) 주고 받는다.
    두번째-(Provider방식). 카메라 APP을 이용하는 방법 
            - 카메라 원본사이즈를 원한다면 Provider방식으로 구현해야 된다.
            a. 진행 과정
               1. 개발한 앱 -> 저장소에 임시로 파일 생성
               2. 개발한 앱 <-> 카메라 APP <-> 카메라
            b. 진행 과정 상세
               1. 개발한 앱에서 저장소에 임시파일 하나를 생성 후 image_uri를 얻어온다.
               2. 개발한 앱에서 카메라 APP에  사진찍어달라 요청
                  - 이때 image_uri를 전송하면서 사진을 이곳에 저장해달라고 요청한다.
               3. 카메라 APP은 카메라를 통해 사진을 찍고, 사진을 받아온다.
                  - 받아온 사진을 image_uri에 저장 한다.
               4. 카메라 APP은 image_uri에 저장후 개발한 앱으로 결과를 전송한다.
               5. 개발한 앱은 image_uri에서 사진을 불러와 사용한다.

3.  File Provider 란
               1. 임시로 다른 APP에게 홈디렉토리(홈저장소)에 접근할 수 있도록 권한을 부여하는 역할을 담당
    File Provider 특징
               1. 저장소는 개발한 앱에서는 홈디렉토리와 같다. (앱에서 마음대로 접근가능)
               2. 카메라 APP은 개발한 앱.홈디렉토리에 접근 할 수 없다.
               3. 이때 카메라 APP에 임시권한부여를 해줘야 된다.
               4. 임시권한부여를 위해서 File Provider를 제공한다.
               5. File Provider를 이용해서 권한이 부여된 image_url을 만들어 카메라 APP으로 전송해준다.
               6. 카메라 APP은 권한 부여받은 image_url에 접근할 수 있다.

    -  기본적으로 카메라 미리보기는 사진이미지가 깨져 보인다.
    -  원본이미지를 보고 싶다면 (간략설명)
         1. 카메라가 사진을 찍은 후 -> 카메라 APP에서 저장소에 저장 후 -> 앱에서  저장소에있는 원본이미지 조회
    -  원본이미지를 보고 싶다면 (상세설명) - Provider 이용
         1. 개발한 앱에서 Provider를 이용해서  저장소_image_Uri생성
         2. 개발한 앱에서 > 카메라 APP을 호출 시  저장소_image_Uri 전송
         3. 카메라 APP이 카메라를 구동시킨다.
         4. 카메라에서 사진을 찍은 후 사진을 카메라 APP으로 전송한다.
         5. 카메라 APP은  저장소_image_Uri  를 이용해 사진을 저장한다.
         6. 개발한 앱은 저장소_image_Uri 에서 사진을 불러드릴 수 있다.

4. 저장소 종류
      1. 일반저장소와 케시저장소 2가지 이다.
      2. 일반저장소
          - APP 삭제 되지 않는 이상 일반저장소의 파일들은 계속 유지 된다.
      3. 케시저장소(임시저장소)
          - 앱이 실행되고 있을때는 유지가 된다.
          - 앱이 종료되었을때는 clear될 수 도 있다.
          - Android os는 기타APP들이 수행도중 저장소가 부족하면 종료된 APP의 캐시저장소를 clear한다.
  

Posted by 농부지기
,

[Android&Kotlin] - Camera App(카메라 앱)

1. Project생성정보

   - Package Name : com.farmerkyh.study.calcurator

   - Language : Kotlin

   - Minimum SDK : API 23: Android 6.0 (Marshmallow)

2. Android Version정보

   - Android Studio : 4.1.2 (2020.12.20)

   - Java : 1.8.0_242

   - AVD Test API : 29

   - Kotlin Plug in version : 1.4.32-release-Sdudio4.1-1

 

3. Layout / 실행화면

 

4. 디렉토리 및 파일 구조

 

5. 프로젝트 소스

    - 프로젝트 전체를 올릴 려고 했으나 10M 이상 초과 되어 파일들만 upload함   

   

CameraA.zip
0.01MB

6. 카메라 등 기타 특징

//개발한 앱에서 카메라 사진찍는 방법 2가지
//  첫번째. 개발한 앱에서 카메라 API를 이용해서 직접 사진을 찍고 사진을 얻어 오는 방법
//          정점, 사진찍기 속도가 빠르다.
//          단점, 폰 기종마다 카메라 성능등이 달라 어려움이 많다.
//  두번째. 카메라 APP을 이용하는 방법 (thumbnail방식)
//          a. 진행 과정
//             1. 개발한 앱 <-> 카메라 APP <-> 카메라
//          b. 진행 과정 상세
//             1. 개발한 앱에서 카메라 APP에 사진찍어달라 요청
//             2. 카메라 APP은 카메라를 통해 사진을 찍고, 사진을 받아온다.
//             3. 카메라 APP은 전달받은 사진을 다시 개발한 앱으로 전송한다.
//          c. 특징
//             1. 위와 진행과정 같은 Process방식은 INTENT를 이용해야 된다.
//             2. INTENT의 용량은 제한적이다. 그래서 thumbnail방식으로만(작은size) 주고 받는다.
//  세번째. 카메라 APP을 이용하는 방법 (Provider방식)
//          - 카메라 원본사이즈를 원한다면 Provider방식으로 구현해야 된다.
//          a. 진행 과정
//             1. 개발한 앱 -> 저장소에 임시로 파일 생성
//             2. 개발한 앱 <-> 카메라 APP <-> 카메라
//          b. 진행 과정 상세
//             1. 개발한 앱에서 저장소에 임시파일 하나를 생성 후 image_uri를 얻어온다.
//             2. 개발한 앱에서 카메라 APP에  사진찍어달라 요청
//                - 이때 image_uri를 전송하면서 사진을 이곳에 저장해달라고 요청한다.
//             3. 카메라 APP은 카메라를 통해 사진을 찍고, 사진을 받아온다.
//                - 받아온 사진을 image_uri에 저장 한다.
//             4. 카메라 APP은 image_uri에 저장후 개발한 앱으로 결과를 전송한다.
//             5. 개발한 앱은 image_uri에서 사진을 불러와 사용한다.
//  File Provider 란
//             1. 임시로 다른 APP에게 홈디렉토리(홈저장소)에 접근할 수 있도록 권한을 부여하는 역할을 담당
//  File Provider 특징
//             1. 저장소는 개발한 앱에서는 홈디렉토리와 같다. (앱에서 마음대로 접근가능)
//             2. 카메라 APP은 개발한 앱.홈디렉토리에 접근 할 수 없다.
//             3. 이때 카메라 APP에 임시권한부여를 해줘야 된다.
//             4. 임시권한부여를 위해서 File Provider를 제공한다.
//             5. File Provider를 이용해서 권한이 부여된 image_url을 만들어 카메라 APP으로 전송해준다.
//             6. 카메라 APP은 권한 부여받은 image_url에 접근할 수 있다.
// 저장소 종류
//    1. 일반저장소와 케시저장소 2가지 이다.
//    2. 일반저장소
//        - APP 삭제 되지 않는 이상 일반저장소의 파일들은 계속 유지 된다.
//    3. 케시저장소(임시저장소)
//        - 앱이 실행되고 있을때는 유지가 된다.
//        - 앱이 종료되었을때는 clear될 수 도 있다.
//        - Android os는 기타APP들이 수행도중 저장소가 부족하면 종료된 APP의 캐시저장소를 clear한다.
//
//기본적으로 카메라 미리보기는 사진이미지가 깨져 보인다.
//원본이미지를 보고 싶다면 (간략)
//   1. 카메라가 사진을 찍은 후 -> 카메라 APP에서 저장소에 저장 후 -> 앱에서  저장소에있는 원본이미지 조회
//원본이미지를 보고 싶다면 (상세) - Provider 이용
//   1. 개발한 앱에서 Provider를 이용해서  저장소_image_Uri생성
//   2. 개발한 앱에서 > 카메라 APP을 호출 시  저장소_image_Uri 전송
//   3. 카메라 APP이 카메라를 구동시킨다.
//   4. 카메라에서 사진을 찍은 후 사진을 카메라 APP으로 전송한다.
//   5. 카메라 APP은  저장소_image_Uri  를 이용해 사진을 저장한다.
//   6. 개발한 앱은 저장소_image_Uri 에서 사진을 불러드릴 수 있다.

7. 소스별 조요 내용 설명

   a. AndroidMenifest.xml

   

   b. provider_paths.xml

       

   c. provider_paths.xml

   

   d. MainActivity.xml

   

 

 

 

 

 

Posted by 농부지기
,

 

ORM

ORM이란 Object Relational Mapping 으로 데이터베이스와 객체 지향 프로그래밍 언어간의 호환되지 않는 데이터를 변환하는 프로그래밍 기법으로 DB 테이블과 매핑되는 객체를 만들고 그 객체에서 DB를 관리하는 것이다.

 

Room

Room은 SQLite에 대한 추상화 레이어를 제공하여 원활한 데이터베이스 액세스를 지원하는 동시에 SQLite를 완벽히 활용해준다. 안드로이드 아키텍처 컴포넌트 룸 라이브러리는 안드로이드 앱에서 SQLite 데이터베이스를 쉽고 편리하게 사용할 수 있도록 하는 기능이다. 이를 다시 정리하면 SQLite 위에 만든 구글의 새로운 ORM 이라고 할 수 있다. 룸 라이브러리는 엔티티(Entity), 데이터 접근 객체(Data Access Object:DAO),  룸 데이터베이스(Room Database),  총 세 개의 요소로  구성되어져 있다.

 

build.gradle

  - Room을 사용하기 위해서는 아래와 같이 gradle을 추가해야 된다.

 

 

사용예

- @Entity

 

- @Dao

 

- @Database

 

Posted by 농부지기
,

Kotlin-@Dao interface class - 예제

 

1. Dao 정의

   - TABLE에 CRUD 수행 작업을 DAO이다

   - SQL문장을 직접기술해서 처리할 수도 있고, @(annotation)을 이용해 처리 할 수도 있다.

   - 테이블인 Entiry Contacts를 쿼리로 접근하는 interface를 만들어주는 부분이다.

   - interface class로 정의해야 된다.

 

2. vararg - 일반함수인 경우

   - 가변인자

   - 인수의 수가 유동적인 경우에 사용한다.

   - vararg keyword는 @Dao뿐만 아니라 일반 함수에서도 사용가능하다.

     

3. vararg - DAO에서 사용한 경우

   - 일반함수 이건, DAO 함수이건 의미 및 사용방법은 동일 하다.

   - 데이터가 여러 개가 필요할 수 있기 때문에 가변인자 vararg를 사용한다

   - Dao사용예 (3건 insert)

      EmployeeDao.insertEmployeeVararg(Employee1, Employee2, Employee3)

     (아직 테스트 해보지 못했음)

 

1. SELECT Dao

   

 

2. INSERT Dao

   

OnConflictStrategy.ABORT 충돌이 발생할 경우 처리 중단
OnConflictStrategy.FAIL 충돌이 발생할 경우 실패처리
OnConflictStrategy.IGNORE 충돌이 발생할 경우 무시
OnConflictStrategy.REPLACE 충돌이 발생할 경우 덮어쓰기
OnConflictStrategy.ROLLBACK 충돌이 발생할 경우 이전으로 되돌리기

 

3. UPDATE Dao

   - Update를 사용하여 Entity set을 update 한다. 

   - return 값으로 변경된 rows 수가 반환된다.

   - update는 PK 기준으로 한다.

   

 

 

 

4. DELETE Dao

   

 

 

Posted by 농부지기
,

[Android&Kotlin] - Calcurator App(계산기앱)

 

1. Project생성정보

   - Package Name : com.farmerkyh.study.calcurator

   - Language : Kotlin

   - Minimum SDK : API 23: Android 6.0 (Marshmallow)

2. Android Version정보

   - Android Studio : 4.1.2 (2020.12.20)

   - Java : 1.8.0_242

   - AVD Test API : 29

   - Kotlin Plug in version : 1.4.32-release-Sdudio4.1-1

 

3. 실행화면

   a. 버튼      

      - 자판중 맨 왼쪽.아래 시계icon이 : 계산기록 보여주기 버튼

      - [계산기록삭제] : db에 저장된 계산기록을 삭제 한다.

   b. 개발SPEC

      - 4칙 연산만 수행한다.

      - ( ) 괄호 , . (소수점) 은 제외 한다.

      - 숫자 15자리 이하만 가능하다.

      - 계산기록은 App이 종료 되어도 db에 계속 남아 있다.

         (그래서 App을 다시 실행해도 [계산이력]버튼 (시계icon)을 클릭 하면 이력을 볼 수 있다.

      - [계산기록삭제]버튼을 누르는 경우에만 계산이력을 삭제 한다.

 

4. 디렉토리 구조

5. 프로젝트 소스

    - 프로젝트 전체를 올릴 려고 했으나 10M 이상 초과 되어 파일들만 upload함   

CalcuratorA-src.zip
0.01MB

6. 각 파일 간략 설명

    a. build.gradle

 

    a. activity_main.xml

         - 계산기 주요화면 Layout

    b. history_row.xml

       - 계산이력 한줄을 보여주는 Layout

    c. history_view_icon.xml

       - vector형 icon

       - 생성방식 : drawable > Right mouse > New > Vector Asset

    d. drawable>button_background.xml

       drawable>button_background_green.xml

       - 버튼 background용

 

    a. HistoryDao.kt

        - @Dao

        - Room에 연결된 dao

    b. History.kt

       - @Entity

       - data class

    c. AppDatabase.kt

       - @Database

       - Database class로 생성

    d. MainActivity.kt

 

7. 소스별 상세 설명

    a. build.gradle

       - viewbinding을 사용하기 위해 gradle  변경

       - room db를 사용하기 위해 gradle  변경

 

    a. activity_main.xml

         - 계산기 주요화면 Layout

 

    b. history_row.xml

       - 계산이력 한줄을 보여주는 Layout

       - 계산식과 계산식에 대한 결과를 보여주는 TextView 2개만 존재

       - activity_main.xml의 LinearLayout.addView( )를 이용해서 계산이력을 한줄 한줄 추가해준다. 

    c. history_view_icon.xml

       - vector형 icon

       - 생성방식 : drawable > Right mouse > New > Vector Asset

    d. drawable>button_background.xml

       drawable>button_background_green.xml

       - 버튼 background용

 

    a. HistoryDao.kt

        - @Dao

        - Room에 연결된 dao

    b. History.kt

       - @Entity

       - data class

    c. AppDatabase.kt

       - @Database

       - Database class로 생성

    d. MainActivity.kt

     

 

 

 

 

 

 

Posted by 농부지기
,