Translate

2013년 11월 30일 토요일

[Mobile][Javascript] touch Event(touchstart, touchmove, touchend) 가 작동하지 않는경우




증상
  - touch Event 가 정상적으로 작동하지 않음
  - 디바이스 기종
      1) iPhone5(A1429) - Safari (iOS7)
      2) Galaxy S2LTE(SHV-E110S) - OEM browser (Android 4.0.3)
      3) Galaxy Tab 10.1(SHW-M380W) - OEM browser(Android 4.0.4)

대부분의 디바이스에서는 정상 작동 하지만 위의 두 디바이스에서 touch이벤트가 정상적으로 작동하지 않았다.
Galaxy 디바이스의 chrome browser 에서는 정상적으로 작동함.





원인
  - 특정 HTML 코드에서 발샘함. (Browser Bug 로 의심됨)

  - 나의경우에는 상단에 다음과 같이 스타일이 있었으며
     style="position:absolute; height:100%; overflow:hidden;"
    touch event 로 실행될 버튼의 상단에 P 태그 (<p>) 가 많이 들어있었다.

    1. 3개의 스타일 중 어떤것 한개라도 삭제하면 touch event 가 정상적으로 동작하였으며
    2. 본문의 P 태그를 많이 삭제하면 touch event 가 정상적으로 동작하였다.

=================================
2013.12.19 추가
기기: SHW-M380W
HTML 파일내에 딱히 의심될 만한 이상한것도 없지만 Touch Event 가 발생하지 않는 문제가 발생을 했다. (역시 Chrome 에서는 정상적으로 작동)

혹시나 싶어 ontouchstart="" 를 사용하니 말끔히 해결..;; -_-
honeycomb 에서 터치 안되는 문제 와는 다른 문제였다.
=================================
2014.01.15 추가
기기: SHW-M380S
Touch Event가 들어간 Element 에 ontouchstart="" 를 사용했으나 touch Event 발생하지 않음.

Script 로 Touch Event 넣은 Element의 Parent Element 에 ontouchstart="" 를 사용하니 정상작동
=================================


    하지만 위의 방법을 사용할 수는 없었다.
    고생끝에 우연히 해결방법을 찾았다.




해결방법
  - Touch Event 를 넣은 Element 의 Parent Elementontouchstart="" 를 입력한다.





2013년 11월 21일 목요일

[CSS] 중첩된 미디어쿼리(MediaQuery)




if 구문 안에 if 구문을 또 넣을 수 있듯이 MediaQuery 또한 중첩으로 사용이 가능하다.
(마우스로 브라우저의 크기를 이리저리 조정하세요)




Portrait

LandScape

width: 1024이상

width: 1024미만

width: 768미만

height: 1024이상

height: 1024미만

height: 768미만




아래는 현재 작동되고 있는 소스


  .div_40013 { border: 1px solid;}

  @media all and (orientation: portrait) {
    #div_port_0359 {background-color: #FCFFA9; }

    @media all and (min-width: 1024px) {
      #div_width_1024up_0359 {background-color: #FCFFA9; }
    }
    @media all and (max-width: 1023px) {
      #div_width_1024down_0359 {background-color: #FCFFA9; }
    }
    @media all and (max-width: 768px) {
      #div_width_768down_0359 {background-color: #FCFFA9; }
    }

    @media all and (min-height: 1024px) {
      #div_height_1024up_0359 {background-color: #FCFFA9; }
    }
    @media all and (max-height: 1023px) {
      #div_height_1024down_0359 {background-color: #FCFFA9; }
    }
    @media all and (max-height: 768px) {
      #div_height_768down_0359 {background-color: #FCFFA9; }
    }
  }

  @media all and (orientation:landscape) {
    #div_land_0359 {background-color: #FCFFA9; }

    @media all and (min-width: 1024px) {
      #div_width_1024up_0359 {background-color: #FCFFA9; }
    }
    @media all and (max-width: 1023px) {
      #div_width_1024down_0359 {background-color: #FCFFA9; }
    }
    @media all and (max-width: 768px) {
      #div_width_768down_0359 {background-color: #FCFFA9; }
    }

    @media all and (min-height: 1024px) {
      #div_height_1024up_0359 {background-color: #FCFFA9; }
    }
    @media all and (max-height: 1023px) {
      #div_height_1024down_0359 {background-color: #FCFFA9; }
    }
    @media all and (max-height: 768px) {
      #div_height_768down_0359 {background-color: #FCFFA9; }
    }
  }



