안녕하세요

프로그램 과정에서 막혔던 문제들에 대한 해결책 정리


페이지 목록

2011년 1월 25일 화요일

[안드로이드] App에서 MediaScanner 호출하기(Android call MediaScanner in App)

sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"
                + Environment.getExternalStorageDirectory())));


엄청난 정보로군요!!


완전 찾고 있던 정본데


멋집니다.


자세한 정보는 


http://www.androidpub.com/61214

[안드로이드] 자바 스트링 파싱하는 방법 (Java String parsing)

Java String Split Example


 /*
Java String split example.
This Java String split example describes how Java String is split into multiple
Java String objects.
*/

public class JavaStringSplitExample{

  public static void main(String args[]){
  /*
  Java String class defines following methods to split Java String object.
  String[] split( String regularExpression )
  Splits the string according to given regular expression.
  String[] split( String reularExpression, int limit )
  Splits the string according to given regular expression. The number of resultant
  substrings by splitting the string is controlled by limit argument.
  */

  /* String to split. */
  String str = "one-two-three";
  String[] temp;

  /* delimiter */
  String delimiter = "-";
  /* given string will be split by the argument delimiter provided. */
  temp = str.split(delimiter);
  /* print substrings */
  for(int i =0; i < temp.length ; i++)
    System.out.println(temp[i]);

  /*
  IMPORTANT : Some special characters need to be escaped while providing them as
  delimiters like "." and "|".
  */

  System.out.println("");
  str = "one.two.three";
  delimiter = "\\.";
  temp = str.split(delimiter);
  for(int i =0; i < temp.length ; i++)
    System.out.println(temp[i]);

  /*
  Using second argument in the String.split() method, we can control the maximum
  number of substrings generated by splitting a string.
  */

  System.out.println("");
  temp = str.split(delimiter,2);
  for(int i =0; i < temp.length ; i++)
    System.out.println(temp[i]);

  }

}

/*
OUTPUT of the above given Java String split Example would be :
one
two
three
one
two
three
one
two.three
*/

출처 : http://www.java-examples.com/java-string-split-example

보다시피, '.' 과 같은 특수한 키의 경우에는 파싱하는 법이 조금 다르다는 것을 알 수 있다.

[안드로이드] 데이트 와 타임 피커 소스(android date picker & time picker source)

package date.picker;

import java.util.Calendar;

import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.app.TimePickerDialog;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.TextView;
import android.widget.TimePicker;

public class hellodatePicker extends Activity {
    /** Called when the activity is first created. */
private TextView mDateDisplay;
    private Button mPickDate;

    private int mYear;
    private int mMonth;
    private int mDay;

    static final int DATE_DIALOG_ID = 0;

    private TextView mTimeDisplay;
    private Button mPickTime;

    private int mHour;
    private int mMinute;

    static final int TIME_DIALOG_ID = 1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // capture our View elements
        mDateDisplay = (TextView) findViewById(R.id.dateDisplay);
        mPickDate = (Button) findViewById(R.id.pickDate);

        // add a click listener to the button
        mPickDate.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                showDialog(DATE_DIALOG_ID);
            }
        });

        // get the current date
        final Calendar c = Calendar.getInstance();
        mYear = c.get(Calendar.YEAR);
        mMonth = c.get(Calendar.MONTH);
        mDay = c.get(Calendar.DAY_OF_MONTH);
      
        // get the current time
        mHour = c.get(Calendar.HOUR_OF_DAY);
        mMinute = c.get(Calendar.MINUTE);

        // display the current date
        updateDateDisplay();
      
     // capture our View elements
        mTimeDisplay = (TextView) findViewById(R.id.timeDisplay);
        mPickTime = (Button) findViewById(R.id.pickTime);

        // add a click listener to the button
        mPickTime.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                showDialog(TIME_DIALOG_ID);
            }
        });

      

        // display the current date
        updateTimeDisplay();
    }
  
    @Override
    protected Dialog onCreateDialog(int id) {
        switch (id) {
        case DATE_DIALOG_ID:
            return new DatePickerDialog(this,
                        mDateSetListener,
                        mYear, mMonth, mDay);
        case TIME_DIALOG_ID:
            return new TimePickerDialog(this,
                    mTimeSetListener, mHour, mMinute, false);
        }
        return null;
    }
  
    // updates the date we display in the TextView
    private void updateDateDisplay() {
        mDateDisplay.setText(
            new StringBuilder()
                    // Month is 0 based so add 1
                    .append(mMonth + 1).append("-")
                    .append(mDay).append("-")
                    .append(mYear).append(" "));
    }
  
    // updates the time we display in the TextView
    private void updateTimeDisplay() {
        mTimeDisplay.setText(
            new StringBuilder()
                    .append(pad(mHour)).append(":")
                    .append(pad(mMinute)));
    }
  
    // the callback received when the user "sets" the date in the dialog
    private DatePickerDialog.OnDateSetListener mDateSetListener =
            new DatePickerDialog.OnDateSetListener() {

                public void onDateSet(DatePicker view, int year,
                                      int monthOfYear, int dayOfMonth) {
                    mYear = year;
                    mMonth = monthOfYear;
                    mDay = dayOfMonth;
                    updateDateDisplay();
                }
            };
          
         // the callback received when the user "sets" the time in the dialog
            private TimePickerDialog.OnTimeSetListener mTimeSetListener =
                new TimePickerDialog.OnTimeSetListener() {
                    public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
                        mHour = hourOfDay;
                        mMinute = minute;
                        updateTimeDisplay();
                    }
                };
                private static String pad(int c) {
                    if (c >= 10)
                        return String.valueOf(c);
                    else
                        return "0" + String.valueOf(c);
                }
}


xml file

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView android:id="@+id/dateDisplay"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text=""/>

    <Button android:id="@+id/pickDate"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Change the date"/>
            
    <TextView android:id="@+id/timeDisplay"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text=""/>

    <Button android:id="@+id/pickTime"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Change the time"/>

</LinearLayout>

android developer의 timepicker와 datepicker를 합친것 -_-b

Best Wishes
You,Guyes

2011년 1월 20일 목요일

[안드로이드] sdcard/audio 에 있는 mp3 album_art를 가져와서 보여주는 소스(andorid show albumart using sdcard mp3)

package how.Album;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;

import android.app.ListActivity;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;

public class albumArt extends ListActivity {
    /** Called when the activity is first created. */
    private static final BitmapFactory.Options sBitmapOptionsCache = new BitmapFactory.Options();
    private static final Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart");
    Context mContext;
    ImageView image;
    FileManager fM;
    ArrayList<Bitmap> albumarts = new ArrayList<Bitmap>();
    ArrayList<String> albumInfo = new ArrayList<String>();
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mContext = this;
        fM = new FileManager();
        fM.initFiles(this);
        image = (ImageView)findViewById(R.id.row_album_art);
    
      
        String[] cols = new String[] {
                MediaStore.Audio.Albums._ID,
                MediaStore.Audio.Albums.ARTIST,
                MediaStore.Audio.Albums.ALBUM,
                MediaStore.Audio.Albums.ALBUM_ART
        };

