实现流程图如下: 源码路径,https://download.youkuaiyun.com/download/gaoyuekang/11594258。
详细描述:
属于系统服务,存放目录在/system/app 下 。本服务,Persisent app拉起。下面是所有的源码.
关键代码如下:
1. 启动:SplitScreenApplication.java
package com.xxx.splitscreen;
import android.app.Application;
import android.util.Log;
import android.content.Intent;
import android.content.ComponentName;
import android.content.Context;
import android.content.ServiceConnection;
import android.os.UserHandle;
import android.os.Binder;
import android.os.IBinder;
import android.os.Parcel;
import android.os.RemoteException;
public class SplitScreenApplication extends Application {
private static final String TAG = Utils.TAG +" Application";
@Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "start");
new Thread(new Runnable() {
@Override
public void run() {
int time = 0;
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.xxx.splitscreen",
"com.xxx.splitscreen.SplitScreenService"));
while (!getApplicationContext().bindService(intent, connection,
Context.BIND_AUTO_CREATE)) {
try {
final int ms = 1000;
Thread.sleep(ms);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
time++;
Log.d(TAG, "bindSplitScreenService = " + time);
}
}
}).start();
}
private final ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.d(TAG, "** onServiceConnected**");
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.d(TAG, "** onServiceDisconnected**");
}
};
}
2. SS服务代码:SplitScreenService.java
package com.xxx.splitscreen;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.ComponentName;
import android.database.ContentObserver;
import android.os.Handler;
import android.os.IBinder;
import android.os.ServiceManager;
import android.provider.Settings;
import android.util.Log;
import android.app.TaskStackListener;
public class SplitScreenService extends Service {
private static final String TAG = Utils.TAG + " Service";
private Utils mUtil = null;
private SplitScreenController mController = null;
private SplitScreenManager mManager = null;
private SplitScreenListener mListener = null;
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "receive bind request");
return mManager;
}
@Override
public void onCreate() {
// mUtil 工具类
mUtil = Utils.getInstance();
mUtil.init(getBaseContext());
// mController 控制类
mController = SplitScreenController.getInstance();
mController.init(getBaseContext());
// mListener 监听类
mListener = new SplitScreenListener(getBaseContext());
mListener.register();
// mManger 对外ibinder类
mManager = new SplitScreenManager();
ServiceManager.addService("SPLITSCREEN", mManager);
// 这行代码是实际处理业务时逻辑用的,不需要care mController.sendHandlerDelayMessage(Utils.HANDLE_MSG_SPLITSCREEN_START_DELAY, 100);
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
if (mListener != null)
mListener.unregister();
if (mController != null)
mController.clearAllCallbacks();
super.onDestroy();
}
}
3. 控制代码:SplitScreenController.java
package com.xxx.splitscreen;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.IActivityManager;
import android.app.WindowConfiguration;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Message;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.WindowManager;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
public class SplitScreenController {
private static final String TAG = Utils.TAG + " Controller";
// 分屏默认launch的app包名和ACT名
private String mLaunchPkgName = Utils.DEFAULT_PKG_NAME;
private String mLaunchActName = Utils.DEFAULT_ACT_NAME;
// 乱七八糟的用于实际业务处理的tag值
private boolean mHasSetDismissState = false;
private boolean mSoftKeyboardState = false;
private boolean mDialogShowing = false; // flag for dialog show/dismiss
private boolean mButtonDoing = false; // flag for float button clicked delay
private boolean mInVideoFullScreen = false; // flag for bt-video in/out full screen
private boolean mIsPopupActivity = false; // flag for popup activity been created
private boolean mWindowShowing = false; // flag for window layout show/dismiss
// 回调集合
private Set<ISSCallBack> mCallbacks = new HashSet<ISSCallBack>();
private int mSplitScreenStatus = Utils.STATUS_DEFAULT;
private Utils mUtil = null;
private Context mContext = null;
private IActivityManager mAm = null;
private WindowManager mWinMgr = null;
public FloatButton mFloatButton = null;
public SplitScreen mSplitScreen = null;
private static class SingletonInst {
private static final SplitScreenController INST = new SplitScreenController();
}
private SplitScreenController() {
}
public static SplitScreenController getInstance() {
return SingletonInst.INST;
}
/
//>> SplitScreenController initialization
/
public void init(Context context) {
mContext = context;
mUtil = Utils.getInstance();
mAm = ActivityManager.getService();
mWinMgr = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
mFloatButton = new FloatButton(mContext);
mWinMgr.addView(mFloatButton, mFloatButton.layoutParams());
mSplitScreen = new SplitScreen(mContext);
}
/
//>> FloatButton clicked onFloatButtonClicked
/
public void onFloatButtonClicked(MotionEvent event) {
if (mButtonDoing)
return;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mFloatButton.selectModeChange();
break;
case MotionEvent.ACTION_UP:
mFloatButton.normalModeChange();
if (Utils.STATUS_SHOW != mSplitScreenStatus) {
showSplitScreen();
} else {
hideSplitScreen();
}
break;
default:
break;
}
}
/
//>> SplitScreen started/restarted
/
public void startSplitScreen() {
mSplitScreen.start();
}
/
//>> TaskStackListener onTaskStackChanged onTaskCreated onTaskMovedToFront
/
public void onTaskStackChanged() {
Log.d(TAG, "onTaskStackChanged");
ActivityManager.RunningTaskInfo topTask = mUtil.getTopTaskInfo();
showOrHideFloatButton(topTask);
}
public void onTaskCreated(int taskId, ComponentName componentName) {
Log.d(TAG, "onTaskCreated: " + componentName.toString());
if (componentName.getPackageName().equals(mLaunchPkgName)) {
mSplitScreen.setTaskId(taskId);
try {
mAm.setFocuse