Portrait
LandScape
width: 1024이상
width: 1024미만
width: 768미만
height: 1024이상
height: 1024미만
height: 768미만




PS.
대부분의 WebBrowser 에서는 상관 없겠지만 모바일 디바이스에서 중첩된 미디어쿼리가 작동하지 않는 문제가 발생해서 원복했다.
확인했던 안되는 디바이스는 다음과 같다.
Android: Honeycomb(3.x) 이하
iOS: 6.x, 4.3

2013년 11월 20일 수요일

[IntelliJ] Tomcat 으로 Static Webpage(html) 띄우기(게시하기)



Tomcat 으로 일반 html 페이지를 띄우려 했는데 WEB-INF 디렉토리가 없는
모듈을 어떻게 띄울 수 있을까 생각했는데 구글에서 찾다가 알아냈다.


'Project Structure' --> 'Artifacts' --> 'Output Layout' --> '+'(add) --> 'Directory Content'









그 후에 정적으로 사용할 Source 디렉토리를 선택하면 된다.



IntelliJ 와 Tomcat 연동방법은 --> 링크
(지금과는 버전이 조금 틀리지만 기본 개념은 다르지 않기에..)


2013년 11월 18일 월요일

[Servlet] Image Proxy (이미지 프록시 - 차단된 사이트의 이미지를 로드할 수 있게..)




차단된 사이트에서 이미지를 가져와야 하는 경우가 생겨서
proxy로 이미지를 보여줄 수 있는 방법을 선택했다.
(그냥 이미지를 로딩하면 warning 페이지가 뜬다.)



ImageProxyServlet.java
public class ImageProxyServlet extends javax.servlet.http.HttpServlet {
    protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
        try {
            String url = request.getParameter("url");
            HttpClient httpClient = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet(url);
            HttpResponse httpResponse = httpClient.execute(httpGet);
            HttpEntity httpEntity = httpResponse.getEntity();
            InputStream inputStream = httpEntity.getContent();
            response.setContentType("image/jpeg");
            IOUtils.copy(inputStream, response.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}



web.xml
    
        ImageProxyServlet
        com.example.ImageProxyServlet
    
    
        ImageProxyServlet
        /imageProxy
    


2013년 11월 14일 목요일

[Android] Preference 에서 설정 목록을 클릭 시 특정 기능이 작동해야 하는경우



App의 Setting 목록 Activity를 만들려 보니 다음과 같은게 필요하다는걸 알았다.

1. PreferenceActivity 를 상속받은 Class
2. res/xml 디렉토리 하위의 xml
3. manifest 등록


쉽게 설명되어있는 링크
어렵게 설명되어있는 링크





해당 Activity Class와 Xml 을 이용해서
클릭 시 리스트중에 선택을 하거나 on, off 기능으로 SharedPreference 에 값을 저장 할 수 있다.



* 하지만 내가 필요한 기능은 그중에 한 옵션은 클릭 시 특정 기능이 수행되어야 했었다.
(구현하려는 기능은 지금까지 쌓아놓은 로그를 지우는 버튼..)

setOnClickListener 나 OnItemClickListener 와 같은 기능이 필요했는데
다음과 같이 해결을 했다.



public class ConfigActivity extends PreferenceActivity {

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        addPreferencesFromResource(R.xml.preferences);
    }

    @Override
    public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
        Toast.makeText(ConfigActivity.this, "preference:"+preference.getKey(), Toast.LENGTH_SHORT).show();
        return super.onPreferenceTreeClick(preferenceScreen, preference);
    }
}


결과로 Toast 에 해당 Preference 의 key 값이 찍혔다.
그래서 if, else 로 key 값을 구분해서 기능을 수행하도록 했다.




2013년 11월 6일 수요일

[Android Studio] 'Theme.NoTitleBar' 작업 시 'You need to use a Theme.AppCompat theme' 에러



