출처 : http://stackoverflow.com/questions/2646028/android-horizontalscrollview-within-scrollview-touch-handling

public
class CustomScrollView extends ScrollView {
private GestureDetector gestureDetector;
View.OnTouchListener gestureListener;

public CustomScrollView(Context context, AttributeSet attrs) {
   
super(context, attrs);
    gestureDetector
= new GestureDetector(new YScrollDetector());
    setFadingEdgeLength
(0);
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
   
return super.onTouchEvent(ev);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
   
//Call super first because it does some hidden motion event handling
   
boolean result = super.onInterceptTouchEvent(ev);
   
//Now see if we are scrolling vertically with the custom gesture detector
   
if (gestureDetector.onTouchEvent(ev)) {
       
return result;
   
}
   
//If not scrolling vertically (more y than x), don't hijack the event.
   
else {
       
return false;
   
}
}

// Return false if we're scrolling in the x direction  
class YScrollDetector extends SimpleOnGestureListener {
   
@Override
   
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
       
try {
           
if (Math.abs(distanceY) > Math.abs(distanceX)) {
               
return true;
           
} else {
               
return false;
           
}
       
} catch (Exception e) {
           
// nothing
       
}
       
return false;
   
}
}

'Android > Tip&Tech' 카테고리의 다른 글

[팁]AutoCompleteTextView랑 DB랑 싱크시키기  (3) 2011.12.05
[팁]ActionBar 커스텀하기  (0) 2011.12.01
Intent 개념 총정리  (2) 2011.11.30
웹뷰 키보드 위치조절(webview)  (0) 2011.11.29
SQL function(함수) 모음  (2) 2011.11.23

안드로이드 프로그래밍에서 중요한 개념 'Intent'

보고있는 책보다도 잘 정리를 해 놓았다.....

[원문] http://gtko.springnote.com/pages/5254593?edit=1

인텐트를 통한 액티비티를 명시적으로 시작하는 방법, 암시적인 인텐트로 데이터의 한 부분에 대해 수행되는 액션을 요청하는 방법, 안드로이드가 그 요청을 서비스할 수 있는 애플리케이션 콤포넌트를 결정하도록 하는 방법을 설명한다.

브로드캐스트 인텐트는 시스템 전역에 이벤트를 알린다. 즉, 브로드캐스트로 전송하고 브로드캐스트 수신자로 이를 받아 처리한다.

어댑터는 데이터 소스와 프리젠테이션(view 들)과 연결하는 방법.

 

인텐트 소개

어 떤 액션이 수행되는데 특정 데이터의 특정 부분을 가지고 수행하라는 선언으로 메시지를 전달하는 메커니즘이다. 즉, activity, native 장치 등 상호간의 작용을 지원한다. 독립적인 콤포넌트들의 컬렉션을 서로 연결된 단일 시스템으로 변경하는 역할이기도 하다.

 

인텐트 역할

액티비티를 명시적( 클래스 지정) 혹은 암시적(데이터의 어느 한 부분에 대해 수행되는 액션을 요청)으로 시작하는 것.

브로드캐스트 인텐트로 이벤트 중심 애플리케이션을 구성할 수 있다

 

인테트로 activity 시작

인텐트는 애플리케이션 내에 있는 activity 간의 시작, 중지, 전이에 사용된다.

 

현재 activity에서 다른 activity 화면을 열려면, startActivity() 를 사용한다. 이 액티비티는 부모 액티비티와 독립적이다.

  1. startActivty(a_intent)
  • Intent a_intent 는 대상 클래스를 명시적으로 지정하거나, 수행할 액션일 수 있다. 액션을 지정하면 런타임은 intent resolution 이라는 과정을 거쳐 acitivity를 선택한다.

 

명시적 activity start

AndroidMenifest에 선언된 activity 를 명시적으로 지정해 시작할 수 있다.

  1. Intent intent = new Intent(MyActivity.this, MyOtherActivity.class);
  2. sgtartActivity(intent);
  • startActivity()가 수행되면 현재 MyActivity는 onPause() 상태로 가고, MyOtherAcitivity 가 활성상태로 스택의 맨 위로 갈 것이다.
  • 새로운 acitivity에서 finish()를 호출하면 MyActivity는 종료되어 스택에서 제거된다.
  • 그렇지 않다면 MyOtherActivity에서 back button을 누르면 MyActivity로 돌아 올 수 있다.

 

  1. Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setClassName(this, MyActivity.class.getName());
    startActivity(intent);

 

암시적 activity start

수행할 액션과 요구되는 데이터로 acitvity를 시작할 수 있다.

 

예를 들어 dialer를 통해 전화걸기를 하려며 새로운 dialer를 구현하기 보다 기존 dialer와 전화목록을 이용하면 될 것이다.

  1. Intent new_intent = new Intent( Intent.ACTION_DIAL, Uri.parse("tel:555-2368")
  2. startAcitivity(new_intent)
  • runtime은 new_intent를 분석해 전화번호에 대한 전화걸기 action을 제공하는 acitivity를 시작한다.
  • 여러 native application은 이런 액션에 대한 콤포넌트를 제공하고, 사용자도 새로운 액션을 지원하거나
  • 네이티브 액션의 대체 공극바를 제공하기 위해 등록될 수 있다.

 

Linkity 로 시작

정 규식 패턴 매칭을 통해 TextView 에 하이퍼링크를 자동으로 생성해 주는 helper class잉다. 즉 패턴에 일치하는 텍스트는 그것을 대상 URI로 사용해 암시적으로 startAcitivity( new Intent(Intent.ACTION_VIEW, uri)) 를 호출하는 하이퍼 링크로 변환된다.

Linkify 클래스는 대표적으로 TextView와 Spinnerable UI 를 사용할 수 있다.

 

코드에서 Likify 사용
  • 텍스트에 있는 http url, email 주소를 likify 한다.
  1. TextView myTextView = (TextView)findViewById(R.id.myTextView);
    Linkify.addLinks(myTextView, Linkify.WEB_URLS|Linkify.EMAIL_ADDRESSES);
  • url 을 클릭하면 웹브라우저가 열리고, email 주소를 클릭하면 email client가 호출된다.

 

view 선언에서 linkify 사용

android:autoLink 속성에 none, web, email, phone, all 에 self-describing-values로 '|'로 구분해 사용할 수 있다.

  1.   <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/linkify_me"
        android:autoLink="phone|email"
      />

 

사용자 정의 linkify 문자열 만들기

사용자 RegExp 를 만들어 linkify 문자열로 사용할 수 있다.

  1.    int flags = Pattern.CASE_INSENSITIVE;
        Pattern pattern = Pattern.compile("\\bquake[0-9]*\\b", flags);
        Linkify.addLinks(myTextView, pattern, "content://com.pad.earthquake/earthquakes/");
  • quake로 시작하고 그 뒤에 숫자가 나오는 모든 문자열 찾아 content://.. URI에 붙여준다.

 

TransformFilter, MatchFilter 인터페이스 이용한 문자열 사용

RegExp 패턴 매치에 추가적인 조건을 더할 수 있다.

  1. MatchFilter matchfilter = new MatchFilter() {
         public boolean acceptMatch(CharSequence s, int start, int end) {
               return (start == 0 || s.charAt(start-1) != '!'); }
     };
    TransformFilter transformfilter =  new TransformFilter() {
           public String  transformUrl(Matcher match, String url) {
               return url.toLowerCase(); }
     };

    String prefixWith = "http://www.";       
    pattern = Pattern.compile("\\bTEST.COM\\b");
    Linkify.addLinks(myTextView, pattern, prefixWith, matchfilter, transformfilter );

  • 문자열 앞에 !가 있는 것은 취소하는 필터 구현.

 

 

액티비티 결과

서 브액티비티를 시작하면 서브 액티비티가 종료할 때 부모의 이벤트 핸들러(onActivityResult())를 호출한다. startActivityForResult() 는 시작할 intent 와 request code 를 사용해서 activity의 결과를 request code로 식별한다.

 

 

명시적으로 서브 액티비티 시작
  1. private static final int SHOW_SUBACTIVITY = 1;
  2. Intent intent = new Intent(getApplicationContext(), MyOtherActivity.class);
    startActivityForResult(intent, SHOW_SUBACTIVITY);

 

암시적 서브 액티비티 시작
  1. private static final int PICK_CONTACT_SUBACTIVITY = 2;
  2. Uri uri = Uri.parse("content://contacts/people");
    Intent intent = new Intent(Intent.ACTION_PICK, uri);
                    // Result resturned in onActivityResult
    startActivityForResult(intent, PICK_CONTACT_SUBACTIVITY);

 

서브액티비티에 데이터 전달하기

Intent intent = new Intent();
Bundle bun = new Bundle();

bun.putString(”param_string”, “the actual string”); // add two parameters: a string and a boolean
bun.putBoolean(”param_bool”, true);

intent.setClass(this, SecondaryActivity.class);
intent.putExtras(bun);
startActivity(intent);

 

서브액티비티에서 전달된 데이터 처리...

Bundle bun = getIntent().getExtras();
String param1 = bun.getString(”param_string”);
boolean param2 = bun.getBoolean(”param_bool”);

 

서브 액티비티 / 인텐트 필터 호출에 응답

암시적으로 호출된 서브액티비티에서 수행할 액션, 데이터를 통해 요청된 작업을 진행한다.

  1. @Override
  2. public void onCreate(Bundle bundle) {
  3.     ...
  4.     Intent intent = getIntent(); // 수행할 action, date 를 얻기 위해.
  5.     String action = intent.getAction();
  6.     Uri data = intent.getData();
  7. ...
  8. }

또한 다음과 같이 startNextMatchingActivity() 메서드로 액션의 처리 책임을 가장 잘 일치하는 컴포넌트로 넘길수 있다. 

즉, 야밤에 다른 intent 로 처리를 넘겨버리는 예이다.

 

  1.     Intent intent = getIntent(); // 수행할 action, date 를 얻기 위해.
  2.     if( isAfterMidnight)
  3.        startNextMatchingActivity(intent);

 

 

서브 액티비티 / 결과 돌려주기

finish()를 호출하기 전에 setResult() 로 결과를 저장한다. 결과 코드와 Intent로 표현된 result payload 로 제공된다.

Activity.RESULT_OK, Activity.RESULT_CANCELED 를 결과로 많이 사용하고, 사용자 정의 결과값을 줄 수 있다. 결과 인텐트에 연락처, 전화번호, 미디어 파일에 대한 URI 정보를 가질 수 도 있다.

  1.         Uri data = Uri.parse("content://horses/" + selected_horse_id);  
            Intent result = new Intent(null, data);
            result.putExtra(IS_INPUT_CORRECT, inputCorrect);
            result.putExtra(SELECTED_PISTOL, selectedPistol);
            setResult(RESULT_OK, result);   
            finish();

 

 

결과 받기

부모 액티비티에서 onActivityresult() 메소드는 서브액티비티의 결과를 받는다.

  • Request code: 서브 액티비티를 시작하는데 사용되었던 요청 코드
  • Result code: 서브 액티비티가 자신의 결과를 나타내기 위해 설정한 코드 예) Activity.RESULT_OK, Activity.RESULT_CANCELED

    • 서브 액티비티가 비정상 종료되거나 결과코드가 지정 안되면 Activity.RESULT_CANCELED 이 결과 코드이다.
  • data: 모든 결과를 담은 인텐트.

 

  1.  @Override
      public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
      
        switch(requestCode) {
          case (SHOW_SUBACTIVITY) :
            if (resultCode == Activity.RESULT_OK) {
              Uri horse = data.getData();
                boolean inputCorrect = data.getBooleanExtra(IS_INPUT_CORRECT, false);
                String selectedPistol = data.getStringExtra(SELECTED_PISTOL);
              Toast.makeText(this, "Pistol Selected: " + selectedPistol, Toast.LENGTH_SHORT).show();               
            }
            break;       
           
          case (PICK_CONTACT_SUBACTIVITY) :
            if (resultCode == Activity.RESULT_OK) {
              Toast.makeText(this, "CONTACT SELECTED", Toast.LENGTH_SHORT).show();
              // TODO Handle contact selection.
            }
            break;      
        }

 

 

Native android action

네이티브 안드로이드 애플리케이션도 역시 인텐트를 사용해 액티비티와 서브 액티비티를 시작한다. Intent 에서 제공하는 네이티브 액션을 살펴보자. 아래 static 문자열은 암시적으로 인테트를 사용할 때 유용하다.

 

상수타겟 컴포넌트액션
ACTION_CALL activity 전화를 걸어라.
ACTION_EDIT activity 사용자에게 편집할 데이터를 표시하라.
ACTION_MAIN activity 데이터 입력과 반환 결과 없이 태스크의 최초의 액티비티로써 액티비티를 실행하라.
ACTION_SYNC activity 모바일 디바이스의 데이터와 서버의 데이터를 동기화하라.
ACTION_BATTERY_LOW broadcast receiver 배터리가 부족하다는 경고.
ACTION_HEADSET_PLUG broadcast receiver 헤드셋이 디바이스에 연결 또는 분리되었다는 것.
ACTION_SCREEN_ON broadcast receiver 스크린이 켜졌다는 것.
ACTION_TIMEZONE_CHANGED broadcast receiver 타임존 설정이 바뀌었다는 것.

ACTION_INSERT : 지정된 커서로 새로운 항목을 삽입할 수 있는 액티비티를 연다. 서브 액티비티느 새로 삽입된 항목에 대한 URI를 리턴해야 한다.

ACTION_PICK: URI 로 부터 데이터 항목 하나를 고를 수 있는 서브 액티비티를 듸운다. 예) content://contacts/people 전달되면 네이티브 연락처 목록이 뜬다.

ACTION_SEARCH; 검색, SearchManager.QUERY 키를 사용하는 인텐트의 엑스트라 문자열 형태.

ACTION_SENDTO: uri에 지정된 사람에게 보내는 액티비티.

ACTION_SEND: 지정된 데이터를 전송하는 액티비티 시작. 인텐트 타입은 setType을 사용해 전송되는 데이터의mime타입으로 설정

ACTION_VIEW: URI가 합리적으로 보여지게 요청. http: 는 브라우져, tel: 다이얼러, geo: 구글맵

ACTION_WEB_SEARCH: uri에 웹검색을 수행하는 액티비티를 연다

Intent intent = new Intent(Intent.ACTION_WEB_SEARCH );
intent.putExtra(SearchManager.QUERY, “검색어”);
startActivity(intent);

참조

http://www.itwizard.ro/how-to-create-a-new-android-activity-82.html

 

 

인텐트 필터를 이용한 암시적 인텐트 서비스

인텐트가 데이터 집합에 대해 수행되는 액션을 위한 요청으로 보면 인텐트 필터는 액티비티, 서비스, 브로드캐스트 수신자를 특정한 종류의 데이터에 대한 액션을 수행하는 존재로 등록하는데 사용.

  1.       <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
          </intent-filter>

        <activity android:name=".EarthquakeDamageViewer" android:label="View Damage">
          <intent-filter>
            <action android:name="com.paad.earthquake.intent.action.SHOW_DAMAGE"/>
            <category android:name="android.intent.category.DEFAULT"/>
            <category android:name="android.intent.category.ALTERNATIVE_SELECTED"/>
            <data android:mimeType="vnd.earthquake.cursor.item/*"/>
          </intent-filter>
        </activity>

  • action: 서비스 되는 액션의 이름. 액션은 유일한 문자열이어야 하므로 자바 패키지 이름 규약을 사용한다.
  • category: 액션이 서비스 되어야 하는 상황을 지정. 여러개의 category 가능.

    • 안드로이드 기본 cagegory

      • android.intent.category.ALTERNATIVE: 기본 액션에 대한 대안 액션임을 선언.
      • android.intent.category.SELECTED_ALTERNATIVE: 대안으로 선택 가능한 것들에 대한 선언.
      • android.intent.category.BROWSABLE: 브라우져 안에서 사용 가능한 액션 지정.
      • android.intent.category.DEFAULT : 데이터 값에 대한 기본 액션으로 지정.
      • android.intent.category.GARGET : 이 액티비티가 다른 액티비티 내부에 포함되어 동작 할 수 있도록 지정.
      • android.intent.category.HOME: 네이티브 홈 스크린의 대안.
      • android.intent.category.LAUNCHER: 애플리케이션 런처.
  • data: 실행 할 수 있는 데이터에 대한 명세. 여러개 지정 가능.

    • android:host: 유효한 호스트 이름
    • android:mimetype: 데이터 형식. 예) <data android:mimeType="vnd.moonbase.cursor.item/*"/> 는 ㅁ든 안드로이드 커서
    • android:path: URI에 대한 유효한 경로 값 예) /transport/boarts/
    • android:port 지정된 호스트에 대한 유효한 포트
    • android:scheme 특정한 스킴. 예) contnet, http
  •  

 

