[현재 접속자 현황]
안드로이드 관련 팁 게시판입니다.
글수 27
상속(extends)의 예
1) 화면 클래스를 만드려면 Activity클래스를 extends하고 Activity의 주요 함수를 구현(onCreate)
2) 백그라운드로 작동하는 클래스를 만드려면 Service 클래스를 extends하고 Service의 주요함수 구현(onStart)
3) 데이터처리하는 클래스를 만드려면 ContentProvider를 extends하고 주요 함수 구현
4) 시스템 이벤트를 감지하는 클래스를 만드려면 BroadCastReceiver를 extends하고 onReceive함수 구현
인터페이스(implements)의 예
1) 클릭이벤트를 처리하려면 OnClickListner인터페이스를 implements하고 onClick 구현
2) GPS의 위치변화를 감지하려면 LocationListener인터페이스를 implements하고 onLocationChanged를 구현
[컴파일 & 빌드 과정]
1) *.java --> *.class (컴파일) --> classes.dex(Dalvik 가상머신 포맷)
2) 각종 리소스(이미지, XML 등 res폴더 파일) --> resources.ap_ (아카이브)
3) 1과 2과 합쳐져서 ---> *.apk가 생성
4) *.apk는 마켓 또는 직접 설치(adb install *.apk)
[변수]
1) 로컬변수 : 함수 블록 안에 정의된 변수
--> 타입 변수명 = 초기값; (';'는 문장 종료 기호)
예) Button btn01 = null;
예) int num01 = 0;
2) 멤버변수(인스턴스 변수): 함수 블록 밖에 정의된 변수(클래스 영역)
--> 접근제한자 타입 변수명 = 초기값; (초기값은 안줄수도 있음)
예) private Button btn01 = null;
예) private int num01 = 0;
# 안드로이드 애플리케이션 타입 4가지
1) <activity> </activity> 액티비티 (화면)
2) <service> </service> 서비스(백그라운드 서비스)
3) <receiver> </receiver> 브로드캐스트 리시버(이벤트 수신)
4) <provider> </provider> 컨텐트 프로바이더 (데이터 처리)
# 실습 2일차
[MyImageView 폰 배경화면 설정하기]
1. 퍼미션 추가
<uses-permission android:name="android.permission.SET_WALLPAPER"/>
2. imgBtn클릭 리스너 설정 (setOnClickListener이용)
3. imgBtn의 onClcik에 다음 내용 추가
WallpaperManager wallpaperManager = WallpaperManager.getInstance(MyImageView.this);
iv.setDrawingCacheEnabled(true);
try {
wallpaperManager.setBitmap(iv.getDrawingCache());
} catch (IOException e) {
e.printStackTrace();
}
[EditText 실습]
1. my_edit_text.xml 수정
1) TextView에 다음의 3개 속성 추가
android:textColor="#FFFF00"
android:textStyle="bold"
android:textSize="20px"
2) EditText에 다음의 2개 속성 추가
android:hint="글자를 입력하면 글자수를 체크합니다"
android:singleLine="true"
2. MyEditText.java를 수정
1) OK버튼을 누르면 입력한 글자로 검색을 실행하게 한다.
: findViewById, setOnClickListener클릭리스너 설정해서 onClick에 들어갈 내용
Intent intent = new Intent(Intent.ACTION_SEARCH);
intent.putExtra(SearchManager.QUERY, ed.getText().toString());
startActivity(intent);
2) CANCEL 버튼을 누르면 에디트 텍스트에 입력된 글자를 지운다.
: findViewById, setOnClickListener 클릭리스너 설정해서 onClick에 들어갈 내용
ed.setText("");
[MyScrollView 수정]
1. Button 추가하기 (for 문 안에)
Button btn = new Button(this);
btn.setText("Button " + i);
layout.addView(btn);
2. Button을 wrap_content로 추가하기
Button btn = new Button(this);
btn.setText("Button " + i);
LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
layout.addView(btn, p);
[MyAppList] : 설치된 App 정보 추출
1. MyAppList.java 라는 ListActivity 작성
//멤버변수 선언
private ArrayList<String> items = new ArrayList<String>();
private List<ApplicationInfo> appList;
2. onCreate함수 오버라이딩
// 설치된 앱리스트 객체 추출 (PackageManager)
appList = getPackageManager().getInstalledApplications(0);
// 어댑터에 사용할 배열(ApplicationInfo) 초기화 (Iterator패턴 사용)
Iterator<ApplicationInfo> itr = appList.iterator();
while (itr.hasNext()) {
ApplicationInfo info = itr.next();
items.add(info.packageName);
}
3. ListView 어댑터 설정
1) ArrayAdapter 생성
ArrayAdapter<String> adapter
= new ArrayAdapter<String> (this, android.R.layout.simple_list_item_1, items);
2) ArrayAdapter 설정
setListAdapter(adapter);
[MyAppList] - 단계2
ArrayAdapter에서 레이아웃을 android.R.layout.simple_list_item_1 대신에 커스텀 레이아웃을 사용하도록 한다.
1. ListView에서 사용할 행에 대한 레이아웃 생성: my_app_row.xml
1) LinearLayout에 ImageView와 TextView를 추가
2) 각각 id는 img, text1
3) ImageView의 src속성은 @drawable/icon으로 설정
2. ArrayAdapter를 다음과 같이 변경
ArrayAdapter<String> adapter2
= new ArrayAdapter<String> (this, R.layout.my_app_row, R.id.text1, items);
setListAdapter(adapter2);
[MyAppList] - 단계3
// 아이템을 선택하면 삭제 화면으로 이동(삭제 요청 인텐트 발생)
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Intent i = new Intent(Intent.ACTION_DELETE);
String pname = (String) l.getItemAtPosition(position);
i.setData(Uri.parse("package:" + pname)); // 인텐트에 패키지 정보 Uri 추가
startActivity(i);
}
[과제] MyMp3List
1. MyMp3List 리스트 액티비티 생성
: public class MyMp3List extends ListActivity
2. MyMp3List의 onCreate 에서 음악 데이터 추출
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
3. 커서어댑터 연결
String[] col_arr = {MediaStore.Audio.Media.TITLE}; // 가져올 컬럼명
int[] view_id_arr = {android.R.id.text1}; // 바인딩할 텍스트 아이디
SimpleCursorAdapter adapter
= new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, cursor, col_arr, view_id_arr);
setListAdapter(adapter);
4. MP3 리스트의 아이템을 클릭하면 다음과 같이 인텐트를 발생 (onListItemClick)
Uri uri = ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, "audio/mp3");
startActivity(intent);
[MyIntentCaller 수정]
1. 버튼을 클릭하면 SMS도 전송
1) 퍼미션 추가
<uses-permission android:name="android.permission.SEND_SMS"/>
2) 문자 전송
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage("010xxxxxxx", null, "테스트:" + ed.getText().toString(), null, null);
* 패키지경로 주의!!: import android.telephony.SmsManager;
[SMS수신]
1. 퍼미션 추가: <uses-permission android:name="android.permission.RECEIVE_SMS" />
2. MySMSReceiver 클래스 작성: MySMSReceiver extends BroadcastReceiver
3. 매니페스트에 MySMSReceiver 추가
<receiver android:name="MySMSReceiver ">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
4. MySMSReceiver onReceive(Context context, Intent intent) 오버라이딩
if(intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")){
Bundle bundle = intent.getExtras();
if(bundle != null) {
Toast.makeText(context, "문자 왔음", 1000).show();
}
}
5. 문자 내용 출력 (Toast 위에 추가)
Object[] pdusObj = (Object[]) bundle.get("pdus");
StringBuilder sb = new StringBuilder();
SmsMessage[] messages = new SmsMessage[pdusObj.length];
for (int i = 0; i< pdusObj.length; i++) {
messages[i] = SmsMessage.createFromPdu ((byte[])pdusObj[i]);
sb.append("보낸사람:");
sb.append(messages[i].getDisplayOriginatingAddress());
sb.append("메시지내용:");
sb.append(messages[i].getDisplayMessageBody());
}
Toast.makeText(context, "문자내용:" + sb.toString(), 2000).show();
[환경설정 항목 2개 추가]
1. my_pref.xml에 다음 2개 항목을 추가
<CheckBoxPreference android:key="my_pref_ori" android:title="항상 가로화면으로 봅니다." />
<EditTextPreference android:key="my_pref_title" android:title="액티비티의 제목을 설정합니다." />
2. MyXMLPrefView.java (onCreate 함수 내에)
1) 키값이 my_pref_title, my_pref_ori인 항목값을 읽어오도록 로직 추가
String activity_title = sp.getString("my_pref_title", "액티비티 제목 없음");
boolean activity_ori = sp.getBoolean("my_pref_ori", false);
2) 액티비티에 적용
setTitle(activity_title); // 액티비티 타이틀 변경
if(activity_ori) setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
// 화면을 항상 가로로 보기
[SD카드로 입출력] MyReadBin.java
1. 권한 추가 (AndroidManifest.xml)
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
2. onResume함수 수정
1) openFileInput부분은 주석처리
// InputStream in = openFileInput(BIN_FILE_NAME);
2) 대신에 다음 2라인 추가
File f = new File("/sdcard/okgosu.txt");
InputStream in = new FileInputStream(f);
3. onPause함수 수정
1) openFileOutput 부분은 주석 처리
// OutputStreamWriter out = new OutputStreamWriter(openFileOutput(BIN_FILE_NAME, 0));
2) 대신에 다음의 4라인 추가
File f = new File("/sdcard/okgosu.txt");
if(!f.exists()) f.createNewFile();
OutputStream os = new FileOutputStream(f);
OutputStreamWriter out = new OutputStreamWriter(os);
#################### 실습 4일차 #####################
[GPS컨트롤]
1. 레이아웃 : my_gps.xml
- LinearLayout에 CheckBox 추가 (id는 cb_gps)
2. 액티비티: MyGPS.java onCreate에서 GPS의 설정을 읽어와 체크박스에 on/off로 표시함
1) onCreate 오버라이딩
setContentView(R.layout.my_gps);
CheckBox cb_gps = (CheckBox)findViewById(R.id.cb_gps);
2) GPS 설정상태 읽어오기
String gs = android.provider.Settings.Secure.getString(getContentResolver(),
android.provider.Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
if (gs.indexOf("gps", 0) < 0) {
cb_gps.setChecked(false);
cb_gps.setText("GPS꺼짐");
} else {
cb_gps.setChecked(true);
cb_gps.setText("GPS켜짐");
}
3. cb_gps 체크 상태가 변경 되면 GPS 설정화면으로 이동
cb_gps.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
Toast.makeText(MyGPS.this, "GPS설정변경", 1000).show();
}
});
4. onCheckedChanged에 GPS 다이얼로그 띄우기
new AlertDialog.Builder(MyGPS.this)
.setTitle("GPS 설정")
.setMessage("GPS 설정변경")
.setPositiveButton("GPS 설정변경", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent (android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
}).show();
------------------------------------------------
상품조회 테이블 (prod)
-----------------------------------------
아이디 상품코드 상품명
_id prod_code prod_name
1 snk01 새우깡
2 snk02 맛동산
3 snk03 양파링....
[MyDBExam 수정, 삭제 처리]
1. 멤버변수 추가
String prod_id = null;
2. onListItemClick 오버라이딩하여 선택한 id값을 prod_id에 저장 및 에디트텍스트에 표시
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
prod_id = String.valueOf(id);
Cursor c = (Cursor) l.getItemAtPosition(position);
c.moveToPosition(position);
ed_prod_code.setText(c.getString(1));
ed_prod_name.setText(c.getString(2));
}
[컨텐트프로바이더]
1) CP호출 URI와 MIME
content://okgosu.net.provider.MyProd/myprods --> "vnd.android.cursor.dir/vnd.okgosu.net.MyProd"
content://okgosu.net.provider.MyProd/myprods/0 --> "vnd.android.cursor.item/vnd.okgosu.net.MyProd"
[컨텐트 프로바이더 활용] MyCPDemo의 로직 설정
1. btn1을 클릭하면 DB데이터 건수 조회
Cursor c = getContentResolver().query(MyProdDBCons.CONTENT_URI, null, null, null, null);
Toast.makeText(MyCPDemo.this, "건수:" + c.getCount(), 1000).show();
2. btn2를 클릭하면DB쿼리결과를ListView에보여줌
String columns[] = {MyProdDBCons.PROD_ID, MyProdDBCons.PROD_CODE}; // select할 컬럼 목록
Cursor c = getContentResolver().query(MyProdDBCons.CONTENT_URI, columns, null, null, null); // 커서 쿼리
String[] cols = {MyProdDBCons.PROD_ID, MyProdDBCons.PROD_CODE}; // 가져올 컬럼의 이름값 배열
int[] view_ids = {android.R.id.text1, android.R.id.text2}; // 컬럼을 매치시킬 View의 ID 배열
SimpleCursorAdapter adapter = new SimpleCursorAdapter(MyCPDemo.this, android.R.layout.simple_list_item_2, c, cols,
view_ids);
setListAdapter(adapter);
3. btn3을 클릭하면 DB에 데이터 1건 입력
ContentValues values = new ContentValues();
values.put(MyProdDBCons.PROD_CODE, ed_prod_code.getText().toString());
values.put(MyProdDBCons.PROD_NAME, ed_prod_name.getText().toString());
getContentResolver().insert(MyProdDBCons.CONTENT_URI, values);
Toast.makeText(MyCPDemo.this, "입력되었습니다", 1000).show();
4. btn4를 클릭하면 DB에 데이터 1건 수정
ContentValues values = new ContentValues();
values.put(MyProdDBCons.PROD_CODE, ed_prod_code.getText().toString());
values.put(MyProdDBCons.PROD_NAME, ed_prod_name.getText().toString());
String where = MyProdDBCons.PROD_ID+ "= ? ";
String[] selectionArgs = {prod_id};
getContentResolver().update(MyProdDBCons.CONTENT_URI, values, where, selectionArgs);
Toast.makeText(MyCPDemo.this, "수정되었습니다", 1000).show();
5. btn5을 클릭하면 DB에 데이터 1건 삭제
String where = MyProdDBCons.PROD_ID+ "= ? ";
String[] selectionArgs = {prod_id};
getContentResolver().delete(MyProdDBCons.CONTENT_URI, where, selectionArgs);
Toast.makeText(MyCPDemo.this, "삭제되었습니다", 1000).show();
[MyCPDemo 수정] 커스텀 레이아웃 생성
: 현재 PROD_ID, PROD_CODE만 보이는데,
PROD_ID, PROD_CODE, PROD_NAME도 같이 보이도록 커스텀 레이아웃을 설정한다.
1. ListView에서 사용할 행에 대한 레이아웃 생성: my_prod_row.xml
1) LinearLayout에 ImageView 1개, TextView 3개를 추가
2) 각각 id는 img, text1, text2, text3
3) ImageView의 src속성은 @drawable/icon으로 설정
4) text1 은 android:textColor="#FF0000" android:layout_width="20dp" android:layout_height="wrap_content"
5) text2 은 android:textColor="#FFFF00" android:layout_width="50dp" android:layout_height="wrap_content"
6) text3 은 android:layout_weight="1"
2. MyCPDemo의 조회 부분을 다음과 같이 변경
String columns[] = {MyProdDBCons.PROD_ID, MyProdDBCons.PROD_CODE, MyProdDBCons.PROD_NAME};
Cursor c = getContentResolver().query(MyProdDBCons.CONTENT_URI, columns, null, null, null);
String[] cols = {MyProdDBCons.PROD_ID, MyProdDBCons.PROD_CODE, MyProdDBCons.PROD_NAME};
int[] view_ids = {R.id.text1, R.id.text2, R.id.text3};
SimpleCursorAdapter adapter = new SimpleCursorAdapter(MyCPDemo.this, R.layout.my_prod_row, c, cols, view_ids);
setListAdapter(adapter);
class MyCursorAdapter extends SimpleCursorAdapter {
public MyCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
super(context, layout, c, from, to);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = getLayoutInflater().inflate(R.layout.my_prod_row, null);
ImageView img = (ImageView)row.findViewById(R.id.img);
TextView text1 = (TextView)row.findViewById(R.id.text1);
TextView text2 = (TextView)row.findViewById(R.id.text2);
TextView text3 = (TextView)row.findViewById(R.id.text3);
Cursor c = getCursor();
c.moveToPosition(position);
text1.setText(c.getString(0));
text2.setText(c.getString(1));
text3.setText(c.getString(2));
img.setImageResource(getResources().getIdentifier( "android.edu:drawable/" + c.getString(1),
null, null));
return row;
}
}
[사진정보 쿼리]: MyAlbum ListActivity
1. onCreate 오버라이딩
Cursor c = getContentResolver().query(Images.Media.EXTERNAL_CONTENT_URI, null, null, null, null);
// 가져올 컬럼의 이름값 배열
String[] cols = {Images.Media.TITLE};
// 컬럼을 매치시킬 View의 ID 배열
int[] view_ids = {android.R.id.text1};
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
android.R.layout.simple_list_item_1, c, cols, view_ids);
// 어댑터 설정
setListAdapter(adapter);
2. 리스트 클릭시 이미지 보이도록 onListItemClick 오버라이딩
Uri uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
############### 실습 5일차 ####################
[RSS리더] HttpClient 사용
0. 웹주소 확인 : http://okgosu.net/zbxe/deveng/rss
1. 액티비티 작성 MyRSS - ListActivity
// 멤버변수 선언
ArrayList<String> items = new ArrayList<String>();
2. onCreate 오버라이딩
HttpClient hc = new DefaultHttpClient();
HttpGet req = new HttpGet("http://okgosu.net/zbxe/deveng/rss");
try {
} catch (Exception e) {
e.printStackTrace();
}
3. try { } 블록 안에 다음 로직 추가 (DOM파싱이므로 dom.Element를 import)
ResponseHandler<String> res = new BasicResponseHandler();
String resStr = hc.execute(req, res); // XML결과값
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(new InputSource( new StringReader(resStr)));
NodeList nl = doc.getElementsByTagName("title");
items.clear();
for(int i=0; i<nl.getLength(); i++){
Element el = (Element)nl.item(i);
String data = (String)el.getFirstChild().getNodeValue(); // Node값
items.add(data);
}
setListAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_1, items));
[MyHandlerService의 onStart로직 수정]
: okgosu.net 블로그 새글 확인 로직
1. HTTP호출
HttpClient hc = new DefaultHttpClient();
HttpGet req = new HttpGet("http://okgosu.net/zbxe/deveng/rss");
try {
} catch (Exception e) {
e.printStackTrace();
}
2. try { } 내용
ResponseHandler<String> resHandler = new BasicResponseHandler();
String resStr = hc.execute(req, resHandler);// RSS XML 리턴
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(new InputSource( new StringReader(resStr)));
NodeList list = doc.getElementsByTagName("item");
for (int i = 0; i < list.getLength(); i++) {
Element el = (Element) list.item(i);
String data = el.getElementsByTagName("pubDate").item(0).getFirstChild().getNodeValue();
Calendar checkDate = Calendar.getInstance();
checkDate.set(2011, 2, 24);//2011.3.24
Calendar itemDate = Calendar.getInstance();
itemDate.setTime(new Date(Date.parse(data)));
if(itemDate.after(checkDate)) {
// 2011.3.24 이후의 새글 등록됨
res = true;
}






okgosu
최근 답변 댓글