기존에 공개되어있던 android 용 pull to refresh 소스가 맘에안들어서 새로 구현했습니다.

이것은 위로 리프래시 말고도 아래로 리프래시도 가능합니다.









pulltorefresh.zip


by cranix 2012. 3. 28. 14:53
예전에 구글에서 제공한 어떤 소스에 공개되어있는것을 뜯어내어서 나름대로 수정해서 사용하기 편하게 만든 버젼입니다.
ListView 사용할때처럼 adapter 만 붙혀주면 간단하게 구현할수 있습니다.


 
by cranix 2012. 3. 26. 15:10

adt r17 에 x86 에뮬레이터 지원한다 그래서 테스트 해봤습니다.

결과적으로는 이전에 비하면 훨씬 좋네요.

 

체감속도가 눈에띄게 향상되었습니다.

부팅속도, 타이핑속도, 앱 실행속도 등이 이전 arm 기반 에뮬레이터에 비해 월등합니다.

사용하기를 권장 드립니다.

 

사용법은 아래와 같습니다.^^


0.  http://software.intel.com/en-us/articles/intel-hardware-accelerated-execution-manager/  설치합니다.

 1. Intel Atom x86 System Image by Intel Corporation 을 설치합니다.

2. (1) 에서 설치한 이미지로 avd 를 만듭니다.

3. 실행해봅니다.




by cranix 2012. 3. 23. 11:51
안드로이드에서 Bitmap.createScaledBitmap 을 사용해서 이미지 크기를 변경하면 exif 정보가 날라간다.
그래서 이것을 유지시켜주는 유틸을 만들었다.

먼저 크기는 변경되기 때문에 크기의 exif 정보만 빼고 나머지를 그대로 복사하는 copyExifWithoutLengthWitdth 함수를 정의한다.


private static void copyExifWithoutLengthWidth(ExifInterface src,ExifInterface dest) {

for (Field f:ExifInterface.class.getFields()) {

String name = f.getName();

if (!name.startsWith("TAG_")) {

continue;

}

String key = null;

try {

key = (String)f.get(null);

} catch (Exception e) {

continue;

}

if (key == null) {

continue;

}

if (key.equals(ExifInterface.TAG_IMAGE_LENGTH) || key.equals(ExifInterface.TAG_IMAGE_WIDTH)) {

continue;

}

String value = src.getAttribute(key);

if (value == null) {

continue;

}

dest.setAttribute(key, value);

}

}





다음으로 위 함수를 이용해서 아래와같이 작성하면 간단하게 복사된다.

ExifInterface originalExif = new ExifInterface(originalFile.getAbsolutePath());

ExifInterface finalExif = new ExifInterface(finalFile.getAbsolutePath());

copyExifWithoutLengthWidth(originalExif,finalExif);

finalExif.saveAttributes();

 
 
by cranix 2012. 3. 20. 19:24
html 에서 아래와같은 태그를 안드로이드 웹뷰에서 사용하고자 한다.


파일 업로드창을 띄워야 하는데 문제는 기존 안드로이드 webview 에서는 공식적으로는 지원하지 않는다는 것이다.
대신 아래와같은 꼼수가 있다.

먼저 아래와같이 webview  에 WebChromeClient 를 셋팅한다.

여기서 중요한점은 @Override 를 쓰면 오류난다는 것이다.
왜냐하면 openFileChooser 메소드는 프레임웍에서 @hidden 처리되어있기때문에 sdk 에서 보이지 않기 때문이다.
하여튼 인앱브라우저에서 파일첨부를 하려고하면 저 메소드가 자동으로 호출되게 된다.

우리가 할일은 위 코드처럼 file chooser 를 열어주고 결과를 uploadMsg 로 다시 돌려주면 된다.
코드는 아래와 같다.


이건 왜 @hidden 처리해놨는지 의문이다.



 
by cranix 2012. 2. 29. 15:51

android 자동빌드환경을 구성할때 가장 힘들었던것이 emulator 가 켜져있어야만 테스트를 돌릴수 있다는 것이었습니다.
google 에서는 emulator 를 자동으로 켜고 부팅시까지 기다리고 자동으로 꺼주는 스크립트를 지원해주지 않는데 자동으로 빌드하기위해선 이런것들이 꼭 필요하기 때문에 직접 만들어보았습니다.

OS 는 윈도우이고 sdk 버젼은 r16 이고 ant build 환경이 갖추어져있다는 가정하에 이 문서를 작성합니다.
(ant 빌드환경 구성방법은 이전 글을 참조하세요.)

build.xml 파일 가운데에 아래 코드를 집어넣습니다.



그리고 아래 명령으로 실행하면 됩니다.