안드로이드가 인텐트 필터를 찾는 방법

인테트 URI 실행시 실행 할 수 있는 액티비티가 여러개 존재하면 그중 가장 좋은 것이 시작될 것이다. 이런 과정을 Intent resolution 이라 한다.

  1. 설치된 패키지로 부터 사용 가능한 모든 인텐트 필터들의 리스트를 구성
  2. action이나 cagegory에 맞지 않는 필터는 제외

    1. 필터가 지정된 액션을 포함하거나 아무런 액션도 지정되지 않은 경우 action matches 가 이루어 진다.
      정의된 action이 있지만 지정된 액션과 일치않으면 실패
    2. category matching: 인텐트 필터는 인텐트에 정의된 모든 category 를 반드시 포함해야 한다. catregory가 지정되지 않은 인텐트 필터는 category가 없는 인텐트하고만 일치된다.
  3. 인텐트에 있는 data uril 의 각 부분이, scheme, permissionk path, mime 등 정의하고 있다면, 인텐트 필터의 data 태그와 비교 된다.

    1. MIME: 와일드카드를 이용해 하위 타입을 일치할 수 있다.
    2. scheme: URI의 프로토코 부분. http, ftp...
    3. host name, URI에서 경로 사이에 있는 부분 www.google.com
    4. 경로
  4. 이 과정에서 하나 이상의 컴포넌트가 확인되면 인턴트 필터 노드에 추가될 수 있는 선택적 태그와 함께 우선순위에 따라 순서가 매겨진다. 그런다음 가장 높은 순위의 컴포넌트가 리턴된다.
웹뷰 키보드 위치조절
1.webview 밖에 scrollview 넣고
2.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);

'Android > Tip&Tech' 카테고리의 다른 글

[팁]HorizontalScrollView랑 scrollview 같이 사용하기  (0) 2011.11.30
Intent 개념 총정리  (2) 2011.11.30
SQL function(함수) 모음  (2) 2011.11.23
Custom Android Button Style and Theme  (1) 2011.11.23
Android PopupWindow 관련 팁  (0) 2011.11.23

The core functions shown below are available by default. Date & Time functions and aggregate functions are documented separately. An application may define additional functions written in C and added to the database engine using the sqlite3_create_function() API.

abs(X) The abs(X) function returns the absolute value of the numeric argument X. Abs(X) returns NULL if X is NULL. Abs(X) return 0.0 if X is a string or blob that cannot be converted to a numeric value. If X is the integer -9223372036854775807 then abs(X) throws an integer overflow error since there is no equivalent positive 64-bit two complement value.
changes() The changes() function returns the number of database rows that were changed or inserted or deleted by the most recently completed INSERT, DELETE, or UPDATE statement, exclusive of statements in lower-level triggers. The changes() SQL function is a wrapper around the sqlite3_changes() C/C++ function and hence follows the same rules for counting changes.
coalesce(X,Y,...) The coalesce() function returns a copy of its first non-NULL argument, or NULL if all arguments are NULL. Coalesce() must be at least 2 arguments.
glob(X,Y) The glob(X,Y) function is equivalent to the expression "Y GLOB X". Note that the X and Y arguments are reversed in the glob() function relative to the infix GLOB operator. If the sqlite3_create_function() interface is used to override the glob(X,Y) function with an alternative implementation then the GLOB operator will invoke the alternative implementation.
ifnull(X,Y) The ifnull() function returns a copy of its first non-NULL argument, or NULL if both arguments are NULL. Ifnull() must have exactly 2 arguments. The ifnull() function is equivalent to coalesce() with two arguments.
hex(X) The hex() function interprets its argument as a BLOB and returns a string which is the upper-case hexadecimal rendering of the content of that blob.
last_insert_rowid() The last_insert_rowid() function returns the ROWID of the last row insert from the database connection which invoked the function. The last_insert_rowid() SQL function is a wrapper around the sqlite3_last_insert_rowid() C/C++ interface function.
length(X) For a string value X, the length(X) function returns the number of characters (not bytes) in X prior to the first NUL character. Since SQLite strings do not normally contain NUL characters, the length(X) function will usually return the total number of characters in the string X. For a blob value X, length(X) returns the number of bytes in the blob. If X is NULL then length(X) is NULL. If X is numeric then length(X) returns the length of a string representation of X.
like(X,Y)

like(X,Y,Z)
The like() function is used to implement the "Y LIKE X [ESCAPE Z]" expression. If the optional ESCAPE clause is present, then the like() function is invoked with three arguments. Otherwise, it is invoked with two arguments only. Note that the X and Y parameters are reversed in the like() function relative to the infix LIKE operator. The sqlite3_create_function()interface can be used to override the like() function and thereby change the operation of the LIKE operator. When overriding the like() function, it may be important to override both the two and three argument versions of the like() function. Otherwise, different code may be called to implement the LIKE operator depending on whether or not an ESCAPE clause was specified.
load_extension(X)

load_extension(X,Y)
The load_extension(X,Y) function loads SQLite extensions out of the shared library file named X using the entry point Y. The result of load_extension() is always a NULL. If Y is omitted then the default entry point of sqlite3_extension_init is used. The load_extension() function raises an exception if the extension fails to load or initialize correctly.

The load_extension() function will fail if the extension attempts to modify or delete an SQL function or collating sequence. The extension can add new functions or collating sequences, but cannot modify or delete existing functions or collating sequences because those functions and/or collating sequences might be used elsewhere in the currently running SQL statement. To load an extension that changes or deletes functions or collating sequences, use the sqlite3_load_extension()C-language API.

lower(X) The lower(X) function returns a copy of string X with all ASCII characters converted to lower case. The default built-in lower() function works for ASCII characters only. To do case conversions on non-ASCII characters, load the ICU extension.
ltrim(X)

ltrim(X,Y)
The ltrim(X,Y) function returns a string formed by removing any and all characters that appear in Y from the left side of X. If the Y argument is omitted, ltrim(X) removes spaces from the left side of X.
max(X,Y,...) The multi-argument max() function returns the argument with the maximum value, or return NULL if any argument is NULL. The multi-argument max() function searches its arguments from left to right for an argument that defines a collating function and uses that collating function for all string comparisons. If none of the arguments to max() define a collating function, then the BINARY collating function is used. Note that max() is a simple function when it has 2 or more arguments but operates as an aggregate function if given only a single argument.
min(X,Y,...) The multi-argument min() function returns the argument with the minimum value. The multi-argument min() function searches its arguments from left to right for an argument that defines a collating function and uses that collating function for all string comparisons. If none of the arguments to min() define a collating function, then the BINARY collating function is used. Note that min() is a simple function when it has 2 or more arguments but operates as an aggregate function if given only a single argument.
nullif(X,Y) The nullif(X,Y) function returns its first argument if the arguments are different and NULL if the arguments are the same. The nullif(X,Y) function searches its arguments from left to right for an argument that defines a collating function and uses that collating function for all string comparisons. If neither argument to nullif() defines a collating function then the BINARY is used.
quote(X) The quote(X) function returns the text of an SQL literal which is the value of its argument suitable for inclusion into an SQL statement. Strings are surrounded by single-quotes with escapes on interior quotes as needed. BLOBs are encoded as hexadecimal literals. Strings with embedded NUL characters cannot be represented as string literals in SQL and hence the returned string literal is truncated prior to the first NUL.
random() The random() function returns a pseudo-random integer between -9223372036854775808 and +9223372036854775807.
randomblob(N) The randomblob(N) function return an N-byte blob containing pseudo-random bytes. If N is less than 1 then a 1-byte random blob is returned.

Hint: applications can generate globally unique identifiers using this function together with hex() and/or lower() like this:

hex(randomblob(16))

lower(hex(randomblob(16)))
replace(X,Y,Z) The replace(X,Y,Z) function returns a string formed by substituting string Z for every occurrence of string Y in string X. TheBINARY collating sequence is used for comparisons. If Y is an empty string then return X unchanged. If Z is not initially a string, it is cast to a UTF-8 string prior to processing.
round(X)

round(X,Y)
The round(X,Y) function returns a floating-point value X rounded to Y digits to the right of the decimal point. If the Y argument is omitted, it is assumed to be 0.
rtrim(X)

rtrim(X,Y)
The rtrim(X,Y) function returns a string formed by removing any and all characters that appear in Y from the right side of X. If the Y argument is omitted, rtrim(X) removes spaces from the right side of X.
soundex(X) The soundex(X) function returns a string that is the soundex encoding of the string X. The string "?000" is returned if the argument is NULL or contains no ASCII alphabetic characters. This function is omitted from SQLite by default. It is only available if the SQLITE_SOUNDEX compile-time option is used when SQLite is built.
sqlite_compileoption_get(N) The sqlite_compileoption_get() SQL function is a wrapper around the sqlite3_compileoption_get() C/C++ function. This routine returns the N-th compile-time option used to build SQLite or NULL if N is out of range. See also the compile_options pragma.
sqlite_compileoption_used(X) The sqlite_compileoption_used() SQL function is a wrapper around the sqlite3_compileoption_used() C/C++ function. When the argument X to sqlite_compileoption_used(X) is a string which is the name of a compile-time option, this routine returns true (1) or false (0) depending on whether or not that option was used during the build.
sqlite_source_id() The sqlite_source_id() function returns a string that identifies the specific version of the source code that was used to build the SQLite library. The string returned by sqlite_source_id() begins with the date and time that the source code was checked in and is follows by an SHA1 hash that uniquely identifies the source tree. This function is an SQL wrapper around the sqlite3_sourceid() C interface.
sqlite_version() The sqlite_version() function returns the version string for the SQLite library that is running. This function is an SQL wrapper around the sqlite3_libversion() C-interface.
substr(X,Y,Z)

substr(X,Y)
The substr(X,Y,Z) function returns a substring of input string X that begins with the Y-th character and which is Z characters long. If Z is omitted then substr(X,Y) returns all characters through the end of the string X beginning with the Y-th. The left-most character of X is number 1. If Y is negative then the first character of the substring is found by counting from the right rather than the left. If Z is negative then the abs(Z) characters preceding the Y-th character are returned. If X is a string then characters indices refer to actual UTF-8 characters. If X is a BLOB then the indices refer to bytes.
total_changes() The total_changes() function returns the number of row changes caused by INSERT, UPDATE or DELETE statements since the current database connection was opened. This function is a wrapper around the sqlite3_total_changes() C/C++ interface.
trim(X)

trim(X,Y)
The trim(X,Y) function returns a string formed by removing any and all characters that appear in Y from both ends of X. If the Y argument is omitted, trim(X) removes spaces from both ends of X.
typeof(X) The typeof(X) function returns a string that indicates the datatype of the expression X: "null", "integer", "real", "text", or "blob".
upper(X) The upper(X) function returns a copy of input string X in which all lower-case ASCII characters are converted to their upper-case equivalent.
zeroblob(N) The zeroblob(N) function returns a BLOB consisting of N bytes of 0x00. SQLite manages these zeroblobs very efficiently. Zeroblobs can be used to reserve space for a BLOB that is later written using incremental BLOB I/O. This SQL function is implemented using the sqlite3_result_zeroblob() routine from the C/C++ interface.

'Android > Tip&Tech' 카테고리의 다른 글

Intent 개념 총정리  (2) 2011.11.30
웹뷰 키보드 위치조절(webview)  (0) 2011.11.29
Custom Android Button Style and Theme  (1) 2011.11.23
Android PopupWindow 관련 팁  (0) 2011.11.23
[펌]Android Traceview War Story  (0) 2011.11.22

출처:http://blog.naver.com/PostView.nhn?blogId=ezmo01&logNo=110093890027&viewDate=&currentPage=1&listtype=0&userTopListOpen=false&userTopListCount=5&userTopListManageOpen=false&userTopListCurrentPage=undefined
Custom Android Button Style and Theme

In this tutorial, we’ll see how it’s possible to create a custom button style for an Android application by using the Android styling API. First of all we need to define the new look for our custom button style. We would use three different NinePatch drawables.

A custom black nine patch drawable background for enabled, not pressed buttons :

A custom orange nine patch drawable background for enabled, pressed buttons :

A custom red nine patch drawable background for disabled buttons :

All of these three custom drawable must be placed in the /res/drawables directory of our Android application. Now we must declare wich background should be used for each possible state of our custom button (pressed, disabled, focused, …). This is done by declaring a selector in a custom XML file :

2.2기준으로 아래 파일은  res/xml-hdpi/btn_custom.xml에 위치해야함.

<selector xmlns:android="http://schemas.android.com/apk/res/android">  <itemandroid:state_enabled="false" android:drawable="@drawable/btn_red" /> <itemandroid:state_pressed="true" android:state_enabled="true"android:drawable="@drawable/btn_orange" /> <item android:state_focused="true"android:state_enabled="true" android:drawable="@drawable/btn_orange" /> <itemandroid:state_enabled="true" android:drawable="@drawable/btn_black" /> </selector>

Each item in the selector associates a drawable to a button state. Items must be declared in a specific order. The android selector draws the first selector item that match the current button state, no matter if another matching item is defined in the selector declaration. For exemple, the selector bellow will never draw the orange background for a disabled and focused button as the first item always applies to disabled button :

여긴 필요없음

<item android:state_enabled="false" android:drawable="@drawable/btn_red" /> <itemandroid:state_pressed="true" android:state_enabled="false"android:drawable="@drawable/btn_orange" />

In order to draw orange background for disabled and focused buttons, and a red background for disabled buttons that are not focused we should have invert the items declaration order :
여기도 필요없음

<item android:state_pressed="true" android:state_enabled="false"android:drawable="@drawable/btn_orange" /> <item android:state_enabled="false"android:drawable="@drawable/btn_red" />

Let’s put our selector declaration in a file called btn_custom.xml in the /res/drawables directory of our Android application. Now, it’s time to define a custom button style that will apply to every buttons in the application. This can be achieve with both the /res/values/styles.xml file and the /res/values/themes.xml file. In the first one we’ll customize our button appearence (selector, text size, text color, shadow, …).

/res/values/styles.xml 에 위치함 중요한건 아래

name="android:background">@drawable/btn_custom</item> <item 을...

>                                          @xml/btn_custom 으로 바꿔야한다.. 2.2에서 좀 바뀐거 같음.

<resources> <style name="Button" parent="@android:style/Widget.Button"> <itemname="android:gravity">center_vertical|center_horizontal</item> <itemname="android:textColor">#FFFFFFFF</item> <itemname="android:shadowColor">#FF000000</item> <item name="android:shadowDx">0</item><item name="android:shadowDy">-1</item> <itemname="android:shadowRadius">0.2</item> <item name="android:textSize">16dip</item><item name="android:textStyle">bold</item> <itemname="android:background">@drawable/btn_custom</item> <itemname="android:focusable">true</item> <item name="android:clickable">true</item></style> </resources>

Then, we must set this style to be used by the Android button Widget. In the /res/values/themes.xml file :

/res/values/themes.xml   기본파일이 없는지 이해가 안되지만... 만들어주자..

<resources> <style name="CustomButton" parent="android:style/Theme.NoTitleBar"> <itemname="android:buttonStyle">@style/Button</item> </style> </resources>

The theme can be applied to the whole application by setting the android:theme attribute in the<application> tag of the AndroidManifest.xml file.

