Deperecated/Android_강의

안드로이드 - Content Provider

누알라리 2020. 2. 20. 03:21
1. Content Provider란?

- 안드로이드 4대 구성 요소 중 하나로 애플리케이션이 저장한 데이터를 다른 애플리케이션이 사용할 수 있도록 제공하는 개념이다.

- 안드로이드OS가 B의 요청을 받고 A가 DB에 저장해놓은 데이터들을 제공하라고 A의 Content Provider를 동작시키고 안드로이드OS가 그 데이터를 받아 최종적으로 B가 받아가는 형식이다.

 

2. 예제 : APP2가 APP1의 데이터의 데이터를 받아와 SELECT/DELETE/UPDATE/DELETE하는 예제.

1. APP1에 ContentProvider()을 상속한 MyContentProvider 클래스를 생성한다.

2. SELECT(query), INSERT, DELETE, UPDATE 함수를 구현한다.

 

lass MyContentProvider : ContentProvider() {

    override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int {
        // Implement this to handle requests to delete one or more rows.
        var helper = DBHelper(context)
        var db = helper.writableDatabase

        return db.delete("TestTable", selection, selectionArgs)
    }

    override fun getType(uri: Uri): String? {
        // TODO: Implement this to handle requests for the MIME type of the data
        // at the given URI.
        throw UnsupportedOperationException("Not yet implemented")
    }

    // 2. INSERT
    // ContentValues에 저장할 데이터와 칼럼들을 세팅한다음에 넘겨주면된다.
    override fun insert(uri: Uri, values: ContentValues?): Uri? {
        // TODO: Implement this to handle requests to insert a new row.
        var helper = DBHelper(context)
        var db = helper.writableDatabase

        db.insert("TestTable", null, values)

        return uri
    }

    override fun onCreate(): Boolean {
        // TODO: Implement this to initialize your content provider on startup.
        return false
    }

    // 1. SELECT
    // projection : 가져올 Column의 이름
    // selection : 조건절
    // selectionArgs : 조건절에 들어갈 배열
    // sortOrder : 정렬
    // 반환타입 : Cursor(DB에 있는 데이터를 가져와서 쓸 수 있는 형식)
    override fun query(uri: Uri, projection: Array<String>?, selection: String?,
                       selectionArgs: Array<String>?, sortOrder: String?): Cursor? {
        // TODO: Implement this to handle query requests from clients.
        var helper = DBHelper(context)
        var db = helper.writableDatabase

        return db.query("TestTable", projection, selection, selectionArgs, null, null, sortOrder)

    }

    override fun update(uri: Uri, values: ContentValues?, selection: String?,
                        selectionArgs: Array<String>?): Int {
        // TODO: Implement this to handle requests to update one or more rows.

        var helper =  DBHelper(context)
        var db = helper.writableDatabase

        return db.update("TestTable", values, selection, selectionArgs)
    }
}

 

3. APP2의 MainActivity에서 APP1의 CotentProvider의 주소를 입력해서 데이터를 받아온다.

// APP1의 ContentProvider에 데이터를 요청할 APP2.
// 깃허브 관리하기 귀찮아서 APP2를 임의로 여기다가 넣어놓는다.



class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        // 1. SELECT
        // 2. ContentProvider를 통해 Hyunndy_01에서 데이터를 가져온다.
        button.setOnClickListener { view ->
            // 3. ContentProvider의 이름가져오기
            var uri = Uri.parse("content://com.example.dbprovider")
            // 4. ConrentResolver를 통해 쿼리 가져오기.
            var c: Cursor? = contentResolver.query(uri, null, null, null, null)
            textView.text = ""
            // 5.
            // 현재에서 다음 row(열)로 계속 넘어간다. 더이상 접근할게 없으면 false.
            // 각 column(행)의 데이터를 가져오려면 column의 이름을 던져서 해당 컬럼이 몇번째 인덱스인지 받아오고, 그 인덱스가 가진 데이터를 가져와야한다.
            while(c?.moveToNext()!!)
            {
                var idx_pos = c.getColumnIndex("idx")
                var textData_pos = c.getColumnIndex("textData")
                var intData_pos = c.getColumnIndex("intData")
                var floatData_pos = c.getColumnIndex("floatData")
                var DateData_pos = c.getColumnIndex("dataData")
                var idx = c.getInt(idx_pos)
                var textData = c.getString(textData_pos)
                var intData = c.getInt(intData_pos)
                var floatData = c.getDouble(floatData_pos)
                var dateData = c.getString(DateData_pos)
                textView.append("idx : ${idx}\n")
                textView.append("textData : ${textData}\n")
                textView.append("intData : ${intData}\n")
                textView.append("floatData : ${floatData}\n")
                textView.append("dateData : ${dateData}\n")
            }
        }
        // 2. INSERT
        button2.setOnClickListener { view ->
            var sdf = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
            var date = sdf.format(Date())
            // (textData, intData, floatData, dataData) values (?, ?, ?, ?) -> 1:1 배치를 함수로 표현.
            var cv1 = ContentValues()
            cv1.put("textData", "문자열33")
            cv1.put("intData", 100)
            cv1.put("floatData", 11.11)
            cv1.put("dataData", date)
            var cv2 = ContentValues()
            cv2.put("textData", "문자열44")
            cv2.put("intData", 200)
            cv2.put("floatData", 22.22)
            cv2.put("dataData", date)
            var uri = Uri.parse("content://com.example.dbprovider")
            contentResolver.insert(uri, cv1)
            contentResolver.insert(uri, cv2)
        }
        // 3. UPDATE
        button4.setOnClickListener { view ->
            var cv = ContentValues()
            cv.put("textData", "문자열100")
            var where = "idx=?"
            var args = arrayOf("3")
            var uri = Uri.parse("content://com.example.dbprovider")
            // uri 주소, 업데이트할 데이터, 조건절, 조건절에 들어갈 배열
            contentResolver.update(uri, cv, where, args)
            textView.text = "수정 완료"
        }
        // 4. DELETE
        button3.setOnClickListener { view ->
            var where = "idx=?"
            var args = arrayOf("3")
            var uri = Uri.parse("content://com.example.dbprovider")
            contentResolver.delete(uri, where, args)
            textView.text = "삭제완료"
        }
    }
}