이것은 에뮬레이터가 꺼져있더라도 켠후에 부팅까지 기다려서 컴파일하고 테스트 돌린후에 다시 에뮬레이터를 죽이라는 명령입니다.
 
by cranix 2012. 2. 24. 12:03

* 목적
android 기본적으로 제공되는 ant 스크립트로 자동 build 환경을 구성하는 방법을 알아보도록 하겠습니다.


* android project 만들기
- 기존 이클립스 프로젝트 만드는것과 동일합니다.


* ant project 만들기
- sdk/tools 디렉토리 path 설정
여기서는 sdk 에 포함되어있는 툴을 많이 사용하기때문에 path 로 잡아두는것이 편합니다.
androidsdk/tools 디렉토리를 path 에 포함시킵니다.


- android update project ./ 실행
해당 프로젝트 디렉토리로 가서 아래 명령어를 실행하면 자동으로 build.xml 파일이 생성됩니다.

android update project –p ./
image

- keystore 설정하기
패키징을 하기위해서는 keystore 파일을 설정해야 합니다.

local.properties 파일을 열어서 아래와같이 keystore 의 위치와 alias 를 잡아줍니다.
image

 

* 컴파일직전에 config 설정하기
- build.xml 수정하기
maven 에서처럼 컴파일전에 자동으로 config 를 수정하도록 하려면 아래와같은 코드를 build.xml 에 추가합니다.
그리고 ant 실행시 파라메터에 config 를 변경해주면 됩니다.

<!-- extension targets. Uncomment the ones where you want to do custom work
     in between standard targets -->
    <property name="config" value="beta" />   
    <target name="-pre-build">
        <echo>config setting!</echo>
        <delete file="src/config.properties" />
        <copy tofile="src/config.properties" file="config/config_${config}.properties" />
    </target>

- 코드상에서 config.properties 사용하기

package net.cranix.android.anthello;


import java.io.IOException;
import java.util.Properties;