여긴 써있는데로 메니페스트에서 변경하고...

<application android:icon="@drawable/icon" android:label="Custom button"android:theme="@style/CustomButton">

Now, that’s what your buttons looks like :

You can browse the full source code of the Eclipse project here :
SampleCustomButton

'Android > Tip&Tech' 카테고리의 다른 글

웹뷰 키보드 위치조절(webview)  (0) 2011.11.29
SQL function(함수) 모음  (2) 2011.11.23
Android PopupWindow 관련 팁  (0) 2011.11.23
[펌]Android Traceview War Story  (0) 2011.11.22
android honeycomb 최적화하기  (0) 2011.11.21

출처 : http://blog.naver.com/PostView.nhn?blogId=ezmo01&logNo=110093886802

정말 이정도 되는예제 아니면 올리지 말았으면 좋겠다. 쓰레기같은 소스들때문에 허비한 시간이 아깝다.


First, create an XML layout, name it popup_layout.xml and in the res/layout/ folder:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/popup_menu_root"
    android:background="#FFFFFF"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
    <Button android:id="@+id/popup_menu_button1"
        android:text="close"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
    <Button android:id="@+id/popup_menu_button2"
        android:text="ok2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
    <Button android:id="@+id/popup_menu_button3"
        android:text="ok3"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

Here I have created a linear layout and put three buttons inside. So that the popup is visible I have made the background white.

Now to the code. You probably already have a class where you need to create a popup. You can declare it wherever you need. I needed to show the popup window after user clicks a button, so I made it class-level and declared in the beginning:

private PopupWindow pw;

Next in the appropriate onClickListener I create the PopupWindow and show it:

// get the instance of the LayoutInflater
LayoutInflater inflater = (LayoutInflater) PopupWindowClass.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// inflate our view from the corresponding XML file
View layout = inflater.inflate(R.layout.popup_menu, (ViewGroup)findViewById(R.id.popup_menu_root));
// create a 100px width and 200px height popup window
pw = new PopupWindow(layout, 100, 200, true);
// set actions to buttons we have in our popup
Button button1 = (Button)layout.findViewById(R.id.popup_menu_button1);
button1.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View vv) {
        // close the popup
        pw.dismiss();
    }
});
Button button2 = (Button)layout.findViewById(R.id.popup_menu_button2);
button2.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View vv) {
        Toast.makeText(PopupWindowClass.this, "Hello", Toast.LENGTH_LONG).show();
    }
});
Button button3 = (Button)layout.findViewById(R.id.popup_menu_button3);
button3.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View vv) {
        finish();
    }
});
// finally show the popup in the center of the window
pw.showAtLocation(layout, Gravity.CENTER, 0, 0);

출처 : http://blog.naver.com/PostView.nhn?blogId=huewu&logNo=110095622035&parentCategoryNo=18&viewDate=&currentPage=1&listtype=0
 

Android Traceview War Story


어플리케이션이 빠르게 동작하도록 만들기

 어플리케이션이 조금만 보잡해져도 여러분은 해당 어플리케이션의 어느 부분이 속도를 느리게 만드는지 예상할 수 없습니다. 왜냐하면 그 누구도 소프트웨어에서 병목 현상을 일으키는 부분이 어떤 곳이라고 콕 찝어낼만큼 똑똑할 수 없기 때문입니다. 최소한 저랑 제 주변에 있는 경험 많은 대부분의 개발자들은 그렇게 믿고있습니다.

 따라서 빠르게 동작하는 어플리케이션을 작성하기 위한 가장 현명한 방법은 어플리케이션을 최대한 단순하게 작성하는 것 입니다. 여러분이 N승 형태로 연산량이 증가되는 바보같은 알고리즘을 사용하거나 안드로이드 UI 상에서 I/O 작업을 수행하는 등의 명백한 실수만 하지 않는다면, 혹시 모르지요. 작성한 어플리케이션이 만족할 만큼 빠르게 작동할 수도 있습니다.

 하지만 만일, 작성한 어플리케이션이 충분히 빠르지 않다면, 왜 그럴까? 하고 추측하거나 고민하지 마세요. 대신, 프로파일러를 사용하여 해당 현상을 측정하고 원인을 분석할 수 있습니다. 예전같으면, System.err.println("Entered at" + System.currentTimeMillis()); 같은 구문을 사용해서 그런 작업을 수행하곤 했습니다. 하지만 다행히 안드로이드에서는 훌륭한 프로파일러를 지원하고 있기 때문에, 이렇게 지저분한 코드는 사용하지 않으셔도 좋습니다.


사례 연구: LifeSaver 2

 저는 얼마전에 안드로이드 마켓에 LifeSaver 2 라고 하는 간단한 유틸리티 어플리케이션을 배포하였습니다. 이 어플에 관한 자세한 내용은 개인 블로그  의 포스트를 참고해 주세요. 이 어플은 안드로이드 폰의 SMS 와 전화 콜 로그를 추출하여 이를 JSON 텍스트 파일 형식으로 SD 카드에 저장해 두는 기능을 갖고 있습니다. 이 작업에 어느정도 시간이 걸리는 작업이기 때문에 멋드러진 프로그레스 바를 표시하도록 하였습니다. 그런데 엄청나게 빠른 기가헤르츠 단위의 프로세서를 갖춘 휴대폰에서, 고작해야 몇백줄의 리코드를 텍스트 파일로 디바이스에 저장하는데 왜 긴 시간이 걸리는지 의문이 들더군요.

 구지 제 충고를 무시하는 분들은 이러한 성능 저하가 ContentProvider 의 Cursor 가 시스템 로그를 읽는 시간때문이라던가, 그게 아니면 SD 카드에 내용을 쓰는데 발생하는 오버헤드라고 지례 짐작 하실 수도 있습니다. 대신에, 우리 스마트한 사람들은 프로파일러를 이용하여 코드를 계측하고 원인을 파악해 냅니다. 한번 해 봅시다.


Trace 시작하기

Saver.java 파일을 열어 run() 메서드 내의 코드를 아래와 같이 묶어 줍니다.

       public void run() {

            android
.os.Debug.startMethodTracing("lsd");

           
// ... method body elided

            android
.os.Debug.stopMethodTracing();
       
}

 첫 번째 문장은 Trace 기능을 작동 시키며, 인자로 사용된 "lsd" (Life Saver Debug 의 약자입니다.) 는 "/sdcard/lsd.trace" 경로에 Trace 로그 정보를 저장하라는 뜻입니다. 주의할 점 한가지. SD 카드에 로그 파일을 저장함으로 WRITE_EXTERNAL_STORAGE 권한을 설정해 두어야 합니다. 실제로 어플리케이션을 릴리즈 할 때는 물론 이 권한 항목을 제거해 두어야 겠지요. 

[업데이트] 안드로이드 개발자 Xavier Ducrohet 는 저에게 "DDMS" 의 "Device View" 에 프로파일을 시작/정지 시킬 수 있는 버튼이 있다는 것을 알려주었습니다. '정지' 버튼을 누르면 생성된 Trace 로그 파일을 기반으로 TraceView 가 실행됩니다. 이 방법이 여러분의 코드에 start/stopMethodTracing 을 직접 넣는 것 처럼 정교한 측정 작업을 사용하는데는 부족함이 있지만, 알아두면 굉장히 유용한 팁이 될 것입니다. 또한, 프로파일링 작업을 위하여 프로요 이전 버전에서는 WRITE_EXTERNAL_STORAGE 권한이 반드시 필요하지만 그 이 후 버전에는 VM 이 Trace 파일을 JDWP 커넥션을 이용하여 SD 카드에 Trace 파일을 전달함으로 권한을 설정할 필요가 없다고 합니다.(와우! 고마워요 Xav!)

그럼 여러분의 어플리케이션을 실행 한 후, Trace 로그 파일을 컴퓨터로 옮겨 TraceView 를 실행 시켜 봅시다.

540> adb pull /sdcard/lsd.trace
541> traceview lsd

 이 시점에서, 여러분은 세 가지를 확인할 수 있습니다. 첫째로, Trace 기능을 실행하면 어플리케이션 실행 속도가 굉장히 느려집니다. 두 번째, Trace 로그 파일은 굉장히 큽니다. 약 4초 정도 돌렸더니 8.6MB 가 되는 군요. 마지막으로 TraceView 는 꽤나 멋지게 생겼습니다.

<그림을 클릭하시면 확대됩니다.> 


 최상단의 바는 어플리케이션에 동작하고 있는 스레드와 각각이 어느 정도의 시간을 소비하고 있는지 알려줍니다. 넥서스 원은 단일 스레드 CPU 이기 때문에 각각의 스레드는 서로 돌아가며 동작합니다. 

<그림을 클릭하시면 확대됩니다.> 


 첫번째 스레드는 우리가 작성한 어플리케이션 코드가 동작하고 있는 부분이고 (붉은 부분은 GC 가 일어난 부분입니다.) 가운데 줄은 UI 스레드가 동작하고 있는 내용이며 프로그레스 바가 업데이트 될 때마다 일정 작업을 수행하고 있습니다. 그리고 마지막 세 번째 HeapWorker 는 정확히 무슨일을 하는지 저는 잘 모르겠습니다만, (주> GC 가 일어날 때, 해당 객체들이 사라지기 전에 Finalize 작업을 수행해주는 스레드입니다. 다음 포스트를 참고해 주세요.) 성능상에 별다른 영향을 주는 거 같지 않군요. 무시하도록 하겠습니다.

 화면 아래쪽에 표시된 내용들은 좀 더 흥미로운 정보를 담고 있습니다.어떤 메서드가 얼마나 많은 시간을 소비하는지 표시해 주며, 여러가지 다양한 방식으로 정렬할 수 있습니다. 처음 두 줄을 한번 살펴봅시다.

<그림을 클릭하시면 확대됩니다.> 


 처음 두 줄은 다음과 같은 의미를 갖습니다. 최상위 루틴에서 일어나는 모든 일을 다 합칠 경우 100% 의 시간을 소비합니다. (뭐, 당연하지요.) 하지만, 루틴 내부적으로 호출되는 메서드를 제외하고, 자기 자신만 따져보면 오직 0.9% 의 시간만을 소비합니다. 다음 라인에는 정말로 재미있는 정보가 담겨있습니다. java.io.PrintStream.printIn(Object) 메서드와 이 메서드가 포함하는 다른 메서드들을 합치면 65.2% 의 시간이 소비됩니다. 이 메서드가 JSON 객체를 SD 카드에 사용됩니다. 따라서 우리는 휴대폰의 ContentProvider 에서 데이터를 꺼내는 부분은 별다른 문제가 되지 않으며, 그 결과를 출력하는 부분이 바로 문제의 원인임을 알 수 있습니다.

 하지만 우리가 이 문제가 바로 SD 카드의 읽기 성능 때문에 발생하는 문제라고 결론 내릴 수 있을까요? 좀 더 상세하게 살펴봅시다. 해당 라인을 클릭하면 보다 자세한 내용이 나타납니다.

<그림을 클릭하시면 확대됩니다.> 



 이런, 놀랍군요. println 메서드는 내부적으로 전달 받은 인자를 String 으로 변환하기 위해 toString() 메서드를 호출 하게 되는데, 이 과정에서 약 50% 정도의 시간이, 그리고 실재로 정보를 출력하기 위한 println(String) 메서드에서 나머지 50% 정도의 시간이 소비됩니다. println(String) 메서드는 더 자세히 살펴볼 필요가 없을거 같네요. SD 카드에 데이터를 쓰기 위해 어느 정도의 시간이 소비 되는 것은 틀림없어 보입니다. 하지만 String.valueOf() 가 호출 될 때는 무슨일이 벌어지는 것 일까요?

<그림을 클릭하시면 확대됩니다.> 


 드디어 진실이 밝혀졌습니다. org.json.JSONObject.toString() 이 문제의 원인이였군요. 그런데 이 메서드는 우리 전문 프로그래머들이, 어... 이 함수는 내가 작성한 것이 아니라, 사용하고 있는 라이브러리에서 제공해주는 메서드이기 때문에 왠만하면 건들고 싶지 않아... 라고 이야기하는 종류의 메서드입니다. (주> 번역이 어렵네요. 원문은 what we professional programmers call a, well, this is a family-friendly operation so I won’t go there. 인데, 뭐라고 해석하면 좋을까요?) 여러분은 이 메서드의 내부를 좀 더 살펴볼 수는 있겠지만 별다른 소득을 얻을 수는 없을 것 입니다.

 대신에 여러분은 각각의 루틴들이 독점적으로 사용하는 시간을 기준으로 프로파일링 결과를 재정렬 해볼 수 있습니다. 아래의 목록은 1% 이상의 CPU 시간을 소비한 루틴들의 목록입니다.


<그림을 클릭하시면 확대됩니다.> 


 GC 관련 작업이나, 안드로이드 프레임워크에서 View 를 그리는 작업과 관련된 것들이 몇몇 눈에 띄기는 하지만, 무엇보다도 org.jason 과 java.lang.StringBuilder 코드 부분에서 가장 큰 시간이 소요됨을 확인 할 수 있습니다.

결론

 이번에 수행한 어플리케이션 프로파일에 관련된 진짜 결론은, 사실 성능 문제에 관하여 별다른 신경을 쓸 필요가 없다는 점 입니다. (뭥미-_-). 위에서 테스트한 루틴은 실재 어플리케이션 상에서 오직 두 번 (옛날 휴대폰에서 한 번, 새로운 휴대폰에서 한 번)만 수행되며, 성능상의 문제는 별로 발생하지 않지요.

 하지만, 만일 제가 위 구문의 성능을 개선시키고자 한다면 어떤 방법을 활용할 수 있을까요? 첫째, JSON 을 사용하지 않거나 JSON 객체를 좀 더 효율적으로 시리얼라이즈 할 수 있는 방법을 찾을 것입니다. 두번째로, println() 메서드의 사용을 최소화 하여 출력하고자 하는 데이타를 하나의 큰 버퍼에 꾸역 꾸역 밀어 넣은 후에, 단 한 번의 I/O 호출로 단번에 SD 카드에 기록하도록 코드를 수정하겠지요.

 여기서 중요한 점은, 만일 제가 이 루틴에서 발생하는 병목현상이 어디서 일어나는지 추측하고자 했다면 아마도 저는 결코 그 원인을 올바르게 짚어내지 못했을 것이라는 점입니다. Traceview 는 훌륭한 툴입니다. 그리고 만일 여러분이 Traceview 에 대해 잘 모르고 있었다면, 꼭 한 번 사용해 보시기 바랍니다.

출처 : http://blog.naver.com/PostView.nhn?blogId=huewu&logNo=110119643374&parentCategoryNo=18&viewDate=&currentPage=1&listtype=0
Optimizing Apps for Android 3.0

원문: http://developer.android.com/guide/practices/optimizing-for-3.0.html


 간만에 Dev Guide 문서를 번역해 보았습니다. 와... 내용이 길군요. 본 문을 두 개의 포스트로 나누고, 중복된 부분과 그다지 필요없다고 여겨지는 부분은 임의로 건너 띈 만큼, 원문을 참고하시면 좋겠네요.


 안드로이드 3.0 허니콤은 어플리케이션 사용자 경험을 향상 시킬 수 있는, 여러가지 새로운 기능을 제공합니다. 물론, 안드로이드는 상위 호환성을 갖기 때문에, 기존에 작성된 어플리케이션이 허니콤 타블렛에서 동작하지 않는 것은 아닙니다. 하지만, 아무래도 훨씬 커다란 화면을 갖고 있는 타블렛 디바이스 상에서 기존 휴대폰과 비슷한 UX 를 갖은 어플리케이션이 근사하다고 할 수는 없겠지요. 여러분의 어플리케이션이 이 새로운 디바이스 위에서 멋진 동시에 잘 동작하게 하고자 한다면 약간의 주의가 필요합니다.


 이 문서는 어떤 방식으로 기존 어플리케이션을 이전 버전과 호환성을 유지한 채 안드로이드 3.0 기반으로 최적화 할 수 있을 지, 혹은 새로운 API 를 기반으로 완전히 업그레이드 된 어플리케이션을 작성할 수 있는지에 관하여 설명합니다.


