Eclipse 를 켜니 갑자기 Initializing Java Tooling 로딩하는척 하며 멈춰있다.

오 갓뎀...

 

해결방법

workspace\.metadata\.plugins\org.eclipse.core.resources\.projects 안에 있는 폴더를 모두 삭제한다.

 

* 모두 삭제 후 재실행을 하니 svn 정보가 안보인다. 분명 프로젝트 폴더 안에 .svn 이 있는데..

그럴때 rename 을 해주면 svn 정보가 갑자기 보인다.

 

 

Posted by 애이불비
l

 

프로젝트를 import 했을때 무수한 오류들이 쏟아졌다.

거의 '.. must override a superclass method' 같은 오류들이었다.

검색을 해보니 @override 를 삭제 하라는 방법도 있었다.

하지만 삭제하기엔 너무도 많기에..

해결한 방법은

프로젝트 속성에서 Java Compiler 버전을 1.6 이상 으로 하니 오류들이 사라졌다.

 

 

Posted by 애이불비
l

카메라나 갤러리로부터 이미지를 가져와서 Crop 하여 Crop된 이미지를 저장하는 코드이다. 

다음 주소들을 참고하였다. (사실 거의 배낀 수준.. 설명이 아주 잘 나와있다.)


http://theeye.pe.kr/entry/example-of-image-crop-with-camera-and-album-picker-on-android

http://blog.naver.com/PostView.nhn?blogId=legendx&logNo=40132435162


- 갤러리에서 이미지 가져오는 부분

private void getPhotoFromGallery() { // 갤러리에서 이미지 가져오기 

Intent intent = new Intent(Intent.ACTION_PICK);

intent.setType(android.provider.MediaStore.Images.Media.CONTENT_TYPE);

startActivityForResult(intent, PICK_FROM_GALLERY);

}



- 카메라 촬영 후 이미지 가져오는 부분

private void getPhotoFromCamera() { // 카메라 촬영 후 이미지 가져오기

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);


// 임시로 사용할 파일의 경로를 생성

String url = "tmp_" + String.valueOf(System.currentTimeMillis()) + ".jpg";

mImageCaptureUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), url));

intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mImageCaptureUri);

startActivityForResult(intent, PICK_FROM_CAMERA);

}



- onActivityResult() 에서 requestCode 별로 동작하도록 함

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

super.onActivityResult(requestCode, resultCode, data);

 

if (resultCode != RESULT_OK)

return;

switch (requestCode) {

case PICK_FROM_GALLERY: 

{

mImageCaptureUri = data.getData();

Log.i("NR", mImageCaptureUri.getPath().toString());


// 이후의 처리가 카메라 부분과 같아 break 없이 진행

}

case PICK_FROM_CAMERA:

{

Intent intent = new Intent("com.android.camera.action.CROP");

intent.setDataAndType(mImageCaptureUri, "image/*");


// crop한 이미지를 저장할때 200x200 크기로 저장

intent.putExtra("outputX", 200); // crop한 이미지의 x축 크기

intent.putExtra("outputY", 200); // crop한 이미지의 y축 크기

intent.putExtra("aspectX", 2); // crop 박스의 x축 비율 

intent.putExtra("aspectY", 1); // crop 박스의 y축 비율

            intent.putExtra("scale", true);

intent.putExtra("return-data", true);

            startActivityForResult(intent, CROP_FROM_CAMERA);


break;

}

case CROP_FROM_CAMERA: 

{

final Bundle extras = data.getExtras();

// crop된 이미지를 저장하기 위한 파일 경로

String filePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/temp/" + System.currentTimeMillis() + ".jpg";


if (extras != null) {

Bitmap photo = extras.getParcelable("data"); // crop된 bitmap 

storeCropImage(photo, filePath);

sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory()))); // 갤러리를 갱신하기 위해..


...

}


File file = new File(mImageCaptureUri.getPath());

if (file.exists()) {

file.delete();

}

}

}



- Bitmap을 SD 카드에 저장하는 부분

private void storeCropImage(Bitmap bitmap, String filePath) {

File copyFile = new File(filePath);

BufferedOutputStream out = null;


try {

copyFile.createNewFile();

out = new BufferedOutputStream(new FileOutputStream(copyFile));

bitmap.compress(CompressFormat.JPEG, 100, out);

out.flush();

out.close();

} catch (Exception e) {         

e.printStackTrace();

}

}



Posted by 애이불비
l

화면마다 동일한 타이틀바가 필요하여 구글링하여 커스텀 타이틀바를 만들어 보았다. 허접하다..


1. 타이틀바 layout 만들기 


