2010년 12월 26일 일요일

[Android] TextView 긴 문장 움직여서 보여주기

 

 

 

 

 

안드로이드 개발하다보면 TextView 의 사이즈보다 Text가 더 길 경우가 생기게 됩니다

 

그럴때 특정 영역에 Text를 모두 보여줄 수 가 있는데 텍스트를 왼쪽으로 움직이면서

 

전체 Text를 보는 방법을 알아 보도록 하겠습니다.

 

사용 예)

xml의 속성값으로

 

android:singleLine="true"
android:ellipsize="marquee"
를 주고

 

자바 코드에서는

 

TextView text = (TextView)findViewById(R.id.text);
text.setSelected(true);

 

이런식으로 선택을 해줘야 합니다.

선택되어진 TextView여야 제대로 동작한다는 걸 알 수 있습니다^^

 

 

 

 

 

 

 

 

 

 

 

2010년 12월 25일 토요일

[JAVA] 문자열에 한글 체크하기

 

 

 

 

 

Character라는 클래스에 getType이라는 메소드가 문자값을 받아

character category값을 리턴해줍니다.

 

public static int getType(char ch)

 

사용예 :

 

String str = "한";

char[] temp = str.toCharArray();

int temp = Character.getType(temp[0]);

 

여기서 temp에 값이 5가 저장되면 한글입니다.

 

 

참 ~~ 쉽쬬잉?

 

 

 

 

 

 

 


 

2010년 12월 20일 월요일

[Android] 화면전환 막기, 가로 세로 화면 설정하기

 

 

 

 

 

 

가로, 세로 화면전환시 실행되고 있는 어플이 초기화 onCreate를 불러들여서,

스레드 돌리다가 뻑나는 경우가 생긴다.



매니페스트 파일내에서 화면전환 방향을 변경할 수 있다.
portrait를 선택하면 세로보기만 된다.



 
 


아니면 Activity 내에서 아래 코드로 화면전환시 할일을 정해주면 된다.


public void onConfigurationChanged(Configuration newConfig) {
		// TODO Auto-generated method stub
		super.onConfigurationChanged(newConfig);
		if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
				할일들.....
		}
	}





[출처] - http://stbaeya.com/tc/240?category=45
 

2010년 12월 16일 목요일

[Android] Selector 사용하기

 

 

 

 

버튼에 대한 이벤트마다 이미지를 변경 시켜주기위해

각각의 터치이벤트에 따라 변경 해주는 귀찮은 작업을

좀더 수월하게 처리해주는 것이 있는데 그건 바로 Selector !

 

res -> drawable-hdpi 폴더에 파일을 하나 생성한다

여기서 파일은 xml확장자를 주어야 한다.

 

 

//on_selector.xml 파일

 

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
 <!-- Non focused states -->
    <item android:state_focused="false"
        android:state_selected="false"
        android:state_pressed="false"
        android:drawable="@drawable/off" />
 
 <!-- Focused states -->
     <item android:state_focused="false"
        android:state_selected="true"
        android:state_pressed="false"
        android:drawable="@drawable/on" />
    <item android:state_focused="true"
        android:state_selected="false"
        android:state_pressed="false"
        android:drawable="@drawable/on" />
    <item android:state_focused="true"
        android:state_selected="true"
        android:state_pressed="false"
        android:drawable="@drawable/on" />

 

 <!-- Pressed -->
    <item android:state_pressed="true"
     android:drawable="@drawable/on" />
</selector>

 

 

각각 아이템마다 3가지 형태에 따라 이미지를 지정해주고

 

<Button
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:background="@drawable/on_selector"
     />

 

 

나중에 버튼에 대한 백그라운드 이미지에 xml파일을 지정해주면 된다.

셀렉터 너무 좋다 +_+;;ㅋㅋ

 

 

 

 

 



 

 

[Android] failed to install .apk on device Unable to open sync connection! 오류

 

 

 

 

 

이런 에러가 뜨는경우

디바이스적 문제가 있다고 보면 된다

해결법으론 어떤분들은 전면에 꼽힌 USB를 후면에 꽂으니까 없어졌다.

그렇게 말씀하시는데 간단하게 USB를 뺏다 꽂으면 해결 되는거 같다!

 

 

 

 

 

 

2010년 12월 13일 월요일

전국 주소 리스트 2010.11.19 [Update!]

 

 

 