안드로이드 3.0 SDK 설치하기

 안드로이드 허니콤 어플리케이션을 개발하고 테스트하기 위해서는 관련 SDK 를 설치 하셔야 합니다. 안드로이드 SDK & AVD 매니저를 통해 아래의 패키지를 설치하세요.

  • SDK Platform Android 3.0
  • Android SDK Tools, revision 10
  • Android SDK Platform-tools, revision 3
  • Documentation for Android SDK, API 11
  • Samples for SDK API 11

허니콤 AVD(Android Virtual Device) 생성하기

 안드로이드 3.0 이상 버전을 타겟으로 설정하고, WXGA 스킨을 선택한니다. (기본 설정입니다.) 안드로이드 3.0 기반에서 어플리케이션을 테스트 하는 최선의 방법은 바로 모토로라 Xoom 과 같은 실재 디바이스를 사용하는 것 입니다. 디바이스가 없는 경우에는 AVD 를 사용해야 합니다.하지만, 안드로이드 에뮬레이터는 ARM 인스트럭션 셋을 시뮬레이팅 해야하고, WXGA 스크린은 일반 AVD 에 비하여 훨씬 크기때문에, 에뮬레이터의 성능은 기대하지 않는 편이 좋습니다. 최초 구동하는데는 굉장히 오랜 시간이 걸리고, 부팅되는 동안 별다른 사용자 피드백도 주어지지 않습니다. 인내심이 필요합니다. 안드로이드 개발 팀은 에뮬레이터의 성능 문제를 해결하기 위하여 열심히 노력하고 있으며, 앞으로 새롭게 릴리즈될 에뮬레이터는 훨씬 좋아질 것 입니다.

TIP: 에뮬레이터 스타트업 시간을 향상 시키기 위하여, 여러분이 생성한 AVD 의 스냅샷 기능을 활용할 수 있습니다. AVD 생성시 'Enable Snapshots' 체크 박스에 체크하고, AVD 을 시작할 때, 'Launch from Snapshot' 과 'Save to Snapshot ' 박스에 체크하시면 됩니다. 이렇게 되면, 에뮬레이터 종료 시 스냅샷 저장을 위한 시간이 소요되지만, AVD 의 상태 정보가 스냅샷으로 저장됩니다. (따라서, 초기 상태의 에뮬레이터 스냅샷을 작성 한 후에는 Save to Snapshot 박스를 체크하지 않는 편이 좋습니다.) 이 후, 에뮬레이터를 시작할 때는 해당 스냅샷이 바로 시작됨으로 부팅 시간이 단축 됩니다.

어플리케이션을 타블렛 용으로 최적화 하기

 만일 여러분이 이전 안드로이드 버전 대응 어플리케이션을 개발했다면, 어플리케이션 호환성을 유지하는 가운데(android:minSdkVersion 을 수정하지 않고) 수정할 수 있는 요소들이 그리 많지 않습니다.


 안드로이드 3.0 최적화를 위하여 다음과 같은 일들을 시도해 볼 수 있습니다.


1. 기존 어플리케이션을 안드로이드 3.0  에서 테스트 합니다.

 기존과 동일한 방식(기존 안드로이드 라이브러리를 활용하여)으로 어플리케이션을 빌드하고, 안드로이드 3.0 AVD 상에서 어플리케이션을 실행해 봅니다. 일반적인 테스트를 수행하고, 어플리케이션이 정상적으로 동작하는지, UI 는 이상하지 않은지 확인하시기 바랍니다.


2. 새로운 "holographic" 테마를 적용합니다.

 메니페스트 파일을 열어서, 아래와 같이 android:targetSdkVersion 값을 '11' 로 설정합니다.

<manifest ... >
   
<uses-sdk android:minSdkVersion="4"
             
android:targetSdkVersion="11" />
   
<application ... >
        ...
   
<application>
</manifest>

 안드로이드 3.0 플랫폼(API Level 11 이상)을 타겟으로 선언 하면, 해당 어플리케이션이 허니콤에서 동작 할 때, 시스템이 자동적으로 'holographic' 테마를 적용해 줍니다. holographic 테마는 허니콤에 어울리는 새롭게 디자인된 위젯들 - 'Button, EditText 등등' 을 제공합니다. 이는 안드로이드 허니콤 어플리케이션에서 기본적으로 사용하는 테마이며, 따라서 여러분의 어플리케이션이 다른 허니콤 어플리케이션과 일관된 Look&Feel 을 갖도록 도와줍니다.



 또한, 엑티비티에 holographic 테마가 적용되면, Option Menu 를 대신하여 새롭게 추가된 Action Bar 를 사용할 수 있습니다. Action Bar 는 기존 타이틀 바를 대체하는데, 사용자가 바로 Option Menu 를 사용 할 수 있도록 해 줍니다. (Action Bar 오른편에 Drop Down 메뉴로 Option 항목이 표시됩니다.)


 어플리케이션을 이전처럼 빌드 한 후, 안드로이드 3.0 AVD 에 인스톨 합니다. 여러분의 어플리케이션 인터페이스가 holographic 테마에 기반하여 잘 동작하는 지 반복 테스트를 수행합니다.

NOTE: 만일 엑티비티에 이미 적용된 테마가 있는 경우, 해당 테마는 기존 안드로이드 스타일 테마가 아니라, holographic 테마를 오버라이드 하게 됩니다. 이 문제를 해결하기 위해서는 플랫폼 버전 구별자를 사용하여, 안드로이드 3.0 플랫폼을 위해서는 holographic 테마에 기반한 다른 테마를 사용하도록 구현할 수 있습니다. 보다 자세한 정보는 다음 문서를 살표보세요.

xlarge 스크린을 위한 별도의 레이아웃 제공하기

'extra lagre' 스크린을 위한 별도의 레이아웃을 제공하면, 호환성을 저해할 수 있는 새로운 API 를 사용하지 않고도. 타블렛 상에서 어플리케이션 사용자 경험을 향상 시킬 수 있습니다. 이를 위해, 'extra lagre' 스크린을 위한 새로운 레이아웃을 생성하고자 한다면, 다음과 같은 점을 고려해볼만 합니다.

  • Landscape Layout (가로 모드 레이아웃): 블렛 스타일의 디바이스는 일반적으로 가로 모드로 사용됩니다. 따라서, 넑찍한 화면에 어울리는 엑티비티 레이아웃을 제공할 필요가 있습니다. 가로 모드를 나타내는 "land" 구분자와 큰 스크린 사이즈를 나타내는 "xlarge" 구분자를 동시에 활용하여, 타블렛 크기의 디바이스를 위한 별도의 레이아웃 셋을 구성할 수 있습니다. res/layout-xlarge-land/) 이때 구분자의 순서를 꼭 지키셔야 합니다. 리소스 구분자에 관한 보다 상세한 문서를 참조하시면 좋습니다.
  • 버튼의 위치와 크기: 버튼은 사용자가 타블렛을 두 손으로 쥐었을 때 사용하기 편리한 곳에 있어야 합니다. 또한, 버튼 크기가 너무 적은 경우 이를 재조정 할 필요도 있습니다. 특히나 "wrap_content" 속성을 사용한 경우 그런 일이 발생합니다. 버튼 크기를 키우기 위해서는 추가적인 패딩 값을 삽입하거나, dp 단위로 구체적인 값을 선언허거나, android:layout_weight 속성을 사용할 수 있습니다. 각각의 스크린 사이즈에 대하여 어떤 방식을 활용하는 편이 최선인지 적절한 판단이 필요합니다. 버튼은 너무 작아도, 너무 커도 곤란합니다.
  • 폰트 크기: 어플리케이션 폰트 크기를 지정할 때는 항상 sp 단위를 사용해야 합니다. sp 단위를 사용해야만, 폰트 크기가 너무 작아져서 글씨을 읽을 수 없는 불상사를 방지할 수 있습니다. sp 단위는 화면 크기에 독립적인 픽셀 단위로 현재 화면 크기에 따라 적절하게 그 값이 변경되기 때문에 그렇습니다. 그럼에도, 특별한 경우에는 'xlarge' 스크린을 위해서는 폰트의 크기를 조금 더 키워야 할 경우가 있을 수도 있습니다.

 이 외에 기본적으로  항상 'Best Practices for Screen Independence' 문서에 설명된 내용을 기억하시기 바랍니다.


타블렛 용으로 어플리케이션 업그레이드 하기

NOTE: 기존 SDK 와 호환성을 유지하면서도 새롭게 추가된 API를 사용할 수 있는 방법이 있습니다. 일반적으로는자바의 Reflection 패키지를 이용하여, 특정 API 가 실재로 존재하는 동적으로 확인하는 방법을 활용하실 수 있습니다. 또는, 안드로이드 팀에서 제공하는Compatibility Library (호환성 라이브러리 / 서포트 라이브러리라고 불립니다.) 를 사용하시면, 새롭게 추가된 몇몇 API 들(Fragment , Loader 등) 프로요 이후 타겟의 어플리케이션에서도 사용하실 수 있습니다. (호환성 라이브러리는 AVD and SDK Manager 를 통해 다운받으실 수 있습니다.)

 만일 여러분이 안드로이드 허니콤의 기능을 최대로 활용하는 어플리케이션을 작성하고자 한다면,  허니콤을 새롭게 추가된 API 를 활용할 필요가 있습니다. (이렇게 되면 하위 호환성이 보장되지 않겠지만요...) 여러분이 기억해야 할 유용한 기능들을 몇 가지 소개해 보겠습니다.


최소 시스템 버전 선언하기

 우선, 어플리케이션 코드를 수정하기전에 메니페스트에 <uses-sdk> 요소를 추가하여,  android:targetSdkVersion 값을 11 로 선언해야 합니다. 이 어플리케이션이 안드로이드 허니콤 API 를 사용하고 있다는 것을 명시하여, 이전 버전의 안드로이드 디바이스로는 배포되지 않도록 보장해줍니다. 

<manifest ... >
   
<uses-sdk android:minSdkVersion="11" />
   
<application ... >
        ...
   
<application>
</manifest>

 앞서 이야기한대로, 타겟 SDK 버전이 변경되게 되면, 여러분이 어플리케이션 테마를 명시적으로 선언하지 않아도 자동적으로 새로운 Holo 테마가 적용됩니다. 다시 한번 말씀드리면 Holo 테마는 안드로이드 허니콤을 위한 표준 테마로, 모든 어플리케이션은 이 테마를 사용합니다. 또한 Holo 테마가 적용되면, 동시에 Action Bar 기능도 활성화 됩니다.


Action Bar 사용하기

 Action Bar 는 기존 엑티비티 타이틀 바를 대체하는 위젯으로, 화면 최상단에 위치합니다. 기본적으로 어플리케이션 로고와 엑티비티 제목을 표시하며, 오른편에 drop-down 형태로 옵션 메뉴를 표시해 줍니다. 


 만일, 특정 메뉴 아이템 리소스에 showAsAction="ifRoom" 속성 값을 선언하거나, 코드 상으로 해당 값을 선언하시면, drop-down 형식 대신, 해당 메뉴 아이템이 바로 Action Bar 에 표시됩니다. (위의 그림에서는 두 개의 메뉴 아이템이 바로  표시되어 있습니다.)  또한, Action Bar 내에 어플리케이션 네이게이션 기능을 추가할 수 있으며, 이를 통해 사용자가 바로 홈 엑티비티 화면혹은 상위의 엑티비티로 이동할 수 있는 기능을 추가할 수도 있습니다. 추가적인 정보에 관해서는 Using Action Bar 문서를 읽어 보시기 바랍니다.


엑티비티를 Fragment 로 분할하기

 Fragment 는 엑티비티 내의 특정 행위나 사용자 인터페이스의 일부분을 나타냅니다. 다시 말해, 엑티비티 내의 한 부분을 구성하는 모듈이라고 생각할 수 있습니다. 이 Fragment 는 고유한 라이프 사이클을 갖고, 독자적으로 Input 이벤트를 받으며, 엑티비티 동작중에 동적으로 추가되거나 삭제될 수 있습니다. Fragment 는 멀티 패널 UI 를 구성하거나, 여러 엑티비티에서 공통적으로 사용되는 부분을 재활용 할 수 있도록 도와주는 좋은 방법입니다. 안드로이드 개발팀은 개발자분들이 엑티비티를 만들 때 Fragment 를 사용할 것을 적극 권장하고 있습니다. 여러분은 보다 동적이고 유연한 사용자 인터페이스를 구성할 수 있을 것 입니다.


 예를 들어, 뉴스 어플리케이션을 작성한다고 생각해 보겠습니다. 하나의 Fragment 는 기사 목록을 보여주고, 다른 하나의 Fragment 는 특정 기사의 본문 내용을 표시합니다. 메인 엑티비티는 두 개의 Fragment 로 이루어져 있으며, 왼편에는 기사의 목록을 보여주고, 오른편에는 선택한 기사의 본문 내용을 표시합니다. 두 개의 Fragment 는 자연스럽게 한 엑티비티에 동시에 표시 될 수 있으며, 각각 독립적인 라이프 사이클과 이벤트 처리 루틴을 갖을 수 있기 때문에, 개발자 분들은 손 쉽게 이런 어플리케이션을 구성할 수 있습니다. 또한, 보다 화면 크기가 작은 디바이스를 위한 레이아웃을 구성하고자 한다면, 필요한 경우에는 각각의 Fragment 를 개별적인 Activity 로 분리할 수 있습니다. 보다 상세한 정보가 필요하면 Fragment  문서를 살펴보시기 바랍니다.


새로운 애니매이션 API 를 사용하기

 완전히 새롭게 변경된 애니메이션 프레임워크를 활용하면, 여러분은 특정 오브젝트(View, Drawable, Fragment, 기타 등등) 속성 값을 손 쉽게 변화시킬 수 있습니다. 기본적으로, 오브젝트의 특정 int , float, color 속성 값에 대하여, 이 값을 시간에 따라 변화 시키기 위한 애니매이션에 설정 값을(기간, 반복 여부, 인터폴네이션 등등)  정의할 수 있습니다. 그러면, 그 값이 어떤 값이던지 간에 지정된 애니매이션에 의해 시간이 지남에 따라 해당 값이 변경 됩니다.


 View 클래스 또한 새로운 애니매이션 프레임워크를 조절할 수 있는 API 를 제공합니다. 개발자들은 엑티비티 내부의 View 대하여 손쉽게 2D / 3D 변환 애니매이션을 적용할 수 있습니다. 이러한 변환 애니매이션은 View 의 레이아웃 위치, 오리엔테이션, 투명도 등등의 값을 제어할 수 있습니다. 보다 상세한 정보는 Property Animation 문서를 참고하시기 바랍니다.


하드웨어 가속기능 사용하기

 안드로이드 3.0 은 하드웨어 가속 OpenGL 랜더러 기능을 제공하며, 2D 그래픽 성능이 크게 향상될 수 있습니다. 메니페스트의 내의 <application> 혹은 개별 <activity> 들에 대하여, android:hardwareAccelerated="true" 속성 값을 사용하면, 하드웨어 가속 기능이 활성화 됩니다. 이렇게 되면, 애니매이션 및 스크롤이 보다 부드러워지고, 전체적인 어플리케이션 반응 속도가 향상 될 수 있습니다. 단, 이 기능을 사용하실 때는, 실재 하드웨어 가속 기능을 지원하는 디바이스 상에서 여러분의 어플리케이션이 어떤식으로 동작하는지 철저히 테스트 해 보시기 바랍니다. (주>하드웨어 특성에 따라 다양한 차이가 발생할 수 있을 듯 하네요.)