        Cursor cur = getContentResolver().query(
                    MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
                    cols , null , null, null);
      
        if (cur.moveToFirst()) {
            String ablum;
            String artist;
            String id;
            String albumArt;
            int idNum;
            int artistColumn = cur.getColumnIndex(MediaStore.Audio.Albums.ARTIST);
            int ablumColumn = cur.getColumnIndex(MediaStore.Audio.Albums.ALBUM);
            int albumArtColumn = cur.getColumnIndex(MediaStore.Audio.Albums.ALBUM_ART);
            String imagePath;
      
            do {
                // Get the field values
             idNum = cur.getInt(0);         // 레코드의 _id를 가져옵니다.
             id = String.valueOf(idNum);
             artist = cur.getString(artistColumn);     // title 필드의 값을 가져옴
             ablum = cur.getString(ablumColumn);   // artist 필드의 값을 가져옴
             albumArt = cur.getString(albumArtColumn);
            
          
          
             Bitmap album_art = getBitmapImage( idNum,200, 200);
                albumarts.add(album_art);       // 두개 합쳐서  array list 에 넣어줌.
                albumInfo.add(ablum + " - " + artist);
              
            } while (cur.moveToNext());
            ArrayAdapter<String> songList = new ArrayAdapter<String>(this,
             android.R.layout.simple_list_item_1, albumInfo);
            setListAdapter(songList);
        }
      
      
    }

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
Bitmap b = albumarts.get(position );
image.setImageBitmap(b);

}
  
  public Bitmap getBitmapImage(int id, int w, int h) {
       ContentResolver res = mContext.getContentResolver();
             Uri uri = ContentUris.withAppendedId(sArtworkUri, id);
             if (uri != null) {
                 ParcelFileDescriptor fd = null;
                 try {
                     fd = res.openFileDescriptor(uri, "r");
                     int sampleSize = 1;
                   
                     sBitmapOptionsCache.inJustDecodeBounds = true;
                     BitmapFactory.decodeFileDescriptor(fd.getFileDescriptor(), null, sBitmapOptionsCache);
                     int nextWidth = sBitmapOptionsCache.outWidth >> 1;
                     int nextHeight = sBitmapOptionsCache.outHeight >> 1;
                     while (nextWidth>w && nextHeight>h) {
                         sampleSize <<= 1;
                         nextWidth >>= 1;
                         nextHeight >>= 1;
                     }
                     sBitmapOptionsCache.inSampleSize = sampleSize;
                     sBitmapOptionsCache.inJustDecodeBounds = false;
                     Bitmap b = BitmapFactory.decodeFileDescriptor(
                             fd.getFileDescriptor(), null, sBitmapOptionsCache);
                     if (b != null) {
                         if (sBitmapOptionsCache.outWidth != w || sBitmapOptionsCache.outHeight != h) {
                             Bitmap tmp = Bitmap.createScaledBitmap(b, w, h, true);
                             b.recycle();
                             b = tmp;
                         }
                     }
                     return b;
                 } catch (FileNotFoundException e) { return null;
                 } catch (Exception e) { return null;
                 } finally {
                     try {
                         if (fd != null)
                             fd.close();
                     } catch (IOException e) {
                     }
                 }
             }
             return null;
      }

}

참조:
http://www.androidpub.com/32022

특히 getBitmapImage 는 댓글의 '아름다운 밤'님의 소스와 100% 동일함을 알려드립니다.

2011년 1월 19일 수요일

[안드로이드] imageview 에 bitmap이미지 넣기

image.setImageBitmap(album_art);

image는 ImageView

album_art = Bitmap

간단하다.
Drawable drawable;
setImageBackgroundDrawable(drawable);

은 ImageView에는 먹히지 않는 사실을 알아 냈다.

[안드로이드] mp3 한글 파일 이름 깨짐 현상 해결

 그렇다. 이것은 나는 나의 문제, 나의 코딩실력의 문제, 내가 부족해서 생겼다고 생각하였다. 그러나, However, but, whenever 이것은 안드로이드 구글 의 문제, 나의 문제가 아니었다.

 이럴 수가. 구글이 잘못 만들어서 나는 캐 고생을 해 버렸다 ㅠ 그래서 나는 해법을 찾아 하이에나가 먹이를 찾아 킬리만자로를 헤매듣이 헤맨 끝에 해결책을 발견하였다.

 미디어를 스캔하기 전에 언어를 한글로 바꿔줘야 하는 것이었다. 언어가 영어인 상태로 미디어를 한 번 스캔 해 버리면 그 후 언어를 한글로 바꿔줘도 깨져버린 파일들은 복구할 도리가 없다. 그러므로 미디어 스캔하기 전에 꼭 한글로 먼저 언어를 바꾼 후에 스캔하도록 하자.

 이미 영어로 지정된 상태에서 스캔을 해 버렸다면 파일들을 다 하드디스크로 옮긴 후 (그리고 sdcard에서는 없애고) 다시 스캔 하고 -> 한글로 언어 변경 -> 다시 미디어 스캔을 하면 된다.

 그 외 인코딩 해 놓은 파일을 바꿔주는 프로그램도 있다고 한다. 그 이름 하여 tagbear

 이 파일을 검색해서 다운 받으면 알아서 곰플레이어 서버에 있는 태그 정보들을 새로 입혀준다고 한다. 그래서 모든 mp3 파일에 앨범 태그라던지 이름 이라던지 모두 새로 고쳐준다.

 출처

[안드로이드] super를 사용하는 이유

안드로이드를 공부하다 보면 super라는 걸 사용하는 걸 보게 된다. super가 무엇일까? 아- 귀찮아 걍 해주면 되는 거 알게 머냐 하고 지나가던 중 그래도 좀 더 깊게 공부하려면 알아야 겠다는 생각이 들어서 검색하였다.

Super란?

 보통 Override 되는 함수의 경우 그 함수 이전에 상위 클래스를 가지게 된다. 그렇기에 이와 같은 함수를 이용할 때는 상위 함수에 우리가 하고 있는 작업에 대한 정보를 전달해 주어야 한다. 이때 사용되는 것이 super이다. super를 사용함으로서 상위 클래스에 현재 작업 내용을 전달하여 상위클래스와의 소통을 하는 것이다. 이로 인해 현재 작업하는 클래스의 정보가 상위 레벨로 전달이 되고 원할하게 프로그램을 만들 수 있게 되는 것이다.

2011년 1월 18일 화요일

