이미지나 구조체 같은 복잡한 데이터는 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://~~가 보인다.
'프로그래밍 > 안드로이드' 카테고리의 다른 글
안드로이드 - 동전 이미지를 드래그 해보자 (0) | 2015.12.05 |
---|---|
안드로이드 - 드래그 섀도우 이미지 변경하기 (0) | 2015.12.05 |
안드로이드 - startDrag메소드를 이용한 드래그 & 드롭 구현하기 (0) | 2015.12.03 |
안드로이드 - 클립보드를 통한 인텐트 복사 (0) | 2015.12.03 |
안드로이드 - Content Provider (콘텐트 프로바이더) (0) | 2015.11.29 |
안드로이드 - 시스템 클립보드를 활용한 데이터 복사 붙여넣기 (0) | 2015.11.07 |
안드로이드 - 압축 파일 사용하기 (0) | 2015.11.05 |
안드로이드 - 파일 탐색기 만들기 (2) | 2015.11.04 |