App Widget 개선하기

 사용자는 App Widget 을 통해 어플리케이션 정보를 홈 스크린에서 바로 접근 하고, 앱과 상호 작용 할 수 있습니다. 안드로이드 3.0 에서는 App Widget 의 기능이 보다 향상되었는데, 기존에는 지원하지 않던 ListView 와 GridView 를 지원하며, 새로운 StackView 를 지원합니다. 이 위젯을 이용하여, 개발자 분들은 스크롤이 가능한 리스트 라던가,  RemoteViewsService 를 통해 자동으로 데이타가 업데이트 되는 보다 인터렉티브한 app widget 을 작성할 수 있습니다.


 또한, 사용자들이 App Widget 을 추가하고자 할 때, 해당 App Widget 이 어떻게 생겼는지 미리 확인 할 수 있도록 프리뷰 이미지를 제공해 주는 기능이 추가되었습니다. 이 기능을 위해 개발자 분들은 여러분이 작성한 App Widget 에 대한 프리뷰 이미지를 생성해야 합니다. 안드로이드 3.0 AVD 에 기본 탑재되어있는 Widget Preview 어플리케이션을 활용하시면 간편하게 프리뷰 이미지를 생성할 수 있으며, 생성한 이미지를 android:previewImage 속성으로 리퍼런스 하시면 됩니다. 


그 외 기능들 활용하기

 안드로이드 3.0 은 이 외에도 다양한 API 를 제공합니다. 예를 들어 Drag&Drap API, 새로운 Bluetooth API, 클립보드 프레임워크, Renderscript 라 불리는 새로운 그래픽 엔진등이 있습니다. 이런 API 들 중에 여러분의 어플리케이션에 유용한 API 가 있는지 잘 살펴볼 필요가 있습니다. 각각의 API 가 어떤 기능을 수행하는지 보다 자세히 알고 싶으시다면, Android 3.0 Platform 문서를 참고하시기 바랍니다.


샘플 예제 활용하기

 허니콤에서 새롭게 추가된 기능들에 대한 샘플 어플리케이션이 제공되고 있습니다. AVD 매니저를 이용하여 "Samples for SDK API 11" 패키지를 설치하시면 <sdk_root>/samples/android-11/ 폴더에 저장됩니다. 다음의 개발자 사이트에 올라와 있는 샘플들에대한 소스 코드 링크입니다.

  • Honeycomb Gallery: Fragment, Action Bar, Drag&Drop, Animation 과 같은 다양한 안드로이드 3.0 API 사용법을 보여줍니다.
  • Fragments: Fragment 레이아웃, Back Stack, 상태 값 저장하기 등등 Fragment 관련된 다양한 예제가 준비되어 있습니다.
  • Action Bar: Tab, Logo, Action Item 같은 다양한 Action Bar 기능을 활용하는 예제가 포함되어 있습니다.
  • Clipboard: 잘라내기&복사하기 기능을 위해 Clipboard 를 활용한 예제입니다.
  • Drag and Drop: 새로운 View 이벤트를 통해 Drag&Drop 를 수행하는 예제입니다.
  • Multi-choice List: ListView 와 GridView 를 사용하여 여러 아이템을 선택하는 예제 입니다. 
  • Content Loaders: 비동기적으로 데이터를 로드할 수 있는 새로운 Loader API 를 활용한 예제 입니다.
  • Property Animation: 오브젝트의 속성 값을 조절하는 새로운 애니메이션 API 를 활용한 몇몇 샘플이 제공됩니다. 
  • Search View Widget: Action Bar 안에 새로운 Search Widget 를 활용한 예제입니다.
  • Renderscript: 계산과 3D 그래픽을 위하여 Renderscript API 를 활용한 몇가지 어플리케이션을 포함하고 있습니다
잘안쓰지만 언젠가는 사용할일이 있겠지 싶은 물건.
주의할점이라고 하면 RadioGroup , RadioButton은 직계 부모 자식 간이어야 합니다.
	<RadioGroup android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/sex"
android:orientation="horizontal">
<RadioButton android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/male"
android:text="@string/male"></RadioButton>
<RadioButton android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/female"
android:text="@string/female"></RadioButton>
</RadioGroup>
먼저 그룹값을 가져온뒤
	RadioGroup sexGroup = (RadioGroup) findViewById(R.id.sex);
그중에 선택퇸 라디오버튼을 다시한번 가져와서
	RadioButton sex = (RadioButton) findViewById(sexGroup.getCheckedRadioButtonId());
그것의 라벨내용을 사용합니다.
	sex.getText().toString();

'Android > Tip&Tech' 카테고리의 다른 글

[펌]Android Traceview War Story  (0) 2011.11.22
android honeycomb 최적화하기  (0) 2011.11.21
[펌]Android Serial(COM)Port 사용 하기  (0) 2011.11.15
커스텀 레이아웃과 R.sttyleable  (0) 2011.11.09
Android tip######  (0) 2011.11.09
출처 : http://blog.naver.com/david_shkim?Redirect=Log&logNo=50112464359

2011/05/30 04:42

복사 http://blog.naver.com/david_shkim/50112464359

Android Serial(COM)Port 사용 하기 ---- [easop에서 가져왔습니다.]


1) Serial Program 받기
        http://code.google.com/p/android-serialport-api/
         Serial Port 관련 정보을 얻을 수 있습니다.
         JNI로 개발 형태로 되어 있습니다.


         Source는 http://android-serialport-api.googlecode.com/svn/trunk/android-serialport-api/
         에서 하나씩 Download 했습니다 . 한번에 받는게 어찌 하는건지 원 ㅠㅠ)

 

2) Cygwin을 통해 포함된 "SerialPort.c"를 컴파일
        Cygwin  ( http://www.cygwin.com/ )
        Android NDK  (http://developer.android.com/sdk/ndk/index.html)

 

        NDK를 받으시면 최신 "android-ndk-r5b"를 받게 되실껍니다.(android-ndk-r5b-windows.zip)
         이전 버전과 컴파일 방식이 약간 다르더군요.
         해당 Project에 jni 폴더에서 "ndk-build -B"를 실행 해야 합니다.
         (ex:"/home/AnNDK/android-ndk-r5/ndk-build -B")
         
3) Eclipse로 앱 컴파일 및 실행
         다운로드 받은 Serial Program을 Eclipse에 로딩(Import)
        Android 시뮬래이터로 연결(혹은 보드로 바로 연결)
        (보드로 바로 연결시에는 adb Driver가 모두 깔릴 상태에서는 자동으로 잡힙니다)


여기까지는 일반적인 JNI 개발및 설정을 하는것입니다.
        (저처럼 처음 하시는 분들은 여러 문서들이 잘 올라와 있으니 잘 찾아보세요.)
        (설정할것도 많고 찾아 봐야 할것도 많고....ㅠㅠ)

        샘플 프로그램도 포함되어있으니 Test도 해보시고 하면 될껍니다.


Program 준비가 완료되었고 실행만 하면 됩니다.

1) 권한 Error
         "You do not have read/write permission to the serial port"

2) 권한 해결-1

         system/cor/init/devices.c에서 
         다음과 같이 추가 하여 권한변경하였습니다.

         { "/dev/s3c2410_serial0",       0777,   AID_ROOT,       AID_ROOT,      0 },
         { "/dev/s3c2410_serial1",       0777,   AID_ROOT,       AID_ROOT,      0 },
         { "/dev/s3c2410_serial2",       0777,   AID_ROOT,       AID_ROOT,      0 },
         { "/dev/s3c2410_serial3",       0777,   AID_ROOT,       AID_ROOT,      0 },
         { "/dev/ttyS0",       0777,   AID_ROOT,       AID_ROOT,      0 },
         { "/dev/ttyS1",       0777,   AID_ROOT,       AID_ROOT,      0 },
         { "/dev/ttyS2",       0777,   AID_ROOT,       AID_ROOT,      0 },
         { "/dev/ttyS3",       0777,   AID_ROOT,       AID_ROOT,      0 },

         /dev/s3c2410_serial0~3은 Odroid-T에서 사용 하는 시리얼 포트입니다.

 

        * ttySAC와 ttyS0의 차는 잘 모르겠내요.. ^^;;;

        시리얼 포트 앱을 실행 하면 Serial Port가 검색 됩니다.
         (저는 총 8개가 잡혀서 모두 777권한으로 바꿨습니다.)
         권한 관련 검색해보시면 많은 자료가 나옵니다.(너무 많다 ㅠㅠ)

 

2) 권한 해결-2
        Superuser 권한 받기 일명 Rooting하기.
        Root Me : Fail
        Universal Androot :  Fail
        SuperOneClickv1.7-ShortFuse : Sucess


         저는 여러가지 돌려 봤는디 "SuperOneClick"로 성공 했습니다.
         (Root Me와 Universal Androot는 앱형태로 Rooting을 하고,
         SuperOneClick는 adb연결로 Rooting을 합니다.


        * Serial Port Program중 public SerialPort()함수를 보면 이런 부분이 있습니다.

                          Process su;
                           su = Runtime.getRuntime().exec("/system/bin/su");
                           String cmd = "chmod 666 " + device.getAbsolutePath() + "\n" + "exit\n";
                           su.getOutputStream().write(cmd.getBytes());
         Superuser 권한으로 권한을 바꾸는 부분입니다.(su -> superuser라는 말 ^^;;)

 

         1번 형태로 권한을 풀경우 요부분이 없어야겠죠? ㅎㅎ

         저는 1번 2번 모두 적용 했습니다.

 

3) 그럼 권한문제는 모두 해결 Program 실행 
         "The serial port can not be opend for an unknown reason." 라는 문구와 함께 Open 중단.
         "IOException"에 걸려서 더이상 진행이 안되는군요.

         http://code.google.com/p/android-serialport-api/에서 확인한결과 (찾는데 올래 걸렸음 ㅠㅠ)
         SerialPort.c파일에서 open Function에서

         fd = open(path_utf, O_RDWR | O_DIRECT | O_SYNC); ====>>> fd = open(path_utf, O_RDWR | O_SYNC);

         O_DIRECT를 빼면 된다는군요. 
         빼내고 다시 컴파일.

         

        *O_DIRECT는 아래링크에 설명이 있내요. (뭔소리인지 원~ ㅡ,.ㅡ;;;)

         http://www.ezdoum.com/upload/2/20020718010518/AArcangeli-o_direct.htm

 

4) 자~ 그럼 다시 확인 Go Go

        우선 "/dev/s3c2410_serial2"를 Open하여 PC쪽과 통신 하니 주고 받고 잘하내요.

         Odroid T에서 /dev/s3c2410_serial2를 Debugging용으로 연결 할 수 있어서 Test에 사용
 
        차후에는 /dev/s3c2410_serial1, /dev/s3c2410_serial3을 주로 사용할 예정입니다.
        (추가 3.3v->12v(15v) 변환 레밸쉬푸터를 더 달고요.)

 

====================================================================

 

아~ 모든게 초행길이라(ㅡ.,ㅡ) 돌인지 떵인지 구별이 안되내요....

/dev/s3c2410_serial1 , /dev/s3c2410_serial3번 연결해서

시리얼 모니터링 앱을 만든후에 1차 Serial Port사용을 마물 해야 겠네요.

앱개발도 공부 할겸~.

 

아 ~

ttyS0 이랑 ttySAC에 대해 아시는분 알려주세요~ ^^* (정말 궁굼함 ㅡ.,ㅡ;;)

 

ttyS0가 리눅스에서는 Serial Port라고 하던데.........
여전히 ttyS0~3은 "IOException"에 걸려서 통신이 안되는군요 (ㅎㅎ)

O_DIRECT 를 사용 못하는 이유도 궁굼하구요.

 

문제 해결에 도움주신 분들게 감사 드립니다.

(제 질뭉에 답변글 올려주신 부들께도 감사 드립니다. *^^*)

R.styleable


xml을 사용하다보면 android:layout_width , android:layout_height 등 android: 로 정의된

각 속성을 정의하게 되어있다.


나만의 레이아웃이나 뷰를 커스텀하게 사용하고자 하는경우

추가로 요구되는 값들이 생길텐데 이러한 값을 xml에서 입력하고자 할때

어케 할까?


예제는 TextButton 에 대한 포스팅에 잘 나와있다.


이번 포스팅은 커스텀 styleable에 대한 내용만 정리해 본다~


1. 나만의 styleable 을 정의하기

해당 내용을 정의할 xml 파일을 만든다. ( my_layout_styleable.xml )


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

<resources>

<declare-styleable name="MyLayoutAttribute">

<attr name="value" format="integer"/>

<attr name="color" format="integer"/>

<attr name="run" format="boolean"/>

</declare-styleable>

</resources>


요렇게하면 MyLayoutAttribete 라는 이름으로 3개의 값을 가지고 있는 styleable이

생겨난다.

R.java 를 살펴보면

R.styleable.MyLayoutAttribute

R.styleable.MyLayoutAttribute_value

R.styleable.MyLayoutAttribute_color

R.styleable.MyLayoutAttribute_run


각각의 아이디가 부여된 것을 알수있다.


2. 레이아웃 클래스 생성

원하는 레이아웃을 상속받은 클래스를 하나 만든다.

그리고, 각 속성값을 저장할 변수들을 선언하고, getter/setter 를 설정한다.

getter/setter는 옵션사항이지만 기존 레이아웃들과 비슷한

모양새를 갖추고, 동적으로 레이아웃을 생성하는 경우를 고려해 만들어 준다.


(기존 레이아웃 항목과 겹칠 수 있으니 멤버 어트리뷰트명은 알아서 잘 할것!! -_-;)

 

public class MyTestLayout extends LinearLayout { 

private int value=0;

private int color=0;

private boolean run=false;


public int getValue() {

return innerColor;

}


public void setValue(int value) {

this.value = value;

}


public int getColor() {

return color;

}

.

.

.

.



}


3. 생성자를 구현한다.

레이아웃이나 뷰를 상속받으면 구현해야 하는 생성자가 1개가 아니다.

옹~ 레이아웃의 경우 2개인데..


public MyTestLayout(Context context, AttributeSet attrs);

public MyTestLayout(Context context);


요 두녀석이다.


일반적으로 사용되는 녀석은 당연 윗녀석~

xml에서 여러 속성이 부여되는데 해당 정보가 생성자에 전달된다.

따라서, 위의 생성자에 속성정보를 얻는 코드가 추가되어야 한다.


obtainStyledAttributes() 메쏘드로 위에 정의한 styleable을 얻고,

하위항목은 각 항목별로 형식에 맞는 메쏘드로 실제 데이터를 읽어온다.


public MyTestLayout(Context context, AttributeSet attrs) {

super(context, attrs);

// TODO Auto-generated constructor stub

// 속성값을 읽어 변수에 저장

TypedArray ta = getContext().obtainStyledAttributes(attrs

R.styleable.MyLayoutAttribute);


innerColor = ta.getInteger(R.styleable.MyLayoutAttribute_value, 0);

borderColor = ta.getInteger(R.styleable.MyLayoutAttribute_color, 0);

isAntiAlias = ta.getBoolean(R.styleable.MyLayoutAttribute_run, false);

}



4. 레이아웃 xml에서 속성에 값넣기

레이아웃 태그에는 네임스페이스를 지정할 수 있다. 안드로이드는

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


요렇게 되어있는데 android 라는 네임스페이스를 사용하겠다라는 의미~

이곳에 메인 패키지로 네임스페이스를 추가한다.

그리고,, 그냥 사용하면 된다. -_-;;;


<com.your.package.MyLayout 

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

xmlns:myspace="http://schemas.android.com/apk/res/com.your.package"


android:layout_width="wrap_content"

android:layout_height="wrap_content"

myspace:value="1"

myspace:color="ff303030"

myspace:run="false">


.

.


</com.your.package.MyLayout>


출처 : http://www.androidpub.com/android_dev_info/636981
개인적으로 작성한 Post가 어느정도 모여서 글을 올려봅니다.

안드로이드 개인 개발자 분들은 주말에도 일하시니까 ^^ 도움이 되시길 바래요.

(저는 개발자라서 주말에는 쳐다도 안보겠죠 ㅎㅎ;)

좋은 주말 보내시구요 질문사항이 있으시면 포스트에 남겨주세요 !~ 주말에 답변할수도

Recent Posts

