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

2012년 10월 18일 목요일

Navigation Bar에 volume up/down, Shutdown, Screenshot 버튼 넣어보기





Tablet UI에서 back, home. recent app 옆에  volume up/down, Shutdown, Screenshot button을 넣어보자.

먼저 frameworks/base/packages/SystemUI/res/drawable-[h,m,x]dpi/에
ic_sysbar_home.png와 동일한 크기의 
ic_sysbar_plus,png, ic_sysbar_minus.png, ic_sysbar_shutdown.png, ic_sysbar_screenshot.png 이란 이미지를 준비합니다.

frameworks/base/packages/SystemUI/res/layout/navigation_bar.xml 에 recent_apps 다음에 4개의 항목을 추가합니다.

 <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps"
                android:layout_width="80dp"
                android:layout_height="match_parent"
                android:src="@drawable/ic_sysbar_recent"
                android:layout_weight="0"
                systemui:glowBackground="@drawable/ic_sysbar_highlight"
                android:contentDescription="@string/accessibility_recent"
                />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/vol_plus"
                android:layout_width="80dp"
                android:layout_height="match_parent"
                android:src="@drawable/ic_sysbar_plus"
                android:layout_weight="0"
                systemui:glowBackground="@drawable/ic_sysbar_highlight"
                android:contentDescription="@string/accessibility_recent"
                />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/vol_minus"
                android:layout_width="80dp"
                android:layout_height="match_parent"
                android:src="@drawable/ic_sysbar_minus"
                android:layout_weight="0"
                systemui:glowBackground="@drawable/ic_sysbar_highlight"
                android:contentDescription="@string/accessibility_recent"
                />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/shutdown"
                android:layout_width="80dp"
                android:layout_height="match_parent"
                android:src="@drawable/ic_sysbar_shutdown"
                android:layout_weight="0"
                systemui:glowBackground="@drawable/ic_sysbar_highlight"
                android:contentDescription="@string/accessibility_recent"
                />
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/screenshot"
                android:layout_width="80dp"
                android:layout_height="match_parent"
                android:src="@drawable/ic_sysbar_screenshot"
                android:layout_weight="0"
                systemui:glowBackground="@drawable/ic_sysbar_highlight"
                android:contentDescription="@string/accessibility_recent"
                />

frameworks/base/packages/SystemUI/res/layout-sw600dp/status_bar.xml도 동일하게 수정 합니다.

frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java 에서 volume up/down과 shutdown을 구현합니다.


//volume control
import android.media.AudioManager;
//shutdown
import com.android.internal.app.ShutdownThread;
//screenshot
import android.content.ComponentName;
import android.content.ServiceConnection;
import android.os.Messenger;


    ImageView mBackButton;
    View mHomeButton;
    View mMenuButton;
    View mRecentButton;
//버튼 3개 추가
    View mVolPlusButton;
    View mVolMinusButton;
    View mShutdownButton;
    View mScreenshotButton;

    ViewGroup mFeedbackIconArea; // notification icons, IME icon, compat icon
    InputMethodButton mInputMethodSwitchButton;
    CompatModeButton mCompatModeButton;





    // used to notify status bar for suppressing notification LED
    private boolean mPanelSlightlyVisible;

AudioManager mAudioManager;

    public Context getContext() { return mContext; }






        mMenuButton = mNavigationArea.findViewById(R.id.menu);
        mRecentButton = mNavigationArea.findViewById(R.id.recent_apps);
        mRecentButton.setOnClickListener(mOnClickListener);
mVolPlusButton = mNavigationArea.findViewById(R.id.vol_plus);
        mVolPlusButton.setOnClickListener(mOnClickListener);
mVolMinusButton = mNavigationArea.findViewById(R.id.vol_minus);
        mVolMinusButton.setOnClickListener(mOnClickListener);
mShutdownButton = mNavigationArea.findViewById(R.id.shutdown);
        mShutdownButton.setOnClickListener(mOnClickListener);

mScreenshotButton = mNavigationArea.findViewById(R.id.screenshot);
        mScreenshotButton.setOnClickListener(mOnClickListener);

        LayoutTransition lt = new LayoutTransition();











        mHomeButton.setVisibility(disableHome ? View.INVISIBLE : View.VISIBLE);
        mRecentButton.setVisibility(disableRecent ? View.INVISIBLE : View.VISIBLE);
        mVolPlusButton.setVisibility(disableRecent ? View.INVISIBLE : View.VISIBLE);
        mVolMinusButton.setVisibility(disableRecent ? View.INVISIBLE : View.VISIBLE);
        mShutdownButton.setVisibility(disableRecent ? View.INVISIBLE : View.VISIBLE);
        mScreenshotButton.setVisibility(disableRecent ? View.INVISIBLE : View.VISIBLE);

        mInputMethodSwitchButton.setScreenLocked(
                (visibility & StatusBarManager.DISABLE_SYSTEM_INFO) != 0);













    private View.OnClickListener mOnClickListener = new View.OnClickListener() {
        public void onClick(View v) {
if (mAudioManager == null)
mAudioManager = (AudioManager)getContext().getSystemService(Context.AUDIO_SERVICE);
            if (v == mRecentButton) {
                onClickRecentButton();
            } else if (v == mInputMethodSwitchButton) {
                onClickInputMethodSwitchButton();
            } else if (v == mCompatModeButton) {
                onClickCompatModeButton();
            } else if (v == mVolPlusButton) {
mAudioManager.handleKeyDown(KeyEvent.KEYCODE_VOLUME_DOWN, AudioManager.STREAM_MUSIC);
} else if (v == mVolMinusButton) {
mAudioManager.handleKeyDown(KeyEvent.KEYCODE_VOLUME_UP, AudioManager.STREAM_MUSIC);
} else if (v == mShutdownButton) {
ShutdownThread.shutdown(mContext,true);
}

} else if (v == mScreenshotButton) {
takeScreenshot(); 
}
        }
    };

