mtk 平台 android 12 添加截屏功能
源码中有很多Tile可以模仿,我们仿照其中一个添加一个tile
1.先创建一张需要在qs tile panel显示的图片,这是我在androidStudio中找的矢量图,你们添加随意找张图就行,
vendor/mediatek/proprietary/packages/apps/SystemUI/res/drawable/ic_screenshot.xml
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M12,8c-2.21,0 -4,1.79 -4,4s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4zM5,15L3,15v4c0,1.1 0.9,2 2,2h4v-2L5,19v-4zM5,5h4L9,3L5,3c-1.1,0 -2,0.9 -2,2v4h2L5,5zM19,3h-4v2h4v4h2L21,5c0,-1.1 -0.9,-2 -2,-2zM19,19h-4v2h4c1.1,0 2,-0.9 2,-2v-4h-2v4z" />
</vector>
1.在 vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/qs/tiles/文件目录下添加截屏ScreenShotTile.java
package com.android.systemui.qs.tiles;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Looper;
import android.view.View;
import android.service.quicksettings.Tile;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.policy.ScreenShotController;
import com.android.internal.logging.MetricsLogger;
import com.android.systemui.R;
import javax.inject.Inject;
public class ScreenShotTile extends QSTileImpl<QSTile.BooleanState> {
private static final String TAG = "ScreenShotTile";
private ScreenShotController mScreenShotController;
@Inject
public ScreenShotTile(
QSHost host,
@Background Looper backgroundLooper,
@Main Handler mainHandler,
FalsingManager falsingManager,
MetricsLogger metricsLogger,
StatusBarStateController statusBarStateController,
ActivityStarter activityStarter,
QSLogger qsLogger,
ScreenShotController screenShotController) {
super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger,
statusBarStateController, activityStarter, qsLogger);
mScreenShotController = screenShotController;
}
@Override
public BooleanState newTileState() {
BooleanState state = new BooleanState();
state.label = mContext.getString(R.string.global_action_screenshot);
state.handlesLongClick = false;
return state;
}
@Override
protected void handleClick(View view) {
android.util.Log.d(TAG, "[handleClick] +");
if (getState().state == Tile.STATE_UNAVAILABLE) {
return;
}
getHost().collapsePanels();
mScreenShotController.takeScreenshot();
refreshState();
android.util.Log.d(TAG, "[handleClick] -");
}
@Override
protected void handleUpdateState(BooleanState state, Object arg) {
state.value = true;
state.state = Tile.STATE_ACTIVE;
state.label = mContext.getString(R.string.global_action_screenshot);
state.icon = ResourceIcon.get(R.drawable.ic_screenshot);
}
@Override
public int getMetricsCategory() {
return 0;
}
@Override
public Intent getLongClickIntent() {
return null;
}
@Override
public CharSequence getTileLabel() {
return mContext.getString(R.string.global_action_screenshot);
}
}
2.实现Controller和ControllerImpl,顾名思义就是管理tile方法的实现和tile的功能
vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/statusbar/policy 文件目录下添加ScreenShotController.java
就一个截屏功能的接口
package com.android.systemui.statusbar.policy;
import com.android.systemui.Dumpable;
public interface ScreenShotController extends Dumpable {
void takeScreenshot();
}
截屏功能实现,SystemUI有自带的功能实现,直接使用
注意:截屏功能的延迟时间可自己决定,多进行横竖屏转换后截屏测试,看有无截屏时SystemUI的残影或其他问题
vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/statusbar/policy 文件目录下添加ScreenShotControllerImpl.java
package com.android.systemui.statusbar.policy;
import static android.view.WindowManager.ScreenshotSource.SCREENSHOT_GLOBAL_ACTIONS;
import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN;
import android.annotation.MainThread;
import android.content.Context;
import android.content.Intent;
import android.os.UserHandle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton;
import com.android.internal.util.ScreenshotHelper;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import javax.inject.Inject;
@SysUISingleton
public class ScreenShotControllerImpl implements ScreenShotController {
private static final String TAG = "ScreenShotControllerImp";
private final Context mContext;
private final Handler mHandler;
private final ScreenshotHelper mScreenshotHelper;
@Inject
public ScreenShotControllerImpl(Context context) {
android.util.Log.d(TAG, "[ScreenShotControllerImpl] +");
mContext = context;
mHandler = new Handler(Looper.getMainLooper(), this::handleMessage);
mScreenshotHelper = new ScreenshotHelper(context);
}
@Override
public void takeScreenshot() {
mHandler.removeMessages(0);
mHandler.sendEmptyMessageDelayed(0, 900);
}
@MainThread
private boolean handleMessage(Message msg) {
if (msg.what == 0) {
mScreenshotHelper.takeScreenshot(TAKE_SCREENSHOT_FULLSCREEN, true, true,
SCREENSHOT_GLOBAL_ACTIONS, mHandler, null);
}
return true;
}
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
}
}
3.将 tile初始化并加载到QS panel(状态栏的快捷面板)
vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java
添加标识: //Modify start //Modify end
package com.android.systemui.qs.tileimpl;
........
import com.android.systemui.qs.tiles.RotationLockTile;
import com.android.systemui.qs.tiles.ScreenRecordTile;
//Modify start
import com.android.systemui.qs.tiles.ScreenShotTile;
//Modify end
import com.android.systemui.qs.tiles.UiModeNightTile;
import com.android.systemui.qs.tiles.UserTile;
import com.android.systemui.qs.tiles.WifiTile;
import com.android.systemui.qs.tiles.WorkModeTile;
import com.android.systemui.util.leak.GarbageMonitor;
/// M: add plugin in quicksetting @{
import com.mediatek.systemui.ext.IQuickSettingsPlugin;
/// add plugin in quicksetting @}
/// M: Add extra tiles in quicksetting @{
import com.mediatek.systemui.ext.OpSystemUICustomizationFactoryBase;
import com.mediatek.systemui.statusbar.util.SIMHelper;
///@}
import javax.inject.Inject;
import javax.inject.Provider;
import dagger.Lazy;
@SysUISingleton
public class QSFactoryImpl implements QSFactory {
private static final String TAG = "QSFactory";
......
private final Provider<DeviceControlsTile> mDeviceControlsTileProvider;
private final Provider<AlarmTile> mAlarmTileProvider;
private final Provider<QuickAccessWalletTile> mQuickAccessWalletTileProvider;
//Modify start
private final Provider<ScreenShotTile> mScreenShottTileProvider;
//Modify end
private final Lazy<QSHost> mQsHostLazy;
private final Provider<CustomTile.Builder> mCustomTileBuilderProvider;
@Inject
public QSFactoryImpl(
Lazy<QSHost> qsHostLazy,
Provider<CustomTile.Builder> customTileBuilderProvider,
Provider<WifiTile> wifiTileProvider,
....................
Provider<AlarmTile> alarmTileProvider,
Provider<QuickAccessWalletTile> quickAccessWalletTileProvider,
//Modify start
Provider<ScreenShotTile> screenShotTileProvider/*//Modify end*/) {
mQsHostLazy = qsHostLazy;
mCustomTileBuilderProvider = customTileBuilderProvider;
mWifiTileProvider = wifiTileProvider;
.........
mAlarmTileProvider = alarmTileProvider;
mQuickAccessWalletTileProvider = quickAccessWalletTileProvider;
//Modify start
mScreenShottTileProvider = screenShotTileProvider;
//Modify end
}
public QSTile createTile(String tileSpec) {
QSTileImpl tile = createTileInternal(tileSpec);
if (tile != null) {
tile.initialize();
tile.postStale(); // Tile was just created, must be stale.
}
return tile;
}
private QSTileImpl createTileInternal(String tileSpec) {
/// M: Add extra tiles in quicksetting @{
Context context = mQsHostLazy.get().getContext();
IQuickSettingsPlugin quickSettingsPlugin = OpSystemUICustomizationFactoryBase
.getOpFactory(context).makeQuickSettings(context);
/// @}
// M: [ALPS06389351] For monkeyTest of camera, don't show cameratoggle
// by commend
if (SystemProperties.getBoolean("persist.disable_cameratoggle", false)
&& "cameratoggle".equals(tileSpec)) {
return null;
}
// Stock tiles.
switch (tileSpec) {
.........
case "alarm":
return mAlarmTileProvider.get();
case "wallet":
return mQuickAccessWalletTileProvider.get();
//Modify start
case "screenshot":
return mScreenShottTileProvider.get();
//Modify end
}
....................
}
.........................
}
4.注入ScreenShotController
vendor/mediatek/proprietary/packages/apps/SystemUI/src/com/android/systemui/statusbar/policy/dagger/StatusBarPolicyModule.java
package com.android.systemui.statusbar.policy.dagger;
import android.os.UserManager;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.settings.UserTracker;
......
import com.android.systemui.statusbar.policy.RotationLockController;
import com.android.systemui.statusbar.policy.RotationLockControllerImpl;
//Modify start
import com.android.systemui.statusbar.policy.ScreenShotController;
import com.android.systemui.statusbar.policy.ScreenShotControllerImpl;
//Modify end
import com.android.systemui.statusbar.policy.SecurityController;
import com.android.systemui.statusbar.policy.SecurityControllerImpl;
import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
import com.android.systemui.statusbar.policy.WalletController;
import com.android.systemui.statusbar.policy.WalletControllerImpl;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.statusbar.policy.ZenModeControllerImpl;
import java.util.concurrent.Executor;
import dagger.Binds;
import dagger.Module;
import dagger.Provides;
/** Dagger Module for code in the statusbar.policy package. */
@Module
public interface StatusBarPolicyModule {
/** */
@Binds
BluetoothController provideBluetoothController(BluetoothControllerImpl controllerImpl);
/** */
@Binds
CastController provideCastController(CastControllerImpl controllerImpl);
.........
/** */
@Binds
WalletController provideWalletController(WalletControllerImpl controllerImpl);
/** */
@Binds
NetworkController.AccessPointController provideAccessPointController(
AccessPointControllerImpl accessPointControllerImpl);
/** */
//Modify start
@Binds
ScreenShotController provideScreenShotController(ScreenShotControllerImpl accessPointControllerImpl);
//Modify end
/** */
@SysUISingleton
@Provides
static AccessPointControllerImpl provideAccessPointControllerImpl(
UserManager userManager,
UserTracker userTracker,
@Main Executor mainExecutor,
AccessPointControllerImpl.WifiPickerTrackerFactory wifiPickerTrackerFactory
) {
AccessPointControllerImpl controller = new AccessPointControllerImpl(
userManager,
userTracker,
mainExecutor,
wifiPickerTrackerFactory
);
controller.init();
return controller;
}
}
5.在配置文件中添加screenshot
vendor/mediatek/proprietary/packages/apps/SystemUI/res/values/config.xml
<string name="quick_settings_tiles_default" translatable="false">
internet,wifi,bt,flashlight,cell,rotation,location,hotspot,airplane,alarm,saver,dnd,battery,screenshot,screenrecord
</string>
注意我这个是精简过的,你们以需求为准,如果只需要添加截屏, 以逗号隔开添加在最后就行,这个string就是加载SystemUI快捷面板的顺序标识,想要调整顺序,只需要换位置就行(mtk平台仅限于Android 12),可能有些顺序调了不起作用,可能结果如下:
1.SystemUI->点击编辑->点击编辑界面重置功能
2.恢复出厂设置
3.在SettingsProvider中查找有没有默认值的写入
loadStringSetting(stmt, Settings.Secure.QS_TILES,R.string.def_sysui_qs_tiles);
截屏功能就添加完成了,remake 项目烧录软件就可以查看功能了