[안드로이드] 미디어 플레이어 앨범 자켓 확인 및 만들기

 앨범 자켓이 없는 mp3는 왠지 허전하다.

 그리고 지금 현재 개발하고 있는 프로그램에서 앨범 자켓을 띄어와서 보여줘야 하므로 굉장히 필요하다.

 현재 mp3 파일들 중 대다수가 앨범 자켓이 뜨지 않는다. 이것은 앨범 자켓이 없어서 그런 것인가, 아니면 프로그램이 잘못 된 것인가. 하는 회의를 하기를 여러 수십 밤(은 오바고)

 그래서 서핑을 다시 열심히 하였다. 내가 원하는 것은 어떻게 해야 안드로이드에서 앨범 자켓 이미지를 잘 가져올 수 있을까? 그렇다. 이를 위해 찾고 또 찾은 끝에 드디어 원하는( 완벽히 일치하지는 않지만) 내용을 찾을 수 있었다.

 그것은 바로 윈도우 탐색기에서 mp3가 앨범 자켓이 있는 지 없는 지 확인하고 없다면 앨범 자켓을 만들어주는 방법에 대한 블로그였다. 그렇다. 이를 통해 나는 나의 문제점을 더 확실히 알 수 있게 되었다.

 mp3 의 자켓 만드는 방법 및 자켓 확인 방법
:http://linkovertheworld.blogspot.com/2010/04/blog-post_28.html

[안드로이드] SD카드에서 가져 온 이미지로 배경화면 만들기(android make background from sd card image)

package skin.file;

import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.Toast;

public class FileManager {
private final static String PATH = "path.txt";
private Context ctx;
public FileManager(){

}
public void initFiles(Context theContext) {
ctx = theContext;
}
public void setBackground(LinearLayout linear){
String iPath = readImagePath();
   /** 완성된 이미지 보여주기  */
BitmapFactory.Options bfo = new BitmapFactory.Options();
bfo.inSampleSize = 2;

Bitmap bm = BitmapFactory.decodeFile(iPath, bfo);

//bitmap을 drawable로
Drawable d =new BitmapDrawable(bm);
linear.setBackgroundDrawable(d);
}
public void setBackground(RelativeLayout linear){
String iPath = readImagePath();
   /** 완성된 이미지 보여주기  */
BitmapFactory.Options bfo = new BitmapFactory.Options();
bfo.inSampleSize = 2;

Bitmap bm = BitmapFactory.decodeFile(iPath, bfo);

//bitmap을 drawable로
Drawable d =new BitmapDrawable(bm);
linear.setBackgroundDrawable(d);
}
public void writeImagePath(String imgPath)
{
try{
// Other = createPackageContext("skin.test",Context.CONTEXT_IGNORE_SECURITY);
FileOutputStream fOut = ctx.openFileOutput(PATH, Context.MODE_PRIVATE);
OutputStreamWriter out1 = new OutputStreamWriter(fOut);
out1.write(imgPath);
out1.close();
}
catch(Throwable t){
Toast
.makeText(ctx, "Exception: "+t.toString(), 5000)
.show();
}
}
public String readImagePath()
{
StringBuffer buf=new StringBuffer();
try{
// Other = createPackageContext("skin.test",Context.CONTEXT_IGNORE_SECURITY);
InputStream mIS1 = ctx.openFileInput(PATH);
InputStreamReader tmp = new InputStreamReader(mIS1);
BufferedReader reader=new BufferedReader(tmp);

String str;


while ((str = reader.readLine()) != null) {
buf.append(str);
}

mIS1.close();

}catch (java.io.FileNotFoundException e) {
Log.i("FileNotFoundException","");
}
catch (Throwable t) {
Toast
.makeText(ctx, "Exception: "+t.toString(), 5000)
.show();
}
String rString = null;
if(buf.length() > 0)
rString = buf.toString();

return rString;
}
}
writeImage의 Parameter에 sdcard의 이미지 경로를 넘겨주면 그 값을 path.txt 에 저장하여 후에 배경화면으로 쓰일 때 이용하는 소스입니다.

 안 되시거나 궁금한 점 있으면 댓글 달아 주세요.

2011년 1월 17일 월요일

[안드로이드] 인텐트 flag를 통한 Activity flow 제어(android activity flow control by intent flag)

인텐트에는 4가지의 flag가 존재한다.


No flag를 포함하면 다섯가지


이 flag들을 통해서 android의 activity stack을 control 할 수 있다.


안드로이드로 개발을 하다보면 뜻하지 않게 엄청난 양의 Activity들이 쌓여나가는 것을 볼 수 있다. 현재 필자가 개발하고 있는 프로그램에서는 GirdView에 image들을 띄우고 그 중 하나의 image를 선택하여 배경화면으로 세팅하는 것이 있다.

이 때 다음과 같은 일이 발생한다.

GridView가 있는 Activity -> GridView에서 선택한 Image를 확대해서 보여주는 Activity -> (확인 클릭 시) GridView가 있는 Activity 로 다시 이동 -> GridView가 있는 Activity에서 다른 Image 선택 -> Image 확대 Activity -> GridView가 있는 Activity -> 확대 된 image가 있는 Activity


이렇게 몇 번 GridView에서 이미지를 선택해주면 엄청난 양의 Activity들이 쌓이는 것을 볼 수있다. 이를 제어하기 위해 인텐트에 플래그를 적용시켜 주는 것이다.


먼저 FLAG_ACTIVITY_SINGLE_TOP 입니다. 우선 간단하게 그림으로 표현해 보았습니다. A 와 B 두 가지 Activity 가 있는 데, A 라는 Activity 는 B 를 B 라는 Activity 는 다시 자기 자신인 B 를 호출 하는 경우라고 가정해 보겠습니다.

호출하는 Activity B 가 이미 Task 의 가장 앞에 위치하는 경우, 또 하나의 B 를 생성하는 대신, 기존에 존재하는 B Activity 가 재활용됩니다. 이 때 B 가 재활용된다는 것을 개발자가 알아채고 새롭게 전달되는 Intent 를 사용할 수 있도록 B Activity 의 onPause() / onNewIntent() / onResume() 가 순차적으로 호출됩니다. 별 생각없이 동일한 Activity 를 여러번 생성하는 것은 메모리 사용량과 Activity 시작 속도 양쪽 모두에 악영향을 끼칠 수 있습니다. (특히 이미지가 덕지덕지 붙어 있는 Activity 라면). 이런 경우 FLAG_ACTIVITY_SINGLE_TOP 를 적절하게 활용하면 제법 큰 효과를 볼 수 있습니다.


두 번째는, FLAG_ACTIVITY_NO_HISTORY 플래그입니다. 우 선 간단하게 그림으로 표현해 보았습니다. A 와 B 두 가지 Activity 가 있는 데, A 라는 Activity 는 B 를 B 라는 Activity 는 A 를 호출한 후 에 (A->B->A) 사용자가 Back 키를 누르는 경우를 가정해 보겠습니다.


말 그대로, FLAG_ACTIVITY_NO_HISTORY 로 설정된 Intent 로 시작된 Activity B 는 Task 에 그 흔적을 남기지 않게 됩니다. B 에서 또다른 A 를 시작한 후, Back 을 누르면 일반적인 경우 이전에 실행되었던 B 가 나타나지만, NO_HISTORY 를 사용하는 경우 맨 처음에 실행 되었던 A 가 화면에 표시됩니다. 몇 가지 주의할 점이 있습니다. 우선 NO_HISTORY 를 사용하게 되면 Task 에 해당 Intent 의 정보가 기록되지 않기 때문에, A->B 인 상황 (그림에서 두 번째 단계...) 에서 홈키등을 눌러 다른 Task 로 전환된 후, 다시 본 Task 로 돌아오게 되면, A Activity 가 화면에 표시됩니다. 또한, B Activity 의 onDestroy() 가 호출되는 시점이 조금 애매합니다.일반적인 예상과는 달리, B 에서 또다른 A Activity 를 호출하는 세 번째 단계에서는 onStop 까지만 호출되고, 이 후에 새롭게 호출된 A Activity 가 사라지는 순간 (네 번째 단계) 에서야 onDestroy() 가 호출 됩니다.

