Translate

2015년 5월 29일 금요일

[Android][Chrome] Lollipop 에서 브라우저 주소창에 색상넣기



Android Lollipop 이 나오며 브라우저에 새로운 기능이 추가되었다.
Chrome v39 부터 지원이 된다고한다.


Android 4.4.2 사용중인 내 LG G2 단말에서는 지원이 되지 않으며
다른 Lollipop 단말기에서 확인해보니 아래와 같이 보여지는 것을 확인했다.



URL접속 시 다음과 같다.


작업관리자 확인 시 브라우저 탭 중에서 해당 탭만 색상이 나타나는 것을 볼 수 있다.





위와같이 헤더와 상태바에 색상을 입히는 방법은 다음과 같다.


<html>
  <head>
    <meta name="theme-color" content="#3F51B5">
    <meta charset="utf-8" />
    <title>TEST</title>
  </head>
  <body>

test page
  </body>
</html>


참조: http://www.androidpolice.com/2014/11/10/chrome-v39-on-lollipop-supports-custom-multitasking-headerstatus-bar-colors-with-a-simple-html-tag/

2015년 5월 20일 수요일

[Redmine] Previous version of BitNami Redmine Stack



이전버전의 BitNami Redmine Stack 다운로드 할 수 있는 링크를 찾을 수 없어서 내가 가지고 있는 버전을 올려서 공유한다.


Download Link

bitnami-redmine-1.4.5-0-windows-installer.exe

bitnami-redmine-2.1.5-0-windows-installer.exe

bitnami-redmine-2.2.0-0-windows-installer.exe

bitnami-redmine-2.6.4-0-windows-installer.exe


2015년 5월 19일 화요일

[Redmine] BitNami Redmine Stack - 2.2.0-0 백업 및 복구



현재 운영되고 있는 BitNami Redmine Stack - 2.2.0-0 에 저장되어 있는 자료를 백업하여 추후에 문제가 생겼을 경우 복구를 할 수 있는 환경을 구성을 해봤다.


작업방법은 그리 어렵지 않다.
(정상적으로 복구가 되는지 확인하는 부분에서 오래걸렸고.. Mysql 같은경우 dump 생성해서 밀어넣고 하면 작업의 단계가 많아져서 초반에 시도를 하다가 Mysql 디렉토리를 통채로 백업하는 방법을 사용했다.)




백업

아래의 디렉토리를 압축하여 백업하면 된다.
1. C:\BitNami\redmine-2.2.0-0\apps\redmine\ 
2. C:\BitNami\redmine-2.2.0-0\mysql\    (Mysql 을 중지시킨 후 작업)





복구

1. BitNami Redmine Stack 의 서비스를 모두 중지시킨 후 아래의 백업한 아래의 디렉토리를 교체 후 서비스를 기동시킨다.

  - C:\BitNami\redmine-2.2.0-0\apps\redmine\ 
  - C:\BitNami\redmine-2.2.0-0\mysql\



PS.
백업&복구 에 사용된 BitNami Redmine Stack 은 2.2.0-0 version 이 사용되었다.
이전버전의 BitNami Redmine Stack 은 아래의 링크에서 받으면 된다.
Link: Previous version of BitNami Redmine Stack

아래의 문제가 발생 할 수 있다.
Link: BitNami Redmine Stack 서비스 구동 시 Thin_redmine 서비스만 Stopped 되는 문제


[Redmine] BitNami Redmine Stack 서비스 구동 시 Thin_redmine 서비스만 Stopped 되는 문제



증상

BitNami Redmine Stack 프로그램에서 'Start All' 버튼을 클릭 시
Thin_redmine
Thin_redmine2
두개의 서비스만 Running 에서 몇 초 지나면 Stopped 로 상태가 변하는 증상




Redmine 접속 시 다음과 같이 화면이 보여진다.








방법

콘솔에서 Thin_redmine 을 직접 띄워서 로그를 보면 원인을 알 수가 있다.

1. Use BitNami Redmine Stack 을 실행한다.


2. 아래와 같이 redmine 을 기동시킨다.


Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.

C:\Bitnami\redmine-2.2.0-0>cd apps\redmine\htdocs

C:\Bitnami\redmine-2.2.0-0\apps\redmine\htdocs>bundle exec thin start -e production -p 3001 --prefix /redmine




