레이블이 android인 게시물을 표시합니다. 모든 게시물 표시
레이블이 android인 게시물을 표시합니다. 모든 게시물 표시

2014년 7월 27일 일요일

[Android] Stop Audio Player

Stop Audio Player 


        Intent intent = new Intent("com.android.music.musicservicecommand");
        intent.putExtra("command", "pause");

        mContext.sendBroadcast(intent);


MediaPlaybackService commands


 public class MediaPlaybackService extends Service {

     public static final String PLAYSTATE_CHANGED = "com.android.music.playstatechanged";
     public static final String META_CHANGED = "com.android.music.metachanged";
     public static final String QUEUE_CHANGED = "com.android.music.queuechanged";

     public static final String SERVICECMD = "com.android.music.musicservicecommand";
     public static final String CMDNAME = "command";
     public static final String CMDTOGGLEPAUSE = "togglepause";
     public static final String CMDSTOP = "stop";
     public static final String CMDPAUSE = "pause";
     public static final String CMDPLAY = "play";
     public static final String CMDPREVIOUS = "previous";
     public static final String CMDNEXT = "next";
     public static final String TOGGLEPAUSE_ACTION = "com.android.music.musicservicecommand.togglepause";
     public static final String PAUSE_ACTION = "com.android.music.musicservicecommand.pause";
     public static final String PREVIOUS_ACTION = "com.android.music.musicservicecommand.previous";
     public static final String NEXT_ACTION = "com.android.music.musicservicecommand.next";

2014년 2월 20일 목요일

[Android] Programmable Bluetooth On/Off.

Android Device의 Bluetooth On/Off 설정 제어하기.


Permissions : 

And add the following permissions into your manifest file:
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

Control On/Off : 

Sample code
public static boolean setBluetooth(boolean enable) {
    BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    boolean isEnabled = bluetoothAdapter.isEnabled();
    if (enable && !isEnabled) {
        return bluetoothAdapter.enable(); 
    }
    else if(!enable && isEnabled) {
        return bluetoothAdapter.disable();
    }
    // No need to change bluetooth state
    return true;
}

But remember these important points:
This is an asynchronous call: it will return immediately, and clients should listen for ACTION_STATE_CHANGED to be notified of subsequent adapter state changes. If this call returns true, then the adapter state will immediately transition from STATE_OFF to STATE_TURNING_ON, and some time later transition to either STATE_OFF or STATE_ON. If this call returns false then there was an immediate problem that will prevent the adapter from being turned on - such as Airplane mode, or the adapter is already turned on.

[Android] Programmable Wi-Fi On/Off

Android Device의 Wi-Fi On/Off 설정 제어하기.


Permissions :

And add the following permissions into your manifest file:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>

Control On/Off.

WifiManager wifiManager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE); 
wifiManager.setWifiEnabled(true);
wifiManager.setWifiEnabled(false);

Check Status.

boolean wifiEnabled = wifiManager.isWifiEnabled()


2014년 2월 15일 토요일

[Android] Adb Shell with RK3066

Rock Chip Device Adb shell 사용하기.

- 참조 : http://linux-rockchip.info/mw/index.php?title=ADB_shell_with_RK3066


Rock Chip device들은 Moborobo 라는 tool을 이용해서 adb 연결을 해야했다.
덕분에 원하지 않더라도 단말에 Moborobo daemon이 설치된다.
개인적으로 이런식의 Apk 설치를 싫어한다.

Windows 와 Linux 환경에서 USB Vendor ID 를 추가를 통해 Android SDK 에 포함된 adb를 이용한 동작을 확인했다.

1. Linux 


1.1 Rock Chip device ( RK3066, RK3188,...) 정보를 Udev rules 파일에 추가.

- Linux 머신과 Device 연결 후 USB Vendor ID 확인. ( RockChip USB Vendor ID는 "2207" 이다.)

$ lsusb
Bus 002 Device 023: ID 2207:0010
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

- Device 정보(USB Vendor ID)를 "/etc/udev/rules.d/51-android.rules" 파일에 추가 후 udev를 restart.
$ sudo vi /etc/udev/rules.d/51-android.rules
SUBSYSTEM=="usb", ATTR{idVendor}=="2207", MODE="0666", GROUP="plugdev"
$ sudo udevadm control --reload-rules

1.2 adb_usb.ini 파일에 RockChip 의 Vendor ID 추가
$ vi ~/.android/adb_usb.ini

# ANDROID 3RD PARTY USB VENDOR ID LIST -- DO NOT EDIT.
# USE 'android update adb' TO GENERATE.
# 1 USB VENDOR ID PER LINE.
0x2207

2. Windows


2.1 Device의 USB Vendor ID를 android_winusb.inf 파일에 추가.
     해당 파일은 Android SDK가 설치된 아래 경로에 존재한다.

path : android\sdk\extras\google\usb_driver\android_winusb.inf
;
; Android WinUsb driver installation.
;


;Google Glass
%SingleAdbInterface%        = USB_Install, USB\VID_18D1&PID_9001
%CompositeAdbInterface%     = USB_Install, USB\VID_18D1&PID_9001&MI_01