/**
* @author cranix
*/
public class Constants {
    private static final Properties config = new Properties();
    static {
        try {
            config.load(Constants.class.getClassLoader().getResourceAsStream("config.properties"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
   
   
    public static final String URL = config.getProperty("url");
}


* ant 를 이용하여 실행하기
- build.xml 수정하기
google 에서 기본적으로 제공하는 ant build 스크립트에는 실행할수있는 스크립트가 없습니다.
그래서 아래와같은 코드를 build.xml 에 추가하면 실행을 해볼수 있습니다.

    <target name="run">
        <xpath input="AndroidManifest.xml" expression="/manifest/@package" output="manifest.package" />
        <xpath input="AndroidManifest.xml" expression="/manifest/application/activity[intent-filter/action/@android:name='android.intent.action.MAIN']/@android:name" output="manifest.mainactivity" />

        <exec executable="${adb}" failonerror="true">
            <arg line="${adb.device.arg}" />
            <arg value="shell" />
            <arg value="am" />
            <arg value="start" />
            <arg value="-a" />
            <arg value="android.intent.action.MAIN" />
            <arg value="-n" />
            <arg value="${manifest.package}/${manifest.mainactivity}" />
        </exec>
    </target>


* ant 를 이용하여 빌드하기
프로젝트 디렉토리에서 아래와같은 명령으로 빌드를 해볼수 있습니다.
단 이전에 ant 는 받아서 path 로 잡혀 있어야 합니다.

- ant debug -> debug 키로 빌드해서 bin 디렉토리에 apk 생성
- ant debug install -> debug 키로 빌드해서 bin 디렉토리에 apk 생성하고 디바이스에 설치
- ant release -> release 키로 빌드해서 bin 디렉토리에 apk 생성
- ant release install -> release 키로 빌드해서 bin 디렉토리에 apk 생성하고 디바이스에 설치
- ant debug install run –> apk 생성하고 디바이스에 설치해서 실행해보기
- ant debug install run –Dconfig=beta –> beta 환경으로 디바이스에서 실행해보기
- ant emma debug install test –> test 를 돌리고 emma coverage report 를 뽑아냅니다. (test 프로젝트에서 실행)


* 문제점
- maven 에서와같이 dependency 를 관리해주지 않아서 수동으로 해야 합니다.

by cranix 2012. 1. 30. 11:14

android 기본 개발환경인 이클립스 ADT 만을 이용하면 환경설정파일을 자동으로 관리해줄수가 없습니다.
그래서 이 문서에서는 maven 을 이용해 환경설정파일을 소스 수정없이 빌드옵션 수정만으로 관리할수있도록 구성하는 방법을 알아봅니다.

* maven 을 이용한 android 자동 빌드환경 구성

   - http://cranix.net/374

 

* resource 디렉토리 만들기
  - src/main/resources 디렉토리를 생성합니다.
image

- 프로젝트 마우스오른쪽 –> maven –> update project configuration 을 실행하면 위와같이 소스폴더에 포함되는것을 확인할수 있습니다.

 


* config 파일 읽기
  - resource 디렉토리에 config.properties 파일을 생성하고 아래와같이 입력합니다.

url = http://test/real

  - properties 파일을 읽기위한 코드는 아래와 같습니다.

package net.cranix.android.hello;


import java.io.IOException;
import java.util.Properties;

/**
* @author cranix
*/
public class Constants {
    private static Properties config = new Properties();
    static {
        try {
            config.load(Constants.class.getClassLoader().getResourceAsStream("config.properties"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
   
   
    public static String URL = config.getProperty("url");
}

   - 이것의 사용은 간단합니다.

package net.cranix.android.hello;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class HelloActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       
        TextView tv = (TextView) findViewById(R.id.textView1);
        tv.setText(Constants.URL);
    }
}

 


* 디렉토리 구조 만들기

   - config 디렉토리를 생성하고 config_beta.properties,config_real.properties 파일을 만들어서 집어넣습니다.

image

  - 위와같은 형태로 디렉토리 구조를 만듭니다.
  - config_beta.properties  파일과 config_real.properties 파일에는 beta 와 real 에서 사용될 적절한 환경변수를 집어넣습니다.

 

* maven pom 파일 수정하기
  - pom 파일을 아래와같이 수정합니다.


<properties>
   …
   <config>beta</config>
</properties>


<build>

    <plugins>
        <plugin>
            <artifactId>maven-antrun-plugin</artifactId>
            <version>1.7</version>
            <executions>
                <execution>
                    <phase>generate-resources</phase>
                    <configuration>
                        <target>
                            <delete
                                file="${project.basedir}/src/main/resources/config.properties" />
                            <copy tofile="${project.basedir}/src/main/resources/config.properties"
                                file="${project.basedir}/config/config_${config}.properties" />
                        </target>
                    </configuration>
                    <goals>
                        <goal>run</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        …
   </plugins>

</build>

   - 위와같이 했을때 execution 에서 오류나는 경우가 있는데 이것은 단순 버그임으로 이클립스의 Problems view 에서 delete 합니다.

image

  - 프로젝트 마우스오른쪽 –> maven –> update project configuration 을 실행합니다.

 

* build 파라메터를 변경하여 실행
   - real 환경으로 실행하기
     --> run as –> maven build … 을 클릭하고 아래와같이 입력하고 실행합니다.
image

   - 이제부터는 위와같이 build 의 parameter 를 변경하는것 만으로 beta 와 real 설정파일을 변경할 수 있습니다.

by cranix 2012. 1. 25. 12:09

* 필요한 eclipse 플러그인 설치 (마켓에서 다운로드 가능합니다.)
- Maven Integration for Eclipse
- Android Configurator for M2E


* 이클립스 환경설정
- maven 3.0.3 이상 설치
--> http://maven.apache.org/download.html
현재의 eclipse 플러그인의 maven 은 3.0.3 이하 버젼이라서 최신버젼을 다운받아야 합니다.
다운받은후에 eclipse 의 maven 설정에서 설치한 3.0.3 을 선택해 줍니다.

- jdk 6이상 선택
이클립스 기본 컴파일러를 jdk 6 이상으로 선택해 줍니다.
jre 가 선택되어 있다면 컴파일시 오류납니다.


* eclipse 에서 android 프로젝트 생성
- 이 부분은 기존의 android 프로젝트 생성하는것과 동일합니다.


* maven 프로젝트로 변경
- 생성된 android 프로젝트에 마우스오른쪽 -> Configure -> Convert to maven project 를 클릭합니다.

위와같이 입력하면 pom.xml 이 생기면서 maven 프로젝트가 됩니다.

- 추가후 바로 오류가 나는데 아래와같이 pom.xml 파일을 변경하면 오류가 없어집니다.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>net.cranix.android</groupId>
    <artifactId>mvnandroidtest2</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>apk</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.google.android</groupId>
            <artifactId>android</artifactId>
            <version>2.3.3</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>


    <build> 
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>com.jayway.maven.plugins.android.generation2</groupId>
                <artifactId>android-maven-plugin</artifactId>
                <version>3.0.0-alpha-13</version>
                <extensions>true</extensions>
            </plugin>
        </plugins>
    </build>
</project>

- 원래 있던 src 폴더를 src/main/java 로 변경하여 아래와같은 구조가 되도록 합니다.

image

- 프로젝트 마우스오른쪽 –> maven –> update project configuration 을 실행해서 pom 에 설정된값을 eclipse 에 적용합니다.
- 이작업을 하면 위의 src/main/java 폴더가 자동으로 소스폴더가 되는것을 확인할수 있습니다.

 

* 빌드 테스트 해보기
- Run As –> maven build … 을 클릭해서 아래와 같이 채웁니다.



- 실행한후에 target 디렉토리에 apk 파일이 생성되었다면 제대로 셋팅 완료된것입니다.

 

* apk 실행하기
apk 를 실행해보기 위해서는 에뮬레이터를 켜놓거나 디버그용 폰을 꼽아놔야 합니다.
그상태에서 maven 으로 아래 명령을 실행하면 됩니다.

 

 

* sign 파일로 서명하기
apk 를 만들때 서명하기 위해서는 아래와같은 플러그인을 추가하면 됩니다.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jarsigner-plugin</artifactId>
    <version>1.2</version>
    <executions>
        <execution>
            <id>signing</id>
            <goals>
                <goal>sign</goal>
            </goals>
            <phase>package</phase>
            <inherited>true</inherited>
            <configuration>
                <archiveDirectory></archiveDirectory>
                <includes>
                    <include>target/*.apk</include>
                </includes>
                <keystore>${keystorepath}</keystore>
                <storepass>${storepass}</storepass>
                <keypass>${keypass}</keypass>
                <alias>${alias}</alias>

            </configuration>
        </execution>
    </executions>
</plugin>

굵은 부분은 자신이 가지고있는 사인파일과 비밀번호로 쓰시고 clean package 를 했을때 오류없이 잘 되었다면 제대로 설정된 것입니다.

 

* 문제점
- 테스트는 지원이 되지만 기존에 ant 기반에서 지원하던 emma coverage report 는 지원되지 않습니다.

--> emma coverage report 를 뽑아내는 과정이 실행되는곳은 test 프로젝트 인데 여기서 원래 프로젝트의 소스가 필요합니다. 그런데 maven 기반이면 각 프로젝트를 dependency 로서 관리하기때문에 따로 소스에 접근할 방법이 없습니다.

 

 

* 참고사이트

- http://code.google.com/p/maven-android-plugin/

by cranix 2012. 1. 25. 10:50

안드로이드에는 이미지크기를 줄일때 Bitmap.createScaledBitmap() 이라는 유용한 함수를 제공해 줍니다.
함수원형을 보면 아래와 같습니다.


public static Bitmap createScaledBitmap (Bitmap src, int dstWidth, int dstHeight, boolean filter)

여기서 문제는 Bitmap 소스가 들어가야 한다는 것입니다.
결국 저 함수를 쓰기위해서는 미리 디코딩 작업을해서 이미지소스를 메모리에 올려야 한다는 것이죠.


Bitmap tempBitmap = BitmapFactory.decodeStream(new FileInputStream(bitmapFile), null, resizeOpts);
Bitmap finalBitmap = Bitmap.createScaledBitmap(tempBitmap, dimen[0], dimen[1], false);
위와 같이 사용해야 합니다.
이러한 형태라면 소스 이미지가 커진다면 메모리도 그만큼 커야하는데 모바일 환경이라 그만큼 큰 가용메모리를 가진디바이스가 별로 없습니다.
결국 OutOfMemoryError 를 벹어내면서 크래시가 나게 되는것이죠.

그래서 있는것이 inSampleSize 라는 옵션입니다.
이것은 decodeStream 을 이용해 이미지를 디코딩할때 애초에 줄여서 디코딩해주는 역할을 하죠.
단점은 정확한 크기를 지정할수 없다는것입니다.
사용법은 아래와 같습니다.

BitmapFactory.Options resizeOpts = new Options();
resizeOpts.inSampleSize = 2;
Bitmap tempBitmap = BitmapFactory.decodeStream(new FileInputStream(bitmapFile), null, resizeOpts);
Bitmap finalBitmap = Bitmap.createScaledBitmap(tempBitmap, dimen[0], dimen[1], false);
이것은 디코딩을 할때 원본크기의 1/2 로 디코딩하라는 말입니다.
즉 inSampleSize 의 역수만큼의 크기로 사이즈를 줄입니다.
예를들어 4 라면 1/4 로 이미지가 줄어서 디코딩 되게 되죠.

어차피 사이즈를 줄일껀데 소스이미지 전체를 메모리에 올릴필요가 없습니다.
결국 이미지를 줄이기 위해서는 inSampleSize 를 이용하여 줄이고자하는 크기의 최대한 근접한 값으로 줄인후에 createScaledBitmap 함수를 호출해서 정확하게 줄이는것이 OutOfMemoryError 를 피하는 방법입니다.

by cranix 2011. 10. 20. 17:58
| 1 2 3 4 |