프로그램에 적용할 전국 주소를 텍스트파일에 정리햇다..

나름 노가다.. 구분자 넣어서 http://www.zipfinder.co.kr/ 에서

제공해주는 주소를 하나하나 다 붙여넣기햇다..

나중에 다시 사용하게 될지 몰라서 보관하기로 했다..

혹시 필요하신분들은 사용하셔도 됩니다..

 

 

 

2010년 12월 12일 일요일

[Android] GPS 위도/경도를 이용한 두지점 거리계산 총집합!

 

 

 

 

 

 

GPS를 이용한 두지점간 거리계산 방법입니다.

 

안드로이드에서 기본적으로 제공해주는 직선거리 구하는 방법

지구는 타원으로 되어있기에 가까운지역인 경우 오차가 없지만,

거리가 멀어지면 오차가 발생하는걸 알 수 있습니다.

 

방법1.

 

double distance;
 
Location locationA = new Location("point A");
 
locationA.setLatitude(latA);
locationA.setLongitude(lngA);
 
Location locationB = new Location("point B");
 
locationB.setLatitude(latB);
LocationB.setLongitude(lngB);
 
distance = locationA.distanceTo(locationB);

 

 

 

방법2.

float[] results = new float[3];
Location location = new Location("start");
location.distanceBetween(
startLatitude, 
startLongitude, 
endLatitude,
endLongitude,
results);
Sring mes = Float.toString(results[0]);
 
===============================================================================
The computed distance is stored in results[0]. 
If results has length 2 or greater, the initial bearing is stored in results[1].
If results has length 3 or greater, the final bearing is stored in results[2].
 
 
국토지리원에서 공개한 거리계산 함수 사용하기.
지구는 완전한 구라는 가정하에 지구를 GRS80타원체로 봤을경우
두지점간 거리와 방위각 구하는 소스
 
//거리 구하는 부분
 public double distance(double P1_latitude, double P1_longitude,
   double P2_latitude, double P2_longitude) {
  if ((P1_latitude == P2_latitude) && (P1_longitude == P2_longitude)) {
   return 0;
  }
  double e10 = P1_latitude * Math.PI / 180;
  double e11 = P1_longitude * Math.PI / 180;
  double e12 = P2_latitude * Math.PI / 180;
  double e13 = P2_longitude * Math.PI / 180;
  /* 타원체 GRS80 */
  double c16 = 6356752.314140910;
  double c15 = 6378137.000000000;
  double c17 = 0.0033528107;
  double f15 = c17 + c17 * c17;
  double f16 = f15 / 2;
  double f17 = c17 * c17 / 2;
  double f18 = c17 * c17 / 8;
  double f19 = c17 * c17 / 16;
  double c18 = e13 - e11;
  double c20 = (1 - c17) * Math.tan(e10);
  double c21 = Math.atan(c20);
  double c22 = Math.sin(c21);
  double c23 = Math.cos(c21);
  double c24 = (1 - c17) * Math.tan(e12);
  double c25 = Math.atan(c24);
  double c26 = Math.sin(c25);
  double c27 = Math.cos(c25);
  double c29 = c18;
  double c31 = (c27 * Math.sin(c29) * c27 * Math.sin(c29))
    + (c23 * c26 - c22 * c27 * Math.cos(c29))
    * (c23 * c26 - c22 * c27 * Math.cos(c29));
  double c33 = (c22 * c26) + (c23 * c27 * Math.cos(c29));
  double c35 = Math.sqrt(c31) / c33;
  double c36 = Math.atan(c35);
  double c38 = 0;
  if (c31 == 0) {
   c38 = 0;
  } else {
   c38 = c23 * c27 * Math.sin(c29) / Math.sqrt(c31);
  }
  double c40 = 0;
  if ((Math.cos(Math.asin(c38)) * Math.cos(Math.asin(c38))) == 0) {
   c40 = 0;
  } else {
   c40 = c33 - 2 * c22 * c26
     / (Math.cos(Math.asin(c38)) * Math.cos(Math.asin(c38)));
  }
  double c41 = Math.cos(Math.asin(c38)) * Math.cos(Math.asin(c38))
    * (c15 * c15 - c16 * c16) / (c16 * c16);
  double c43 = 1 + c41 / 16384
    * (4096 + c41 * (-768 + c41 * (320 - 175 * c41)));
  double c45 = c41 / 1024 * (256 + c41 * (-128 + c41 * (74 - 47 * c41)));
  double c47 = c45
    * Math.sqrt(c31)
    * (c40 + c45
      / 4
      * (c33 * (-1 + 2 * c40 * c40) - c45 / 6 * c40
        * (-3 + 4 * c31) * (-3 + 4 * c40 * c40)));
  double c50 = c17
    / 16
    * Math.cos(Math.asin(c38))
    * Math.cos(Math.asin(c38))
    * (4 + c17
      * (4 - 3 * Math.cos(Math.asin(c38))
        * Math.cos(Math.asin(c38))));
  double c52 = c18
    + (1 - c50)
    * c17
    * c38
    * (Math.acos(c33) + c50 * Math.sin(Math.acos(c33))
      * (c40 + c50 * c33 * (-1 + 2 * c40 * c40)));
  double c54 = c16 * c43 * (Math.atan(c35) - c47);
  // return distance in meter
  return c54;
 }