FLAG_ACTIVITY_NO_HISTORY 는 여러가지로 쓸모가 있는데, 특히 특정한 이벤트에 대한 알람등을 위해 다이얼로그 형태로 화면에 표시되는 Activity 들에적용하기에 편리합니다. (대게의 경우 팝업은 해당 시점에 한번만 보여주면 되니까.)

다음으로 굉장히 유용한 플래그 두 가지를 동시에 설명해보고자 합니다. FLAG_ACTIVITY_REORDER_TO_FRONT 와 FLAG_ACTIVITY_CLEAR_TOP 플래그입니다. 우선 간략하게 그림으로 살펴 보겠습니다. A Activity 에서 B Activity 를 그리고 B 에서 A 를 호출하는 상황을 가정해보았습니다. (A->B->A)

FLAG_ACTIVITY_REORDER_TO_FRONT 는 매우 특이하게도 Task 의 순서 자체를 뒤바꿔 줍니다. 이 플래그를 사용하면, 런치하고자 하는 Activity 가 이미 Task 상에 존재하는 경우 해당 Activity 를 새롭게 생성하는 대신, 아래쪽에 위치한 Activity 의 순서를 Task 의 가장 위로 끌어올려줍니다. 따라서 A->B->A 의 순서로 Activity 호출이 일어날때, 새로운 A 가 생성되는 대신 아래쪽에 위치한 A 가 위로 올라와 최종적으로 B->A 의 형태로 Task 가 구성되게 됩니다. 어떤 Activity 에서 특정 Activity 로 점프하는 형식의 Flow 를 구성해야하는 경우 요긴하게 사용될 수도 있지만, Task 의 순서를 뒤섞는 다는 점에서 사용에 주의를 기울일 필요가 있습니다. (별 생각없이 남발하게 되면 Back 키가를 누를 때 엉뚱한 Activity 가 표시되어 사용자들이 굉장히 혼란스러워 하는 경우가 있습니다.)

마지막으로 소개해 드릴 플래그는 바로 FLAG_ACTIVITY_CLEAR_TOP 입니다. 제가 개인적으로 가장 사랑스럽게 생각하는 녀석입니다. 이 플래그가 사용되는 경우 런치하고자 하는 Activity 가 이미 Task 상에 존재하는 경우, 해당 Activity 위에 존재하는 다른 Activity 를 모두 종료시켜 줍니다. 따라서 A->B->A 로 호출이 일어나는 경우, B Activity 가 종료 되고, A Activity 만 Task 에 남게 됩니다. (A->B->C->A 인 경우에도 마찬가지로 B와 C 가 종료되고 A 만 남게 됩니다.)

이 Flag 는 특정 어플리케이션의 대쉬보드 (혹은 홈) Activity 를 호출할 때 굉장히 유용하게 사용될 수 있습니다. 즉 하나의 어플리케이션이 하나 혹은 두 가지의 주요한 Activity 와 그 외 특정 값을 선택하는등 단순한 일을 수행하기 위한 여러 개의 Sub-Activity 로 구성되어 있다면, 주요 Activity 를 호출하는데 이 Flag 를 사용함으로서 어플리케이션의 홈버튼등을 손쉽게 구현할 수 있습니다. 또 이 Flag 는 FLAG_ACTIVITY_REORDER_TO_FRONT 와는 달린 Task 의 순서를 뒤섞지 않음으로 사용자에게도 큰 혼란을 주지 않습니다. (사용을 적극 권장합니다.)

한 가지 주의해야할 점은 A->B->A 형태로 Activity 를 호출 하고자 할 때, 단순히 FLAG_ACTIVITY_CLEAR_TOP 만을 사용하게 되면, 기존에 생성되었던 A Activity 가 종료된 후 (onDestroy() 가 호출됨) 새롭게 A 가 생성 (onCreate()) 됩니다. 만일 기존에 사용된 A Activity 가 계속 사용되기를 원한다면, SINGLE_TOP 플래그와 함께 사용해야 합니다.

FLAG_ACTIVITY_SINGLE_TOP

Activity가 스택의 맨 위에 존재 하는 경우에 기존 Activity를 재활용 한다.

(Activity호출순서) 0->1->2->3 이렇게 스택이 쌓인 경우(스택의 맨 위는 3)

view plaincopy to clipboardprint?
intent = new Intent(this, Activity3.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

0->1->2->3 그래도 유지 된다. 대신 Activity3는 onPause()->onNewIntent() -> onResume() 호출된다.

3번 액티비티가 존재하지 않거나 스택의 맨 위가 아닌 경우 그냥 스택에 쌓이게 되며 onNewIntent() 도 호출된다.

FLAG_ACTIVITY_NO_HISTORY

해당 플래그를 주고 액티비티를 호출하면 호출된 액티비티는 스택에 남지 않는다.

0->1->2->3 호출할때 Activity2 에서 Activity 3를 호출할때

view plaincopy to clipboardprint?
intent = new Intent(this, ActivityTest3.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);

하면 스택에는 0->1->3 만 남게 된다. 하지만 Activity 2의 Destory()의 시점은 Activity 3이 종료 된 이후에 호출된다라는것을 주의한다.

FLAG_ACTIVITY_REORDER_TO_FRONT

스택의 순서를 변경해 준다.

0->1->2->3 일때 Activity 3에서 Activity 1을 호출 할때 이 플래그를 설정하면

0->2->3->1 로 변경된다. (안드로이드 문서에서 FLAG_ACTIVITY_CLEAR_TOP플래그를 무시한다고 되어 있다.)

FLAG_ACTIVITY_CLEAR_TOP

스택에 기존에 사용하던 Activity가 있다면 그 위의 스택을 전부 제거해 주고 호출한다.

0->1->2->3 일때 Activity 3에서 Activity 1을 호출할때 이 플래그를 설정하면

0->1 만 남게 된다. (2, 3은 제거) 이때 Activity 1은 onDestory() -> onCreate()가 호출된다. 삭제하고 다시 만들게 된다.

그래서~~ FLAG_ACTIVITY_SINGLE_TOP와 같이 써준다. 그러면 onNewIntent()-> onResume() 가 호출된다.

만약 스택에 없다면~~ 당연히 아무것도 지우지 못하고 맨 위에 올라가게 된다.

view plaincopy to clipboardprint?

intent = new Intent(this, ActivityTest1.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);

[출처] [안드로이드] Intent Flag|작성자 늘순수하게

위 사이트에 들어가면 미처 스크랩 해 오지 못한 이미지들을 볼 수 있다. 이 이미지들이 플래그의 기능을 이해하는 데 도움을 줄 것입니다.

[안드로이드] 자바 생성자 (android java creator)

생성자의 역할
생성자란 ? 객체를 생성할 때 객체의 초기화 작업을 위한 명령 구문
객체가 생성될 때 최초로 실행되는 메서드의 형태로서 생성 시에만 호출하여 수행
특징
생성자의 이름은 클래스명과 같아야함
생성자의 접근 제어자는 private, protected, public 올수 있으며, 생략가능
메서드 아님
리턴 타입표기 않함, 'void' 표기안함
생성자는 상속되지 않음
중복정의 가능
기본 생성자
기본생성자란? 클래스 정의 시 생성자 정의를 하지 않을 경우, JVM에서 자동으로 제공되는 생성자
public 클래스 이름() {}
특징
인자가 없음
생성자 코드 블록의 본문이 비어있음
'new 클래스이름();' 형태로 객체 생성
클래스 정의 시 최소 1개 이상의 생성자가 정의되면 기본 생성자는 제공되지 않음
기본 생성자가 없는 경우, 'new 클래스 기본생성자();'를 이용해 객체 생성할 수 없음
특별한 목적이 없는 경우, 클래스 정의 시에 기본 생성자도 함께 정의함
생성자 정의
생성자 정의 방법
메서드와 비슷
생성자 이름은 메서드 이름과 반드시 같아야 하고 리턴 타입을 표기 하지 않음
생성자 코드 블록의 본문은 객체 생성 시 초기화를 위한 수행 구문으로 구현
      예)     [접근제어자] 클래스이름 ([인자(Argument)리스트]} {초기화 수행구문}