출처 : http://cafe.naver.com/embeddedcrazyboys.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=9766&

13.안드로이드 블루투스 BlueTooth

http://junho85.springnote.com/pages/6481569

목차


  1. 안드로이드 블루투스 BlueTooth
    1. 블루투스
    2. 다중 연결
    3. 안드로이드 블루투스 게임
    4. UUID - Universally unique identifier
    5. 참고

 

안드로이드 블루투스 BlueTooth#

블루투스#

http://developer.android.com/reference/android/bluetooth/package-descr.html

http://developer.android.com/reference/android/bluetooth/package-summary.html

 

 Bluetooth 

http://developer.android.com/guide/topics/wireless/bluetooth.html

이 문서를 열심히 공부해야 겠다!!!

 

http://gtko.springnote.com/pages/5396297

한글 번역 되어 있음

 

Manifest 에서 두가지 퍼미션을 허용해준다.

    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.BLUETOOTH" />

 

 

안드로이드 블루투스로 할 수 있는 일?

 

RFCOMM?

이걸로 데이터 스트림을 주고 받는 듯 하다.

 

 

SDK에 BluetoothChat 이라는 예제가 있다. 확인해 보자.

http://developer.android.com/resources/samples/BluetoothChat/index.html

 

 10 안드로이드 하드웨어 

http://gtko.springnote.com/pages/5396297

상당히 잘 정리 되어 있다.

 

 G1(ADP1)에서 블루투스 사용하기 - 1, 2, 3

http://android.sirini.net/grblog/?p=2

http://android.sirini.net/grblog/?p=4

http://android.sirini.net/grblog/?p=5

예전 버전 G1에서 블루투스를 어떻게 구현해 보려고 애써 본 흔적인듯. 지금은 별 의미 없을 듯.

그나저나 내 G1은 블루투스가 잘 될까? CyanogenMod로 2.2 까지 업했고 2.2SDK 예제에 블루투스 관련 예제가 있는데 함께 테스트 해볼 기기가 없어 아직 못해봄.

 

다중 연결#

 Android Bluetooth API connect to multiple devices at the same time

http://stackoverflow.com/questions/2956619/android-bluetooth-api-connect-to-multiple-devices-at-the-same-time

I wrote a test app about a week ago that connected to two separate serial devices simultaneously. It commanded both of them independently and the performance was awesome.

답변은 이게 끝. 되기는 되는가 보다.

 

TODO : 서버 하나 만들고 두대가 접속하기를 기다렸다가 두대가 접속하면 메시지 날려 주는 프로그램 하나 만들어 보자

 

안드로이드 블루투스 게임#

에어하키

galcon

 

 [기타] 갤럭시S 블루투스 게임 컨트롤러 Zeemote

http://www.applclub.com/bbs/board.php?bo_table=B&wr_id=174210

 

UUID - Universally unique identifier#

범용 고유 번호 128비트 숫자들의 조합

 

 Universally unique identifier

http://en.wikipedia.org/wiki/UUID

 

 [블루투스]UUID (Universally Unique Identifiers)

http://www.cyworld.com/tizbeam/3986964

 

 UUID (Universally Unique Identifiers)

http://zene.egloos.com/4973651

 

참고#

 [android] 안드로이드 블루투스 데이터 통신 - bluetooth Socket communication

http://blog.naver.com/oh4zzang/40112145084

 

 [android] 안드로이드 블루투스 연결 - bluetooth connectt (내용 추가)

http://blog.naver.com/oh4zzang/40111958220

 

 [android] 안드로이드 Bluetooth UUID

http://blog.naver.com/oh4zzang/40111957130


[Android] 갤럭시탭을 위해 레이아웃 맞추기 Android / 개발

2010/12/28 14:47

복사 http://blog.naver.com/notinoti/80121268628

어플 개발을 하다보면 갤럭시S기준으로 만들게 되고 나중에 갤럭시 탭에서도 실행해 보았는데

 

화면 레이아웃이 조금씩 어긋나는 경우가 있습니다. 그럴때 다음과 같이 바꾸어서 해보면 어느정도 잡힐것입니다^_^

 

 

 

 

 

1. manifest 파일에 <uses-sdk android:minSdkVersion="7" /> 을 추가합니다. (버전 7이상 권장)

 

그렇지 않으면 화면 가운데로 몰리는 현상이 발생해버리기 때문에 추가해야만 화면크기에 맞게 꽉 차서 나옵니다.

 

 

 

2. http://blog.naver.com/notinoti/80118619288

 

위에서 말한 내용처럼 모든 단위는 dp(간격, 크기), sp(폰트 사이즈) 로 개발합니다.

 

 

 

3. 레이아웃은 Linearlayout 보다 Relativelayout 이 더 좋다고 합니다.

(그러나 대부분이 Linearlayout으로는 다 구현 가능하지만, 안될때에는 Relativelayout으로 바꾸어보자. 사실 Linear를 여러개 겹쳐 쓰는게 가장 쉽긴 합니다^^)

 

 

 

4 위젯의 width는 fill_parent로 정하고 그대신 layout_weight 를 주어 가중치를 조절하여 화면에 배치합니다.

(이것 역시 직접 50dp 같이 숫자로 주어도 무방하나 간혹 깨지는 경우나 만족하지 못하는 구성이 나올때 사용해봅니다.)

 

 

 

 

5. 지금까지 해본 결과 갤럭시탭 해상도 전용의 폴더를 두어 따로 관리하는게 가장 좋습니다!

 

res 폴더안에 기존에 drawable-hdpi 폴더와 layout 폴더이외에 새로 갤럭시 탭 용의

 

drawable-hdpi-1024x600 폴더와 layout-1024x600 폴더를 생성하여 필요한 리소스를 넣으면 됩니다.

 

이 때, 중요한 점은 기존폴더의 모든 리소스를 그대로 복사해도 되지만, 그렇게 하면 어플 용량이 더 많아지게 되므로

 

갤탭에서 조정해야할 필요한 리소스만 복사해와서 따로 수정해 주면 됩니다.

 

나머지 없는 리소스들은 apk 파일로 만들때(빌드) 자동으로 기본 폴더(drawable-hdpi, layout)에서 가져다가 사용하기 때문입니다^^

 

 

그리고 한가지 팁!

 

기존의 기본 이미지를 사용하다보면 스마트폰보다 갤탭이미지가 뭉개지는 경우가 있는데

 

포토샵에서 이미지 크기를 1.25배 늘려서 위에서 말한 drawable-hdpi-1024x600 에 넣어 놓으면 스마트폰과 동일한 이미지 크기의 비율을 얻을수 있습니다^^

 

 

 

6. 그리고 소스상에서 그냥 고치겠다... 라고 한다면 화면 디스플레이의 타입을 직접 계산해서 조절하면 됩니다.

 

화면 디스플레이의 타입을 얻어오는 소스는 다음과 같습니다.

 

 

public static String getDiviceDisplay(){
        Display d = ((WindowManager)getSystemService(this.WINDOW_SERVICE)).getDefaultDisplay();
        int width = d.getWidth();
        int height = d.getHeight();
       
        // HVGA :(320 x 480)
        // WVGA :(480 x 800)
        // WSVGA :(600 x 1024)
       
        // 세로모드
        if(width < height){
            if(width < 480){
                return "HVGA";
            }
            else if(width == 480){
                return "WVGA";
            }
            else{
                return "WSVGA";
            }
        }
        // 가로모드
        else{
            if(height < 480){
                return "HVGA";
            }
            else if(height == 480){
                return "WVGA";
            }
            else{
                return "WSVGA";
            }
        }
    }

 

 

 

HVGA는 저해상도 폰 (옵티머스원),

WVGA는 고해상도 폰 (일반적인 폰, 갤럭시 시리즈 등)

WSVGA는 갤럭시 탭 의 해상도입니다.

 

 

위 소스를 적용해서 레이아웃마다 다르게 하고자 한다면 다음 예제처럼 적용하면 됩니다.

 

 

        RelativeLayout layout = (RelativeLayout)findViewById(R.id.login_widget);
        LinearLayout.LayoutParams param =
                (LinearLayout.LayoutParams)layout.getLayoutParams();
       
        if(CommonUtil.getDiviceDisplay().equals("HVGA")){
            param.topMargin = 130;
            param.bottomMargin = 15;
        }
        else if(CommonUtil.getDiviceDisplay().equals("WVGA")){
            param.topMargin = 225;
            param.bottomMargin = 36;
        }
        else if(CommonUtil.getDiviceDisplay().equals("WSVGA")){
            param.topMargin = 300;
            param.leftMargin = 70;
            param.rightMargin = 70;
            param.bottomMargin = 105;
        }
       
        layout.setLayoutParams(param);

 

'Android > Tip&Tech' 카테고리의 다른 글

Android tip######  (0) 2011.11.09
안드로이드 블루투스 정보모음  (0) 2011.11.07
무선으로 ADB 연결하기(2.2부터)  (0) 2011.10.31
[펌]안드로이드 tipssoft.com 강좌 링크  (0) 2011.10.24
ADB 명령어 정리  (0) 2011.10.22
출처 : http://tjandroid.blogspot.com/2011/06/adb.html
usb 악세서리를 개발하게 되면 폰이 악세서리와 usb 로 연결 되어 있기 때문에 디버깅 하기가 여간 힘든게 아니다.

만약 PC 와 안드로이드 폰이 같은 네트워크 안에 있다면 예를 들어 같은 무선 공유기에 접속해 있다면 adb 를 usb 연결 없이 네트워크로 사용할 수 있다.

참조: http://developer.android.com/guide/topics/usb/index.html 의 Debugging considerations 부분

일반적인 방법
1. PC 와 폰 모두 같은 공유기에 접속한다.
2. PC 와 폰을 usb 로 연결한다.
3. PC 의 terminal 창을 열고 adb 명령을 다음과 같이 수행한다.
 - adb tcpip 5555
 - 이후 부터 usb 연결을 해제해도 된다.
4. 폰의 ip 주소를 확인한다.
 - settings > wireless & networks > wifi settings > 연결된 AP 를 터치 하면 할당된 ip 주소를 확인할 수 있다.
5. PC 의 terminal 창에서 다음과 같이 adb 명령을 수행한다.
 - adb connect [ip address]:5555
 - 예를 들어 폰의 ip address 가 192.168.1.15 이면 adb connect 192.168.1.15:5555 를 수행한다.
6. usb 연결을 해제하고 adb logcat 을 수행해 본다.
 - usb 로 연결할 때와 똑같이 앱 설치 등의 adb 의 모든 명령어를 사용할 수 있다.

안드로이드 폰 벤더가 위 기능을 허용하지 않을 수 있다.
위 방법은 안드로이드 폰 벤더가 기능을 허용한 경우에만 가능한 방법이다.
대부분의 안드로이드 2.2 버전을 포함한 이전 버전의 폰에서는 위 기능이 활성화 되어 있지 않다.
만약 폰을 루팅하였다면 adbWireless 를 다운로드 받아 설치한 후 실행하여 adb wireless 를 활성화 시킨 후 위 과정을 수행하면 무선으로 adb 를 사용할 수 있다.

결론
일반적인 방법을 사용해 보고 만약 연결이 되지 않는 다면 루팅하는 방법을 찾아보고 루팅이 가능하다면 adbWireless 를 사용한 상태에서 다시 위 과정을 수행하면 되겠다.

폰 벤더도 허용을 하지 않고 루팅도 할 수 없다면 사용할 수 없다.
출처 : http://blog.naver.com/mujjingun/60144443786

1. 이클립스 없이 안드로이드 개발환경 구축하기1 ( JDK 설치, 안드로이드 SDK 설치, 에뮬레이터 실행 )
 
 
2. 이클립스 없이 안드로이드 개발환경 구축하기2 ( 프로젝트 생성, 컴파일, 실행 )
 
 
2-1 프로젝트 환경 파일 재구성하기 - Update Project
 
 
3. 안드로이드 프로그래밍 시작하기
 
 
4. 버튼 사용하기
 
 
5. 에디트텍스트(EditText) 사용하기
 
 
6. 리스트뷰 사용하기 - 기초편
 
 
7. 리스트뷰의 사용하기 - 활용편
 
 
8. 쓰레드(Thread) 의 이해 - 기초편
 
 
9. 스트림(Stream)의 이해 - 바이트 스트림
 
 
10. 소켓(Socket) 통신의 이해 - 클라이언트
 
 
11. 소켓(Socket) 통신의 활용 - MFC 서버와 통신하기
 
 
12. TimerTask 클래스를 사용한 스톱워치
 
 
13. 서버 화면을 캡쳐하여 클라이언트에 전송하기
 
 
14. 액티비티(Activity)의 이해
 
 
15. 액티비티 전환하기 - 명시적 전환
 
 
16. 컨텍스트(Context)
 
 
17. 사진 촬영 후 이미지뷰에 출력하기
 
 
18. TTS ( TextToSpeech )
 
 
19. 사진 촬영 후 서버로 전송하기
 
 
20. 음성 인식(Voice Recognition) 
    http://www.tipssoft.com/bulletin/tb.php/FAQ/961
 
 
21. 음성인식을 이용한 발음 테스트 예제
 
 
22. 그림그리기의 기초와 구조
 
 
23. 사용자정의 뷰 생성 및 배치1
 
 
24. 사용자조작 처리하기 ( TouchEvent Handler )
    http://www.tipssoft.com/bulletin/tb.php/FAQ/973
 
 
25. 뷰의 터치위치 좌표로 출력하는 예제
 
 
26. 터치를 이용한 간단한 게임
 
 
27. 메뉴( Menu ) - 기초
    http://www.tipssoft.com/bulletin/tb.php/FAQ/980
 
 
28. 메뉴( Menu ) - Context Menu
 
 
29. 메뉴( Menu ) - Options Menu
 
 
30. 메뉴( Menu ) - Sub Menu
 
 
31. 탭 레이아웃(Tab Layout) 사용하기 - Intent 방식1
    http://www.tipssoft.com/bulletin/tb.php/FAQ/987
 
 
32. 탭 레이아웃(Tab Layout) 사용하기 - Intent 방식2
 
 
33. 어플리케이션에서 한글 사용하기
 
 
34. 간단한 대화상자( 다이얼로그 ) 사용하기
 
 
35. 대화상자의 이해 1
 
 
36. 대화상자의 이해 2
 
 
37. 대화상자에 리스트, 체크, 라디오 버튼 사용하기
 
 
38. 원형 프로그래스 대화상자
 
 
39. 바(Bar)형 프로그래스 대화상자
    http://www.tipssoft.com/bulletin/tb.php/FAQ/1007
 
 
40. "Back" 키 두번 터치하여 종료하기 
 
 
41. 꺼지지 않는 화면 설정하기
 
 
42. 토스트( Toast ) 사용하기 - 기본
 
 
43. 진동 울리기 ( 지정시간 진동과 패턴 진동)
 
 
44. 회전 방향별로 다른 레이아웃 적용하기
    http://www.tipssoft.com/bulletin/tb.php/FAQ/1031
 
 
45. 어플리케이션 회전 방지하기 (화면 방향 고정하기)
    http://www.tipssoft.com/bulletin/tb.php/FAQ/1032
 
 
46. 센서를 사용하기 위한 공통 루틴
    http://www.tipssoft.com/bulletin/tb.php/FAQ/1033
 
 
47. 센서 - 조도 측정하기
 
 
48. 센서 - 근접센서를 이용하여 거리 측정하기
 
 
49. 센서 - 방향센서 사용하기
 
 
*. 나침반 예제
 
 
50. 센서 - 가속도 센서 사용하기

출처 : http://whitet8899.egloos.com/1322431
ADB (Android Debug Bridge)



ADB의 구성

client : development machine에서 동작. shell에서 client를 invocation해서 command 실행 가능. ADT, DDMS도 client

server : development machine의 background process이며, client와 daemon 사이에서의 communication을 관리

daemon : 각각의 device에서 동작하는 background process