//방위각 구하는 부분
 public short bearingP1toP2(double P1_latitude, double P1_longitude,
   double P2_latitude, double P2_longitude) {
  // 현재 위치 : 위도나 경도는 지구 중심을 기반으로 하는 각도이기 때문에
  //라디안 각도로 변환한다.
  double Cur_Lat_radian = P1_latitude * (3.141592 / 180);
  double Cur_Lon_radian = P1_longitude * (3.141592 / 180);
  // 목표 위치 : 위도나 경도는 지구 중심을 기반으로 하는 각도이기 때문에
  // 라디안 각도로 변환한다.
  double Dest_Lat_radian = P2_latitude * (3.141592 / 180);
  double Dest_Lon_radian = P2_longitude * (3.141592 / 180);
  // radian distance
  double radian_distance = 0;
  radian_distance = Math.acos(Math.sin(Cur_Lat_radian)
    * Math.sin(Dest_Lat_radian) + Math.cos(Cur_Lat_radian)
    * Math.cos(Dest_Lat_radian)
    * Math.cos(Cur_Lon_radian - Dest_Lon_radian));
  // 목적지 이동 방향을 구한다.(현재 좌표에서 다음 좌표로 이동하기 위해서는 
  //방향을 설정해야 한다. 라디안값이다.
  double radian_bearing = Math.acos((Math.sin(Dest_Lat_radian) - Math
    .sin(Cur_Lat_radian)
    * Math.cos(radian_distance))
    / (Math.cos(Cur_Lat_radian) * Math.sin(radian_distance)));
  // acos의 인수로 주어지는 x는 360분법의 각도가 아닌 radian(호도)값이다.
  double true_bearing = 0;
  if (Math.sin(Dest_Lon_radian - Cur_Lon_radian) < 0) {
   true_bearing = radian_bearing * (180 / 3.141592);
   true_bearing = 360 - true_bearing;
  } else {
   true_bearing = radian_bearing * (180 / 3.141592);
  }
  return (short) true_bearing;
 }
 
 
이외 거리 구하는 참고자료는 첨부파일 참고해주세요~
 
 
 
 
 

2010년 12월 10일 금요일

윈도우 XP에서 외장HDD, 메모리가 제거 되지 않을경우

 

 

 

 

 

 

 

 

 

작업관리자에서 explorer.exe를 강제 종료 시킨 후에 재실행하면 제거 가능하다.

<작업관리자에서 explorer.exe를 종료시킨 후>

<파일 -> 새 작업 클릭>

<explorer.exe를 재실행>

그 후에 USB 하드디스크 혹은 메모리를 제거하면 된다.









2010년 12월 8일 수요일

[Android] 폰트(글씨체)변경 하기 (FontType Change)

 

 

 

 

 

 

안드로이드를 개발하다보면 제공해주는 글씨체가 3개밖에 없습니다.

그래서 보다 더 깔끔하고 이쁘게 꾸미기 위해

폰트를 변경하는 방법을 적어보도록 하겠습니다.

C:\WINDOWS\Fonts폴더에 보시면 윈도우에 제공해주는 폰트들이 있습니다.

그중에 아래 그림의 아이콘이 안드로이드에서 사용가능한 폰트파일 입니다.

 

 

 

 

 

 

원하시는 폰트를 복사해서

안드로이드 프로젝트에 assets/fonts 폴더 아래 넣어주게 합니다.

그리고

 