;Rock Chip
%SingleAdbInterface%        = USB_Install, USB\VID_2207&PID_0006&M1_01
%CompositeAdbInterface%     = USB_Install, USB\VID_2207&PID_0006&REV_0222&MI_01


2.2 하드웨어 ID 확인하기.
    - 장치관리자의 속성에서 확인 가능






















2.3 adb_usb.ini 파일에 RockChip 의 Vendor ID 추가


$ vi /cygdrive/c/Users/wschoi/.android/adb_usb.ini

# ANDROID 3RD PARTY USB VENDOR ID LIST -- DO NOT EDIT.
# USE 'android update adb' TO GENERATE.
# 1 USB VENDOR ID PER LINE.
0x2207

2.4 Adb 연결 확인










오늘은 여기까지....

2014년 1월 8일 수요일

[Android] Device Power Off Flow


전원키를 통한 안드로이드 디바이스 Power Off의 경우 아래와 같은 flow를 통해 전원 컨트롤이 이루어진다.
PowerManageService ( ShutdownThread :: rebootOrShutdown(boolean reboot, String reason))
-> JNI -> System Call
-> kernel -> PMIC

============================================================
Android Frameworks
============================================================
PowerManagerService.java

    /**
     * Reboots the device.
     */
    public void reboot(boolean confirm, String reason, boolean wait) {
        try {
            shutdownOrRebootInternal(false, confirm, reason, wait);
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
    }

    /**
     * Shuts down the device.
     */
    @Override // Binder call
    public void shutdown(boolean confirm, boolean wait) {
        try {
            shutdownOrRebootInternal(true, confirm, null, wait);
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
    }

    private void shutdownOrRebootInternal(final boolean shutdown, final boolean confirm,
            final String reason, boolean wait) {

        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                synchronized (this) {
                    if (shutdown) {
                        ShutdownThread.shutdown(mContext, confirm);
                    } else {
                        ShutdownThread.reboot(mContext, reason, confirm);
                    }
                }
            }
        };
         ......
    }


ShutdownThread.java
    public static void rebootOrShutdown(boolean reboot, String reason) {
        if (reboot) {
            Log.i(TAG, "Rebooting, reason: " + reason);
            try {
                PowerManagerService.lowLevelReboot(reason);
            } catch (Exception e) {
                Log.e(TAG, "Reboot failed, will attempt shutdown instead", e);
            }
            ......
        }

        // Shutdown power
        Log.i(TAG, "Performing low-level shutdown...");
        PowerManagerService.lowLevelShutdown();
    }

PowerManagerService.java
    /**
     * Low-level function turn the device off immediately, without trying
     * to be clean.  Most people should use {@link ShutdownThread} for a clean shutdown.
     */
    public static void lowLevelShutdown() {
        nativeShutdown();
    }

============================================================
JNI / Native
============================================================
com_android_server_power_PowerManagerService.cpp
static void nativeShutdown(JNIEnv *env, jclass clazz) {
    android_reboot(ANDROID_RB_POWEROFF, 0, 0);
}

static JNINativeMethod gPowerManagerServiceMethods[] = {
    /* name, signature, funcPtr */
    ......
    { "nativeShutdown", "()V",
            (void*) nativeShutdown },
    ......
};

Android_reboot.c
int android_reboot(int cmd, int flags, char *arg)
{
    switch (cmd) {
        case ANDROID_RB_RESTART:
            ret = reboot(RB_AUTOBOOT);
            break;

        case ANDROID_RB_POWEROFF:
            ret = reboot(RB_POWER_OFF);
            break;

        case ANDROID_RB_RESTART2:
            ret = __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
                           LINUX_REBOOT_CMD_RESTART2, arg);
            break;

        default:
            ret = -1;
    }

reboot.h
#define RB_POWER_OFF    LINUX_REBOOT_CMD_POWER_OFF

============================================================
Kernel
============================================================
kernel/sys.c
/*
 * Reboot system call: for obvious reasons only root may call it,
 * and even root needs to set up some magic numbers in the registers
 * so that some mistake won't make this reboot the whole machine.
 * You can also set the meaning of the ctrl-alt-del-key here.
 *
 * reboot doesn't sync: do that yourself before calling this.
 */
SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
void __user *, arg)
{
    ......
switch (cmd) {
        ......
case LINUX_REBOOT_CMD_HALT:
kernel_halt();
do_exit(0);
panic("cannot halt");

case LINUX_REBOOT_CMD_POWER_OFF:
kernel_power_off();
do_exit(0);
break;
        ......
       }
}

2013년 11월 21일 목요일

[Android] Booting 시간 Debuging 하기

* BootChart 활용법

0. 사전 준비 - 리눅스 PC에 분석 툴 설치
    웹 혹은 첨부의 bootchart.jar 파일을 Linux BootChart Log 분석 폴더로 복사
    $ sudo apt-get install bootchart

1. Target Board에 Bootchart Log 저장을 위한 소스 수정.
    ./android/system/core/init/bootchart.h
    #define BOOTCHART 1//로 수정.

2. Build
   $ export INIT_BOOTCHART=true <== Build PC 환경 변수 설정 후 Full Build