Android Studio 에서 프로젝트를 생성 후 TitleBar 를 없애기 위해서
AndroidManifest.xml 의 Activity 에 다음과 같이 기술했었다.

android:theme="@android:style/Theme.NoTitleBar"

하지만 황당하게도 에러가 발생을 하면서 앱이 종료가 된다.



Android Studio (version: 0.3.2)
 AndroidManifest.xml

        <activity android:name="MainActivity"
                  android:theme="@android:style/Theme.NoTitleBar"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>



 Exception

11-06 17:55:02.108  13995-13995/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.myapplicationtest/com.example.myapplicationtest.MainActivity}: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2202)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2252)
            at android.app.ActivityThread.access$600(ActivityThread.java:146)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1240)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5168)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:564)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
            at android.support.v7.app.ActionBarActivityDelegate.onCreate(ActionBarActivityDelegate.java:111)
            at android.support.v7.app.ActionBarActivityDelegateICS.onCreate(ActionBarActivityDelegateICS.java:58)
            at android.support.v7.app.ActionBarActivity.onCreate(ActionBarActivity.java:98)
            at com.example.myapplicationtest.MainActivity.onCreate(MainActivity.java:18)
            at android.app.Activity.performCreate(Activity.java:5200)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2166)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2252)
            at android.app.ActivityThread.access$600(ActivityThread.java:146)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1240)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5168)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:564)
            at dalvik.system.NativeStart.main(Native Method)



하지만 IntelliJ Ultimate version 에서는 똑같이 프로젝트를 생성 후 해당 부분을 넣어줘도 문제가 발생하지 않는다.


IntelliJ Ultimate 에서 정상적으로 돌아간 소스를 Android Studio 에 import 해서 테스트 해봤더니 정상적으로 돌아가긴 한다.
Android Studio 에서 특정 파일에 필요한 내용을 넣지 않았거나 하는 생각이 든다.

그냥 Android Studio 의 버그로 판단..;;

[Android Studio] 라이브러리(jar) 파일 import 시키는 방법



Android Studio 에서 프로젝트를 처음 생성 후 'Project Structure' 를 보면
다음과 같이 왼쪽에 패널이 몇개 없는것을 볼 수 있다. (원인 -> 링크)








라이브러리(jar)를 어떻게 추가할 수 있을까 알아보다가 의외로 간단하다는걸 알아냄.


1. 첫번째 방법


모듈이나 프로젝트에서 오른쪽 누른 후 'Open Module Settings' 누르면 다음과 같이 나온다.
그리고 라이브러리 추가하면 됨.





2. 두번째 방법

파일 또는 디렉토리에서 오른쪽 버튼을 누른 후 'Add as Library...' 클릭.






3. 세번째 방법

'Project Structure' 에서 다른 패널들이 나온다면 거기서 그냥 추가..;;

[Android Studio] 'Project Structure' 에서 왼쪽의 패널(메뉴)이 보이지 않을때



얼마전부터 Android Studio 를 통해서 이것저것 만져보는데
예전에 만들었던 프로젝트를 로드해서 가져왔을때에는 'Project Structure' 에서 왼쪽에
Project, Modules, Libraries, SDKs, Global Libraries 등등 여러 메뉴가 나왔는데




이렇게..







Android Studio 에서 새로 만든 프로젝트의 'Project Structure' 를 보면 왼쪽에 나와야할 다른 메뉴들이 빠져있다.







인터넷을 찾다보니 다음과 같은 걸 찾았다.
http://stackoverflow.com/questions/18877728/android-studio-project-structure-is-almost-empty

 Gradle project 에서는 버그같은게 발생하는게 아니라면 패널이 숨겨진다. (라고..)



build, src 와 같은 디렉토리에 있는 {module_name-module_name}.iml 파일을
(나의경우에는 WebSpider-WebSpider.iml)
삭제하거나 뒤에 .bak 으로 이름을 변경 후 프로젝트를 닫고 다시 열어보니 다음과 같이 모든 패널이 나오는것을 확인했다.






PS.
iml 파일을 수정하지 않은 상태로 라이브러리(jar) 임포트는 다음과 같이 했다. -> 링크