final Object mScreenshotLock = new Object();
    ServiceConnection mScreenshotConnection = null;

    final Runnable mScreenshotTimeout = new Runnable() {
        @Override public void run() {
            synchronized (mScreenshotLock) {
                if (mScreenshotConnection != null) {
                    mContext.unbindService(mScreenshotConnection);
                    mScreenshotConnection = null;
                }
            }
        }
    };

    // Assume this is called from the Handler thread.
    private void takeScreenshot() {
        synchronized (mScreenshotLock) {
            if (mScreenshotConnection != null) {
                return;
            }
            ComponentName cn = new ComponentName("com.android.systemui",
                    "com.android.systemui.screenshot.TakeScreenshotService");
            Intent intent = new Intent();
            intent.setComponent(cn);
            ServiceConnection conn = new ServiceConnection() {
                @Override
                public void onServiceConnected(ComponentName name, IBinder service) {
                    synchronized (mScreenshotLock) {
                        if (mScreenshotConnection != this) {
                            return;
                        }
                        Messenger messenger = new Messenger(service);
                        Message msg = Message.obtain(null, 1);
                        final ServiceConnection myConn = this;
                        Handler h = new Handler(mHandler.getLooper()) {
                            @Override
                            public void handleMessage(Message msg) {
                                synchronized (mScreenshotLock) {
                                    if (mScreenshotConnection == myConn) {
                                        mContext.unbindService(mScreenshotConnection);
                                        mScreenshotConnection = null;
                                        mHandler.removeCallbacks(mScreenshotTimeout);
                                    }
                                }
                            }
                        };
                        msg.replyTo = new Messenger(h);
                        msg.arg1 = msg.arg2 = 0;
                        //if (mStatusBar != null && mStatusBar.isVisibleLw())
                            msg.arg1 = 1;
                        //if (mNavigationBar != null && mNavigationBar.isVisibleLw())
                            msg.arg2 = 1;
                        try {
                            messenger.send(msg);
                        } catch (RemoteException e) {
                        }
                    }
                }
                @Override
                public void onServiceDisconnected(ComponentName name) {}
            };
            if (mContext.bindService(intent, conn, Context.BIND_AUTO_CREATE)) {
                mScreenshotConnection = conn;
                mHandler.postDelayed(mScreenshotTimeout, 10000);
            }
        }

    }

2012년 3월 27일 화요일

ODROID(ICS) screenshot 찍기

android Honeycomb부터 iOS 처럼 screenshot이 가능합니다.

Volume Down + Power Key 조합입니다.

하지만 ODROID는 Volume Up/Down키와 Power Key가 동시에 눌러지지 않는 형태입니다.



Screenshot으로 검색해 보면 PhoneWindowManager.java에 관련 코드가 찾아 집니다.

frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java


public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags, boolean isScreenOn) {
...


    switch (keyCode) {
            case KeyEvent.KEYCODE_VOLUME_DOWN:
            case KeyEvent.KEYCODE_VOLUME_UP:
            case KeyEvent.KEYCODE_VOLUME_MUTE: {
                if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
                    if (down) {
                        if (isScreenOn && !mVolumeDownKeyTriggered
                                && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
                            mVolumeDownKeyTriggered = true;
                            mVolumeDownKeyTime = event.getDownTime();
                            mVolumeDownKeyConsumedByScreenshotChord = false;
                            cancelPendingPowerKeyAction();
                            interceptScreenshotChord();
                        }
                    } else {

여기서 KEYCODE_VOLUME_DOWN -> KEYCODE_SEARCH으로 바꿉니다.



    switch (keyCode) {
            case KeyEvent.KEYCODE_SEARCH:
            case KeyEvent.KEYCODE_VOLUME_UP:
            case KeyEvent.KEYCODE_VOLUME_MUTE: {
                if (keyCode == KeyEvent.KEYCODE_SEARCH) {
                    if (down) {
                        if (isScreenOn && !mVolumeDownKeyTriggered
                                && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
                            mVolumeDownKeyTriggered = true;
                            mVolumeDownKeyTime = event.getDownTime();
                            mVolumeDownKeyConsumedByScreenshotChord = false;
                            cancelPendingPowerKeyAction();
                            interceptScreenshotChord();
                        }
                    } else {

그럼 Power Key와 Search Key를 동시에 1초 누르면 screenshot이 찍힙니다.