3. Target Board Bootchart Log 저장을 위한 환경 설정.
   - Target Board 부팅 후
    $ adb shell
    # mkdir /data/bootchart
    # echo 120 > /data/bootchart-start <== Polling Time 설정.

4. Target Board 재부팅 후 Bootchart Log 확보
    $ adb shell
    # echo 1 > /data/bootchart-stop <= Bootchart stop
    $ adb pull /data/bootchart ./Linux_PC_LogPath

5. Linux_PC_LogPath bootchart.png 생성
    $ tar czf bootchart.tgz *
    $ java -jar bootchart.jar ./bootchart.tgz
   ==> bootchart.png 생성 됨

Process별로 CPU 사용정보 및 I/O 정보 확인

* Kernel initcall Debuging

./kernel/init/main.c
int initcall_debug = 1; // 0 -> 1변경 후 빌드
==> Booting 시 전체 initcall section별로 호출되는 함수 및 소요 시간 정보 아래와 같이 출력됩니다.

callingcpu_stop_init+0x0/0xcc @ 1 <== 호출되는 시점.
initcall cpu_stop_init+0x0/0xcc returned 0 after 19531 usecs <== 소요 시간

2013년 11월 16일 토요일

[Android] Property를 이용한 Log Level 조절로 Log 출력하기.

Property를 이용한 Log Level 조절로 Log 출력하기.


- 형식
#setprop log.tag.<log_tag> <level>


- 예제
public class SQLiteQueryBuilder
{
    private static final String TAG = "SQLiteQueryBuilder";

        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "Performing query: " + sql);
        }
}

위와 같은 경우, Log.isLoggable 을 확인해 보면,
log.tag."TAG" 값이 DEBUG 이상이면 동작한다.
ex) adb shell setprop log.tag.SQLiteQueryBuilder DEBUG


Framework Log.javapublic final class Log {
    /**
     * Priority constant for the println method; use Log.v.
     */
    public static final int VERBOSE = 2;
    /**
     * Priority constant for the println method; use Log.d.
     */
    public static final int DEBUG = 3;
    /**
     * Priority constant for the println method; use Log.i.
     */
    public static final int INFO = 4;
    /**
     * Priority constant for the println method; use Log.w.
     */
    public static final int WARN = 5;
    /**
     * Priority constant for the println method; use Log.e.
     */
    public static final int ERROR = 6;
    /**
     * Priority constant for the println method.
     */
    public static final int ASSERT = 7;
}

Native android_util_log.cppstruct levels_t {
    jint verbose;
    jint debug;
    jint info;
    jint warn;
    jint error;
    jint assert;
};

static levels_t levels;
static int toLevel(const char* value)
{
    switch (value[0]) {
        case 'V': return levels.verbose;
        case 'D': return levels.debug;
        case 'I': return levels.info;
        case 'W': return levels.warn;
        case 'E': return levels.error;
        case 'A': return levels.assert;
        case 'S': return -1; // SUPPRESS
    }
    return levels.info;
}

int register_android_util_Log(JNIEnv* env)
{
    jclass clazz = env->FindClass("android/util/Log");
    if (clazz == NULL) {
        LOGE("Can't find android/util/Log");
        return -1;
    }
 
    levels.verbose = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "VERBOSE", "I"));
    levels.debug = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "DEBUG", "I"));
    levels.info = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "INFO", "I"));
    levels.warn = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "WARN", "I"));
    levels.error = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "ERROR", "I"));
    levels.assert = env->GetStaticIntField(clazz, env->GetStaticFieldID(clazz, "ASSERT", "I"));
             
    return AndroidRuntime::registerNativeMethods(env, "android/util/Log", gMethods, NELEM(gMethods));
}

2013년 11월 14일 목요일

[Android] Installing Sun JDK6 - Ubuntu 12.04 64bit

How to install Sun JDK 6

Android 개발환경을 위한 JDK6 설치했던 방법을 정리합니다.- OS : 64bit Ubuntu 12.04 LTS


Installing Sun JDK 6 Update on Ubuntu 12.04
  1. Download the jdk-6u32-linux-i586.bin from the Sun Java Download Centre. If you are on 64-bit Ubuntu, you should grab jdk-6u32-linux-x64.bin.
  2. Make the bin file executable:
    1chmod +x jdk-6u32-linux-x64.bin
  3. Extract the bin file:
    1./jdk-6u32-linux-x64.bin
  4. Move extracted folder to this location:
    1sudo mv jdk1.6.0_32 /usr/lib/jvm/
  5. Install the new Java source in system:
    1sudo update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/jdk1.6.0_32/bin/javac 1
    2sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/jdk1.6.0_32/bin/java 1
    3sudo update-alternatives --install /usr/bin/javaws javaws /usr/lib/jvm/jdk1.6.0_32/bin/javaws 1
  6. Choose default Java:
    1sudo update-alternatives --config javac
    2sudo update-alternatives --config java
    3sudo update-alternatives --config javaws
  7. Check the Java version:
    1java -version
  8. Verify the symlinks all point to the new Java location:
    1ls -la /etc/alternatives/java*