2013년 11월 5일 화요일

[Mac][OSX] top 명령어에서 CPU, Memory 별로 소팅하는 방법



리눅스에서는 top 명령어 실행 후 Shift + 괄호('<', '>') 를 입력해서
CPU나 Memory 등등..  컬럼별로 소팅이 가능했었다.

하지만 OSX 의 top 명령어에서는 소팅하는 방법이 달랐다.
인터넷으로 찾고.. manual 로 뒤늦게 확인하는 센스란..;;
(역시 manual 에 다 있다.)

출처: http://figgure-out.blogspot.kr/2011/10/os-x-top-command-sort-by-column.html


 top 실행중에 소문자 'o'를 입력 후 소팅하기 원하는 리소스의 키워드를 넣으면 된다.





top 명령어 실행 시 기본으로 나타나는 모습..





소문자 'o' 를 입력 시 primary key [-pid]: 라고 문자열이 나타난다.





cpu 를 입력하고 엔터를 누르면 다음과 같이 cpu 사용량으로 소팅이 된다.





mem 을 입력 후 엔터를 눌렀을 때 메모리 사용량으로 소팅된 모습.





각 리소스의 키워드는 원본출처의 페이지에 잘 나와있다.
좀더 자세한 정보는 터미널에 $ man top 이라고 입력해서 manual 을 보면 자세히 나와있다.


[Android Studio] 프로젝트 생성 시 fragment_main.xml 파일 생성되지 않도록 설정



의외로 간단한 거였는데..
나처럼 찾아보는 사람이 있을 수 있으니..



원래 요로코롬 되어있는걸..


이렇게 변경해 주면 된다.



출처: http://google-android-studio.blogspot.kr/2013/10/creating-non-frame-layout-with-android.html





================================================
2014.04.24 업데이트

박찬후님 댓글을 보고 다시한번 Android Studio 를 다운받아서 테스트를 해봤다.



테스트 버전은 다음과 같다.
(그동안 버전이 많이 올라갔다. 이전에 내가 테스트 했던 버전은 0.3.x)




정말로 이름을 똑같이 하니 unique 한 이름으로 변경해 달라고 하면서
Finish 버튼이 비활성화로 변했다.




어떻게 해야 하나 구글에서 이것저것 찾아보다가 결국 찾지 못하고 그냥 디폴트로 생성했는데 이상하게도 예전에 내가 테스트를 했던 것 처럼 fragment 파일이 생성되지 않고 activity 만 생성이 되었다!?





'New Project' 로 프로젝트 생성시 다음과 같이 별다른 설정 없이 'Next'만 누름.








'Finish'를 누르고 프로젝트를 생성 했을 시 fragment 파일은 생성되지 않고
딸랑 Activity 파일 하나만 생성이 되었다.








==================================================
중요 내용


Android Studio 0.4.6 버전을 다운 받아서 실행 시 업데이트 할 수 있다고 나왔었는데
위의 테스트가 끝나고 업데이트를 받아보았다.







새로운 버전은 0.5.5 라고 한다.






설치가 다 되면 0.5.5 버전으로 업그레이드 된걸 확인 할 수 있다.





Activity 특성을 선택할 수 있는 항목이 늘어났다.






일반적인 방법대로 'Black Activity' 를 선택.







응!? fragment 에 대한 항목이 빠져있었다.







'Finish' 를 누르니 0.4.6 버전과 같이 동일하게 생성이 되었다.






바로 어제(2014.04.24) 0.4.6을 받아서 설치 시 Android 개발자 사이트에도 올리지 않은 update 항목이 있다고 하는걸로 봐서는 0.4.6에서는 fragment 파일을 강제로 만들지 않게 수정을 했지만 프로젝트 생성 시 해당 항목이 빠져야 하는데 빠지지 않은 버그로 추측이 된다.
(업데이트 시 fragment 항목이 빠진걸 보면...)

아직 베타버전이다보니 버그도 많고 기능의 변경도 휙휙 바뀌기 때문에..
Android Studio 의 사용은 아직 시기상조가 아닐까 싶다.
차라리 IntelliJ Community 버전(무료)을 받아서 사용하는게 정신건강에 좋을듯..