客户要求在状态栏新增截屏功能。。
实现效果如下:
实现步骤
在配置文件alps\vendor\mediatek\proprietary\packages\apps\SystemUI\res\values\config.xml添加\screenshot 显示
一个是固定位置显示, 另一个是编辑时候的显示
wifi,bt,dnd,flashlight,rotation,battery,cell,airplane,cast,screenshot
wifi,cell,battery,dnd,flashlight,rotation,bt,airplane,location,hotspot,inversion,saver,work,cast,night,screenshot
在\vendor\mediatek\proprietary\packages\apps\SystemUI\src\com\android\systemui\qs\tileimpl\QSFactoryImpl.java新增如下代码.
import com.android.systemui.qs.tiles.ScreenShotTile;
public class QSFactoryImpl implements QSFactory {
......
public QSTile createTile(String tileSpec) {
......
else if (tileSpec.equals("screenshot")) return new ScreenShotTile(mHost);
......
}
......
}
在alps\vendor\mediatek\proprietary\packages\apps\SystemUI\src\com\android\systemui\qs\tiles目录下新增一个类,ScreenShotTile.java
package com.android.systemui.qs.tiles;
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.nano.MetricsProto.MetricsEvent;
import com.android.systemui.screenshot.GlobalScreenshot;
import android.os.RemoteException;
import com.android.systemui.statusbar.policy.ScreenShotController;
import android.os.Messenger;
import com.android.systemui.qs.QSHost;
import com.android.systemui.plugins.qs.QSTile.BooleanState;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.Dependency;
public class ScreenShotTile extends QSTileImpl {
private static final String TAG = "ScreenShotTile";
private static final int SCREEN_SHOT_MESSAGE = 10000;
private static GlobalScreenshot mScreenshot;
private final ScreenShotController mScreenShotController;
private final ActivityStarter mActivityStarter;
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(QSHost host) {
super(host);
mScreenShotController=Dependency.get(ScreenShotController.class);
mActivityStarter = Dependency.get(ActivityStarter.class);
}
@Override
public BooleanState newTileState() {
return new BooleanState();
}
@Override
public void handleSetListening(boolean listening) {
}
@Override
protected void handleClick() {
//mActivityStarter.postStartActivityDismissingKeyguard(
// new Intent(), 0);//此方法会自动解锁
mHost.collapsePanelsForce();
Message msg = mHandler.obtainMessage(SCREEN_SHOT_MESSAGE);
mHandler.sendMessageDelayed(msg,1000);
}
@Override
protected void handleLongClick() {
//mActivityStarter.postStartActivityDismissingKeyguard(
// new Intent(), 0);////此方法会自动解锁
mHost.collapsePanelsForce();
Message msg = mHandler.obtainMessage(SCREEN_SHOT_MESSAGE);
mHandler.sendMessageDelayed(msg,1000);
}
@Override
public CharSequence getTileLabel() {
return mContext.getString(R.string.screenshot);
}
@Override
public Intent getLongClickIntent() {
return new Intent();
}
@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 MetricsEvent.QS_SCREEN_SHOT;
}
}
新增一个接口alps\vendor\mediatek\proprietary\packages\apps\SystemUI\src\com\android\systemui\statusbar\policy\ScreenShotController.java
package com.android.systemui.statusbar.policy;
public interface ScreenShotController{
boolean isSupportScreenShot();
}
实现接口ScreenShotController.java
alps\vendor\mediatek\proprietary\packages\apps\SystemUI\src\com\android\systemui\statusbar\policy\ScreenShotControllerImpl.java
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;
}
}
在alps\vendor\mediatek\proprietary\packages\apps\SystemUI\src\com\android\systemui\Dependency.java定义
import com.android.systemui.statusbar.policy.ScreenShotController;
import com.android.systemui.statusbar.policy.ScreenShotControllerImpl;
......
public class Dependency extends SystemUI {
......
@Override
public void start() {
......
mProviders.put(ScreenShotController.class, () ->
new ScreenShotControllerImpl(mContext));
......
}
......
}
alps\vendor\mediatek\proprietary\packages\apps\SystemUI\src\com\android\systemui\screenshot\GlobalScreenshot.java修改权限
class GlobalScreenshot 修改为 public
把
void takeScreenshot(Runnable finisher, boolean statusBarVisible, boolean navBarVisible) {
mDisplay.getRealMetrics(mDisplayMetrics);
takeScreenshot(finisher, statusBarVisible, navBarVisible, 0, 0, mDisplayMetrics.widthPixels,
mDisplayMetrics.heightPixels);
}
改成
public void takeScreenshot(Runnable finisher, boolean statusBarVisible, boolean navBarVisible) {
mDisplay.getRealMetrics(mDisplayMetrics);
takeScreenshot(finisher, statusBarVisible, navBarVisible, 0, 0, mDisplayMetrics.widthPixels,
mDisplayMetrics.heightPixels);
}
至此 就可以实现截屏功能了 ,都是有个问题 就是在步骤3说的 ,mActivityStarter.postStartActivityDismissingKeyguard(
new Intent(), 0);调用此方法会自动解锁 ,导致在锁屏界面无法截取锁屏界面。
为此 新定义一个方法。
实现步骤3的collapsePanelsForce方法
在alps\vendor\mediatek\proprietary\packages\apps\SystemUI\src\com\android\systemui\qs\QSHost.java新增
public interface QSHost {
......
void collapsePanelsForce();
......
}
在alps\vendor\mediatek\proprietary\packages\apps\SystemUI\src\com\android\systemui\qs\QSTileHost.java里实现接口
/** Platform implementation of the quick settings tile host **/
public class QSTileHost implements QSHost, Tunable, PluginListener {
......
/**
note screen
*/
@Override
public void collapsePanelsForce() {
mStatusBar.postAnimateCollapsePanelsForce();
}
......
}
在alps\vendor\mediatek\proprietary\packages\apps\SystemUI\src\com\android\systemui\statusbar\phone\StatusBar.java 新增如下方法
/**
* A:@ for screenshot
* */
public void animateCollapsePanelsForce() {
animateCollapsePanelsForce(CommandQueue.FLAG_EXCLUDE_NONE);
}
/**
* A:@ for screenshot
* */
private final Runnable mAnimateCollapsePanelsForce = new Runnable() {
@Override
public void run() {
animateCollapsePanelsForce();
}
};
/**
* A:@ for screenshot
* */
public void postAnimateCollapsePanelsForce() {
mHandler.post(mAnimateCollapsePanelsForce);
}
/**
* A:@ for screenshot
* */
public void animateCollapsePanelsForce(int flags) {
animateCollapsePanelsForce(flags, true /* force */, false /* delayed */,
1.0f /* speedUpFactor */);
}
/**
* A:@for screenshot
* */
public void animateCollapsePanelsForce(int flags, boolean force, boolean delayed,
float speedUpFactor) {
if (!force && mState != StatusBarState.SHADE) {
runPostCollapseRunnables();
return;
}
if (SPEW) {
Log.d(TAG, "animateCollapse():"
+ " mExpandedVisible=" + mExpandedVisible
+ " flags=" + flags);
}
if ((flags & CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL) == 0) {
if (!mHandler.hasMessages(MSG_HIDE_RECENT_APPS)) {
mHandler.removeMessages(MSG_HIDE_RECENT_APPS);
mHandler.sendEmptyMessage(MSG_HIDE_RECENT_APPS);
}
}
if (mStatusBarWindow != null) {
// release focus immediately to kick off focus change transition
mStatusBarWindowManager.setStatusBarFocusable(false);
mStatusBarWindow.cancelExpandHelper();
System.out.println("tuliyuan mstats is "+mState);
if(mState == StatusBarState.KEYGUARD) {
mStatusBarView.collapsePanelForce(true /* animate */, delayed, speedUpFactor);
}else{
mStatusBarView.collapsePanel(true /* animate */, delayed, 2.5f);//speedUpFactor ->2.5f
}
}
}
在alps\vendor\mediatek\proprietary\packages\apps\SystemUI\src\com\android\systemui\statusbar\phone\PanelBar.java新增如下方法
/**
* A:@ for screenshot
* */
public void collapsePanelForce(boolean animate, boolean delayed, float speedUpFactor) {
boolean waiting = false;
PanelView pv = mPanel;
if (animate && !pv.isFullyCollapsed()) {
//pv.collapse(true /* delayed */);
if(pv instanceof NotificationPanelView){
((NotificationPanelView)pv).animateCloseQs();
}else{
pv.collapse(true,speedUpFactor/* delayed */);
}
waiting = true;
} else {
pv.resetViews();
pv.setExpandedFraction(0); // just in case
pv.cancelPeek();
}
if (DEBUG) LOG("collapsePanel: animate=%s waiting=%s", animate, waiting);
if (!waiting && mState != STATE_CLOSED) {
// it's possible that nothing animated, so we replicate the termination
// conditions of panelExpansionChanged here
go(STATE_CLOSED);
onPanelCollapsed();
}
}
在alps\frameworks\base\proto\src\metrics_constants.proto 新增定义
QS_SCREEN_SHOT = 1144;
在资源文件新增定义
ScreenShot
截屏
新增图片;也可以用矢量画出图片
ic_qs_screenshot
到此已经实现啦。。。。。。