PS.
bundle exec thin start -e production -p 3001 --prefix /redmine
위의 명령어를 입력 시 GUI 툴에서 Thin_redmine 을 구동시킨 것과 같다.
정상적으로 명령어가 수행 시 프롬프트가 나타나지 않으며 Redmine 웹페이지에 정상적으로 접속이 가능하다.









다음과 같은 경우가 있다.

1. DB 연결에 문제가 있는경우
  (Redmine 을 백업&복구 시키는 경우에 mysqldump 를 이용했다면 발생할 수 있다.)
  (DB접속 계정의 패스워드가 틀렸을 것이다.)


C:\Bitnami\redmine-2.2.0-0\apps\redmine\htdocs>bundle exec thin start -e production -p 3001 --prefix /redmine
>> Using rack adapter
C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/mysql2-0.3.11-x86-mingw32/lib/mysql2/client.rb:44:in `connect': Access denied for user 'bitnami'@'localhost' (using password: YES) (Mysql2::Error)
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/mysql2-0.3.11-x86-mingw32/lib/mysql2/client.rb:44:in `initialize'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.2.9/lib/active_record/connection_adapters/mysql2_adapter.rb:16:in `new'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.2.9/lib/active_record/connection_adapters/mysql2_adapter.rb:16:in `mysql2_connection'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.2.9/lib/active_record/connection_adapters/abstract/connection_pool.rb:315:in `new_connection'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.2.9/lib/active_record/connection_adapters/abstract/connection_pool.rb:325:in `checkout_new_connection'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.2.9/lib/active_record/connection_adapters/abstract/connection_pool.rb:247:in `block (2 levels) in checkout'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.2.9/lib/active_record/connection_adapters/abstract/connection_pool.rb:242:in `loop'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.2.9/lib/active_record/connection_adapters/abstract/connection_pool.rb:242:in `block in checkout'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/1.9.1/monitor.rb:211:in `mon_synchronize'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.2.9/lib/active_record/connection_adapters/abstract/connection_pool.rb:239:in `checkout'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.2.9/lib/active_record/connection_adapters/abstract/connection_pool.rb:102:in `block in connection'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/1.9.1/monitor.rb:211:in `mon_synchronize'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.2.9/lib/active_record/connection_adapters/abstract/connection_pool.rb:101:in `connection'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.2.9/lib/active_record/connection_adapters/abstract/connection_pool.rb:410:in `retrieve_connection'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.2.9/lib/active_record/connection_adapters/abstract/connection_specification.rb:171:in `retrieve_connection'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.2.9/lib/active_record/connection_adapters/abstract/connection_specification.rb:145:in `connection'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.2.9/lib/active_record/model_schema.rb:308:in `clear_cache!'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.2.9/lib/active_record/railtie.rb:97:in `block (2 levels) in <class:Railtie>'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/activesupport-3.2.9/lib/active_support/callbacks.rb:418:in `_run__347369653__prepare__704607500__callbacks'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/activesupport-3.2.9/lib/active_support/callbacks.rb:405:in `__run_callback'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/activesupport-3.2.9/lib/active_support/callbacks.rb:385:in `_run_prepare_callbacks'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/activesupport-3.2.9/lib/active_support/callbacks.rb:81:in `run_callbacks'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/actionpack-3.2.9/lib/action_dispatch/middleware/reloader.rb:74:in `prepare!'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/actionpack-3.2.9/lib/action_dispatch/middleware/reloader.rb:48:in `prepare!'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/railties-3.2.9/lib/rails/application/finisher.rb:47:in `block in <module:Finisher>'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/railties-3.2.9/lib/rails/initializable.rb:30:in `instance_exec'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/railties-3.2.9/lib/rails/initializable.rb:30:in `run'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/railties-3.2.9/lib/rails/initializable.rb:55:in `block in run_initializers'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/railties-3.2.9/lib/rails/initializable.rb:54:in `each'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/railties-3.2.9/lib/rails/initializable.rb:54:in `run_initializers'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/railties-3.2.9/lib/rails/application.rb:136:in `initialize!'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/railties-3.2.9/lib/rails/railtie/configurable.rb:30:in `method_missing'
        from C:/Bitnami/redmine-2.2.0-0/apps/redmine/htdocs/config/environment.rb:14:in `<top (required)>'
        from C:/Bitnami/redmine-2.2.0-0/apps/redmine/htdocs/config.ru:3:in `require'
        from C:/Bitnami/redmine-2.2.0-0/apps/redmine/htdocs/config.ru:3:in `block in <main>'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/rack-1.4.1/lib/rack/builder.rb:51:in `instance_eval'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/rack-1.4.1/lib/rack/builder.rb:51:in `initialize'
        from C:/Bitnami/redmine-2.2.0-0/apps/redmine/htdocs/config.ru:1:in `new'
        from C:/Bitnami/redmine-2.2.0-0/apps/redmine/htdocs/config.ru:1:in `<main>'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/thin-1.3.1/lib/rack/adapter/loader.rb:36:in `eval'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/thin-1.3.1/lib/rack/adapter/loader.rb:36:in `load'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/thin-1.3.1/lib/rack/adapter/loader.rb:45:in `for'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/thin-1.3.1/lib/thin/controllers/controller.rb:169:in `load_adapter'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/thin-1.3.1/lib/thin/controllers/controller.rb:73:in `start'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/thin-1.3.1/lib/thin/runner.rb:185:in `run_command'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/thin-1.3.1/lib/thin/runner.rb:151:in `run!'
        from C:/Bitnami/redmine-2.2.0-0/ruby/lib/ruby/gems/1.9.1/gems/thin-1.3.1/bin/thin:6:in `<top (required)>'
        from C:/Bitnami/redmine-2.2.0-0/ruby/bin/thin:23:in `load'
        from C:/Bitnami/redmine-2.2.0-0/ruby/bin/thin:23:in `<main>'

C:\Bitnami\redmine-2.2.0-0\apps\redmine\htdocs>





2. 특정 번들(모듈)을 찾을 수 없는경우
  (bundle install 명령어로 설치 및 복구)


C:\Bitnami\redmine-2.2.0-0\apps\redmine\htdocs>bundle exec thin start -e product
ion -p 3001 --prefix /redmine
[31mCould not find vpim-0.695 in any of the sources [0m
[33mRun `bundle install` to install missing gems. [0m

C:\Bitnami\redmine-2.2.0-0\apps\redmine\htdocs>bundle install
Fetching gem metadata from http://rubygems.org/.........
Fetching gem metadata from http://rubygems.org/.........
Using rake (0.9.2.2)
Using i18n (0.6.0)
Using multi_json (1.3.6)
Using activesupport (3.2.9)
Using builder (3.0.0)
Using activemodel (3.2.9)
Using erubis (2.7.0)
Using journey (1.0.4)
Using rack (1.4.1)
Using rack-cache (1.2)
Using rack-test (0.6.1)
Using hike (1.2.1)
Using tilt (1.3.3)
Using sprockets (2.2.1)
Using actionpack (3.2.9)
Using mime-types (1.19)
Using polyglot (0.3.3)
Using treetop (1.4.10)
Using mail (2.4.4)
Using actionmailer (3.2.9)
Using arel (3.0.2)
Using tzinfo (0.3.33)
Using activerecord (3.2.9)
Using activeresource (3.2.9)
Using coderay (1.0.6)
Using daemons (1.1.8)
Using eventmachine (1.0.0)
Using rack-ssl (1.3.2)
Using json (1.7.5)
Using rdoc (3.12)
Using thor (0.15.4)
Using railties (3.2.9)
Using jquery-rails (2.0.3)
Using mysql2 (0.3.11)
Using net-ldap (0.3.1)
Using ruby-openid (2.1.8)
Using rack-openid (1.3.1)
Using bundler (1.2.1)
Using rails (3.2.9)
Using rmagick (2.13.1)
Using thin (1.3.1)
Installing vpim (0.695)
Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem
is installed.

C:\Bitnami\redmine-2.2.0-0\apps\redmine\htdocs>




참조: http://180bpm.tistory.com/97



연관글
[Redmine] BitNami Redmine Stack - 2.2.0-0 백업 및 복구
[Redmine] 이전 버전의 BitNami Redmine Stack


[Windows] Windows 7 에서 Linux 명령어인 watch 사용하기



Linux 에는 주기적으로 같은 명령어를 실행시켜주는 watch 라는 명령어가 있다.
시스템을 모니터링 한다거나 할 때 자주 사용했던 명령어 인데..


윈도우 에서는 다음과 같은 명령어로 비슷한 기능을 수행했다.

시작 => 실행 => cmd

C:\>
C:\>PowerShell
Windows PowerShell
Copyright (C) 2009 Microsoft Corporation. All rights reserved.

// 사용방법: while(1) { 명령어; start-sleep -seconds 5; clear}

PS C:\> while(1) { adb shell dumpsys meminfo -a com.android.phone; start-sleep -seconds 5; clear}



Android 에서 특정 앱의 메모리 사용량을 보기위한 명려어인
adb shell dumpsys meminfo -a com.android.phone
라는 명령어가 5초 주기로 실행이 된다.






아래와 같은 화면이 5초마다 갱신되는 것을 확인 할 수 있었다.


Applications Memory Usage (kB):
Uptime: 5989518 Realtime: 5989518

** MEMINFO in pid 3974 [com.android.phone] **
                   Pss      Pss   Shared  Private   Shared  Private  Swapped     Heap     Heap     Heap
                 Total    Clean    Dirty    Dirty    Clean    Clean    Dirty     Size    Alloc     Free
                ------   ------   ------   ------   ------   ------   ------   ------   ------   ------
  Native Heap        0        0        0        0        0        0        0     4744     4446      133
  Dalvik Heap     7773        0    14912     7620        0        0    11052    37524    29985     7539
 Dalvik Other      436        0        8      436        0        0        0
        Stack      308        0        0      308        0        0        4
       Ashmem        2        0        4        0        0        0        0
    Other dev        5        0       60        0        0        4        0
     .so mmap      966        4     2112      800     4632        4     2812
    .apk mmap      603      400        0        0     1592      400        0
    .ttf mmap       84        0        0        0      716        0        0
    .dex mmap     2992     2568        0        0     1092     2568        0
    code mmap     3255     2224        0        0    20804     2224        0
   image mmap     2997        0     2088     1452    13212        0       12
   Other mmap       47        0        8        4      380        0        0
      Unknown     2949        0      308     2948        0        0       32
        TOTAL    22417     5196    19500    13568    42428     5200    13912    42268    34431     7672

 Dalvik Details
        .Heap     7765        0    14912     7612        0        0    11052
         .LOS        8        0        0        8        0        0        0
          .GC      436        0        8      436        0        0        0

 Objects
               Views:        0         ViewRootImpl:        0
         AppContexts:       24           Activities:        0
              Assets:        9        AssetManagers:        9
       Local Binders:      118        Proxy Binders:       49
    Death Recipients:       12
     OpenSSL Sockets:        0

 SQL
         MEMORY_USED:     1076
  PAGECACHE_OVERFLOW:      377          MALLOC_SIZE:       62

 DATABASES
      pgsz     dbsz   Lookaside(b)          cache  Dbname
         4       32            140         7/30/4  /data/data/com.android.providers.telephony/databases/nwk_info.db
         4      184            430      170/35/12  /data/data/com.android.providers.telephony/databases/telephony.db
         4      272            225     206/110/25  /data/data/com.android.providers.telephony/databases/mmssms.db
         4       20             23         5/28/2  /data/data/com.android.phone/databases/autoreject.db



참고: http://superuser.com/questions/191063/what-is-the-windows-analog-of-the-linux-watch-command


2015년 5월 18일 월요일

[Android] System Permission App 만들기 - Google Signed App




Android 의 특정 기능들은 일반 개발자가 해당 기능을 이용해서 앱을 제작할 수가 없다.
바로 제조사의 keystore 파일을 이용해서 signing 을 해야 하기 때문이다.



안드로이드 개발자 사이트의 manifest 의 permission 부분을 보면 특정 권한들은 아래와 같이 'Not for use by third-party applications.' 라고 보여진다.

http://developer.android.com/reference/android/Manifest.permission.html

public static final String DELETE_PACKAGES

Added in API level 1
Allows an application to delete packages.
Not for use by third-party applications.
Constant Value: "android.permission.DELETE_PACKAGES"





제조사의 keystore 파일을 이용해 signed APK 를 만들게되면 시스템 권한의 사용이 가능해 지는데 LG, 삼성과 같은 제조사의 keystore 파일은 해당 제조사에서 관리를 하며 오픈하지 않는다.
실질적으로는 단말기 출시할 때 기본 탑재되는 앱을 만드는 일이 아니라면 일반 Android App 개발자는 해당 기능을 사용할 수 없는 환경이다.
(LG/삼성에서 단말 출시 할 때 KT/SKT 전용 앱이 기본적으로 설치되어 있으며 그중에 일부의 앱만 제조사 signing을 받아 단말에 탑재되어 출시된다.)




아는사람들은 다 아는 방법같은데..
난 Google signed APK 를 만들어서 제조사 signing 없이 개발 및 테스트 할 수 있는 방법을 최근에야 알게 되었다.






시스템권한의 App을 개발 및 테스트 할 수 있는 환경은 다음과 같다.

1. Android Emulator 에서 구동 및 테스트
2. Firmware 가 userdebug mode 로 탑재되어있는 단말기
(userdebug mode Firmware 탑재 단말은 일반 Android App 개발자의 경우 단말제조사나 SKT/KT/LG U+ 관련 직종에서 일을 해야만 손에 넣을 수 있다.)






System Permission 을 사용하는 App을 만들기 위해 Google keystore 파일을 만들어 보겠다.

1. https://github.com/android/platform_build/tree/master/target/product/security 사이트에서 platform.pk8, platform.x509.pem 파일을 가져온다.

2. 다음의 명령으로 platform.jks 파일을 생성한다.
(OS 환경설정에 해당 명령어의 path가 잡혀있지 않으면 openssl, keytool 명령어 전체경로를 적어줘야 할 수 있다.)


$ openssl pkcs8 -inform DER -nocrypt -in platform.pk8 -out platform.pem
$ openssl pkcs12 -export -in platform.x509.pem -inkey platform.pem -out platform.p12 -password pass:android -name androiddebugkey

$ keytool -importkeystore -deststorepass android -destkeystore platform.jks -srcstoretype PKCS12 -srcstorepass android -srckeystore platform.p12


3. 생성된 platform.jks (keystore) 파일을 이용해서 App 을 다시 빌드하면 Google Platform Android 에뮬레이터에서 시스템 권한을 사용 할 수 있다.


생성된 keystore 파일을 다운받을 수 있게 올려 놓았다.
platform_google.jks 다운받기




참고: http://blog.naver.com/PostView.nhn?blogId=kimyow&logNo=50117944249&parentCategoryNo=6&categoryNo=&viewDate=&isShowPopularPosts=false&from=postView





Android 에서 사용 가능한 권한은 아래와 같다.
https://android.googlesource.com/platform/frameworks/base/+/master/packages/SystemUI/AndroidManifest.xml

  1. <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
  2. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  3. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  4. <uses-permission android:name="android.permission.ACCESS_ALL_EXTERNAL_STORAGE" />
  5. <uses-permission android:name="android.permission.WAKE_LOCK" />
  6. <uses-permission android:name="android.permission.INJECT_EVENTS" />
  7. <uses-permission android:name="android.permission.DUMP" />
  8. <uses-permission android:name="android.permission.WRITE_SETTINGS" />
  9. <uses-permission android:name="android.permission.STATUS_BAR_SERVICE" />
  10. <uses-permission android:name="android.permission.STATUS_BAR" />
  11. <uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
  12. <uses-permission android:name="android.permission.REMOTE_AUDIO_PLAYBACK" />
  13. <uses-permission android:name="android.permission.MANAGE_USERS" />
  14. <uses-permission android:name="android.permission.READ_PROFILE" />
  15. <uses-permission android:name="android.permission.READ_CONTACTS" />
  16. <uses-permission android:name="android.permission.CONFIGURE_WIFI_DISPLAY" />
  17. <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
  18. <uses-permission android:name="android.permission.GET_APP_OPS_STATS" />
  19. <!-- Networking and telephony -->
  20. <uses-permission android:name="android.permission.BLUETOOTH" />
  21. <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
  22. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  23. <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
  24. <uses-permission android:name="android.permission.READ_PHONE_STATE" />
  25. <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
  26. <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
  27. <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" />
  28. <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
  29. <uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY" />
  30. <uses-permission android:name="android.permission.CONTROL_VPN" />
  31. <!-- Physical hardware -->
  32. <uses-permission android:name="android.permission.MANAGE_USB" />
  33. <uses-permission android:name="android.permission.DEVICE_POWER" />
  34. <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
  35. <uses-permission android:name="android.permission.MASTER_CLEAR" />
  36. <uses-permission android:name="android.permission.VIBRATE" />
  37. <!-- ActivityManager -->
  38. <uses-permission android:name="android.permission.REAL_GET_TASKS" />
  39. <uses-permission android:name="android.permission.GET_DETAILED_TASKS" />
  40. <uses-permission android:name="android.permission.REORDER_TASKS" />
  41. <uses-permission android:name="android.permission.REMOVE_TASKS" />
  42. <uses-permission android:name="android.permission.STOP_APP_SWITCHES" />
  43. <uses-permission android:name="android.permission.SET_SCREEN_COMPATIBILITY" />
  44. <uses-permission android:name="android.permission.START_ANY_ACTIVITY" />
  45. <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
  46. <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
  47. <uses-permission android:name="android.permission.GET_TOP_ACTIVITY_INFO" />
  48. <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" />
  49. <uses-permission android:name="android.permission.START_TASKS_FROM_RECENTS" />
  50. <!-- WindowManager -->
  51. <uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW" />
  52. <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
  53. <uses-permission android:name="android.permission.READ_FRAME_BUFFER" />
  54. <uses-permission android:name="android.permission.MANAGE_APP_TOKENS" />
  55. <uses-permission android:name="android.permission.SET_ORIENTATION" />
  56. <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
  57. <!-- DreamManager -->
  58. <uses-permission android:name="android.permission.READ_DREAM_STATE" />
  59. <uses-permission android:name="android.permission.WRITE_DREAM_STATE" />
  60. <!-- Alarm clocks -->
  61. <uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
  62. <!-- Keyguard -->
  63. <uses-permission android:name="android.permission.CONTROL_KEYGUARD" />
  64. <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
  65. <uses-permission android:name="android.permission.GET_ACCOUNTS" />
  66. <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
  67. <uses-permission android:name="android.permission.BIND_DEVICE_ADMIN" />
  68. <uses-permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" />
  69. <uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL" />
  70. <uses-permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE" />
  71. <uses-permission android:name="android.permission.TRUST_LISTENER" />
  72. <!-- Needed for WallpaperManager.clear in ImageWallpaper.updateWallpaperLocked -->
  73. <uses-permission android:name="android.permission.SET_WALLPAPER"/>
  74. <!-- Recents -->
  75. <uses-permission android:name="android.permission.BIND_APPWIDGET" />
  76. <!-- Wifi Display -->
  77. <uses-permission android:name="android.permission.CONFIGURE_WIFI_DISPLAY" />
  78. <uses-permission android:name="android.permission.CAMERA" />
  79. <!-- Screen Capturing -->
  80. <uses-permission android:name="android.permission.MANAGE_MEDIA_PROJECTION" />



2015년 5월 16일 토요일

[IntelliJ] Not a valid package name 우회하기




IntelliJ 를 일년넘게 사용하며 여러가지 편리한 점이 있었지만 아래와 같이 불편한 점이 있었다.


패키지를 새로 만들 때 다음과 같은 메시지가 보여진다.
(Eclipse를 사용 할 때는 문제가 없었는데 말이다..)
Not a valid package name, it would be impossible to create a class inside




패키지명 중간에 1004lucifer 와 같이 숫자로 시작하는 패키지명이 문제가 된 것인데..
내가 사용하는 도메인이 1004lucifer.co.kr 인데 이걸 무시하고 패키지명을 만들 수 없을까 했었는데..

Package naming Rule 을 찾아보니 내가 잘못했다.
https://docs.oracle.com/javase/tutorial/java/package/namingpkgs.html

Oracle에서 알려준대로 패키지명을 다시 수정하니 정상적인 패키지명으로 인식되었다.
(이걸 이제서야 알게되다니;;)



2015년 5월 11일 월요일

[Android] java.lang.IncompatibleClassChangeError: Couldn't find 이슈




Lib: Gson v2.3.1


Lollipop 이 출시가 되고 삼성 단말에서 ANR과 함께 아래와 같은 로그가 발생했다.


??-?? ??:??:??  3048  8514 E AndroidRuntime: FATAL EXCEPTION: Thread-1548
??-?? ??:??:??  3048  8514 E AndroidRuntime: Process: com.???.????????, PID: 3048
??-?? ??:??:??  3048  8514 E AndroidRuntime: java.lang.IncompatibleClassChangeError: Couldn't find com.google.gson.annotations.SerializedName.value
??-?? ??:??:??  3048  8514 E AndroidRuntime:    at libcore.reflect.AnnotationAccess.toAnnotationInstance(AnnotationAccess.java:659)
??-?? ??:??:??  3048  8514 E AndroidRuntime:    at libcore.reflect.AnnotationAccess.toAnnotationInstance(AnnotationAccess.java:641)
??-?? ??:??:??  3048  8514 E AndroidRuntime:    at libcore.reflect.AnnotationAccess.getDeclaredAnnotation(AnnotationAccess.java:170)
??-?? ??:??:??  3048  8514 E AndroidRuntime:    at java.lang.reflect.Field.getAnnotation(Field.java:242)
??-?? ??:??:??  3048  8514 E AndroidRuntime:    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getFieldName(ReflectiveTypeAdapterFactory.java:71)
??-?? ??:??:??  3048  8514 E AndroidRuntime:    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getFieldName(ReflectiveTypeAdapterFactory.java:67)
??-?? ??:??:??  3048  8514 E AndroidRuntime:    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:142)
??-?? ??:??:??  3048  8514 E AndroidRuntime:    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:83)
??-?? ??:??:??  3048  8514 E AndroidRuntime:    at com.google.gson.Gson.getAdapter(Gson.java:359)
??-?? ??:??:??  3048  8514 E AndroidRuntime:    at com.google.gson.Gson.fromJson(Gson.java:809)
??-?? ??:??:??  3048  8514 E AndroidRuntime:    at com.google.gson.Gson.fromJson(Gson.java:775)
??-?? ??:??:??  3048  8514 E AndroidRuntime:    at com.google.gson.Gson.fromJson(Gson.java:724)
??-?? ??:??:??  3048  8514 E AndroidRuntime:    at com.google.gson.Gson.fromJson(Gson.java:696)
??-?? ??:??:??  3048  8514 E AndroidRuntime:    at com.???.?????????.run(?????.java:302) 




에러가 발생한 부분은 다음과 같다.
https://android.googlesource.com/platform/libcore/+/android-5.0.2_r3/luni/src/main/java/libcore/reflect/AnnotationAccess.java

private static <A extends Annotation> A toAnnotationInstance(Class<?> context, Dex dex,
        Class<A> annotationClass, EncodedValueReader reader) {
    int fieldCount = reader.readAnnotation();
    if (annotationClass != context.getDexCacheType(dex, reader.getAnnotationType())) {
        throw new AssertionError("annotation value type != return type");
    }
    AnnotationMember[] members = new AnnotationMember[fieldCount];
    for (int i = 0; i < fieldCount; i++) {
        int name = reader.readAnnotationName();
        String nameString = dex.strings().get(name);
        Method method;
        try {
            method = annotationClass.getMethod(nameString, NO_ARGUMENTS);
        } catch (NoSuchMethodException e) {
            throw new IncompatibleClassChangeError(
                    "Couldn't find " + annotationClass.getName() + "." + nameString);
        }
        Class<?> returnType = method.getReturnType();
        Object value = decodeValue(context, returnType, dex, reader);
        members[i] = new AnnotationMember(nameString, value, returnType, method);
    }
    return AnnotationFactory.createAnnotation(annotationClass, members);
}





Lollipop 에서 Memory 이슈가 많던데..
아마 이것도 Garbage Collection 문제가 아닐까 싶다.

https://code.google.com/p/android/issues/detail?id=172339
http://jackson-users.ning.com/forum/topics/android-jackson-parsing-using-annotations
http://stackoverflow.com/questions/29619052/how-to-fix-incompatibleclasschangeerror-during-android-jackson-parsing-using-ann


위의 링크를 보면 모두 Lollipop 에서만 문제가 발생하고 있으며
Samsung Device 에서만 발생한다는 답변도 보인다.



처음에는 네트워크 불안한문제나 우리의 로직에 문제가 있지 않을까 싶었는데..
Lollipop 이슈로 결론을 짓고 AssertionError, IncompatibleClassChangeError 에 대한 예외처리를 따로 하는게 맞을 듯 싶다.


2015년 5월 7일 목요일

[Android] 루팅 했는데도 나오는 read-only file system 문제




/system/app/[App_Name]/ 디렉토리에 APK 파일을 넣으려 하자
read-only file system 라는 오류가 발생을 했다.

구글에 read-only file system android 라고 검색을 해보면 대부분 다음과 비슷한 명령어가 나온다.
mount -o rw,remount -t yaffs2 /dev/block/mtdblock3 /system



하지만 단말기에서 실제로 해보면 정상적으로 되지 않는다.
이유는 Data Type 과 마운트 경로가 틀렸는데 다음과 같이 작업을 하면 된다.



adb shell 로 접속 후 mount 명령어를 입력하면 /system 디렉토리의 실제 마운트 경로와 포멧 타입을 알 수 있다.


shell@p1:/ $ mount
mount
rootfs / rootfs ro,relatime 0 0
tmpfs /dev tmpfs rw,seclabel,nosuid,relatime,size=1426416k,nr_inodes=356604,mode=755 0 0
devpts /dev/pts devpts rw,seclabel,relatime,mode=600 0 0
proc /proc proc rw,relatime 0 0
sysfs /sys sysfs rw,seclabel,relatime 0 0
selinuxfs /sys/fs/selinux selinuxfs rw,relatime 0 0
debugfs /sys/kernel/debug debugfs rw,relatime 0 0
none /acct cgroup rw,relatime,cpuacct 0 0
none /sys/fs/cgroup tmpfs rw,seclabel,relatime,size=1426416k,nr_inodes=356604,mode=750,gid=1000 0 0
tmpfs /mnt/asec tmpfs rw,seclabel,relatime,size=1426416k,nr_inodes=356604,mode=755,gid=1000 0 0
tmpfs /mnt/obb tmpfs rw,seclabel,relatime,size=1426416k,nr_inodes=356604,mode=755,gid=1000 0 0
none /dev/cpuctl cgroup rw,relatime,cpu 0 0
pstore /sys/fs/pstore pstore rw,relatime 0 0
/mnt/pstore /mnt/pstore pstore rw,relatime 0 0
adb /dev/usb-ffs/adb functionfs rw,relatime 0 0
/dev/block/bootdevice/by-name/system /system ext4 ro,seclabel,noatime,data=ordered 0 0
/dev/block/bootdevice/by-name/cache /cache ext4 rw,seclabel,nosuid,nodev,noatime,noauto_da_alloc,errors=continue,data=ordered 0 0
/dev/block/bootdevice/by-name/userdata /data ext4 rw,seclabel,nosuid,nodev,noatime,noauto_da_alloc,resuid=1000,errors=continue,data=ordered 0 0
/dev/block/bootdevice/by-name/persist /persist ext4 rw,seclabel,nosuid,nodev,noatime,noauto_da_alloc,errors=continue,data=ordered 0 0
/dev/block/bootdevice/by-name/modem /firmware vfat ro,context=u:object_r:firmware_file:s0,relatime,uid=1000,gid=1000,fmask=0337,dmask=0227,codepage=437,iocharset=iso8859-1,shortname=lower,errors=remount-ro 0 0
/dev/block/bootdevice/by-name/sns /sns ext4 rw,seclabel,nosuid,nodev,noatime,noauto_da_alloc,errors=continue,data=ordered 0 0
/dev/block/bootdevice/by-name/drm /persist-lg ext4 rw,seclabel,nosuid,nodev,noatime,noauto_da_alloc,errors=continue,data=ordered 0 0
/dev/block/bootdevice/by-name/mpt /mpt ext4 rw,seclabel,nosuid,nodev,noatime,noauto_da_alloc,errors=continue,data=ordered 0 0
/data/media /mnt/shell/emulated sdcardfs rw,nosuid,relatime,uid=1023,gid=1023,derive=legacy 0 0
/data/media /storage/emulated/legacy sdcardfs rw,nosuid,relatime,uid=1023,gid=1023,derive=legacy 0 0
shell@p1:/ $



위의 정보를 토대로 다음과 같이 remount 작업을 하면 된다.
("su -" 명령어를 이용해 root 권한에서 작업해야 한다.)


shell@p1:/ # mount -o rw,remount -t ext4 /dev/block/bootdevice/by-name/system /system



=============================
2015.05.11 추가

mount -o rw,remount /system

LG단말에서 위 명령어 사용시 바로 remount가 되었다.





2015년 5월 6일 수요일

[Android] 시스템설정의 폰트크기 에 따라 WebView 의 레이아웃이 변경되는 경우 (Lollipop 이슈)



문제

  - 시스템설정의 글자크기 변경 시 WebView 에서도 글자 크기가 변경이 되는 이슈




증상

1. 시스템설정 - 글꼴 크기 변경 부분





2. 글꼴 크기를 가장 크게 설정했을 때 WebView 에서 글자들의 사이즈가 커진것을 볼 수 있다.






3. 글꼴 크기를 보통으로 설정했을 때 WebView 에서 글자들의 사이즈가 정상적으로 표시되는 것을 볼 수 있다.









해결

package com.example;

import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.webkit.WebSettings;
import android.webkit.WebView;

public class MyActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        WebView webview = (WebView) findViewById(R.id.webview);
        WebSettings settings = webview.getSettings();
        settings.setJavaScriptEnabled(true);
        
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH)
            settings.setTextZoom(100);

        webview.loadUrl("http://www.google.co.kr");
    }
}


아마 나와 같은 이슈가 아닐까 싶다.
http://stackoverflow.com/questions/29816804/fixed-text-size-in-webview-android-lollipop/30072051#30072051