Android
오픈 소스와 오픈 API와 관계된 사항은 자유로이 추가, 수정 하셔도 됩니다. 모두의 동참을 바랍니다.
오픈소스 비즈니스 컨설팅에 대한 문의는
으로 메일 주세요.
오픈소스 비즈니스 컨설팅
오픈소스 모바일 플랫폼인 안드로이드(Android)를 정리 한다.
- 홈페이지 : http://www.android.com/
- Android Developers : http://developer.android.com/
- Android Source : http://source.android.com/, http://android.git.kernel.org/
- Linux 커널 : GNU GPL
- 안드로이드 플랫폼 : Apache 2.0
- 플랫폼 : Android 모바일 Platform
- 안드로이드 마켓플레이스
- OHA(Open Handset Alliance)
목차 |
안드로이드 개요
안드로이드(Android) : 휴대전화와 모바일 디바이스를 위한 운영체제, 미들웨어 그리고 핵심 애플리케이션을 포함한 소프트웨어 스택
안드로이드 역사
- 2005년 7월 : 안드로이드 사를 구글에서 인수
- 2007년 11월 5일
- 하드웨어, 소프트웨어, 통신 회사가 모여 만든 OHA(Open Handset Alliance) 결성
- OHA에서 모바일 기기용 공개 표준 개발
- 2007년 11월 12일 : 휴대전화용 안드로이드 플랫폼 발표 (무료로 공개)
- 안드로이드 SDK, 동작 샘플, 안드로이드 시스템 구조, 안드로이드 내장 SW 개발 구조 공개
- 2008년 9월 : Android SDK 1.0 발표
- 2008년 10월 21일 : 안드로이드를 오픈소스(아파치 라이선스)로 공개
- 2008년 10월 22일 : 미국 T-Mobile에서 최초의 Android 폰인 G1 출시
- 2008년 10월 22일 : Android Market 정식 오픈
- 2009년 2월 19일 부터 유료 애플리케이션도 제공
OHA - Open Handset Alliance
- 휴대전화 제조, 서비스, 칩 제조 등 전세계 65개 업체가 가입 (2009년말)
- 휴대폰 제조 업체 : 삼성전자, LG전자, 모토롤라, HTC
- 이동통신 업체 : 스프린트, T-모바일, NTT 도코모, KDDI
- 칩 제조 업체 : 퀄컴, 브로드컴, 인텔, 텍사스인스트루먼트
안드로이드 마켓 플레이스
- 2008년 10월 22일 : Android Market 정식 오픈
- 2009년 2월 19일 부터 유료 애플리케이션도 제공
- SDK 다운 등은 무상
- 판매 수익은 CP/솔루션업체와 이동통신사가 7:3으로 분배
안드로이드의 타겟 시장
- 스마트폰
- 넷북
- 인터넷 전화기
- 휴대용 기기 (이북 등)
스마트폰의 장치 및 기능
스마트폰 장치
- 스마트폰 장치 입출력
- 버튼
- 화면 (Display)
- 그래픽 : OpenGL ES 1.0
- Touch Screen
- Multi Touch
- 제스쳐
- 오디오 (재생, 녹음), 비디오 (재생, 녹화)
- FM 라디오
- 카메라 : 사진, 동영상
- USB, MicroSD
- 광학 조이스틱 (Optical Joystick)
- 트랙볼
- 전화(Telephony)
- 음성 통신 (GSM)
- 메시징 : SMS, MMS
- 인터넷/네트워크
- 3G, GRPS, EDGE
- Wi-Fi
- Bluetooth
- 테더링(Tethering) : USB, Bluetooth, Wi-Fi
- 스마트폰용 센서
| 자이로 센서 |
|
| 가속도 센서 |
|
| 기울기 센서 |
|
| GPS |
|
| 나침반 센서 |
|
| 근접 센서 |
|
| 조도 센서 |
|
| 컴파스 |
Smartphone UX
- GPS (Global Positioning System)
- Augmented Reality
- Touch Screen Technology
- 리모콘 : TV 리모콘, 자동차 시동 장치
- Network
- VOIP
- 모바일 인터넷
- 스마트폰 <-> 노트북
- M2M
- OCR (문자 인식)
- 바코드
- 음악 검색
- 형상 검색
- 음성 검색
- 참고 문헌
Push Notification Service
Push <-> Polling
- Push framework
- MIDP 2.0, Push Registry/WMA
- OMA WAP Push
- RIM: Hosted Data Push Service
- Android's C2DM
- 번역: 안드로이드 Android Cloud to Device Messaging(C2DM), 2010.5
- Froyo(SDK 2.2)부터 Push Service 지원, google에 서버의 Register ID를 등록을 해야 함
- 푸쉬 처리를 해주는 Agent가 대표 서버에 붙어있는 방식
- C2DM(Cloud to Device Messaging)
- Google Push (Android)
- MQTT Push (Android et.al.)
- 동기화 : Exchange ActiveSync, IMAP4, POP3 지원
- iPhone's APNS
- Apple Push Notifications
- 아이폰의 푸시 서비스 구조, 2010.2
- SMS를 활용한 Push Service
- 장점: 밧데리의 소모가 없다.
- WAP 1.2 부터 Push 기능이 나오기 시작했는데 이때는 MMS(SMS) 방식에 헤더에 identifier 를 넣어서 구분 했다. 즉 문자 전송방식에 일정한 구분자를 넣고, 내용이나 링크를 넣어서 보내는 방식으로 이러한 방식은 통신사와 제휴하지 않으면 구현이 쉽지 않다.
- 참고 문헌
Android 개발 환경
사전 준비 사항
Android 개발 환경 설정
- Android Plugin 설치
- 이클립스에서 "Help -> Install New Software..." 메뉴를 선택 한다.
- "Add" 버튼을 선택 한 후 다음과 같이 등록 한다.
- Name : Android
- Location : http://dl-ssl.google.com/android/eclipse/
- "Developer Tools"의 모든 Plugin을 설치 한다.
- 정상적으로 설치가 되면 "Window -> Android SDK and AVD Manager" 메뉴가 보인다.
- Android SDK 설치
- http://developer.android.com/ 사이트에서 "SDK" 탭을 선택 한 후 "android-sdk_r3-windows.zip" 파일을 다운로드 한다.
- 다운로드 받은 파일의 압축을 풀어 c:/appl/androidSDK/ 폴더에 저장 한다.
- "Window -> Preferences -> Android" 메뉴를 선택 한다.
- "SDK Location"에 "c:/appl/androidSDK/"를 지정 한다.
- "Window -> Android SDK and AVD Manager -> Available Packages" 메뉴를 선택 한다.
- 모든 설치 가능한 Packages를 선택 하고 하단의 "Install Selected" 버튼을 선택하여 설치 한다. (끈기를 가지고 설치가 완료될 때까지 기다리자.)
- 오류가 나서 일부만 설치되면 한두번 더 설치를 시도해 보자.
- Android용 Virtual Device 생성
- "Window -> Android SDK and AVD Manager -> Virtual Devices" 메뉴에서 "New..." 버튼을 선택 한다.
- 다음과 같이 설정한 후 "Create AVD" 버튼을 선택 한다.
- Name : Android_Device_2.1
- Target : Android 2.1 - API Level 7
- SD Card
- Size : 1024 MiB
- "Window -> Android SDK and AVD Manager -> Virtual Devices" 메뉴에서 실행할 AVD를 선택 한 후 "Start" 버튼을 선택 하면 Virtual Device를 실행할 수 있다. (OS가 기동하는 동안 끈기 있게 기다리자.)
- 주의: OS에서 한글 계정으로 로그인한 경우 제대로 동작하지 않을 수 있다. 사실 한글 계정은 여러곳에서 문제가 된다.
- Eclipse에서 안드로이드 컴파일 환경을 변경하는 방법
- default.properties에서 "target=Google Inc.:Google APIs:8"을 변경 한다.
- 예) 안드로이드 2.1 : target=Google Inc.:Google APIs:7
- 예) 안드로이드 2.2 : target=Google Inc.:Google APIs:8
- 참고 문헌
안드로이드 애뮬레이터
- 애뮬레이트 생성 및 실행
android create avd --name 이름 --target 버전(예, 4) -sdcard 256M emulator @이름
- 애뮬레이터 키
- 홈 : Home
- 메뉴 : F2, Page_Up
- 스타 : Shift_F2, Page_Down
- 백 : Esc
- 전화 걸기/끊기 : F3 / F4
- 검색 : F5
- 전원 : F7
- 네트워크 접속 토클 : F8
- 볼륨 업/다운 : +, Ctrl_F5 / -, Ctrl_F6
- 카메라 : Ctrl_+, 5, Ctrl_F3
- Portrait, Landscape 전환 : 7, 9, Ctrl_F11, Ctrl_F12
- ~.apk
- /data/app/ 에 설치됨
- Tools
- set path=$ANDROID_SDK/tools/;$ANDROID_SDK/platforms/android-7/tools/
- $ANDROID_SDK/tools/
acp.exe adb.exe dmtracedump.exe emulator.exe etc1tool.exe fastboot.exe hprof-conv.exe mksdcard.exe sqlite3.exe zipalign.exe
- $ANDROID_SDK/platforms/android-7/tools/
aapt.exe aidl.exe dexdump.exe
- AAPT (ANDROID ASSET PACKAGING TOOL)
- ADB (ANDROID DEBUG BRIDGE)
- adb devices
- adb [-d 1] shell
- adb shell install ~.apk
- adb shell uninstall ~.apk
- 애뮬레이터 콘솔
- telnet localhost 5554
help|h|? print a list of commands event simulate hardware events geo Geo-location commands gsm GSM related commands kill kill the emulator instance network manage network settings power power related commands quit|exit quit control session redir manage port redirections sms SMS related commands avd manager virtual device state window manage emulator window try 'help <command>' for command-specific help
안드로이드 애뮬레이터 폴더 구조
/data/
/app/ : 배포된 애플리케이션 저장 폴더
com.jopenbusiness.android.apk
/data/ : 배포된 애플리케이션 설치 폴더
/com.jopenbusiness.android/
/databases/ : SQLite (sqlite3) Database file
alarms.db
/files/
/lib/
/shared_prefs/ : SharedPreferences XML 파일 저장 위치
AlarmClock.xml
/sdcard/ : SD (Secure Digital) 플래시 메모리 카드
/system/
/app/ : Android 내장 애플리케이션 저장 폴더
Contacts.apk
/etc/permissions/
/framework/~.jar
apk Decompile
- 라이브러리 다운로드
- AndroidSDK : Android SDK Location - C:/appl/androidSDK
- Jad Decompiler : jad 명령어를 사용할 수 있도록 path에 등록 한다.
- dexdump.zip
- dexdump.zip의 압축을 풀어 C:/appl/androidSDK/tools/ 폴더에 복사 한다.
- Contacts.apk 파일을 Decompile 해보자.
- Contacts.apk 파일을 Contacts 폴더에 압축을 푼다.
- java -DASDKLoc=. -jar undx.jar -s C:/appl/androidSDK -f Contacts/classes.dex
- gen/classes.dex.jar 파일이 생성 된다.
- gen/classes.dex.jar 파일의 압축을 풀어 jad로 decompile 한다.
- jad -o -r -sjava -dsrc **/*.class
- XML 파일을 사람이 읽기 편한 형태로 변환 한다.
- java -jar AXMLPrinter2.jar Contacts/AndroidManifest.xml > out/AndroidManifest.xml
Android SDK
Android 입출력
Android 입출력 개요
안드로이드(Android)의 구성 요소를 프로그램의 가장 기본인 MVC 모델에 맞추어 한번 살펴 보자.
| View |
안드로이드에서 View는 화면을 구성하는 가장 기본적인 요소로 View에서 파생된 Layout, Control, Widget, ViewGroup, Menu 등을 사용하여 화면을 구성하고 사용자와 상호작용을 한다. |
| Control |
비즈니스 로직을 처리 하는 구성 요소로는 Activity, Service, BroadcastReceiver가 있다. |
| Model |
데이터 관리를 위한 구성 요소로는 SQLite, ContentProvider가 있고 그외에 여러가지 형태의 데이터를 관리 한다. 안드로이드는 다양한 센서를 내장하고 있는데 센서를 통한 데이터 관리도 가능 하다. |
여기서는 Model에 해당하는 것을 조금 더 살펴 보자. 안드로이드 앱은 Android Package 형태로 패키징 되어 스마트폰에 배포된다. Android Package를 기준으로 Model을 살펴 보자. Android Package는 Linux 기반에서 동작을 하므로 Package는 소유자의 권한으로 실행이 되며 Package별로 Context를 가지고 있다. Context는 Activity, Service, BroadcastReceiver 등의 상위 클래스로 Context를 통해 Package에 속한 자원에 접근할 수 있다. (Package : Context, 소유자)
| Package 내부 |
Package 내부의 자원은 Package에서만 접속이 가능하며, 다른 Package에서 접근하려면 패키지 사용자를 동일하게 맞추거나 Context를 통해서만 접속이 가능하다.
|
| Package 외부 |
Package 외부의 자원은 여러 Package가 공유하여 사용할 수 있는 공용의 자원이다.
|
| 스마트폰 외부 |
Smart Phone 외부의 자원에 접속하기 위해서는 Network를 통해 접속 한다. 네트워크로는 3G, Wi-Fi, Bluetooth 등이 있다. |
Application내 정보 교환
Application에 포함된 Activity, Service, BroadcastReceiver간 아래와 같은 방법으로 정보를 교환할 수 있다.
| Static class |
public class MessagesSQLiteOpenHelper extends SQLiteOpenHelper {
public static final String MESSAGE_ID = "id";
}
import static com.jopenbusiness.android.messages.MessagesSQLiteOpenHelper.MESSAGE_ID;
//--- 프로그램에서 MESSAGE_ID를 직접 사용할 수 있다.
|
| Context |
|
| Application |
Activity와 Service는 자신이 포함된 Application에 접근할 수 있다. Application을 사용하여 Activity와 Service간 정보를 교환해 보자.
public class SmartAndroidApplication extends Application {
//--- Activity, Service에서 같이 사용할 함수를 정의 한다.
}
<application android:icon="@drawable/icon" android:name=".SmartAndroidApplication" android:label="@string/app_name"> </application>
SmartAndroidApplication app = (SmartAndroidApplication)getApplication(); boolean rtcd = app.checkLogin(strUserid, strPassword); |
| Intent의 Extras (Bundle) |
//--- Intnet에 정보를 저장 한다.
Intent intent = new Intent(getApplicationContext(), MessageActivity.class);
intent .putExtra("name", "value");
startActivity(intent);
//--- Intent에 저장된 정보를 가져 온다.
Intent intent = getIntent();
String value = data.getStringExtra("name");
|
Resource 입출력
SharedPreferences 입출력
- Context를 통한 SharedPreferences XML 파일 접근
- /data/data/$PACKAGE_HOME/shared_prefs/~.xml
- Linux (Android)에 파일로 저장되므로 접근 권한을 가짐
- SharedPreferences 사용
//--- accessMode : Linux에서 파일의 Other 권한 설정 //--- Context.MODE_PRIVATE, MODE_WORLD_READABLE, MODE_WORLD_WRITEABLE SharedPreferences pref = getSharedPreferences(String filename, int accessMode); pref.getString(name, default); //--- SharedPreferences에 lock을 설정 한다. Editor prefEditor = pref.edit(); //--- value type : String, boolean, float, int, long prefEditor.putString(name, value); //--- SharedPreferences에 unlock을 설정 한다. prefEditor.commit();
- 다른 애플리케이션의 SharedPreferences 사용
Context context = createPackageContext("com.msi.prefs", int accessMode);
context.getSharedPreferences(String filename, int accessMode);
File 입출력
- File 입출력
- /data/data/$PACKAGE_HOME/files/fileName
byte[] buf = new byte[1024 + 1];
FileInputStream finp = OpenFileInput(filename);
FileOutputStream fout = OpenFileOutput(filename, Context.MODE_PRIVATE);
while (finp.read(buf) != -1) {
new String(buf);
}
finp.close();
fout.write(String.getBytes());
fout.flush();
fout.close();
- 동일 사용자 아이디로 파일 공유
- AndroidManifest.xml 파일에서 android:sharedUserId = "sameUser";
SD 입출력
- SD (Secure Digital) 플래시 메모리 카드 입출력
- 파일 위치 : /sdcard
- Tools : mksdcard
- FAT (File Allocation Table) 파일 시스템
File file = new File("/sdcard/~");
FileOutputStream fout = new FileOutputStream(file);
SQLite 입출력
- SQLite (sqlite3)
- 동일 패키지 내에서만 접근 가능
- /data/data/$PACKAGE_HOME/databases/dbname.db
- public abstract class android.database.sqlite.SQLiteOpenHelper
- SQLiteOpenHelper -> SQLiteDatabases
- Cursor : 조회
- ContentValues : 등록, 수정
- : 삭제
SQLiteOpenHelper helper = new SQLiteOpenHelper(Context, dbName, null, version(=3));
//--- SQLiteDatabase getWritableDatabase(), getReadableDatabase()
android.database.sqlite.SQLiteDatabase db = helper.getWritableDatabase();
android.database.Cursor cur = null;
ContentValues values = new ContentValues();
String[] COLS = new String[] {"_id", "zip"};
db.beginTransaction();
//--- execSQL(String sql)
//--- execSQL(String sql, Object bindArgs[])
db.execSQL(~);
values.put(name, value);
db.insert(dbTable, null, values);
db.update(dbTable, values, 조건, 조건_변수s);
db.delete(dbTable, 조건, 조건_변수s);
db.endTransaction();
//--- Cursor query(boolean distinct, String table, String columns[], String selection,
//--- String selectionArgs[], String groupBy, String having, String orderBy, String limit)
//--- Cursor rawQuery(String sql, String selectionArgs[])
cur = db.query(true, dbTable, COLS, 조건, null, null, null, null);
cur.moveToFirst();
for (int i = 0;i < cur.getCount();i++) {
cur.getLong(0), cur.getString(1), cur.getInt(2)
cur.moveToNext();
}
if ((cur != null) && (!cur.isClosed())) {
cur.close();
}
- sqlite3 Tools
cd $ANDROID_HOME/tools adb shell sqlite3 /data/data/$PACKAGE_HOME/databases/~.db
- 참고 문헌
ContentProvider 입출력
- 서로 다른 애플리케이션 사이에서 데이터 공유
- ContentProvider의 URI 예
- content://contacts/people
- content://contacts/people/?
- ContentProvider 가져오기
android.content.ContentResolver resolver = android.content.Context.getContentResolver();
InputStream openInputStream(Uri uri)
OutputStream openOutputStream(Uri uri)
OutputStream openOutputStream(Uri uri, String mode)
Uri resolver.insert(Uri url, ContentValues values)
int resolver.update(Uri uri, ContentValues values, String where, String selectionArgs[])
int resolver.delete(Uri url, String where, String selectionArgs[])
//--- Cursor query(Uri uri, String projection[],
//--- String selection, String selectionArgs[], String sortOrder)
Cursor cur = resolver.query(URI, COLS, null, null, sort);
//--- Cursor의 Lifecycle이 Activity에 의해서 관리됨
Cursor Activity.managedQuery(Uri uri, String projection[],
String selection, String selectionArgs[], String sortOrder)
- 확인이 필요한 사항
- Android 내장 ContentProvider의 종류와 사용법
- 참조
Network 입출력
- Mobile IP Network 입출력
- WiFi, 3G
- Network 상태 확인
android.net.ConnectivityManager cMgr = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE); android.net.NetworkInfo netInfo = cMgr.getActiveNetworkInfo(); //--- CONNECTED, CONNECTING, DISCONNECTED, DISCONNECTING, SUSPENDED, UNKNOWN netInfo.getState() netInfo.isConnected(), isAvailable()
- Socket
java.net.ServerSocket server = new ServerSocket(PORT, 1);
while (true) {
Socket client = server.accept();
while (true) {
BufferedReader reader = new BufferedReader(
new InputStreamReader(client.getInputStream()));
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(client.getOutputStream()));
String textLine = reader.readLine();
writer.write(textLine, 0, textLine.length());
writer.flush();
}
client.close();
}
java.net.Socket socket = new Socket(ip, port);
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream()));
BufferedReader reader = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
- HttpURLConnection
java.net.URL url = new URL(location); java.net.HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(); BufferedReader inp = new BufferedReader(new InputStreamReader(urlConn.getInputStream())); inp.close(); urlConn.disconnect();
- HttpClient
org.apache.http.client.ResponseHandler<String> handler = new ResponseHandler<String>() {
public String handleResponse(org.apache.http.HttpResponse response) {
StatusLine status = response.getStatusLine();
HttpEntity entity = response.getEntity();
String result = StringUtils.inputStreamToString(entity.getContent());
return result;
}
}
DefaultHttpClient client = new DefaultHttpClient();
client.addRequestInterceptor(
new HttpRequestInterceptor() {
public void process(HttpRequest request, HttpContext context)
throws HttpException, IOException {
request.addHeader(key, value);
}
}
);
client.getCredentialsProvider().setCredentials(
AuthScope.ANY, new UsernamePasswordCredentials(user, pass));
HttpGet method = new HttpGet(url);
client.execute(method , handler);
//--- MIME : application/x-www-form-urlencoded, text/html, text/plain
HttpPost method = new HttpPost(url);
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair(key, value));
method.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
client.execute(method , handler);
- 웹서비스
- POX (Plain Old XML over HTTP)
- REST
- POST : create, update, delete
- GET : read
- PUT : create, replace
- DELETE : delete
- SOAP
SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser sp = spf.newSAXParser(); XMLReader xr = sp.getXMLReader(); xr.setContentHandler(handler); xr.parse(new InputSource(new StringReader(xmlString)));
내장 ContentProvider 입출력
- 참고 문헌
주소록 입출력
- Android의 주소록 구조
- import android.provider.ContactsContract.Contacts : 최상위 주소록
- import android.provider.ContactsContract.RawContacts : 주소록의 출처별 주소록
- import android.provider.ContactsContract.Data : 주소록에 포함되어 있는 데이터 (예, 전화번호, 이메일 등)
- 주소록 입출력 권한
<uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.WRITE_CONTACTS" />
- Contacts 조회 (Android 2.2)
StringBuffer buf = null;
Cursor contacts = null;
long contactID = 0l;
buf = new StringBuffer();
// String sortOrder = Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
// Cursor contactCursor = managedQuery(uri, projection, selection, selectionArgs, sortOrder);
contacts = getContentResolver().query(Contacts.CONTENT_URI,
new String[] {
Contacts._ID, Contacts.CONTACT_PRESENCE, Contacts.CONTACT_STATUS,
Contacts.CONTACT_STATUS_ICON, Contacts.CONTACT_STATUS_LABEL, Contacts.CONTACT_STATUS_RES_PACKAGE,
Contacts.CONTACT_STATUS_TIMESTAMP, Contacts.CUSTOM_RINGTONE, Contacts.DISPLAY_NAME,
Contacts.HAS_PHONE_NUMBER, Contacts.IN_VISIBLE_GROUP, Contacts.LAST_TIME_CONTACTED,
Contacts.LOOKUP_KEY, Contacts.PHOTO_ID, Contacts.SEND_TO_VOICEMAIL,
Contacts.STARRED, Contacts.TIMES_CONTACTED
},
null, null, null);
contacts.moveToFirst();
if (!contacts.isAfterLast()) {
do {
contactID = contacts.getLong(0);
buf.append("--- Contacts Lists ---\n");
for (int idx = 0;idx < contacts.getColumnCount();idx++) {
if (contacts.getString(idx) != null) {
buf.append(contacts.getColumnName(idx).toUpperCase() + ": " + contacts.getString(idx) + "\n");
}
}
buf.append("\n");
} while (contacts.moveToNext());
}
contacts.close();
return buf.toString();
- RawContacts 조회 (Android 2.2)
StringBuffer buf = null;
Cursor rawContacts = null;
long rawContactID = 0l;
buf = new StringBuffer();
rawContacts = getContentResolver().query(RawContacts.CONTENT_URI,
new String[] {
RawContacts._ID, RawContacts.ACCOUNT_NAME, RawContacts.ACCOUNT_TYPE,
RawContacts.AGGREGATION_MODE, RawContacts.CONTACT_ID, RawContacts.CUSTOM_RINGTONE,
RawContacts.DELETED, RawContacts.DIRTY, RawContacts.LAST_TIME_CONTACTED,
RawContacts.SEND_TO_VOICEMAIL, RawContacts.SOURCE_ID, RawContacts.STARRED,
RawContacts.SYNC1, RawContacts.SYNC2, RawContacts.SYNC3,
RawContacts.SYNC4, RawContacts.TIMES_CONTACTED, RawContacts.VERSION
},
RawContacts.CONTACT_ID + "=?", new String[] {String.valueOf(contactID)}, null);
rawContacts.moveToFirst();
if (!rawContacts.isAfterLast()) {
do {
rawContactID = rawContacts.getLong(0);
buf.append("--- RawContacts Lists ---\n");
for (int pos = 0;pos < rawContacts.getColumnCount();pos++) {
if (rawContacts.getString(pos) != null) {
buf.append(rawContacts.getColumnName(pos).toUpperCase() + ": " + rawContacts.getString(pos) + "\n");
}
}
buf.append("\n");
} while (rawContacts.moveToNext());
}
rawContacts.close();
return buf.toString();
- Data 조회 (Android 2.2)
StringBuffer buf = null;
Cursor contactData = null;
buf = new StringBuffer();
contactData = getContentResolver().query(Data.CONTENT_URI,
new String[] {
Data._ID, Data.MIMETYPE, Data.RAW_CONTACT_ID,
Data.IS_PRIMARY, Data.IS_SUPER_PRIMARY, Data.DATA_VERSION,
Data.DATA1, Data.DATA2, Data.DATA3, Data.DATA4, Data.DATA5
},
Data.RAW_CONTACT_ID + "=?", new String[] {String.valueOf(rawContactID)}, null);
buf.append("--- Data Lists ---\n");
contactData.moveToFirst();
if (!contactData.isAfterLast()) {
do {
for (int idx = 0;idx < contactData.getColumnCount();idx++) {
if (contactData.getString(idx) != null) {
buf.append(contactData.getColumnName(idx).toUpperCase() + ": " + contactData.getString(idx) + "\n");
}
}
buf.append("\n");
} while (contactData.moveToNext());
}
contactData.close();
return buf.toString();
- 전화번호 가져오기
import ContactsContract.CommonDataKinds.Phone; Cursor PhoneNumberCursor = getContentResolver().query(Phone.CONTENT_URI, null, null, null, null);
- 연락처 등록
ContentValues values = new ContentValues(); values.put(RawContacts.ACCOUNT_TYPE, "basic"); values.put(RawContacts.ACCOUNT_NAME, "test"); Uri rawContactUri = getContentResolver().insert(RawContacts.CONTENT_URI, values); long rawContactId = ContentUris.parseId(rawContactUri);
- 연락처 수정
int resolver.update(Uri uri, ContentValues values, String where, String selectionArgs[])
- 연락처 삭제
int resolver.delete(Uri url, String where, String selectionArgs[])
- 자신의 번호를 조회
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> TelephonyManager mTelephonyMgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); String myNumber = mTelephonyMgr.getLine1Number();
- 참고 문헌
Android 센서 입출력
Telephony 입출력
- TelephonyManager
- android.telephony.TelephonyManager
android.telephony.TelephonyManager telMgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); //--- PHONE_TYPE_NONE, PHONE_TYPE_GSM, PHONE_TYPE_CDMA int phoneType = telMgr.getPhoneType(); //--- SIM_STATE_UNKNOWN, SIM_STATE_ABSENT, SIM_STATE_PIN_REQUIRED //--- SIM_STATE_PUK_REQUIRED, SIM_STATE_NETWORK_LOCKED, SIM_STATE_READY int simState = telMgr.getSimState(); //--- CALL_STATE_IDLE, CALL_STATE_RINGING, CALL_STATE_OFFHOOK int callState = telMgr.getCallState(); String line1Number = telMgr.getLine1Number(); GsmCellLocation cellLocation = (GsmCellLocation) telMgr.getCellLocation();
- PhoneStateListener
PhoneStateListener listener = new PhoneStateListener() {
public void onCallStateChanged(int state, String incomingNumber) {
}
}
telMgr.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
- 전화 걸고 받기
- Permission
- android.Manifest.permission
- 참조: http://developer.android.com/reference/android/Manifest.permission.html
전화 걸기 : CALL_PHONE = "android.permission.CALL_PHONE" 긴급 통화 : CALL_PRIVILEGED = "android.permission.CALL_PRIVILEGED" 폰 상태 읽기 : READ_PHONE_STATE = "android.permission.READ_PHONE_STATE" 폰 상태 수정 : MODIFY_PHONE_STATE = "android.permission.MODIFY_PHONE_STATE" 브로드케스팅 수신 : PROCESS_OUTGOING_CALLS = "android.permission.PROCESS_OUTGOING_CALLS" 전화 걸기 이전 : ACTION_NEW_OUTGOING_CALL = "android.intent.action.NEW_OUTGOING_CALL"
- 권한 설정 예: <uses-permission android:name="android.permission.CALL_PHONE" />
- ACTION_DIAL
Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + TelNumber));
startActivity(intent);
- ACTION_CALL
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + TelNumber));
startActivity(intent);
- Utility
- android.telephony.PhoneNumberUtils
- SMS/MMS 보내고 받기
- android.Manifest.permission
수신 모니터링 : RECEIVE_SMS = "android.permission.RECEIVE_SMS" 읽기 가능 : READ_SMS = "android.permission.READ_SMS" 발송 가능 : SEND_SMS = "android.permission.SEND_SMS" SMS Provider로 전송 : WRITE_SMS = "android.permission.WRITE_SMS" BROADCAST_SMS = "android.permission.BROADCAST_SMS"
- SMS 메시지 보내기
android.telephony.SmsManager sms = SmsManager.getDefault();
PendingIntent sentIntent = PendingIntent.getActivity(this, 0, new Intent(SmsSendCheck), 0);
if (PhoneNumberUtils.isWellFormedSmsAddress(dest)) {
//--- sendTextMessage(String destinationAddress, String scAddress,
//--- String text, PendingIntent sentIntent, PendingIntent deliveryIntent)
//--- sendMultipartTextMessage(String destinationAddress, String scAddress,
//--- ArrayList parts, ArrayList sentIntents, ArrayList deliveryIntents)
sms.sendTextMessage(dest, null, dest, sentIntent, null);
}
- SMS 메시지 받기
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
Object[] pdus = (Object[]) bundle.get("pdus");
for (Object pdu : pdus) {
android.telephony.SmsMessage smsMessage = SmsMessage.createFromPdu((byte[])pdu);
smsMessage.getDisplayMessageBody();
}
}
- 관련 용어
- GSM (Global System for Mobile communications)
- SIM (Subscriber Identity Module)
SMS 입출력
- SMS 발송 화면 표시
Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse("smsto://" + contact.getHandphone()));
// intent.putExtra("sms_body", "The SMS text");
// intent.setType("vnd.android-dir/mms-sms");
startActivity(intent);
- 참고 문헌
Email 입출력
- 이메일 발송 화면 표시
Intent intent = new Intent(Intent.ACTION_SENDTO, Uri.parse("mailto:" + contact.getEmail()));
startActivity(intent);
Location 입출력
- 위치 정보 저장 및 전송을 위한 포맷
- GPX (The GPS Exchange Format)
- 중간 지점, 트랙, 경로 등을 저장할 수 있는 XML Schema
- http://www.topografix.com/GPX/1/1/
- KML (Keyhole Markup Language)
- LocationProvider 종류
- Network, 기지국을 활용한 삼각측량법, GPS
- LocationProvider 제공 정보
- 위도와 경도, 속도, 방위 및 고도
- android.location.LocationManager
- Permission : android.Manifest.permission
GPS Provider : ACCESS_FINE_LOCATION = "android.permission.ACCESS_FINE_LOCATION"
Network Provider : ACCESS_COARSE_LOCATION = "android.permission.ACCESS_COARSE_LOCATION"
LocationManager locManager= (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
//--- GPS_PROVIDER, NETWORK_PROVIDER
LocationProvider locProvider = (LocationProvider) locManager.getProvider(LocationManager.GPS_PROVIDER);
Location loc = locManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
//--- lat. 위도, log. 경도
int lat = (int) (loc.getLatitude() * LocationHelper.MILLION);
int lon = (int) (loc.getLongitude() * LocationHelper.MILLION);
LocationListener locListener = new LocationListener() {
public void onLocationChanged(final Location loc) {
}
}
locManager.requestLocationUpdates(locProvider.getName(), 3000, 185000, locListener);
Bluetooth
Camera
compass
- 나침판
accelerometer
- 가속도 센서
이미지
비디오
오디오
Hello Android
첫번째 안드로이드 애플리케이션으로 "Hello Android"를 출력하는 애플리케이션을 만들어 봅시다.
- "File -> New -> Android Project" 메뉴를 선택하여 다음과 같이 입력한 후 "Finish" 버튼을 누른다.
- Project name : Hello_Android
- Build Target : Android 2.1 을 선택
- Applicatin name : HelloAndroid
- Package name : com.jopenbusiness.android
- Create Activity : .HelloAndroid
- 애플리케이션의 화면을 수정 합니다.
- "Hello_Android -> res -> layout -> main.xml"을 더블 클릭 한다.
- "Window -> Show View" 메뉴에서 아래 두개의 View를 추가 한다.
- Outline : 화면에 표시되는 Control 또는 Widget 등을 보고 선택할 수 있다.
- Properties : 화면에 표시되는 Control 또는 Widget 등의 속성을 수정할 수 있다.
- main.xml의 Outline에서 "TextView:를 선택 한다.
- Properties에서 Text size에 25px를 입력 한다. (폰트 크기 변경)
- "Hello_Android -> res -> values -> strings.xml"을 더블 클릭 한다.
- "hello" 문자열을 선택한 후 Value에 "Hello Android!"를 입력 한다.
- 수정한 애플리케이션을 애뮬레이터를 통해 실행 한다.
- "Hello_Android" 애플리케이션을 선택한다.
- 오른쪽 마우스를 눌른 후 "Run As -> Android Application"을 선택 한다.
- 애뮬레이터에서 애플리케이션이 실행되어 "Hello Android!"가 25px 폰트 사이즈로 화면에 표시되는 것을 확인할 수 있다.
- 애뮬레이터의 처음 실행헤 시간이 조금 걸리므로 끊기 있게 기다리자.
- 처음 이후의 실행은 애뮬레이터가 떠 있는 상태이므로 빨리 결과를 확인할 수 있다.
안드로이드 커뮤니티
Google 커뮤니티
| Google 모바일 |
|
| Android Developers | |
| Google Code : Android |
|
안드로이드 커뮤니티
| Korea Android |
|
| 안드로이드펍 |
|
| Android Side |
|
| mSurf Lab 안드로이드 개발 정보방 |
|
| 안드로이드 클럽 |
|
| AndroLib |
|
스마트폰 커뮤니티
| 재미있는 재임스 |
|
참고 문헌
- Google's App Inventor
- appcelerator의 Titanium : 다양한 모바일 환경을 지원하는 플랫폼
- 안드로이드 2.0 SDK + 이클립스 3.5 개발환경 설정 방법 .., 2009.11
- 구글 안드로이드 (android) 완벽정리, 2010.2
- 전자통신동향분석, 한국전자통신연구원, 2010.2
- 커니의 안드로이드 이야기 : 안드로이드와 관련된 사항이 잘 분류되어 정리되어 있습니다.
- 껍데기 안드로이드폰야그
- 퀄컴, 안드로이드용 증강현실 SDK 무료 공개, 2010.7
- 10 안드로이드 하드웨어, 2010.3
- Android Decompile
- 참고 파일