생성자 중복 정의
클래스는 여러 개의 생성자를 정의할 수 있음
생성자의 이름은 같고, 인자를 다르게 하여 여러 개 정의 가능
인자의 개수, 순서, 데이터 타입을 다르게 하여 정의
생성자의 사용
클래스 정의 시, 생성자를 정의한 경우 해당 생성자를 지정하여 객체 생성이 가능
생성자를 호출할 때 인자의 데이터 타입, 순서, 개수 검사해서 해당 생성자 수행
기본 생성자를 이용한 객체 생성 방법
          클래스이름 참조변수 = new 클래스생성자();
생성자를 지정하여 객체 생성 방법
         클래스 이름 참조변수 = new 클래스생성자(초기화1, 초기화2,);
출처: http://skql.tistory.com/72

오늘 안드로이드에서 내가 원하는 함수들을 따로 묶은 자바 클래스를 하나 만들었다. (Activity를 상속받지 않는)

그리고 삽질을 하게 되었다. 계속해서 에러가 나는 것이었다. 이 자바 클래스를 이용할 때 마다 null point exception이 뜨는 것이 아닌가.. 이상 하다 이상하다... 도저히 무엇을 잘못한 것인가

결국 알아낸 것은 null point exception을 뜨지 않게 하기 위해서는 class를 동적 할당을 해줘야 한다는 것이었다. 이것은 자바의 특성인가?? 아니면 무슨 이유에서 꼭 동적할당을 해줘야 되는 것인가? 아시는 분은 제발 답글로 가르쳐 주시기 바랍니다.

문제점

java class - FileManager.java 를 만들었다.

그리고 이 클래스를 사용하기 위해

다른 class에 FileManager fManager; 을 만들고

fManager 내의 함수를 사용하였다.

fManager.readImage();

결과 - NullPointException

해결 방법

FileManager fManager;

fManager = new FileManager();

fManager.init(getBaseContext());

위와 같이 new로 class를 동적할당 하고 내가 필요로 하는 변수들을

init 함수를 통해 지정해주니 해결되었다.

[안드로이드] 갑자기 로그캣이 보이지 않을 때 (android cannot logcat not found)

3. 로그 관리

DDMS에서 가장 많이 사용하는 창 중 하나입니다. 에뮬레이터/기기의 상태와 관련된 로그들을 확인할 수 있으며, 런타임 에러가 발생한 경우 여기에 출력되는 로그 확인을 통해 구체적으로 어디에서 문제가 발생했는지 알 수 있습니다.

LogCat 화면에 로그가 표시되지 않는 경우가 있는데, 이는 대부분 로그를 받아올 에뮬레이터 혹은 기기가 선택되어 있지 않아서 발생합니다. 아래와 같이 로그를 받아올 에뮬레이터 혹은 기기를 선택해주면 로그가 정상적으로 표시됩니다.


혹은, 에뮬레이터는 실행되었는데 Devices 목록에 에뮬레이터가 표시되지 않는 경우가 있습니다. 이는 주로 저사양 컴퓨터 -_-에서 자주 발생합니다. 에뮬레이터를 실행시키고 일정 시간 내에 에뮬레이터로부터 응답이 와야 하는데, 응답이 오지 않아 ADB가 그 에뮬레이터를 버린(?) 셈이죠. 이럴 때에는 에뮬레이터를 다시 실행시키지 않아도 대부분의 경우 ADB를 리셋하면 다시 에뮬레이터가 Devices 목록에 표시됩니다.

ADB를 리셋하기 위해서는 Devices 화면 오른쪽 상단의 메뉴를 누른 후, reset adb 항목을 선택하시면 됩니다.

유명하신 커니님의 사이트에서 스크랩

[안드로이드] openFileOutput 인식 문제(android undefined openFileOutput)

openFileOutput 을

openFileOutput(path, Context.MODE_PRIVATE);

을 이용하여 사용하였다.

그런데 openFileOutput 밑에 빨간 줄이 그이는 게 아닌가!!
TIP) openFileOutput을 사용할 때 (아마도) extends Activity를

한 상태가 아니라면 Context를 받아줘야 한다.

즉, 해당하는 Context명의 openFileOutput 이 되어야 한다.

예) Context ctx;

ctx.openFileOutput( path, Context.MODE_PRIVATE);

빙고-!!

2011년 1월 14일 금요일

[안드로이드] 액티비티 간 데이터 전송 (android data transfer to another activity)

자료를 전송하고자 하는 액티비티에서 다음과 같이 해당 액티비티를 불러온다.

Intent intent = new Intent(this, Connect.class);  //Connect.java가 있어야한다. (액티비티)
intent.putExtra("key", "원하는 문자열 값");  //key는 해당 문자열을 알기 위한 값 받는 액티비티는 이 key를 통해서 문자열을 검색.
startActivity(intent);

--------------------------------------------------------------------------------------------

Connect 액티비티에서 문자열 값을 받는 방법.

String str = getIntent().getStringExtra("key"); //인텐트의 key값을 통해 해당 String을 받는다.
Toast.makeText(this, str, Toast.LENGTH_LONG).show(); //토스트 기능으로 확인해보자.

(AndroidManifest에 Connect 액티비티를 추가해주는 것을 잊지 말자.)

[안드로이드] 스타일 xml 파일 이용하기 (android styles.xml)

오늘 styles.xml이라는 파일을 이용해서

좀 더 쉽게 이미지를 view에 적용시키는 방법을 알게 되었다.

아래 링크를 따라가면 손쉽게 이용할 수 있을 것이다.