<custom_title.xml>


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

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

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:background="@android:color/background_dark>

    <Button android:id="@+id/backBtn" 

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_alignParentLeft="true"

        android:layout_centerVertical="true"

        android:layout_marginLeft="5dp"

        android:text="@string/btn_back" />

    

    <TextView android:id="@+id/titleTextView"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_centerInParent="true"

        android:textSize="18sp" />

    

    <Button android:id="@+id/nextBtn" 

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_alignParentRight="true"

        android:layout_centerVertical="true"

        android:layout_marginRight="5dp"

        android:text="@string/btn_next" />

    

</RelativeLayout>



2. values폴더의 styles.xml 에 테마 관련 정보 추가하기


<style name="CustomTitle" parent="android:Theme">

<item name="android:windowTitleSize">48dp</item>    

<item name="android:windowTitleBackgroundStyle">@style/CustomWindowTitleBackground</item>

</style>

    

<style name="CustomWindowTitleBackground">

<item name="android:background">#00000000</item>

</style>



3. AndroidManifest.xml 에 테마 설정하기 


<activity 

android:name=".Activity"

android:theme="@style/CustomTitle" />



4.  Activity.java에 다음 코드 넣기 


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);

setContentView(R.layout.main);

getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title);


...

}



끝.



Posted by 애이불비
l

액티비티 위에 새로운 액티비티가 뜨면서  

getResource().getDrawable(id) 부분에서 Out of Memory 오류가 발생하였다 오 갓뎀.....

결국 Manifest.xml 에서 Application 부분에 android:largeHeap="true" 옵션을 추가하였다.


뭔가 찝찝하여 largeHeap 옵션 없이 오류를 안 나게 하기 위해...  

기존 액티비티의 onPause() 에 DrawableUtil.recursiveRecycle(View root) (=> 구글에서 찾으면 쉽게 소스를 찾을 수 있다) 를 추가하였고, 새로운 액티비티의 onPause() 에도 넣었다. (onDestroy() 함수에  recycle 함수가 추가되어 있긴 했는데 onDestroy()가 호출되기 전에 다른 액티비티가 생성되어서 문제가 났다. 일일히 로그를 찍어보면서 확인..)

오류 없이 되긴 했는데.. 함수 호출 순서가 뒤엉켜서 애매했다. 


결국 largeHeap 추가로 끝.


http://aroundck.tistory.com/378 

여기를 보면 largeHeap 옵션은 HoneyComb (3.0) 부터 쓸 수 있고, 다른 App들을 죽일 수 있다고 한다.


Posted by 애이불비
l

앱에서 Facebook에 로그인을 하려고 하니 

error_code=1 Error 1349040 Invalid Application ID: The specified application ID is invalid 

라는 오류가 났다. 

APP ID는 이상이 없는데 말이다.


결론적으로는 Facebook 앱 설정에서 SandBox Mode(?) 를 체크해제 해야 한다.

SandBox Mode가 체크되어 있으면 개발자만 접근 가능하다나 뭐라나...


http://stackoverflow.com/questions/9019924/facebook-response-is-error-code-1-error-1349040-invalid-application-id-the-spec

(여기에서 해결했다고 하지만.. 무슨 말인지 모르겠다는게 함정...)





Posted by 애이불비
l

JXL 라이브러리 사용할때 한글이 안 나오는 경우 WorkbookSettings 을 이용하여 인코딩을 지정해주면 출력된다.

* 애뮬레이터에서는 안되고, 테스트폰에서는 됐다...

InputStream is = getBaseContext().getResources().getAssets().open("test.xls");

WorkbookSettings setting = new WorkbookSettings();

setting.setEncoding("UTF-8");

workbook = Workbook.getWorkbook(is, setting);

Posted by 애이불비
l

ContactsContract.Groups.CONTENT_URI 를 이용하여 연락처 그룹 정보 가져오기

 

private void getGroup() {

Uri uri = ContactsContract.Groups.CONTENT_URI;

String[] projection = new String[] {
    ContactsContract.Groups._ID,
    ContactsContract.Groups.TITLE,
    ContactsContract.Groups.ACCOUNT_NAME,
    ContactsContract.Groups.ACCOUNT_TYPE,
    ContactsContract.Groups.DELETED,
    ContactsContract.Groups.GROUP_VISIBLE
};
//  String selection = ContactsContract.Groups.DELETED + "=0" + " AND " +
//      ContactsContract.Groups.GROUP_VISIBLE + "=1";

String selection = null;
String sortOrder = null;
Cursor cursor = managedQuery(uri, projection, selection, null, sortOrder);
String groupType = null;
String groupTitle = null;
String accountName = null;
  

while (cursor.moveToNext()) {

Log.d(TAG, "Id ===> " + cursor.getString(0));

Log.d(TAG, "Title ===> " + cursor.getString(1));
Log.d(TAG, "Account Name ===> " + cursor.getString(2));
Log.d(TAG, "Account Type ===> " + cursor.getString(3));
Log.d(TAG, "Deleted ===> " + cursor.getString(4));
Log.d(TAG, "Visible ===> " + cursor.getString(5));
   
groupTitle = cursor.getString(1);
groupType = cursor.getString(3);

getGroupSummaryCount(cursor.getString(0));

}

}

 

