安卓8.0 SystemUI 中的quick setting加入屏幕截图功能
2017-11-16 17:20
916 查看
在安卓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 != nul d347 l) { 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有点区别的。
相关文章推荐
- C#软件开发实例.私人订制自己的屏幕截图工具(七)加入放大镜的功能
- 本人在安卓程序开发时用到的各种小功能(一) 屏幕截图
- 本人在安卓程序开发时用到的各种小功能(一) 屏幕截图
- C#软件开发实例.个人定制自己的屏幕抓图工具(八)加入了截图功能键盘
- 关于Selenium的UI自动化测试屏幕截图功能实例代码
- 【安卓学习之代码学习】 屏幕截图
- C#软件开发实例.私人订制自己的屏幕截图工具(一)功能概览
- cocos2d-x实现简易屏幕截图功能
- 在平板导航栏添加屏幕截图功能
- nose测试中修改nose_html_reporting插件,使生成的html报告加入显示截图功能
- Vuforia应用之屏幕截图功能
- 安卓8.0 新功能 新特性
- 【Android应用开发】-屏幕截图功能--截取全屏,无需Root(附源码)
- windowsSDK实现 屏幕实时监控 热键截图 功能
- Vb.net2005实现屏幕截图功能
- 【Android应用开发】-(13)屏幕截图功能--截取全屏,无需Root(附源码)
- 基于Selenium的UI自动化测试屏幕截图功能实践
- iphone5,小米手机,Mac OS X系统自带屏幕截图功能
- 使用安卓Camera类完成视频截图功能
- 重新打包用户量过亿的开源截图软件——加入图片自动上传到图床的功能