您的位置:首页 > 产品设计 > UI/UE

安卓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有点区别的。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: