安卓8.0 SystemUI 中的quick setting加入屏幕截图功能

来源:互联网 发布:人人宽客量化交易源码 编辑:程序博客网 时间:2024/06/06 01:57



   在安卓8.0的QS中增加一个选项 和在安卓7.0上的大致相同,可能还会有一点点的小区别。现在开始总结一下,如果有什么问题,欢迎提出。嘿嘿

     1.首先在/frameworks/base/packages/SystemUI/res/values/config.xml里面添加截屏screenshot的选项


<string name="quick_settings_tiles_stock" translatable="false">        wifi,cell,battery,dnd,flashlight,screenshot  </string>

     2.当然了/frameworks/base/packages/SystemUI/res/values/strings.xml里面还要加一个字符串

<string name="quick_settings_screenshot">Screenshot</string>

     3.下面就开始重点了frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenShotTile.java
 要在这个tiles这个文件夹下面添加这个java文件,注意这里继承的是QSTileImpl,这点和7.0不一样。

package com.android.systemui.qs.tiles;import android.content.res.Configuration;import android.content.res.Resources;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import com.android.systemui.R;//import com.android.systemui.qs.QSTile;import com.android.systemui.qs.tileimpl.QSTileImpl;import android.content.Intent;import android.util.Log;import android.content.Context;import com.android.internal.logging.MetricsLogger;//import com.android.internal.logging.MetricsProto.MetricsEvent;import com.android.internal.logging.nano.MetricsProto.MetricsEvent;import android.content.ServiceConnection;import android.content.ComponentName;import android.os.Message;import android.os.Messenger;import android.os.Handler;import android.os.IBinder;import android.os.UserHandle;import android.os.RemoteException;import android.os.ServiceManager;import com.android.systemui.plugins.qs.QSTile.BooleanState;import com.android.systemui.qs.QSHost;import android.widget.Switch;public class ScreenShotTile extends QSTileImpl<BooleanState> {    public ScreenShotTile(QSHost host) {        super(host);    }    @Override    public BooleanState newTileState() {        return new BooleanState();    }    @Override    protected void handleClick() {        mHost.screenShot();    }    @Override    public int getMetricsCategory() {        return MetricsEvent.QS_PANEL;    }    @Override    public Intent getLongClickIntent() {        return new Intent(mContext,com.android.systemui.screenshot.ScreenShotActivity.class);    }    @Override    public CharSequence getTileLabel() {        return mContext.getString(R.string.quick_settings_screenshot);    }    @Override    protected void handleUpdateState(BooleanState state, Object arg) {        state.label = mContext.getString(R.string.quick_settings_screenshot);        state.icon = state.icon = ResourceIcon.get(R.drawable.icon_screenshot);        state.value = false;        //return;        state.expandedAccessibilityClassName = Switch.class.getName();    }    public void setListening(boolean listening) {    }    final Object mScreenshotLock = new Object();    ServiceConnection mScreenshotConnection = null;    private Handler mHandler = new Handler();    final Runnable mScreenshotTimeout = new Runnable() {        @Override public void run() {            synchronized (mScreenshotLock) {                if (mScreenshotConnection != null) {                    mContext.unbindService(mScreenshotConnection);                    mScreenshotConnection = null;                }            }        }    };    private final Runnable mScreenshotRunnable = new Runnable() {        @Override        public void run() {            takeScreenshot();        }    };    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;                        try {                            messenger.send(msg);                        } catch (RemoteException e) {                        }                    }                }                @Override                public void onServiceDisconnected(ComponentName name) {}            };            if (mContext.bindServiceAsUser(                    intent, conn, Context.BIND_AUTO_CREATE, UserHandle.CURRENT)) {                mScreenshotConnection = conn;                mHandler.postDelayed(mScreenshotTimeout, 15000);            }        }    }}


4.在/frameworks/base/packages/SystemUI/src/com/android/systemui/qs/QSHost.java 文件中加入方法screenshot方法。