자바파일:
TextView tv=(TextView)findViewById(R.id.custom);
Typeface face=Typeface.createFromAsset(getAssets(), "fonts/폰트이름.ttf");

main.xml 파일:

<TextView
            android:id="@+id/custom"
            android:text="Hello, world!"
            android:textSize="20sp" />

 

 

이런식으로 폰트를 변경 할 수 있습니다.

현재는 TextView 단일 위젯만 변경이 가능하지만, 혹시 클래스나

레이아웃 전체를 변경 하실 수 있는 방법을 아시는 분은 좀 알려주세요 ㅠ.ㅠ

 

 

 

 

ps. 안드로이드로 사용가능한 폰트 몇개 올려둡니다.

 

 

 

 

 

 

 

 

 

 

 

 

[Android] 음성 인식 API 소스

 

 

 

 

구글링중에 음성인식 API를 사용해서 음성인식 하는 방법을 찾았다.

나름 인식률 80프로 이상 인거 같다..

인식률이 잘나오는 만큼 다방면에 사용될거 같은..

음성 입력후 패턴분석된 결과 리스트가 나열되는 소스이다.

 

 

voiceDemo.java 파일

 

 

public class voiceDemo extends Activity implements OnClickListener {
 private static final int REQUEST_CODE = 1234;
 private ListView mList;
 private ListView mDebug;

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  Button speakButton = (Button) findViewById(R.id.btn_speak);
  speakButton.setText("음성입력");
  mList = (ListView) findViewById(R.id.list);
  PackageManager pm = getPackageManager();
  List<ResolveInfo> activities = pm.queryIntentActivities(new Intent(
    RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
  if (activities.size() != 0) {
   speakButton.setOnClickListener(this);
  } else {
   speakButton.setEnabled(false);
   speakButton.setText("Recognizer not Present");
  }
 }

 public void onClick(View v) {
  if (v.getId() == R.id.btn_speak) {
   startVoiceRecognitionActivity();
  }
 }

 private void startVoiceRecognitionActivity() {
  try {
   Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
   intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
     RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
   intent.putExtra(RecognizerIntent.EXTRA_PROMPT,
     "Free Form Language Model Demo");
   startActivityForResult(intent, REQUEST_CODE);
  } catch (ActivityNotFoundException ex) {
   Toast
     .makeText(voiceDemo.this, "Activity Not Found",
       Toast.LENGTH_LONG).show();
  }
 }

 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
   ArrayList<String> matches = data
     .getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
   mList.setAdapter(new ArrayAdapter<String>(this,
     android.R.layout.simple_list_item_1, matches));
  }
  super.onActivityResult(requestCode, resultCode, data);
 }
}

 

 

 

 

 

 

main.xml 파일

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
 <TextView
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:paddingBottom="4dip" />
 <Button
 android:id="@+id/btn_speak"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:text="@string/speak_button" />
 <ListView
 android:id="@+id/list"
 android:layout_width="fill_parent"
 android:layout_height="0dip" android:layout_weight="1" />
</LinearLayout>

 

 

 

2010년 12월 7일 화요일

[Android] 2.3 Platform SDK Update!!!

 

 

 

오늘 새벽에 2.3 생강빵 올라왓네요

 

http://developer.android.com/sdk/android-2.3.html

 

조금전에 확인하고 바로 SDK 업데이트 시켯지만..

 

잘못 햇는지 이런 오류뜨네요//

 

뭐 sdk폴더 위치 지정이 잘못된거 같은데.. 흠...

 

시간도 그렇고 자고 내일 일어나서 해야겟음..

 

여러분도 조심해서 업데이트 하시길..

 

 

 

 

 

 

 

 

 

Could not find
C:\..\tools\adb.exe!
Please check the Android plugin's preferences.

 

 

// 에러 원인을 찾았다..

문제는 이클립스 플러그인 (ADT)를 업데이트 하지 않았기 때문..

 

 

 

Eclipse 3.5 (Galileo) and 3.6 (Helios)
  1. Start Eclipse, then select Help > Install New Software....
  2. Click Add, in the top-right corner.
  3. In the Add Repository dialog that appears, enter "ADT Plugin" for the Name and the following URL for the Location:
    https://dl-ssl.google.com/android/eclipse/

    Note: If you have trouble acquiring the plugin, try using "http" in the Location URL, instead of "https" (https is preferred for security reasons).

    Click OK.

  4. In the Available Software dialog, select the checkbox next to Developer Tools and click Next.
  5. In the next window, you'll see a list of the tools to be downloaded. Click Next.
  6. Read and accept the license agreements, then click Finish.
  7. When the installation completes, restart Eclipse.

 

 

 

 