client를 시작하면, ADB server가 실행중인지 확인해서 실행중이지 않으면 server를 시작시킨다. server가 시작되면 TCP의 5037 port로 binding해서 adb client로부터의 command를 받아들이는데, 모든 client는 server와 communication 하기 위해 5037 port를 사용.

실행파일 : ${android_sdk_path}/tools/adb



Command 입력 형식

adb [-d | -e | -s <serialNumber>] <command>

adb devices : adb server와 연결된 device를 보여준다.
형식 : [serialNumber] [state]

serialNumber = type-consolePort (ex : emulator-5554)
state = offline (device가 adb와 아직 연결되지 않았거나 응답이 없는 상태)
            device (adb server와 연결된 상태)

-s option : 여러개의 device가 연결되어 있는 상태에서 특정 device에 command를 입력하고 싶을 때 사용
형식
adb -s <serialNumber> <command>

ex : adb -s emulator-5554 install sample.apk



Port forwarding

device의 port를 forwarding 하고 싶을 때 사용하는 명령

ex : port 6100에서 7100으로 forwarding 하고 싶은 경우
adb forward tcp:6100 tcp:7100



Copying files

pull
device에서 file을 copy해 올 때 사용 (recursively)
adb pull <remote> <local>

push
pull과 반대로 file을 device에 복사해 넣고 싶을 때 사용 (recursively)
adb push <local> <remote>

ex : adb push foo.txt /sdcard/foo.txt) (/sdcard/foo.txt 에서 /sdcard는 device에 존재하는 path



Listing of adb Commands

Options

-d
연결된 USB device에만 direct로 command 전송
USB device가 하나 이상이면 error return

-e
실행중인 device에만 command 전송
하나 이상의 device가 실행중이면 error return

-s <serialNumber>
특정 device에만 command 전송 (serialNumber 형식은 위 내용 참조)


General

devices
연결된 모든 device list 출력

help
제공되는 adb command list 출력

version
adb version 출력


Debug

logcat [<option>] [<filter-specs>]
log data 출력

bugreport
bugreport를 위한 dumpsys(system data dump), dumpstate(state dump), logcat data 출력

jdwp
특정 device의 JDWP process들의 list(pid) 출력


Data

install <path-to-apk>
application 설치

pull <remote> <local>
push <local> <remote>
위 내용 참조


Ports and Networking

forward <local> <remote>
특정 local port를 remote port로 fowarding
Scheme
tcp:<portnum>
local:<UNIX domain socket name>
dev:<character device name>
jdwp:<pid>

ppp <tty> [parm]...
USB로 PPP 실행
<tty> : PPP stream을 위한 tty
[parm] : PPP option


Scripting

get-serialno
adb의 serial number 출력

get-state
adb의 state 출력 (device / offline)

wait-for-device
device가 online일 때 까지 command 실행 정지

ex : adb wait-for-device shell getprop (state가 device가 되면 shell getprop command 실행

Note : 완전히 boot 된 이후에 사용 가능한 install 등의 command를 함께 사용할 경우 wait-for-device는 device state만 확인하므로 fully boot 되지 않았을 경우 error 발생 가능


Server

start-server
adb server가 실행중인지 확인해서 running 상태가 아니면 실행

kill-server
adb server process를 종료


Shell

shell
target device 안에서 remote shell을 시작

shell [<shellCommand>]
target device 안에서 shell command를 실행하고 remote shell을 빠져나간다



Shell Command 실행

ADB는 ash shell을 제공하는데, ash shell의 실행 바이너리는 device 내부의 /system/bin 경로에 존재

adb [-d | -e | -s <serialNumber>] shell로 remote shell을 실행한 후에 shell을 종료하고 싶으면 Ctrl + D or exit 입력



UI/Application Exerciser Monkey

User event의 random stream을 생성해 device에서 실행시키는 tool (stress test 용도)

ex : adb shell monkey -v -p packageName 500 (500가지의 random stream)



Other Shell Commands

device의 /system/bin 경로의 file들을 살펴보거나, adb -help로 확인

dumpsys
system data의 dump를 표시

dumpstate
state의 dump를 file로 저장

logcat [<option>]...[<filter-spec>]
logging을 가능하게 하거나 화면에 표시

dmesg
kernel debugging message를 화면에 출력

start
device를 시작(재시작)

stop
device 종료



Using logcat Commands

adb logcat
단순히 전체 log를 보고싶은 경우 사용 또는 remote shell에서 logcat 실행

Android에서 모든 log message는 tag와 priority를 가지고 있음
tag : system component를 짧은 문자열로 표현 (ex : view system의 경우 "View")
priority (ordered from lowest to highest)
V (Verbose)
D (Debug)
I (Info)
W (Warning)
E (Error)
F (Fatal)
S (Silent)

logcat 실행 후에 나타나는 log message에서 tag와 priority가 첫 column에 priority/tag 형태로 표시

ex : I/ActivityManager( 585) : Starting activity : Intent { action = android.intent.action... }

logcat의 filter는 tag:priority 형태로 표현하는데 tag는 표시하려는 tag의 이름을 입력하면 되고 입력한 priority와 상위 priority의 log들을 표시

ex : adb logcat ActivityManager:I MyApp:D *:S
ActivityManager의 I(Info) level 이상, MyApp의 D(Debug) level 이상의 log들만 표시


default filter expression

환경변수 ANDROID_LOG_TAGS에 default로 사용할 filter expression을 setting 후에 export 해서 사용

ex : export ANDROID_LOG_TAGS="ActivityManager:I MyApp:D *:S"

Note : remote shell을 사용해서 logcat을 실행하고 있을 경우 export 되지 않음 (?)


Controlling Log Output Format

-v option을 사용해서 출력되는 log의 format 변경 가능

output format
brief : priority/tag, PID 표시 (default)
process : PID only
tag : priority/tag only
thread : process:thread, priority/tag only
raw : 다른 metadata field 없이 raw log message 표시
time : date, invocation time, priority/tag, PID
long : 모든 metadata filed와 message 표시

ex : adb logcat -v thread


Viewing Alternative Log Buffers

Android logging system은 log message들을 위해 여러 개의 circular buffer를 가지고 있고 default circular buffer가 모든 log를 보관하지 않기 때문에 다른 circular log buffer의 내용을 보고 싶을 때에는 -b option을 사용해서 circular buffer를 변경해주어야 한다.

Buffers
radio : radio/telephony 관련된 log message를 보관하는 buffer
events : related-events
main : main log buffer (default)

ex : adb logcat -b radio



Viewing stdout and stderr
Android에서는 default로 stdout과 stderr ouput을 /dev/null로 내보내는데, file에 쓰도록 변경 가능하고 이 경우 변경 전에 device를 stop 후 setprop shell command를 실행해서 redirection 설정해야 한다. device start 이후에는 stop 전까지 설정이 유지된다. default로 설정을 유지하고 싶다면, /data/local.prop에 기록

ex :
adb shell stop
adb shell setprop log.redirect-stdio true
adb shell start



Listing of logcat Command Options

-b <buffer>
load log buffer

-c
모든 log를 clear하고 빠져나간다

-d
log를 화면에 dump하고 종료

-f <filename>
log를 <filename>에 기록. default는 stdout

-g
특정 log buffer의 size를 출력하고 종료

-n <count>
rotated log의 최대값을 <count>로 설정. default는 4, -r option이 필요

-r <kbytes>
log file을 <kbytes>씩 rotate. default는 16, -f option 필요

-s
default filter를 silent로 설정

-v <format>
log format을 <format>으로 설정. default는 brief format.



[출처] : https://docs.google.com/View?id=dhj7zms7_0cfm752gq

공유하기 버튼

 
싸이월드 공감트위터페이스북
출처 : http://codemuri.tistory.com/693

일반 개발자들은 주로 USB 를 이용하여 adb 를 사용합니다. 하지만 TCP 를 이용하여 adb 를 이용한 디버깅을 해본 사람들은 많지 않을 것입니다. 그도 그럴 것이 Rooting 또는 Engineering 빌드 버전이 아니면 TCP 설정이 적용되지가 않기 때문에 실 장치를 가지고 테스트를 해보기가 쉽지 않겠죠.

이 글을 읽고 계신 분들은 Rooting 폰 또는 Engineering 빌드 버전의 장치를 가지고 있다고 가정하겠습니다.

TCP 를 이용하여 디버깅을 하면 USB 를 연결하지 않아도 adb 명령을 이용하여 app 을 설치하거나, logcat 의 로그를 모으는 등의 USB 와 연결된 것과 동일한 모든 adb 기능을 사용할 수 있습니다.

시중에 이러한 설정을 편리하게 해주는 (원클릭으로 Wireless 디버깅 on/off를 해주는) 유료 앱을 팔고 있던데, 이 App 은 알고보면 아무것도 아닙니다. Rooting 된 폰에서 TCP 디버깅 설정을 on/off 하는 것은 별로 어렵지 않기 때문이죠.

자 이제 adb 에서 제공하는 TCP 를 이용한 디버깅 설정방법을 알아 보겠습니다. 크게 매뉴얼 설정과 자동 설정 두가지로 나누어 살펴보겠습니다.

1. 매뉴얼 설정

먼저 안드로이드 장치의 디버깅 모드를 활성화 한 후 USB 를 연결합니다. TCP 를 이용한 Adb 를 설정하기 위해서는 adb shell 을 이용해야 하기 때문에 처음에 한번은 연결이 필요합니다. 이글 말미에 Rooting 된 폰에서 이를 자동화하는 방법을 소개하겠습니다. (구현은 제공하지 않고 숙제로 남겨두겠습니다.)

TCP 를 이용한 adb 디버깅을 하기 위해서는 현재 무선공유기등과 같은 Wifi 망이 이용가능해야 합니다.

1
$ adb devices

를 입력하여 현재 연결된 장치를 확인합니다.

그리고는 다음을 입력하여 adb 데몬(device 에서 adb 를 서비스하는 프로세스, adbd)의 설정을 변경합니다.

1
$ adb tcpip 5555

뒤의 5555 는 5555번 port 를 사용하겠다는 것을 의미합니다. 위와 같이 입력하면 adbd 데몬 프로세스(장치에서 실행되며 실질적인 adb 기능을 수행함)를 tcpip 모드로 재시작합니다. 이제 장치는 tcpip 를 연결할 수 있는 상태가 되었습니다.

(TCP 연결 성공을 체크하기 위해 기존에 연결된 USB 케이블을 해제하시기 바랍니다.)

PC 와 장치를 연결하기 위해서는 장치에 할당된 IP 를 확인해야 합니다. 이는
"설정 > 무선 및 네트워크 > Wi-Fi 설정" 에서 연결된 Wi-Fi 네트워크를 선택하면 확인할 수 있습니다.


저의 경우 192.168.0.4 입니다. 이제 PC 에서 장치로 연결하는 명령을 줍니다.

1
$ adb connect 192.168.0.4:5555

를 입력하면 연결 성공 메시지를 볼 수 있으며, 이렇게 연결된 이후에는 adb 명령을 동일하게 사용할 수 있습니다.

2. 자동 설정

원터치 Wireless 설정을 지원하는 방법을 살펴보겠습니다. 키포인트는 위에서 실행했던 "adb tcpip <port>" 명령을 어떻게 장치에서 수행하느냐 입니다.

그 명령은 아래와 같습니다.

1
2
3
4
$ su
# setprop service.adb.tcp.port 5555
# stop adbd
# start adbd

위 명령을 장치에서 실행하기만 하면 되는 것입니다. 위 예제와 같이 su 명령을 이용하여 root 권한을 얻게 되는데, 바로 이런 권한이 필요하기 때문에 production 장치에서는 수행할 수 가 없는 것입니다.

끝으로 안드로이드 App 에서 su 권한을 체크하는 방법을 소개해 드리며, 이 예제 코드와 tcp 설정 스크립트를 이용하면 시중에 돌고 있는 원터치 Wireless Adb 설정 App 을 개발할 수 있습니다. (이 예제도 당연 Rooting 된 폰에서만 root 권한을 얻습니다.) 
☞ su 명령이 수행된다고 가정을 하겠습니다. 만약 su 가 존재하지 않으면 su 는 검색하면 쉽게 구할 수 있습니다. 약간의 보안 방어막을 가한 super user 라는 app 도 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Process p; 
try
   // Preform su to get root privledges 
   p = Runtime.getRuntime().exec("su");  
   
   // Attempt to write a file to a root-only 
   DataOutputStream os = new DataOutputStream(p.getOutputStream()); 
   os.writeBytes("echo \"Do I have root?\" >/system/sd/temporary.txt\n"); 
   
   // Close the terminal 
   os.writeBytes("exit\n"); 
   os.flush(); 
   try
      p.waitFor(); 
           if (p.exitValue() != 255) { 
              // TODO Code to run on success 
              toastMessage("root"); 
           
           else
               // TODO Code to run on unsuccessful 
               toastMessage("not root"); 
           
   } catch (InterruptedException e) { 
      // TODO Code to run in interrupted exception 
       toastMessage("not root"); 
   
} catch (IOException e) { 
   // TODO Code to run in input/output exception 
    toastMessage("not root"); 

이것만 가지고 어떻게 만들어요라고 되묻지 마시고, 한번 시도해 보시기 바랍니다. Just do it!


3. 기타

1
$ adb shell getprop

을 입력하면 현재 장치의 설정 정보를 볼 수 있습니다. 만약 tcpip 로 설정되어 있다면 getprop 에서도 그 목록이 나와야 합니다.

1
$ adb shell setprop service.adb.tcp.port -1

은 tcp 설정을 해제합니다.

참고:

su 권한을 크랙하는 방법은 아래 글을 참고하세요.


! 추가 확인 필요

아래 명령은 디폴트 설정을 변경한다고 합니다. (위에 설정은 장치가 리부팅되면 usb 모드로 돌아갑니다.) 이게 제대로 동작하는지 확인이 필요합니다. 안된다는 말도 있구요... 확인 요함.

1
$ adb shell setprop persist.adb.tcp.port 5555

관련글:

SAMSUNG, LG, Smart Phone Android Open Source

삼성 안드로이드폰 소스 입니다.
http://opensource.samsung.com/reception/reception_main.do?method=reception_list&menu_item=mobile


LG 안드로이드 소스 입니다.
http://opensource.lge.com

옵티머스 큐는 LU2300입니다

출처 : http://www.androidpub.com/index.php?mid=android_dev_info&search_target=title_content&search_keyword=%EB%A9%94%EB%89%B4&document_srl=1577289
안드로이드에  기본 내장되어 있는  QuickContactBadge 은   주소록에 한정해서 사용이 가능한듯합니다. 


http://developer.android.com/reference/android/widget/QuickContactBadge.html



검색해 보니까  같은 방식의 UI를  아무곳에나 적용기 가능한 소스를 공개한 사람이 있더군요.


http://www.londatiga.net/it/how-to-create-quickaction-dialog-in-android/



mina1.jpg mina2.jpg newqa.jpg theaters.jpg




위 는 예  스크린샷 입니다. 


수고하세요!

'Android > Tip&Tech' 카테고리의 다른 글

wiress 를 이용한 adb 통신  (0) 2011.10.19
삼성,LG 오픈소스  (0) 2011.10.16
[팁]android pdf 또는 hwp 소스 실행하기  (0) 2011.10.02
안드로이드 만보기 소스  (1) 2011.09.28
[펌]custom seek bar 만들기  (3) 2011.09.26

Intent intent = new Intent();
  intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  intent.setAction(android.content.Intent.ACTION_VIEW);
  intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
  if (file.getName().endsWith(".pdf")){
 intent.setDataAndType(Uri.fromFile(file), "application/pdf");
  }else if (file.getName().endsWith(".hwp")){
intent.setDataAndType(Uri.fromFile(file), "application/hwp");
  }
  try{
   startActivity(intent);
  }catch(ActivityNotFoundException e){
   util.showLongToast("해당파일을 실항할 수 있는 어플리케이션이 없습니다.\n파일을 열 수 없습니다.");
   e.printStackTrace();
  }

안녕하세요~ 이번에 안드로이드에 대해 독학으로 공부하고 있는 학생입니다.

 

기본 지식이 많이 없는 편이라 이렇게 질문을 올리게 되었습니다.

 

귀찮더라두 끝까지 봐주시고 저에게 좋은 스승이 되어주세요

 

질문은 가속도 센서를 이용해서 만보기를 만들어 볼라고 하는데요

 

여차여차 소스를 구하게 되었습니다. 그래서 이것을 토대로 공부를 하고 싶어하는데요

 

소스들이 무엇을 의미하는지 몰라서 이렇게 질문을 하게 되었습니다 스승님들 저에게 가르침을 주세요~

 

자세한 설명 부탁드리겠습니다!! (__)꾸벅!

 

 

 

[MainActivity.java]

 

package com.androday.test;

import! android.app.Activity;


import! android.content.BroadcastReceiver;
import! android.content.Context;
import! android.content.Intent;
import! android.content.IntentFilter;
import! android.os.Bundle;
import! android.view.View;
import! android.view.View.OnClickListener;
import! android.widget.Button;
import! android.widget.TextView;
import! android.widget.Toast;

public class MainActivity extends Activity {
   
 
    Button btnStopService;
   
    Intent intentMyService;       

    BroadcastReceiver receiver;
   
    boolean flag = true;
   
    Toast toast;
   
    TextView CountText;
   
    String serviceData;
   
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);     
          
        intentMyService = new Intent(this,MyServiceIntent.class);   
        //실행되기 원하는 서비스 등록
               
      
        receiver = new MyMainLocalRecever();       
       
        CountText = (TextView)findViewById(R.id.TextView01);      
              
        btnStopService = (Button)findViewById(R.id.btnStopService);
        //서비스 중지
       
       
        btnStopService.setOnClickListener(new OnClickListener() {
   
   @Override
   public void onClick(View v) {
    
    
    if(flag)
    {
     
     
     btnStopService.setText("Stop !!");
     
     // TODO Auto-generated method stub
     try{
      
      IntentFilter mainFilter = new IntentFilter("com.androday.test.step");       
           
      registerReceiver(receiver, mainFilter);
      
      startService(intentMyService);     
      //txtMsg.setText("After stoping Service:\n"+service.getClassName()); 
      Toast.makeText(getApplicationContext(), "서비스 시작", 1).show();
     }
     catch (Exception e) {
      // TODO: handle exception
      Toast.makeText(getApplicationContext(), e.getMessage(), 1).show();
     }
    }
    
    
    else
    {

    
     btnStopService.setText("Go !!");
     
     // TODO Auto-generated method stub
     try{
      
      unregisterReceiver(receiver);
      
      stopService(intentMyService);      
      
      Toast.makeText(getApplicationContext(), "서비스 중지", 1).show();
      //txtMsg.setText("After stoping Service:\n"+service.getClassName());     
     }
     catch (Exception e) {
      // TODO: handle exception
      Toast.makeText(getApplicationContext(), e.getMessage(), 1).show();
     }     
    }  
    
    flag = !flag;
    
   }
  });
       
        }
   
   
    class MyMainLocalRecever extends BroadcastReceiver {

     @Override
     public void onReceive(Context context, Intent intent) {
      // TODO Auto-generated method stub
      
      serviceData = intent.getStringExtra("serviceData");
      
      CountText.setText(serviceData);
      
      Toast.makeText(getApplicationContext(), "Walking . . . ", 1).show();    

     }

    }
   
   
   
}


 

 

[MyServiceIntent.java]

 

package com.androday.test;

import! android.app.Service;


import! android.content.Intent;
import! android.hardware.Sensor;
import! android.hardware.SensorEvent;
import! android.hardware.SensorEventListener;
import! android.hardware.SensorManager;
import! android.os.IBinder;
import! android.util.Log;

public class MyServiceIntent extends Service implements SensorEventListener  {
 
 
 int count = values.Step;
 
 private long lastTime;
    private float speed;
    private float lastX;
    private float lastY;
    private float lastZ;
  

    private float x, y, z;
    private static final int SHAKE_THRESHOLD = 800;
  

    private static final int DATA_X = SensorManager.DATA_X;
    private static final int DATA_Y = SensorManager.DATA_Y;
    private static final int DATA_Z = SensorManager.DATA_Z;
  

    private SensorManager sensorManager;
    private Sensor accelerormeterSensor;
 
   
 @Override
 public IBinder onBind(Intent intent) {
  // TODO Auto-generated method stub
  return null;
 }

 @Override
 public void onCreate() {
  // TODO Auto-generated method stub  
  super.onCreate();
  Log.i("MyServiceIntent","Service is Create"); 
  
   sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
         accelerormeterSensor = sensorManager
                 .getDefaultSensor(Sensor.TYPE_ACCELEROMETER);    

     }    
 
 @Override
 public void onStart(Intent intent, int startId) {
  // TODO Auto-generated method stub
  super.onStart(intent, startId);
  Log.i("MyServiceIntent","Service is started"); 
  

        if (accelerormeterSensor != null)
            sensorManager.registerListener(this, accelerormeterSensor,
                    SensorManager.SENSOR_DELAY_GAME);
 }

 @Override
 public void onDestroy() {
  // TODO Auto-generated method stub
  super.onDestroy();    
  Log.i("MyServiceIntent","Service is destroy");  
  
    if (sensorManager != null)
             sensorManager.unregisterListener(this);

 }

 @Override
 public void onAccuracyChanged(Sensor sensor, int accuracy) {
  // TODO Auto-generated method stub
  
 }

 @Override
 public void onSensorChanged(SensorEvent event) {
  // TODO Auto-generated method stub
     if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
             long currentTime = System.currentTimeMillis();
             long gabOfTime = (currentTime - lastTime);
   

             if (gabOfTime > 100) {
                 lastTime = currentTime;
   

                 x = event.values[SensorManager.DATA_X];
                 y = event.values[SensorManager.DATA_Y];
                 z = event.values[SensorManager.DATA_Z];
   

                 speed = Math.abs(x + y + z - lastX - lastY - lastZ) / gabOfTime * 10000;

   

if (speed > SHAKE_THRESHOLD) {
                  
Log.e("Step!", "SHAKE");
                  
Intent myFilteredResponse = new Intent("com.androday.test.step");
                  
values.Step = count++;
                
String msg = values.Step + "" ;
                  myFilteredResponse.putExtra("serviceData", msg);
                  
                  sendBroadcast(myFilteredResponse);

                 }
                 lastX = event.values[DATA_X];
                 lastY = event.values[DATA_Y];
                 lastZ = event.values[DATA_Z];
             }
         }

 } 

}

 