ACCOUNT_TYPE 은 그룹이 휴대폰 자체 그룹인지 메일 등 다른 데에서 동기화된 그룹인지를 알려준다.

ACCOUNT_NAME 은 메일 등에서의 그룹이면 메일을 알려준다.

그리고 DELETED 은 그룹이 삭제되었음에도 테이블에서는 사라지지 않아서 조건에 붙여야 했다.  

GROUP_VISIBLE 은 그룹의 visible 상태를 리턴하는데

갤럭시 넥서스에서 외부에서 동기화된 그룹의 visible이 0으로 나왔다. 그래서 조건으로 넣지 않았다.

 

그룹의 멤버수를 알기 위해서 ContactsContract.Groups.CONTENT_SUMMARY_URI 를 이용하면 된다.

 

private void getGroupSummaryCount(String groupId) {

Uri uri = ContactsContract.Groups.CONTENT_SUMMARY_URI;

String[] projection = new String[]  { 

ContactsContract.Groups.SUMMARY_COUNT,
ContactsContract.Groups.ACCOUNT_NAME,
ContactsContract.Groups.ACCOUNT_TYPE

};
String selection = ContactsContract.Groups._ID + "=" + groupId;
Cursor cursor = managedQuery(uri, projection, selection, null, null);
int cnt = 0;
while (cursor.moveToNext()) {

Log.w(TAG, item.getGroupTitle() + ",  SummaryCount ===> " + cursor.getInt(0));

cnt = cursor.getInt(0);

}

}

 

Posted by 애이불비
l

Contacts API 를 이용하여 연락처 정보 가져오기

 

private void LoadContacts() {

Uri uri = ContactsContract.Contacts.CONTENT_URI;

String[] projection = new String[] {
    ContactsContract.Contacts._ID,
    ContactsContract.Contacts.DISPLAY_NAME,
    ContactsContract.Contacts.HAS_PHONE_NUMBER };
 

Cursor cursor = managedQuery(uri, projection, null, null, null);
ContactItem item = null;

if (cursor.getCount() > 0) {
    while (cursor.moveToNext()) {
        if (cursor.getInt(2) == 1) 
         LoadPhoneNumbers(cursor.getString(0));
    }

}

}

 

ContactsContract.Contacts.CONTENT_URI 를 이용하여 id 와 name 을 가져온다.

HAS_PHONE_NUMBER 의 결과값이 1일 경우 id 를 넘겨서

ContactsContract.CommonDataKinds.Phone.CONTENT_URI 를 이용하여

해당 id의 전화번호를 가져온다.

 

private void LoadPhoneNumbers(String id) {

Uri uri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI;

String[] projection = new String[] {

ContactsContract.CommonDataKinds.Phone.TYPE, 

ContactsContract.CommonDataKinds.Phone.NUMBER

};

 

String selection = ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=?";
Cursor cursor = managedQuery(uri, projection, selection, new String[] {id}, null);

while (cursor.moveToNext()) {
   Log.w(TAG, "Number Type ==> " + cursor.getString(0));
   Log.w(TAG, "Number ==> " + cursor.getString(1));

}

}

 

타입별로 전화번호를 가져오는 방법은 대략 다음과 같이 하면 될 것 같다.

 

private String getNumberType(int type) {

String numberType = null;

switch (type) {

case Phone.TYPE_MOBILE:
    numberType = "mobile";
    break;

case Phone.TYPE_HOME:
    numberType = "home";

    break;

......

}

return numberType;

}

 

 

 

Posted by 애이불비
l

1. 자바 홈페이지에서 최신 JDK 을 다운로드
- 환경 변수 Path에 ...\jdk\bin 입력

2. Eclipse 다운로드

3. Android SDK 다운로드
- 환경 변수 Path에 ...\tools 입력

4. Eclipse의 Help - Install New Software - add 에서
Location에
https://dl-ssl.google.com/android/eclipse 를 입력하고 설치

5. Eclipse의 Window - Preferences - Android 에서
SDK Location에 Android SDK 경로를 입력 ( Ex >  ...\android-sdk-windows )

6. Eclipse의 Window - Android SDK and AVD Manager - Available Packages 으로 가서 설치

Posted by 애이불비
l