styles.xml의 이점은

이 xml 파일에 이미지에 대한 정보를 입력시켜 놓으면

해당 이미지를 손쉽게 가져다 쓸 수 있다는 것이다.

즉, 새로운 이미지 버튼을 만들때 스타일에 미리 만들어 놓은

이미지를 갖다 쓸 수 있기에 편리하게 작업할 수 있다.

출처:
http://www.androidpub.com/55225

[안드로이드] 레이아웃에 배경화면 삽입하기 (android layout background)

//bitmap을 drawable로
  Drawable d =new BitmapDrawable(bm);
  linear.setBackgroundDrawable(d); 

위와 같이 비트맵을 drawable로 바꾼다음에 layout에 삽입하면 간단하게 해결 됩니다. 오랫동안 고민했었는데 이렇게 쉽게 되니 허무하군요...... 근데 작은 크기의 bitmap을 삽입하면 늘어나는 문제점이 있습니다. 바둑판 식으로나 화면 중앙에 크기에 맞게 나오게 하는 방법도 연구해 봐야겠습니다.

[안드로이드] 비트맵을 레이아웃에 추가하는 방법(android how to add bitmap to layout)

대충 소스를 보니깐 리니어레이아웃을 하나 만들어 놓고

비트맵을 받아서 그 비트맵을 새로 만든 View에 다가 넣은 후에

리니어레이아웃에 Add하는 방식으로 되어 있다.

개인적으로 원했던 코드는 리니어레이아웃에 배경화면으로 비트맵이 들어가는 거였기에 조금 핀트가 안 맞는 코드이다.

내가 원했던 코드
배경화면으로 비트맵이 깔리고

그 위에 버튼, 텍스트 등 내가 원하는 일을 할 수 있다.

이 예제 코드
이미 만들어 진 레이아웃 밑으로 레이아웃이 붙는다.
예)
만들어 진 레이아웃에 버튼이 있다.

거기에 예제 코드를 적용한 경우

버튼
비트맵

즉, 버튼 밑으로 비트맵 이 들어 간다.

child layout을 생각하면 이해가 빠를 듯

Layout
     button
인 상태에서 이 소스를 이용해서 add를 시키면

Layout
     button
     layout

이 된다.
http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/DensityActivity.html

[안드로이드] setBackgroundDrawable

/** 전송메시지 */
  Intent i = getIntent();
  Bundle extras = i.getExtras();
  String imgPath = extras.getString("filename");

  /** 완성된 이미지 보여주기  */
  BitmapFactory.Options bfo = new BitmapFactory.Options();
  bfo.inSampleSize = 2;
  ImageView iv = (ImageView)findViewById(R.id.imageView);
  Bitmap bm = BitmapFactory.decodeFile(imgPath, bfo);
  Bitmap resized = Bitmap.createScaledBitmap(bm, imgWidth, imgHeight, true);
  iv.setImageBitmap(resized);

  /** 리스트로 가기 버튼 */
  Button btn = (Button)findViewById(R.id.btn_back);
  btn.setOnClickListener(this);

  //bitmap을 drawable로
  Drawable d =new BitmapDrawable(bm);
  btn.setBackgroundDrawable(d);

위 코드로 bitmap을 drawable로 바꿔서 저장할 수 있다.

Drawable d = new BitmapDrawable(bm);
bm = Bitmap  //  d = Drawable
이렇게 비트맵에서 Drawable로 전환된 것을
btn.setBackgroundDrawable(d);
setBackgoundDrawable을 이용해서 삽입할 수 있다.

그 위의 코드는 filepath를 통해 비트맵 이미지를 sdcard에서

가져오는 것.

2011년 1월 12일 수요일

[안드로이드] 레이아웃을 2개 이상 사용할 경우 주의점(android layout more than 2 layout)

레이아웃을 두개 이상 사용할 경우

예)

<LinearLayout>
          <linearLayout>
           <LinearLayout>

위와 같은 경우

하위 두개의 레이아웃 중 하나라도
width 와 height 가 (보통 height) fill_parent 라면

다른 layout을 덮어 버리게 된다.

항상 wrap_content를 사용하도록 주의하자.

[안드로이드] getapplicationcontext

Context context 란 항목에서

보통 this를 넘겨주게 된다.

그런데

OnClickListener 내부라던지 어쨋든

특수한 상황에서 this가 먹히지 않는 경우가 있다.

그럴 경우에는

getapplicationcontext() 를 이용하여

context를 넘겨주면 된다.

[안드로이드] 토스트를 이용한 간단한 디버깅 (android toast debugging)

안드로이드에는 토스트라는 팝업창이 있다.

메세지를 잠깐동안 activity 위에 보여주는 데 사용한다.

이를 이용해서 간단한 디버깅을 할 수 있다.

왜냐하면 printf 처럼 activity 위에 원하는 값을 뿌려주기 때문이다.

다음과 같이 사용한다.

Toast toast;

토스트 함수 정의

Toast.makeText(this, "Toast Message",Toast.LENGTH_SHORT).show();

처음 파라미터는 출력할 activity
두 번째 파라미터는 띄울 메세지
세 번째 파라미터는 띄우는 시간이다.

더 자세한 정보는 아래 사이트를 이용하세요.
http://neodreamer.tistory.com/405

[안드로이드] seekBar (android seekBar)

xml에 적을 것
<SeekBar android:id="@+id/seek"
                android:layout_width="240dp"
                android:layout_height="wrap_content"
                android:max="100"
                android:progress="50"
                android:secondaryProgress="75" "/>

4) seekbar에 대한 이벤트 감지
mSeekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
      public void onStopTrackingTouch(SeekBar seekBar) {
      }
      public void onStartTrackingTouch(SeekBar seekBar) {
      }
      public void onProgressChanged(SeekBar seekBar, int progress,
                           boolean fromUser) {
                mplayer.seekTo(progress);
      }
});

5) seekbar 위치 변경
       position / maxvalue 의 위치로 설정
           sk.setMax(maxvalue);
           sk.setProgress(position);

출처
http://bunhere.tistory.com/113

seekBar에 관련된 다른 블로그(예제)
http://android-er.blogspot.com/2010/02/seekbar.html

2011년 1월 11일 화요일

[안드로이드] java.net.ConnectException: Connection refused: connect

컴퓨터를 재부팅하세요 -_-b

[안드로이드] sdcard 내에 이미지 파일을 불러와서 갤러리에 올리기

sdcard 내에 이미지 파일을 불러와서 갤러리 올리기

참조사이트
http://mainia.tistory.com/497

그리드 뷰 만들기 참조사이트
http://wefu.tistory.com/55

오늘은 왠지 직접 글을 쓰기가 싫은 날이로다 =3

[안드로이드] sdcard 에 쉽게 파일을 넣는 법

안드로이드에서

Setting -> applications -> Development -> USB debugging

을 해제한다.

그러면 device에서 해당 장치를 usb 처럼 인식하게 된다.

그리고 device에 USB connected 라는 제목하여

영어로 된 이야기가 나오고(이건 중요치 않음)

밑에 보면 Turn on USB storage라는 버튼이 생긴다.