[values.java]

 

package com.androday.test;

public class values {

 public static int Step = 0;
}

 

 

스승님들 좋은 가름침 부탁드리겠습니다!!

출처 : http://www.mokasocial.com/2011/02/create-a-custom-styled-ui-slider-seekbar-in-android/

Create a Custom-Styled UI Slider (SeekBar) in Android

MokaSocial-Blog-Headers-Slider

An Android slider (or a SeekBar as it’s called in the Android world) is a pretty slick UI tool which we recently used in our Call Your Folks! app as a means of choosing a reminder frequency between one day and three months.

I’ll walk you through creating a custom-styled seekbar for your Android application using nothing but a few XML and image drawables.

In this tutorial, I assume that you know how to implement a SeekBar in your app; if you don’t, check out the Android API demos, specifically SeekBar1.java and seekbar_1.xml.

Step 1: Create Your Image Drawables (9-Patch)

Before creating any XML drawables, make sure you create the image drawables (including one 9-patch drawable) needed for the seekbar background, handle, and progress sections. The 9-patch drawables will be put to use by the XML drawables in the steps below.

Create the following drawables and place them in your /res/drawable/ folder:

Step 2: SeekBar Progress Drawable

Now create an XML drawable for the Android seekbar progress (the blue-striped section in the example), call it seekbar_progress_bg.xml, and place it in your /res/drawable/ folder:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?xml version="1.0" encoding="utf-8"?>
 <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <clip>
            <shape>
                <gradient
                    android:startColor="#FF5e8ea3"
                    android:centerColor="#FF32a0d2"
                    android:centerY="0.1"
                    android:endColor="#FF13729e"
                    android:angle="270"
                />
            </shape>
        </clip>
    </item>
    <item>
        <clip>
        <bitmap xmlns:android="http://schemas.android.com/apk/res/android"
            android:src="@drawable/stripe_bg"
            android:tileMode="repeat"
            android:antialias="true"
            android:dither="false"
            android:filter="false"
            android:gravity="left"
        />
        </clip>
    </item>
</layer-list>

The above XML first draws a semi-transparent, blue gradient, then layers the semi-transparent stripe image on top of the gradient. The highlighted line of code (line 20) refers to the stripe (semi-transparent) image inside your drawable folder, created in Step 1.

For more information on creating custom shapes via XML, check out the Android drawable resources docs, specifically the bitmap and shape sections.

Step 3: SeekBar Background Drawable

Next create the main seekbar progress drawable; it’ll assign a drawable to the seekbar progress and secondaryProgress actions inside your seekbar. Name your drawable something like seekbar_progress.xml, place it inside your /res/drawable/ folder:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/background">
        <nine-patch
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:src="@drawable/seekbar_background"
            android:dither="true"
         />
    </item>
    <item android:id="@android:id/secondaryProgress">
        <clip>
            <shape>
                <gradient
                    android:startColor="#80028ac8"
                    android:centerColor="#80127fb1"
                    android:centerY="0.75"
                    android:endColor="#a004638f"
                    android:angle="270"
                />
            </shape>
        </clip>
    </item>
    <item
        android:id="@android:id/progress"
        android:drawable="@drawable/seekbar_progress_bg"
    />
</layer-list>

The first bit of highlighted code above (line 8) is referring to the seekbar background image (9-patch drawable) created in Step 1 and (line 29) is referring to the drawable you created above in Step 2.

Step 4: Bringing it all together…

At this point, all you need to do is call your seekbar_progress drawable when declaring your seekbar:

01
02
03
04
05
06
07
08
09
10
<SeekBar
        android:id="@+id/frequency_slider"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:max="20"
        android:progress="0"
        android:secondaryProgress="0"
        android:progressDrawable="@drawable/seekbar_progress"
        android:thumb="@drawable/seek_thumb"
/>

The two lines of highlighted code are setting the progress and thumb drawables for the SeekBar item. The @drawable/seekbar_progress refers to the XML drawable created in the previous step.

See it in action!

For a “live demo” of the seekbar bar being used, download our Call Your Folks! app.

For more information on the Android SeekBar, check out the Android docs.


출처 : http://www.androidside.com/bbs/board.php?bo_table=B52&wr_id=7278
아래 싸이트를 보고 이미지만 편집해서 해봤는데요
nine-patch이미지 만드는게 쉽지 않네요.
리소스를 잘 만들지 못해서 깔끔하지가 않지만
찾으시는 분이 많은 것 같아서 해봤습니다.
커스텀 토글 만드실 분은 아래 링크 참고 하셔서 만드시면 되겠습니다.
그리고 이렇게 토글로 만들면 이미지만 변경되는 것일 뿐 슬라이드 처리가 되지 않기 때문에
seekbar로 만들면 더 효과가 비슷할 것으로 보이네요. 위에 링크 걸어놓은 싸이트로 들어가시면 custom seekbar 만드는 법도 가능합니다

- 화면 해상도 알아내기 -

방법 #1
 
1 DisplayMetrics metrics = new DisplayMetrics();
2 getWindowManager().getDefaultDisplay().getMetrics(metrics);
3   
4 int ScreenWidth  = metrics.widthPixels
5 int ScreenHeight = metrics.heightPixels


방법 #2
 
1 WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
2 Display dsp = wm.getDefaultDisplay();
3   
4 int height = dsp.getHeight();
5 int width = dsp.getWidth();

- 화면 상태 확인하기 -

현재 화면이 가로인지 새로인지 확인하는 방법은 화면 해상도를 확인하는 방법도 있겠지만 API 에서 제공하는 함수로도 확인 할 수 있다. 가로 혹은 세로 해상도가 같은 경우에는 API 함수를 이용하는 것이 보다 정확할 것이다.

Android 2.1 이하에서는 getOrientation() 만 동작하며 Android 2.2 이상에서는 getOrientation() 과 getRotation() 이 동작을 한다.

Android 2.1 이하
 
1 WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
2 Display disp = wm.getDefaultDisplay();
3   
4 int orientation = disp.getOrientation(); // Android 2.1
5 Log.i( "Orientation", "orientation : " + orientation );            

Android 2.2 이상
 
01 WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
02 Display disp = wm.getDefaultDisplay();
03   
04 int rotation = disp.getRotation(); // Android 2.2
05 Log.i( "Rotation", "rotation : " + rotation );
06   
07 switch ( rotation )
08 {
09 case Surface.ROTATION_0: 
10     Log.i( "Roation", "Portrait : 0" ); 
11     break;
12       
13 case Surface.ROTATION_90:
14     Log.i( "Roation", "Landscape : 90" );
15     break;
16       
17 case Surface.ROTATION_180:
18     Log.i( "Roation", "Portrait : 180" );
19     break;
20       
21 case Surface.ROTATION_270:
22     Log.i( "Roation", "Landscape : 270" );
23     break;
24 }    
출처 : http://kpbird.blogspot.com/2011/08/android-check-application-is-running.html

Android: Check application is running ?

| Wednesday, August 17, 2011
Android has different application lifecycle, Many times user press Home hardware button and application goes in background, Application is still running but it's in background, Now We want to identify that application is running in background or not. It require when we don't want to create new instance of Activity. Android SDK provide class named ActivityManager. Using ActivityManager we can check application is running in background.

Here is the simple code for the same. you just need to change package name as per your requirement.

01 ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
02  // get the info from the currently running task
03 List < ActivityManager.RunningTaskInfo > taskInfo = am.getRunningTasks(1);
04   
05 Log.d("current task :", "CURRENT Activity ::" + taskInfo.get(0).topActivity.getClass().getSimpleName());
06   
07 ComponentName componentInfo = taskInfo.get(0).topActivity;
08 //if  app is running
09 if(componentInfo.getPackageName().equalsIgnoreCase(*Package Name*))
10 {
11  //do the implementation for if your app is running
12 }

Reference:
http://developer.android.com/reference/android/app/ActivityManager.html

자답입니다.

출처 : http://blog.naver.com/kkamci25?Redirect=Log&logNo=10098212677

각 위젯에서 제공하는 setTextSize Method는 2가지를 제공하고 있다.


1. Pixel 값으로 설정하는 방법

setTextSize(float size) : size는 pixel value를 입력하면 된다.


2. Unit Type을 함께 설정하는 방법

setTextSize(int unit, float size)

unit 값은 TypedValue class에 정의되어 있는 값으로 다음과 같은 값을 갖는다.


/** {@link #TYPE_DIMENSION} complex unit: Value is raw pixels. */
public static final int COMPLEX_UNIT_PX = 0;
/** {@link #TYPE_DIMENSION} complex unit: Value is Device Independent
* Pixels. */
public static final int COMPLEX_UNIT_DIP = 1;
/** {@link #TYPE_DIMENSION} complex unit: Value is a scaled pixel. */
public static final int COMPLEX_UNIT_SP = 2;
/** {@link #TYPE_DIMENSION} complex unit: Value is in points. */
public static final int COMPLEX_UNIT_PT = 3;
/** {@link #TYPE_DIMENSION} complex unit: Value is in inches. */
public static final int COMPLEX_UNIT_IN = 4;
/** {@link #TYPE_DIMENSION} complex unit: Value is in millimeters. */
public static final int COMPLEX_UNIT_MM = 5;

'Android > Tip&Tech' 카테고리의 다른 글

android 해상도 및 가로/세로 알아내기  (1) 2011.09.26
[펌]Android: Check application is running  (0) 2011.09.21
c2dm php 팁#1  (3) 2011.09.21
크롬용 웹 개발툴 설치 주소.  (0) 2011.09.20
[펌]안드로이드 C2DM 소스  (0) 2011.09.20

+ Recent posts