[Android] 어플리케이션 Process 를 얼추 죽이는 새로운 방법

 

 

 

프로세스를 정상종료 하려고 구글링 하다가 발견한 방법..

기존의 프로세스 죽이는 방법은 2.1까지만 지원되다가

2.2 부터는 아직까지 정확하게 프로세스를 정상종료 시키는 방법이 없다고 합니다.

하지만 거의(얼추) 죽이는 방법이 있다고 해서 포스팅 해봅니다.

 

 

 

 

public void requestKillProcess(final Context context){
	
	//#1. first check api level.
	int sdkVersion = Integer.parseInt(Build.VERSION.SDK);
	if (sdkVersion < 8){
		//#2. if we can use restartPackage method, just use it.
		ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
		am.restartPackage(getPackageName());
	}else{
		//#3. else, we should use killBackgroundProcesses method.
		new Thread(new Runnable() {
			@Override
			public void run() {
				ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
				String name = getApplicationInfo().processName;
				RunningServiceInfo si;
				
				//pooling the current application process importance information.
				while(true){
					List<RunningAppProcessInfo> list = am.getRunningAppProcesses();
					for(RunningAppProcessInfo i : list){
						if(i.processName.equals(name) == true){
							//#4. kill the process,
							//only if current application importance is less than IMPORTANCE_BACKGROUND
							if(i.importance >= RunningAppProcessInfo.IMPORTANCE_BACKGROUND)
								am.restartPackage(getPackageName());	//simple wrapper of killBackgrounProcess
							else
								Thread.yield();
							break;
						}
					}
				}
			}
		}, "Process Killer").start();
	}
}

 

안드로이드 프로요 2.2 아래 버젼 일경우 ..

1.메니페스트 파일에 RESTART_PACKAGES 권한을 사용한다고 선언한다.
<uses-permission android:name="android.permission.RESTART_PACKAGES"/>

2.ActivityManager 의 restartPackage API 를 호출한다.
ActivityManager am
             = (ActivityManager)getSystemService(ACTIVITY_SERVICE);
am.restartPackage(getPackageName());

이것도 말끔히 종료 되진 않지만 그래도 얼추 죽일 수 있다고 하네요..

 

 

 

 

안드로이드 프로요 2.2 윗 버젼 일경우 ..

 

SDK 버전과 관계없이 프로세스를 종료할 때 사용할 수 있는 requestKillProcess() 라는 메서드를 구현하였습니다. 프로요 이전 버전인 경우, 기존에 사용하던 방법이 그대로 별다른 생각없이 restartPackage() 메서드를 호출 하도록 구현되어 있습니다.


 프로요 이 후 버전인 경우가 조금 골치 아픈데, 어느 시점에 해당 어플리케이션 프로세스의 우선 순위가 변경될지 알아내는 방법을 잘 몰라서, 주기적으로 프로세스 상태 정보를 폴링하도록 구현되었습니다. 스레드를 하나 생성한 후, 프로세스의 상태를 반복 체크하다가, 프로세스 중요도가 IMPORTANCE_BACKGROUND 보다 낮아지는 순간, restartPackage() 를 호출 하도록 되어있습니다.

 어째, 구현 내용이 좀 꺼림직 하긴 합니다만, 어플리케이션 내에서 사용하는 어플리케이션 컴포넌트 (Service / Activity / BroadcastReceiver ) 관리에만 신경을 써 준다면 (시작한 Service 는 잊지 않고 정지 시켜주는 등), 기존 restartPackage() 와 같이 어플리케이션 어느 시점에 호출에도 얼추 비슷하게 동작하는 것은 확인 하였습니다. (스레드가 계속 도니까;;;;)

 

 

 

[출처] - http://huewu.blog.me/110089551997

2010년 12월 6일 월요일

[Android] 자신의 전화번호 가져오기

 

 

 

TelephonyManager telManager = (TelephonyManager)context.getSystemService(context.TELEPHONY_SERVICE);
String phoneNum = telManager.getLine1Number();

 

이렇게 하면 가져올 수 있습니다..

 

그리고

manifest 파일에 uses-permission 을 설정 해야 되겠습니다.
<uses-permission android:name="android.permission.READ_PHONE_STATE" />