因项目需要,机种改为移远的4G方案,本文主要介绍Android 7.1.2 在下拉状态栏添加截屏快捷方式
本文参考了https://blog.csdn.net/evahuangchen/article/details/53543390 非常感谢
在他的基础上做了代码的修改,避免了很多编译报错,建议编译的时候先make systemimage方便查找错误。
实现步骤
1.在配置文件frameworks\base\packages\SystemUI\res\values\config.xml添加\screenshot 显示
<!-- The default tiles to display in QuickSettings -->
<string name="quick_settings_tiles_default" translatable="false">
wifi,cell,dnd,flashlight,rotation,bt,airplane,screenshot <!-- jokey 3 -->
</string>
<!-- Tiles native to System UI. Order should match "quick_settings_tiles_default" -->
<string name="quick_settings_tiles_stock" translatable="false">
wifi,cell,dnd,flashlight,rotation,bt,airplane,screenshot,location,hotspot,inversion,saver,work,cast,night <!-- jokey 3-->
</string>
2.在frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\phone\QSTileHost.java新增如下:(该import的不要漏!!!)
import com.android.systemui.qs.tiles.ScreenShotTile;//add by jokey
import com.android.systemui.statusbar.policy.ScreenShotController;//add by jokey
private final ScreenShotController mScreenShotController; //add by jokey
public QSTileHost( .....,ScreenShotController screenshot/*add by jokey*/) {
.....
mScreenShotController=screenshot;//add by jokey
.....
}
//add by jokey start
public ScreenShotController getScreenShotController()
{
return mScreenShotController;
}
//end
public QSTile<?> createTile(String tileSpec) {
.....
else if(tileSpec.equals("screenshot")) return new ScreenShotTile(this);//add by jokey
.....
}
3.新增一个类 在里面实现截屏功能frameworks\base\packages\SystemUI\src\com\android\systemui\qs\tiles\ScreenShotTile.java(这个针对参考文修改了 部分代码)
/*
* create by jokey
*/
package com.android.systemui.qs.tiles;
import com.android.systemui.qs.QSTile;
import com.android.systemui.qs.QSTile.BooleanState;
import com.android.systemui.qs.QSTile.State;
import com.android.systemui.R;
import android.os.Message;
import android.os.Handler;
import android.content.Context;
import android.content.Intent;
import com.android.internal.logging.MetricsLogger;
import com.android.systemui.screenshot.GlobalScreenshot;
import android.os.RemoteException;
import com.android.systemui.statusbar.policy.ScreenShotController;
import android.os.Messenger;
public class ScreenShotTile extends QSTile<BooleanState> {
private static final String TAG = "ScreenShotTile";
private static final int SCREEN_SHOT_MESSAGE = 10000;
private static GlobalScreenshot mScreenshot;
private final ScreenShotController mScreenShotController;
Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case SCREEN_SHOT_MESSAGE:
final Messenger callback = msg.replyTo;
if (mScreenshot == null) {
mScreenshot = new GlobalScreenshot(mContext);
}
mScreenshot.takeScreenshot(new Runnable() {
@Override public void run() {
Message reply = Message.obtain(null, 1);
try {
if(callback != null){
callback.send(reply);
}
}catch(RemoteException e){
}
}
}, msg.arg1 > 0, msg.arg2 > 0);
break;
default:
break;
}
}
};
public ScreenShotTile(Host host) {
super(host);
mScreenShotController=host.getScreenShotController();
}
@Override
public BooleanState newTileState() {
return new BooleanState();
}
@Override
public void setListening(boolean listening) {
}
@Override
public Intent getLongClickIntent(){
return new Intent();
}
@Override
public CharSequence getTileLabel(){
return null;
}
@Override
protected void handleClick() {
mHost.startActivityDismissingKeyguard(new Intent()); //hide statusbar
Message msg = mHandler.obtainMessage(SCREEN_SHOT_MESSAGE);
mHandler.sendMessageDelayed(msg,1000);
}
@Override
protected void handleLongClick() {
mHost.startActivityDismissingKeyguard(new Intent()); //hide statusbar
Message msg = mHandler.obtainMessage(SCREEN_SHOT_MESSAGE);
mHandler.sendMessageDelayed(msg,1000);
}
@Override
protected void handleUpdateState(BooleanState state, Object arg) {
state.value=false;
state.autoMirrorDrawable=false;
state.label = mContext.getString(R.string.screenshot);
state.icon = ResourceIcon.get(R.drawable.ic_qs_screenshot);
// state.visible = true;
}
@Override
public int getMetricsCategory(){
// return MetricsLogger.QS_SCREEN_SHOT;
return 1144;
}
}
4.在alps\frameworks\base\proto\src\metrics_constants.proto 新增定义
//add by jokey
QS_SCREEN_SHOT = 1144;
这里说明一下,我在getMetricsCategory()返回里面直接返回MetricsLogger.QS_SCREEN_SHOT;编译报错,我就粗暴的直接1144了,有兴趣的可以研究下。此外newTileState()的修饰词必须是public,因为父类是public,不能用小的修饰词。
5.新增一个接口frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\policy/ScreenShotController.java
/*
* create by jokey
*/
package com.android.systemui.statusbar.policy;
public interface ScreenShotController{
boolean isSupportScreenShot();
}
6.在frameworks\base\packages\SystemUI\src\com\android\systemui\qs\QSTile.java新增(import不能丟!!!)
import com.android.systemui.statusbar.policy.ScreenShotController;//add by jokey
public interface Host {
.....
ScreenShotController getScreenShotController();//jokey
.....
}
7.在frameworks/base/packages/SystemUI/res/values/strings.xml添加,如果要中文的,在中文values-zh-rCN里也同样加上
<string name="screenshot">ScreenShot</string>
<string name="screenshot">截屏</string>
8.在frameworks/base/packages/SystemUI/res/drawable目录下新建文件ic_qs_screenshot.xml,文件内容如下
<!-- add by jokey -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="64dp"
android:height="64dp"
android:viewportWidth="48.0"
android:viewportHeight="48.0">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M 48.00,0.00
C 48.00,0.00 48.00,48.00 48.00,48.00
48.00,48.00 0.00,48.00 0.00,48.00
0.00,48.00 0.00,0.00 0.00,0.00
0.00,0.00 48.00,0.00 48.00,0.00 Z
M 12.74,5.34
C 10.77,4.60 8.82,7.07 7.61,8.31
4.18,11.82 4.05,13.40 9.00,15.00
9.00,15.00 9.00,39.00 9.00,39.00
9.00,39.00 33.00,39.00 33.00,39.00
33.44,40.36 33.66,42.07 35.26,42.66
37.23,43.40 39.18,40.93 40.39,39.69
43.82,36.18 43.95,34.60 39.00,33.00
39.00,33.00 39.00,15.00 39.00,15.00
31.35,20.68 33.00,24.31 33.00,33.00
33.00,33.00 18.00,33.00 18.00,33.00
23.35,27.65 37.10,14.14 40.00,8.00
40.00,8.00 39.00,7.00 39.00,7.00
33.12,9.79 19.63,25.36 15.00,31.00
15.00,31.00 15.00,15.00 15.00,15.00
22.33,15.00 27.29,16.58 31.00,9.00
31.00,9.00 15.00,9.00 15.00,9.00
14.56,7.64 14.34,5.93 12.74,5.34 Z" />
</vector>
9.在frameworks/base/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java修改权限
public class GlobalScreenshot {
.....
}
public void takeScreenshot(...){
.....
}
public void takeScreenshot(...){
.....
}
10.在frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\phone\PhoneStatusBar.java新增
import com.android.systemui.statusbar.policy.ScreenShotControllerImpl;//add by jokey
ScreenShotControllerImpl mScreenShotController;//add by jokey
if (container != null) {
final QSTileHost qsh = SystemUIFactory.getInstance().createQSTileHost(.....mScreenShotController);
.....
}
11.实现接口ScreenShotController.java
如下frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\policy\ScreenShotControllerImpl.java
/*
* create by jokey
*/
package com.android.systemui.statusbar.policy;
import android.content.Context;
public class ScreenShotControllerImpl implements ScreenShotController{
private static final String TAG="ScreenShotControllerImpl";
private final Context mContext;
public ScreenShotControllerImpl(Context context){
mContext=context;
}
@Override
public boolean isSupportScreenShot(){
return true;
}
}
12.在frameworks/base/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTests.java修改,添加最后一个null,因为参数多了一个screenshot
QSTileHost host = new QSTileHost(mContext, null, null, null, null,
networkController, null,
Mockito.mock(HotspotController.class), null,
null, null, null, null, null, null, null, null,null);//add last null by jokey
13.在frameworks/base/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java同样修改,
public QSTileHost createQSTileHost(.....,ScreenShotController mScreenShotController/*add by jokey*/) {
return new QSTileHost(......,mScreenShotController);
}
编译完成。
最后附上成功截图,祝大家都能成功!