이 버튼을 클릭하면 컴퓨터에서 device의 sdcard를

인식하게 된다.

이제 sdcard로 file들을 drag 하기만 하면 저절로 복사가 된다.

usb에 파일을 옮기는 방법과 동일하다.

[안드로이드] 비트맵 제어 (android control bitmap function)

비트맵 관련 함수가 잘 정리되어 있는 사이트

쓰기 귀찮 =_=;;

가보세요.

출처 : http://mainia.tistory.com/468

2011년 1월 10일 월요일

[안드로이드] res- drawable 뒤에 달린 hdpi,ldpi, mdpi 네 놈들은 무엇이냐?

드디어 알아냈다.!

별거 아니더군요.

hdpi - 고해상도의 이미지
ldpi - 저해상도의 이미지
mdpi - 중해상도의 이미지

-_-b

[안드로이드] android unknownhostexception host is unresolved

  • AndroidMenifest.xml에서 INTERNET 퍼미션 설정을 해줍니다.
  • 애뮬레이터가 네트워크 서비스가 가능한 환경으로 설정되어 있는지 확인합니다.
멋진 정보를 주신 아래 블로거님에게 감사합니다.
출처 - http://androidnote.co.kr/entry/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-unknownhostexception-%EC%97%90%EB%9F%AC

2011년 1월 8일 토요일

[안드로이드] R.java 문제에 대한 또 하나의 팁(android R error)

프로젝트를 하다 보면 Package를 새로 만들게 되는 경우가 있다.

그러면 밑에 처럼 나타날 것이다.
project명
     src
            sample.text
            sample.draw

위와 같이 두개의 package가 있을 경우

sample.text를 main package로 가정하겠다.

그러면 sample.draw에서 R.java에 접근 하기 위해서는

sample.text를 import할 필요가 있다.

즉, sample.draw package 내에서  R.java에 접근하는 파일의

경우 " import sample.text.* " 을 해주어야 한다.

=== main package가 아니면 메인 package를 import하라 ===

import 메인 페키지명.*;

예) import sample.text.*;

[안드로이드] 이클립스 유용한 단축키 (android eclipse useful keyboard shortcut)

Ctrl-Shift-o = Organize imports (import 관리 - 알아서 필요한 import를
                                                  하고 불필요한 import 제거)
Ctrl-Shift-t = load class by name (이름으로 class를 불러온다)
Ctrl-Shift-r = load non-class resource by name (class가 아닌 다른 리소스
                    들을 이름으로 불러 온다 - 주로 작업하고 있는 프로젝트
                    내의 file들)
Ctrl-1 = quick fix (빠른 고침 - 이 버튼을 누르면 해당 하는 커서의 file
             명을 쉽게 바꾼다. 그리고 해당하는 project의 명도 쉽게 바꿀
             수 있다)
Ctrl-e = Recently viewed files (최근에 본 파일들이 화면 오른쪽에 나타남)
Ctrl-space = auto complete (자동 완성 - 해당 커서에서 사용할 수 있는
                                            모든 함수들이 나타남)
Shift-Alt-r = refactor:rename (해당 하는 변수의 이름 새로 고치기 - 쉽게
                                             클래스명이나 변수명을 바꿀 수 있다)
Shift-Alt-v = refactor:move (잘 모르겠음 - 아마 해당하는 변수를 다른 곳
                                                                    으로 옮기는 것)

2011년 1월 7일 금요일

[안드로이드] 심플한 음악재생 오픈 소스( android music player open source)

 간단한 음악 재생 플레이어 소스를 발견하였다.

아래 사이트에서 확인하기 바란다.

리스트에 음악 재생 목록 들이 뜨고( sd card의 바탕화면에 존재하는 음악들)

해당 하는 제목을 클릭하면 해당 노래가 나온다.

출처: http://www.helloandroid.com/tutorials/musicdroid-audio-player-part-i

[안드로이드] 프로젝트 생성 시 R.java 파일 미 생성 문제 (android new project R.java)

안드로이드에서 새로 프로젝트를 만들었을 때 R.java file이 생성되지 않았다. 이 전에는 잘 생성되다가 갑자기 생성 되지 않아서 굉장히 당황 했다.

 해결 방법은 프로젝트를 "Build"하는 것이다.

Project -> build automatically를 켜니 저절로 해결 되었다.

아마 manual로 하더라도 build를 하면 해결이 될 것이다.

[안드로이드] R 인식 문제 ( android R can't be recognized)

갑자기 R을 인식하지 못하는 문제가 생겼다.

먼가 자동적으로 R을 잡아주는 곳에서 문제가 생긴 듯 했다.

구글링을 통해 import android.R 을 지워주면 된다는 것을 알게 되었다. 신기하게도 지우니 문제가 해결 되었다 -_-b

2011년 1월 6일 목요일

[안드로이드] 자바 칼린더 (Android Java Calendar)

Calendar calToday;
  calToday = Calendar.getInstance();
  int year = calToday.get(Calendar.YEAR);
  int month = calToday.get(Calendar.MONTH);
  int date = calToday.get(Calendar.DATE);
  int hour = today.get(Calendar.HOUR);
  int min = today.get(Calendar.MINUTE);
  int sec = today.get(Calendar.SECOND);

칼린더에서 현재 날짜를 가져온다. Calender.getInstance() 그 후에 위와 같은 명령어를 이용해서 연, 월, 일, 시, 분, 초를 int 형으로 환산하여 얻어 올 수 있다. 이 외에도 요일이라던지 하는 다양한 값을 가져 올 수 있다. 자세한 기능은 아래 사이트에서 알 수 있다.
http://download.oracle.com/javase/1.4.2/docs/api/java/util/Calendar.html

[안드로이드] Button OnclickListener 사용하기

public class DateTime extends Activity implements OnClickListener {
    /** Called when the activity is first created. */
 Button nyear;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.datetime); 
      
        nyear = (Button)findViewById(R.id.nyear);
            
        nyear.setOnClickListener(this);

       }
 @Override
 public void onClick(View v) {
  // TODO Auto-generated method stub
  switch(v.getId()){
  case R.id.nyear:
   break;
    }
 }
}

위의 예제는 OnClickListener를 사용하는 간단한 예제이다.

위에 노란색으로 강조해 논 것처럼 OnclickListener를 implement해서 사용하는 방법을 나타 내었다. findViewById를 이용하여 자신이 Control 하고자 하는 Button을 호출한다. 그 후 OnClickListener를 이용하여 OnClick 함수를 호출, 그 후 switch 문을 통해서 view의 id를 받아서 해당 하는 id 인 경우에 case문 안에서 원하는 동작을 수행하게 된다.

TIP) OnClickListener를 implement 했을 시에 class 명에 빨간색 오류가 나타나는 경우가 있다. 그 경우에는 해당하는 class명에 마우스를 가져가면 Add Unimplemented methods 라는 항목을 볼 수있다. 해당하는 항목을 클릭하면 저절로 필요한 methods가 import 된다.

[안드로이드] Relative Layout 정렬 종류(android relative layout arrange)