import java.util.Collection;public interface QSHost {    void warn(String message, Throwable t);    void collapsePanels();    void forceCollapsePanels();   ///M:START@{        void screenShot();   ///END @}    void openPanels();    Context getContext();    Collection<QSTile> getTiles();    void addCallback(Callback callback);    void removeCallback(Callback callback);    TileServices getTileServices();    void removeTile(String tileSpec);

5.在/frameworks/base/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java中加入相应方法

 @Override    public void warn(String message, Throwable t) {        // already logged    }    ///START@{    @Override    public void screenShot() {        mStatusBar.screenShot();    }    /// END @}    @Override    public void collapsePanels() {        mStatusBar.postAnimateCollapsePanels();    }    @Override    public void forceCollapsePanels() {        mStatusBar.postAnimateForceCollapsePanels();    }

6.在/frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java,这个里面会加载所有的title 这个也是8.0上新增加的。

需要导包import com.android.systemui.qs.tiles.ScreenShotTile;
public QSTile createTile(String tileSpec) {        if (tileSpec.equals("wifi")) return new WifiTile(mHost);        else if (tileSpec.equals("bt")) return new BluetoothTile(mHost);        else if (tileSpec.equals("cell")) return new CellularTile(mHost);        else if (tileSpec.equals("dnd")) return new DndTile(mHost);        else if (tileSpec.equals("inversion")) return new ColorInversionTile(mHost);        else if (tileSpec.equals("airplane")) return new AirplaneModeTile(mHost);        else if (tileSpec.equals("work")) return new WorkModeTile(mHost);        else if (tileSpec.equals("rotation")) return new RotationLockTile(mHost);        else if (tileSpec.equals("flashlight")) return new FlashlightTile(mHost);        else if (tileSpec.equals("location")) return new LocationTile(mHost);        else if (tileSpec.equals("cast")) return new CastTile(mHost);        else if (tileSpec.equals("hotspot")) return new HotspotTile(mHost);        else if (tileSpec.equals("user")) return new UserTile(mHost);        else if (tileSpec.equals("battery")) return new BatterySaverTile(mHost);        else if (tileSpec.equals("saver")) return new DataSaverTile(mHost);        else if (tileSpec.equals("night")) return new NightDisplayTile(mHost);        else if (tileSpec.equals("nfc")) return new NfcTile(mHost);        // Intent tiles.        else if (tileSpec.startsWith(IntentTile.PREFIX)) return IntentTile.create(mHost, tileSpec);        else if (tileSpec.startsWith(CustomTile.PREFIX)) return CustomTile.create(mHost, tileSpec);        ///M: START@{        else if (tileSpec.equals("screenshot")) return new ScreenShotTile(mHost);        ///END @}        else {            Log.w(TAG, "Bad tile spec: " + tileSpec);            return null;        }


7.在frameworks/base/packages/SystemUI/src/com/android/systemui/screenshot/ScreenShotActivity.java 这个文件夹下面加这个activity

package com.android.systemui.screenshot;import android.app.Activity;import android.os.Bundle;import com.android.systemui.R;import android.content.ServiceConnection;import android.content.ComponentName;import android.os.Message;import android.os.Messenger;import android.os.Handler;import android.os.IBinder;import android.os.UserHandle;import android.os.RemoteException;import android.os.ServiceManager;import android.content.Context;import android.content.Intent;public class ScreenShotActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.screenshot);        mHandler.postDelayed(mScreenshotRunnable, 100);    }    private Handler mHandler = new Handler(){        @Override        public void handleMessage(Message msg) {            if (mScreenshotConnection != null) {                ScreenShotActivity.this.unbindService(mScreenshotConnection);                mScreenshotConnection = null;            }            ScreenShotActivity.this.finish();        }    };    final Object mScreenshotLock = new Object();    ServiceConnection mScreenshotConnection = null;    final Runnable mScreenshotTimeout = new Runnable() {        @Override public void run() {            synchronized (mScreenshotLock) {                mHandler.sendEmptyMessage(0);            }        }    };    private final Runnable mScreenshotRunnable = new Runnable() {        @Override        public void run() {            takeScreenshot();        }    };    private void takeScreenshot() {        synchronized (mScreenshotLock) {            if (mScreenshotConnection != null) {                mHandler.sendEmptyMessage(0);                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) {                            mHandler.sendEmptyMessage(0);                            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) {                                        ScreenShotActivity.this.unbindService(mScreenshotConnection);                                        mScreenshotConnection = null;                                        mHandler.removeCallbacks(mScreenshotTimeout);                                    }                                }                            }                        };                        msg.replyTo = new Messenger(h);                        msg.arg1 = msg.arg2 = 0;                        try {                            messenger.send(msg);                        } catch (RemoteException e) {                        }                        mHandler.sendEmptyMessage(0);                    }                }                @Override                public void onServiceDisconnected(ComponentName name) {}            };            if (ScreenShotActivity.this.bindServiceAsUser(                    intent, conn, Context.BIND_AUTO_CREATE, UserHandle.CURRENT)) {                mScreenshotConnection = conn;                mHandler.postDelayed(mScreenshotTimeout, 10000);            }        }    }}


8.上面加载了一个layout这可以在frameworks/base/packages/SystemUI/res/layout/screenshot.xml里面加一个layout就可以了哈


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"></LinearLayout>


9./frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java在这里面加最后的逻辑。

 //screenshot    private final Runnable mTakeScreenshot = new Runnable() {        @Override        public void run() {            screenshot();        }    };    private void screenshot() {        if (mStatusBarWindow != null) {            // release focus immediately to kick off focus change transition            mStatusBarWindowManager.setStatusBarFocusable(false);            mStatusBarWindow.cancelExpandHelper();            mStatusBarView.collapsePanel(true /* animate */, false, 1.0f);        }
           //这里有delay延时设置            mHandler.postDelayed(mScreenshotRunnable, 500);    }    public void screenShot(){        mHandler.post(mTakeScreenshot);    }    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;        }            }        }    };    private final Runnable mScreenshotRunnable = new Runnable() {        @Override        public void run() {            takeScreenshot();        }    };    private void takeScreenshot() {        synchronized (mScreenshotLock) {            if (mScreenshotConnection != null) {                mHandler.sendEmptyMessage(0);                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;                        try {                            messenger.send(msg);                        } catch (RemoteException e) {                        }                        mHandler.sendEmptyMessage(0);                    }                }                @Override                public void onServiceDisconnected(ComponentName name) {}            };            if (mContext.bindServiceAsUser(                    intent, conn, Context.BIND_AUTO_CREATE, UserHandle.CURRENT)) {                mScreenshotConnection = conn;                mHandler.postDelayed(mScreenshotTimeout, 10000);            }        }    }

嘿嘿 大致就这样婶了。这是加了一个完整的功能,所以看着有点多。安卓8.0上SystemUI还是和7.0有点区别的。

 
原创粉丝点击