이미지나 구조체 같은 복잡한 데이터는 URI를 통해 간접적으로 복사한다.

 

붙여 넣는 쪽에서는 URI를 먼저 구하고 CP에게 데이터를 요청하여 실제 데이터를 구하는 방시긍ㄹ 쓴다.

 

URI로 데이터를 전달하려면 주는 쪽에서는 이 URI에 반응할 수 있는 CP를 반드시 제공해야 한다.

 

다음 예제를 실행하려면 콘텐트프로바이더 예제를 먼저 실행 시켜서 insert버튼을 눌러둔다..

 

또한 위의 콘텐트프로바이더 예제의 매니페스트 파일에서 다음과 같이 grantUriPermissions를 선언해야 한다.

안그러면 Permission 에러가 발생한다.( 여기 참고)

 

<!-- 위에서 추가한 퍼미션은 아래와 같이 사용된다 -->

<provider

android:name="EWProvider"

android:authorities="com.example.ch20_contentprovider"

android:exported="true"

android:readPermission="de.test.READ_DATABASE"

android:writePermission="de.test.WRITE_DATABASE"

android:grantUriPermissions="true"

     ></provider>

 

 

 

 

위와 같이 수정해야 할 것은 3군데이다.

 

다음은 AndroidManifest.xml 파일이다.

여기서 유의할 점은 ContentProvider를 사용하기위해서 퍼미션을 주는 것이다.

아래의 퍼미션은 ContentProvider를 구현한 앱의 매니페스트 파일에서 확인 할 수 있다.

 

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

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="com.example.ch27_copyuri"

android:versionCode="1"

android:versionName="1.0" >

 

<uses-sdk

android:minSdkVersion="19"

android:targetSdkVersion="19" />

 

<!-- ContentProvider 구현한 앱에서 정의한 퍼미션을 그대로 써줘야한다. -->

<uses-permission android:name="de.test.READ_DATABASE" />

    <uses-permission android:name="de.test.WRITE_DATABASE" />

 

 

<application

android:allowBackup="true"

android:icon="@drawable/ic_launcher"

android:label="@string/app_name"

android:theme="@style/AppTheme" >

<activity

android:name=".CopyUri"

android:label="@string/app_name" >

<intent-filter>

<action android:name="android.intent.action.MAIN" />

 

<category android:name="android.intent.category.LAUNCHER" />

</intent-filter>

</activity>

</application>

 

</manifest>

 

다음은 copyuri.xml 파일이다.

 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:orientation="vertical"

    android:layout_width="match_parent"

    android:layout_height="match_parent" >

<Button

    android:id="@+id/btncopy"

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:onClick="mOnClick"

    android:text="Copy" />

<TextView

    android:id="@+id/pastetext1"

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:text="paste here" />

<Button

    android:id="@+id/btnpasteuri"

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:onClick="mOnClick"

    android:text="Paste" />

<TextView

    android:id="@+id/pastetext2"

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:text="paste here" />

<Button

    android:id="@+id/btnpastetext"

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:onClick="mOnClick"

    android:text="Paste Text" />

</LinearLayout>

 

다음은 CopyUri.java 파일이다.

 

package com.example.ch27_copyuri;

 

import android.app.Activity;

import android.content.ClipData;

import android.content.ClipDescription;

import android.content.ClipboardManager;

import android.content.ContentResolver;

import android.content.Context;

import android.database.Cursor;

import android.net.Uri;

import android.os.Bundle;

import android.view.View;

import android.widget.TextView;

import android.widget.Toast;

 

public class CopyUri extends Activity {

 

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.copyuri);

    }

 

    public void mOnClick(View v){

        switch(v.getId()){

        case R.id.btncopy:

            copyUri();

            break;

        case R.id.btnpasteuri:

            pasteUri();

            break;

        case R.id.btnpastetext:

            pasteUriText();

            break;

        }

    }

    

    void copyUri(){

        ClipboardManager cm = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE);

        Uri copyuri = Uri.parse("content://com.example.ch20_contentprovider/word/boy");

        

        //클립데이터를 만듬

        ClipData clip = ClipData.newUri(getContentResolver(), "URI", copyuri);

        //클립데이터를 저장함.

        cm.setPrimaryClip(clip);

        Toast.makeText(this, "Uri Copied", 0).show();

        

    }

    

    void pasteUri(){

        ClipboardManager cm = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE);

        //클립데이터가 있는지 조사해봄

        if(cm.hasPrimaryClip() == false){

            Toast.makeText(this, "Clipboard Empty", 0).show();

            return;

        }

        

        //클립보드에 저장된 데이터에 대한 설명을 가져옴

        //URI 목록인지 확인함

        if(cm.getPrimaryClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_URILIST) == false){

            Toast.makeText(this, "Clip is not uri", 0).show();

            return;

        }

        

        //클립 데이터를 가져옴

        ClipData clip = cm.getPrimaryClip();

        //클립 데이터를 여기서 가져옴 0번째가 보통 저장된 곳임.

        ClipData.Item item = clip.getItemAt(0);

        

        Uri pasteuri = item.getUri();//Uri 가져옴

        //CP 사용하기 위한 콘텐트리졸버를 선언

        ContentResolver cr = getContentResolver();

        String uriMime = cr.getType(pasteuri);//Content Provider 이미 getType 정의해둠

        //아래 MIME 맞는지 비교 보안을 위한 것임

        if(uriMime == null || uriMime.equals("vnd.EnglishWord.andexam.cursor.dir/word")==false){

            Toast.makeText(this, "Clip is not EnglishWord", 0).show();

        }

        

        //CP에서 정의한 query문을 보면 이해가 것임

        Cursor pastecursor = cr.query(pasteuri, null, null, null, null);

        

        //쿼리에 올린 값을 실제로 가져오는 부분

        if(pastecursor != null){

            if(pastecursor.moveToFirst()){

                TextView pastetext = (TextView)findViewById(R.id.pastetext1);

                //데이터베이스에서 1번째 컬럼과 2번째 컬럼 값을 가져옴

                pastetext.setText(pastecursor.getString(0) + ":" + pastecursor.getString(1));

            }

            //커서를 닫음

            pastecursor.close();

        }else{//없으면

            Toast.makeText(this, "Data not found", 0).show();

        }

        

    }

    

    void pasteUriText(){

        //클립보드 매니저를 선언함.

        ClipboardManager cm = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE);

        //클립보드가 비었으면?

        if(cm.hasPrimaryClip() == false){

            Toast.makeText(this, "Clipboard Empty", 0).show();

            return;

        }

      

        //클립데이터를 만듬

        ClipData clip = cm.getPrimaryClip();

        ClipData.Item item = clip.getItemAt(0);//데이터를 가져옴

        TextView pastetext = (TextView)findViewById(R.id.pastetext2);

        //coerceToText 타입에 상관없이 강제로 문자열 형태로 바꿔읽는다.

        //그다음 텍스트뷰에 출력함.

        pastetext.setText(item.coerceToText(this).toString());

        

    }

 

}

 

 

실행화면

 

Copy 버튼을 누른뒤

 

붙여넣기를 하면 다음과 같이 된다.

 

다음화면에서 boy:머스마 는 Pate 버튼을 누른것이고 Paste Text버튼을 누르면 위의 content://~~가 보인다.

블로그 이미지

가카리

프로그래밍, 취업 및 직장생활, 주식 부동산 재테크 전문 블로그

댓글을 달아 주세요