속성
설명
layout_above
~ 위에 배치한다.
layout_below
~ 아래에 배치한다.
layout_toLeftOf
~ 왼쪽에 배치한다.
layout_toRightOf
~ 오른쪽에 배치한다.
layout_alignLeft
~ 왼쪽 변을 맞춘다.
layout_alignTop
~ 위쪽 변을 맞춘다.
layout_alignRight
~ 오른쪽 변을 맞춘다.
layout_alignBottom
~ 아래쪽 변을 맞춘다.
layout_alignParentLeft
true이면 부모와 왼쪽 변을 맞춘다.
layout_alignParentTop
true이면 부모와 위쪽 변을 맞춘다.
layout_alignParentRight
true이면 부모와 오른쪽 변을 맞춘다.
layout_alignParentBottom
true이면 부모와 아래쪽 변을 맞춘다.
layout_alignBaseline
~ 베이스라인을 맞춘다.
layout_alignWithParentIfMissing
layout_toLeftOf 등의 속성에 대해 앵커가 발견되지 않으면 부모를 앵커로 사용한다.
layout_centerHorizontal
true이면 부모의 수평 중앙에 배치한다.
layout_centerVertical
true이면 부모의 수직 중앙에 배치한다.
layout_centerInParent
true이면 부모의 수평, 수직 중앙에 배치한다.


출처 : 김상형 - 안드로이드 http://www.winapi.co.kr/android/
제3장 3 - 1 Relative Layout 중에서

2011년 1월 5일 수요일

[안드로이드] final을 쓰는 이유( android final)

final을 쓰게 되면 지역 변수는 상수화 되어서 계속 해서 지속되게 된다(?). 그래서 쉽게 말하면  Listener로 전달하고 싶은 지역변수는 final 로 처리해야 한다는 말이다.
 조금 더 자세히 이야기 하자면, Oncreate에 선언한 변수들은 지역변수로서 Oncreate function이 종료하면 사라지게 된다. 그 경우 Onclick 이나 OnTouch와 같이 click 이나 Touch 할 때 마다 불리는 함수에서는 지역변수를 접근할 수가 없다. Oncreate function이 종료함과 동시에 그 안에서 호출된 지역변수들은 모두 사라지기 때문이다. 하지만 final을 붙여주면 그 변수는 상수화 되어 메모리에 계속 남아 있게 되는 것이다.(?) 아마도..
 조금 내용이 어려워서 제대로 이해 했는 지 모르겠다.
 자세한 이야기는 밑의 블로그에 잘 나와있다.

출처: http://devbible.tistory.com/30

[안드로이드] 로그를 사용한 디버깅 (android debugging by log)

잠깐. 새 플랫폼 공부를 시작하려면 어떻게 디버그 로그를 출력하는지 아는 것이 중요합니다. Logcat을 통해 디버그 로그를 출력하는 방법을 알고 넘어갑시다. android.util.Log.i(“my log”, “중얼중얼”) 하면 됩니다. android.util.Log 클래스엔 e(rror), w(arning), i(nfo), d(ebug), v(erbose) 메서드가 있습니다. 취향것 쓰시면 되고요, error나 warning의 경우 오류객체(Throwable)만 집어던져도 됩니다. Log 클래스를 쓰게되면 Android Debug Bridge로 해당 로그 메시지를 보내주므로 Eclipse 에서 로그메시지를 편하게 확인할 수 있습니다.
Log.d(“hehehe”, “onCreate is executed”);를 onCreate 메서드에 적절히 넣으시고, 디버그를 시작하시면 Log 창에 뭔가 잔뜩 출력되는 것을 볼 수 있습니다. “hehehe”만 보시려면 + 버튼을 눌러 로그필터를 만드세요. by Log Tag 부분에 hehehe를 입력하시면 내가 찍은 로그만 따로 볼 수 있습니다.
출처: http://xrath.com/2009/11/android-%EC%8A%A4%ED%84%B0%EB%94%94-%EA%B3%84%EC%82%B0%EA%B8%B0-%EB%A7%8C%EB%93%A4%EA%B8%B0/

[안드로이드] 스트링을 정수로, 정수를 스트링으로 (android string to int, int to string)

int strint = Integer.parseInt(str); // 스트링을 정수로 고침
String yearText = Integer.toString(year); //정수를 스트링으로 고침

[안드로이드] 스피너 (콤보박스) 사용방법 (android spinner(combobox))

안드로이드에서는 콤보박스를 스피너라고 부른다는 것을 알게 되었다.

그리고 사용방법은 조금은 복잡하다.

layout 에 spinner를 정의해 주고, spinner에 들어가는 항목들은 따로 arrays.xml 파일을 만들어서 이곳에 넣어준다. 그리고 java file에 이 arrays.xml과 spinner 를 연결 시켜 주면 사용할 수 있게 된다.

자세한 설명은 아래 사이트를 참조
http://ribbit.tistory.com/6

2011년 1월 4일 화요일

[안드로이드] font 변경

TextView text  = (TextView)findViewById(R.id.TextView01);
      
// 원하는 글꼴 assets/디렉토리 에 포함..
Typeface face = Typeface.createFromAsset
(getAssets(),"fonts/ALGER.TTF");
      
text.setTypeface(face);

TextView에 원하는 글꼴을 포함시키는 방법이다. assets에 fonts directory를 만들고 그 안에 fonts들을 넣는다. 그 후 위와 같은 코드를 사용해서 해당 하는 textview 의 폰트를 바꿀 수 있다.

[안드로이드] 오드로이드 timeout exception

오드로이드 usb를 뽑았다 다시 꽃아 주세요 -_-b

[안드로이드] 오드로이드 연동 및 인식 문제 해결

http://dev.odroid.com/projects/odroid/download/note/11

위 사이트에 들어가면 odroid 용 adb driver가 있다.

이 드라이버를 받고 설치하면 odroid를 컴퓨터와 연동시킬 수 있다.

 드라이버는 두 종류가 있다.

 amd64, x86

내 컴퓨터는 amd64 드라이버를 인식하여 설치하였다.

 아마도 컴퓨터와 맞는 드라이버는 자동적으로 인식되는 듯하다.

 드라이버 수동 검색을 통한 인스톨을 할 때 x86 폴더를 지정하면

드라이버를 인식하지 못하였지만 amd64폴더로 잡으니 저절로

인식이 되고 인스톨 되었다.

그 후 두 번째 문제는 한동안은 eclipse와 연동하여 안드로이드용

프로그램을 잘 개발하고 있었는 데 어느순간 mass storage 즉,

오드로이드 sd card 정보만 읽고 오드로이드 기계 자체는 eclipse

와 연동되지 않는 문제가 나타났다. 그래서!!! 엄청 헤매었다.

고마운 밑의 사이트의 도움으로 결국 해결하였다 -_-b

아무것도 아닌 문제였던 것이었던 것이다!!! 아놩 ㅠ

문제는 setting -> application -> development -> usb debugging을

활성화 시키면 해결된다. -_-+ 아혹 왠지 열받아 ㅠ

http://www.aesop.or.kr/?document_srl=84948