Android 8.1上状态栏新增截屏功能

1.需求

客户要求在状态栏新增截屏功能。。

实现效果如下:

Android 8.1上状态栏新增截屏功能_第1张图片Android 8.1上状态栏新增截屏功能_第2张图片

实现步骤

步骤1

在配置文件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
    

步骤2

在\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);
		......
    }
	......
}

步骤3

在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; 
} 
}

步骤4

新增一个接口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();    
}

步骤5

实现接口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;    
   }    
}    

步骤6

在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));
		......
    }

   ......
}

步骤7

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);
    }

步骤8

至此 就可以实现截屏功能了 ,都是有个问题 就是在步骤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();
	......
}

步骤9

在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();
    }
	......

}

步骤10

在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
            }
        }
    }

步骤11

在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();
        }
    }

步骤12

在alps\frameworks\base\proto\src\metrics_constants.proto 新增定义

QS_SCREEN_SHOT = 1144;

步骤13 

在资源文件新增定义

ScreenShot
截屏

步骤14

新增图片;也可以用矢量画出图片

ic_qs_screenshot

到此已经实现啦。。。。。。

你可能感兴趣的:(Android8.1)