最近在开发同屏,做了个Dome,记录下成果!
首先是web端和服务器端,这里我使用node.js来做的
服务端:service.js
var http = require('http');
var sio = require('socket.io');
var fs = require('fs');
var server = http.createServer(function(req,res){
res.writeHead(200,
{
'Content-type':'text/html'
}
);
res.end(fs.readFileSync('./main.html'));
});
server.listen(8083);
var socket = sio.listen(server);
var webs = socket;
socket.on('connection',function(socket){
console.log("Connection...");
setTimeout(function(){
socket.emit('news',{shuju:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMkAAAArCAYAAADSSqyMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3ppVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTMyIDc5LjE1OTI4NCwgMjAxNi8wNC8xOS0xMzoxMzo0MCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDphZjg5Njc3Mi01MWVhLTUxNDUtOTBiNS00YmI5M2I5MWEyZDYiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RjBCRTQyNDlDQTg2MTFFNkExQjlGQzgwNDkwMzhDMTMiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RjBCRTQyNDhDQTg2MTFFNkExQjlGQzgwNDkwMzhDMTMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTUuNSAoTWFjaW50b3NoKSI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOmEzM2Y2NjI4LTljMWUtNDBkZC05MWE4LWZjZDVlZmI0ZDNjNyIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDphZjg5Njc3Mi01MWVhLTUxNDUtOTBiNS00YmI5M2I5MWEy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'});
},1000);
setTimeout(function(){
socket.emit('news',{shuju:'data:image/jpeg;base64,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'});
},3000);
socket.on('users',function(data){
console.log(data)
if(data=="web"){
webs = socket;
}
});
socket.on('data',function(data){
console.log("data is OK..");
webs.emit('news',{shuju:data});
});
})
web端接收图片显示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>MAIN</title>
</head>
<body>
<img id="imgs" style="width:100%" src=""/>
</body>
<script src="http://abcwhatsappad.com:8080/wa/dist/easyui/jquery.min.js"></script>
<script src="http://cdn.bootcss.com/socket.io/1.7.3/socket.io.js"></script>
<script>
var socket = io.connect("ws://192.168.1.194:8083");
socket.emit("users","web");
socket.on('news',function(data){
$(function(){
$("#imgs").attr("src",data.shuju);
});
});
</script>
</html>
接下来是Android端,这里要求是在5.0以下版本上开发同屏功能,我找了好多网上案例,现在也只能做到截图传输,效果也不尽人意。
首先导入io.socket有关的jar包:engine.io-client-0.8.3.jar, okhttp-3.6.0.jar,okio-1.11.0.jar,socket.io-client-0.8.4-SNAPSHOT.jar
连接服务器:SocketStreamWork.java
public class SocketStreamWork implements Runnable {
private static final String TAG = "Alin-SocketStreamWork";
private final static String SOCKET_SERVER_URL = "http://192.168.1.194:8083";
private static final String IMAGE_TITLE = "data:image/png;base64,";
private Socket mSocket;
private boolean isConnected;
private String result;
public SocketStreamWork(String result) {
this.result = result;
}
@Override
public void run() {
//建立Socket连接
Log.e(TAG, "run");
initSocketHttp();
connectSocket();
}
private void initSocketHttp() {
try {
mSocket = IO.socket( SOCKET_SERVER_URL ); // 初始化Socket
Log.e(TAG, "initSocketHttp");
} catch ( URISyntaxException e ) {
e.printStackTrace();
}
}
private void connectSocket() {
try {
mSocket.connect();
mSocket.emit("data", IMAGE_TITLE + result);
Log.e(TAG, "connectSocket");
} catch (Exception e ) {
e.printStackTrace();
}
mSocket.on( Socket.EVENT_CONNECT, onConnect );// 连接成功
mSocket.on( Socket.EVENT_DISCONNECT, onDisconnect );// 断开连接
mSocket.on( Socket.EVENT_CONNECT_ERROR, onConnectError );// 连接异常
mSocket.on( Socket.EVENT_CONNECT_TIMEOUT, onConnectTimeoutError );// 连接超时
mSocket.on( "data", onConnectMsg );// 监听消息事件回调
}
private void disConnectSocket() {
mSocket.disconnect();
mSocket.off( Socket.EVENT_CONNECT, onConnect );// 连接成功
mSocket.off( Socket.EVENT_DISCONNECT, onDisconnect );// 断开连接
mSocket.off( Socket.EVENT_CONNECT_ERROR, onConnectError );// 连接异常
mSocket.off( Socket.EVENT_CONNECT_TIMEOUT, onConnectTimeoutError );// 连接超时
mSocket.off( "data", onConnectMsg );// 监听消息事件回调
}
private Emitter.Listener onConnectMsg = new Emitter.Listener() {// 监听消息事件回调
@Override
public void call( final Object... args ) {
// 在这里处理你的消息
Log.e( TAG, "服务器返回来的消息 : " + args[0] );
}
};
/*实现消息回调接口*/
private Emitter.Listener onConnect = new Emitter.Listener() {// 连接成功
@Override
public void call( final Object... args ) {
Log.e( TAG, "连接成功 ");
if (!isConnected) { // 如果已经断开,重新发送
/*try {
mSocket.emit("data", result);
} catch (Exception e ) {
e.printStackTrace();
}*/
isConnected = true;
}
}
};
private Emitter.Listener onDisconnect = new Emitter.Listener() {// 断开连接
@Override
public void call( Object... args ) {
Log.e( TAG, "断开连接 " + args[0] );
isConnected = false;
}
};
private Emitter.Listener onConnectError = new Emitter.Listener() {// 连接异常
@Override
public void call( final Object... args ) {
Log.e( TAG, "连接 失败" + args[0] );
}
};
private Emitter.Listener onConnectTimeoutError = new Emitter.Listener() {// 连接超时
@Override
public void call( final Object... args ) {
Log.e( TAG, "连接 超时" + args[0] );
}
};
}
截取屏幕图片:ScreenUtil.java
这里使用的是adb截屏功能,截取的图片是保存在路径里的,要获取还是要用FileInputStream()方法获取
public class ScreentUtil {
private static final String TAG = "ScreentShotUtil";
private static final String CLASS1_NAME = "android.view.SurfaceControl";
private static final String CLASS2_NAME = "android.view.Surface";
private static final String METHOD_NAME = "screenshot";
private static ScreentUtil screentShotUtil;
private Display mDisplay;
private DisplayMetrics mDisplayMetrics;
private Matrix mDisplayMatrix;
private WindowManager wm;
private SimpleDateFormat format;
private static File outputImage = null;
public static ScreentUtil getInstance(){
synchronized (ScreentUtil.class) {
if (screentShotUtil == null){
screentShotUtil = new ScreentUtil();
}
}
return screentShotUtil;
}
private Bitmap screenShot(int width, int height){
Log.i(TAG, "android.os.Build.VERSION.SDK : " + android.os.Build.VERSION.SDK_INT);
Class<?> surfaceClass = null;
Method method = null;
try{
Log.i(TAG, "width : " + width);
Log.i(TAG, "height : " + height);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2){
surfaceClass = Class.forName(CLASS1_NAME);
} else {
surfaceClass = Class.forName(CLASS2_NAME);
}
method = surfaceClass.getDeclaredMethod(METHOD_NAME, new Class[]{int.class, int.class});
method.setAccessible(true);
return (Bitmap) method.invoke(null, width, height);
}catch (NoSuchMethodException e){
Log.e(TAG, e.toString());
}catch (IllegalArgumentException e){
Log.e(TAG, e.toString());
}catch (IllegalAccessException e){
Log.e(TAG, e.toString());
}catch (InvocationTargetException e){
Log.e(TAG, e.toString());
}catch (ClassNotFoundException e){
Log.e(TAG, e.toString());
}
return null;
}
/**
* Takes a screenshot of the current display and shows an animation.
* @return
*/
@SuppressLint("NewApi")
public Bitmap ScreenShot(Context context){
Bitmap mBitmap = null;
if(outputImage == null){
format = new SimpleDateFormat("yyyyMMddHHmmss");
String fileName = format.format(new Date(System.currentTimeMillis())) + ".png";
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
outputImage = new File(path, fileName);
Log.e("Alin", "path : " + path + " , outputImage : " + outputImage);
}
if(ShellUtil.checkRootPermission()){
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH){
ShellUtil.execCommand("/system/bin/screencap -p "+ outputImage, true);
Log.d("Alin", "保存截图");
if(outputImage.exists()){
try {
mBitmap = FileUtil.getInstance().getBitmapFromBytes(FileUtil.getInstance().readInputStream(new FileInputStream(outputImage)), null);
} catch (Exception e) {
e.printStackTrace();
}
}
}
} else {
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH){
wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
mDisplay = wm.getDefaultDisplay();
mDisplayMatrix = new Matrix();
mDisplayMetrics = new DisplayMetrics();
// We need to orient the screenshot correctly (and the Surface api seems to take screenshots
// only in the natural orientation of the device :!)
mDisplay.getRealMetrics(mDisplayMetrics);
float[] dims = {
mDisplayMetrics.widthPixels/2, mDisplayMetrics.heightPixels/2
};
float degrees = getDegreesForRotation(mDisplay.getRotation());
boolean requiresRotation = (degrees > 0);
if (requiresRotation){
// Get the dimensions of the device in its native orientation
mDisplayMatrix.reset();
mDisplayMatrix.preRotate(-degrees);
mDisplayMatrix.mapPoints(dims);
dims[0] = Math.abs(dims[0]);
dims[1] = Math.abs(dims[1]);
}
Bitmap mScreenBitmap = screenShot((int) dims[0], (int) dims[1]);
if (requiresRotation){
// Rotate the screenshot to the current orientation
Bitmap ss = Bitmap.createBitmap(mDisplayMetrics.widthPixels/2, mDisplayMetrics.heightPixels/2,
Bitmap.Config.RGB_565);
Canvas c = new Canvas(ss);
c.translate(ss.getWidth() / 2, ss.getHeight() / 2);
c.rotate(degrees);
c.translate(-dims[0] / 2, -dims[1] / 2);
c.drawBitmap(mScreenBitmap, 0, 0, null);
c.setBitmap(null);
mScreenBitmap = ss;
if (ss != null && !ss.isRecycled()){
ss.recycle();
}
}
// If we couldn't take the screenshot, notify the user
if (mScreenBitmap == null){
Toast.makeText(context, "Alin : screen shot fail", Toast.LENGTH_SHORT).show();
}else {
// Optimizations
mScreenBitmap.setHasAlpha(false);
mScreenBitmap.prepareToDraw();
saveBitmap2file(context, mScreenBitmap, outputImage.toString());
}
mBitmap = mScreenBitmap;
}
}
return mBitmap;
}
public void saveBitmap2file(Context context, Bitmap bmp, String fileName){
//Log.e("Alin", bmp.getWidth()+"----------"+fileName);
int quality = 100;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, quality, baos);
InputStream is = new ByteArrayInputStream(baos.toByteArray());
byte[] buffer = new byte[1024];
int len = 0;
File file = new File(fileName);
if (!file.exists()){
try{
file.getParentFile().mkdir();
file.getParentFile().createNewFile();
}catch (IOException e){
Log.e("Alin", e.toString());
}
}else{
try{
file.getParentFile().delete();
file.getParentFile().createNewFile();
}catch (IOException e){
Log.e("Alin", e.toString());
}
}
FileOutputStream stream = null;
try{
stream = new FileOutputStream(file);
while ((len = is.read(buffer)) != -1){
stream.write(buffer, 0, len);
}
stream.flush();
}catch (FileNotFoundException e){
Log.i(TAG, e.toString());
}catch (IOException e){
Log.i(TAG, e.toString());
}finally{
if (is != null) {
try{
is.close();
} catch (IOException e) {
Log.i(TAG, e.toString());
}
}
if (stream != null){
try{
stream.close();
}catch (IOException e){
Log.i(TAG, e.toString());
}
}
}
if (bmp != null && !bmp.isRecycled()){
bmp.recycle();
}
}
/**
* @return the current display rotation in degrees
*/
private float getDegreesForRotation(int value){
switch (value){
case Surface.ROTATION_90:
return 360f - 90f;
case Surface.ROTATION_180:
return 360f - 180f;
case Surface.ROTATION_270:
return 360f - 270f;
}
return 0f;
}
}
adb shell命令文件ShellUtil.java
/**
* ShellUtils
* <ul>
* <strong>Check root</strong>
* <li>{@link ShellUtil#checkRootPermission()}</li>
* </ul>
* <ul>
* <strong>Execte command</strong>
* <li>{@link ShellUtil#execCommand(String, boolean)}</li>
* <li>{@link ShellUtil#execCommand(String, boolean, boolean)}</li>
* <li>{@link ShellUtil#execCommand(List, boolean)}</li>
* <li>{@link ShellUtil#execCommand(List, boolean, boolean)}</li>
* <li>{@link ShellUtil#execCommand(String[], boolean)}</li>
* <li>{@link ShellUtil#execCommand(String[], boolean, boolean)}</li>
* </ul>
*/
public class ShellUtil {
public static final String COMMAND_SU = "su";
public static final String COMMAND_SH = "sh";
public static final String COMMAND_EXIT = "exit\n";
public static final String COMMAND_LINE_END = "\n";
private ShellUtil() {
throw new AssertionError();
}
/**
* check whether has root permission
*
* @return
*/
public static boolean checkRootPermission() {
return execCommand("echo root", true, false).result == 0;
}
/**
* execute shell command, default return result msg
*
* @param command command
* @param isRoot whether need to run with root
* @return
* @see ShellUtil#execCommand(String[], boolean, boolean)
*/
public static CommandResult execCommand(String command, boolean isRoot) {
return execCommand(new String[] {command}, isRoot, true);
}
/**
* execute shell commands, default return result msg
*
* @param commands command list
* @param isRoot whether need to run with root
* @return
* @see ShellUtil#execCommand(String[], boolean, boolean)
*/
public static CommandResult execCommand(List<String> commands, boolean isRoot) {
return execCommand(commands == null ? null : commands.toArray(new String[] {}), isRoot, true);
}
/**
* execute shell commands, default return result msg
*
* @param commands command array
* @param isRoot whether need to run with root
* @return
* @see ShellUtil#execCommand(String[], boolean, boolean)
*/
public static CommandResult execCommand(String[] commands, boolean isRoot) {
return execCommand(commands, isRoot, true);
}
/**
* execute shell command
*
* @param command command
* @param isRoot whether need to run with root
* @param isNeedResultMsg whether need result msg
* @return
* @see ShellUtil#execCommand(String[], boolean, boolean)
*/
public static CommandResult execCommand(String command, boolean isRoot, boolean isNeedResultMsg) {
return execCommand(new String[] {command}, isRoot, isNeedResultMsg);
}
/**
* execute shell commands
*
* @param commands command list
* @param isRoot whether need to run with root
* @param isNeedResultMsg whether need result msg
* @return
* @see ShellUtil#execCommand(String[], boolean, boolean)
*/
public static CommandResult execCommand(List<String> commands, boolean isRoot, boolean isNeedResultMsg) {
return execCommand(commands == null ? null : commands.toArray(new String[] {}), isRoot, isNeedResultMsg);
}
/**
* execute shell commands
*
* @param commands command array
* @param isRoot whether need to run with root
* @param isNeedResultMsg whether need result msg
* @return <ul>
* <li>if isNeedResultMsg is false, {@link CommandResult#successMsg} is null and
* {@link CommandResult#errorMsg} is null.</li>
* <li>if {@link CommandResult#result} is -1, there maybe some excepiton.</li>
* </ul>
*/
public static CommandResult execCommand(String[] commands, boolean isRoot, boolean isNeedResultMsg) {
int result = -1;
if (commands == null || commands.length == 0) {
return new CommandResult(result, null, null);
}
Process process = null;
BufferedReader successResult = null;
BufferedReader errorResult = null;
StringBuilder successMsg = null;
StringBuilder errorMsg = null;
DataOutputStream os = null;
try {
process = Runtime.getRuntime().exec(isRoot ? COMMAND_SU : COMMAND_SH);
os = new DataOutputStream(process.getOutputStream());
for (String command : commands) {
if (command == null) {
continue;
}
// donnot use os.writeBytes(commmand), avoid chinese charset error
os.write(command.getBytes());
os.writeBytes(COMMAND_LINE_END);
os.flush();
}
os.writeBytes(COMMAND_EXIT);
os.flush();
result = process.waitFor();
// get command result
if (isNeedResultMsg) {
successMsg = new StringBuilder();
errorMsg = new StringBuilder();
successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String s;
while ((s = successResult.readLine()) != null) {
successMsg.append(s);
}
while ((s = errorResult.readLine()) != null) {
errorMsg.append(s);
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (os != null) {
os.close();
}
if (successResult != null) {
successResult.close();
}
if (errorResult != null) {
errorResult.close();
}
} catch (IOException e) {
e.printStackTrace();
}
if (process != null) {
process.destroy();
}
}
return new CommandResult(result, successMsg == null ? null : successMsg.toString(), errorMsg == null ? null
: errorMsg.toString());
}
/**
* result of command
* <ul>
* <li>{@link CommandResult#result} means result of command, 0 means normal, else means error, same to excute in
* linux shell</li>
* <li>{@link CommandResult#successMsg} means success message of command result</li>
* <li>{@link CommandResult#errorMsg} means error message of command result</li>
* </ul>
*
* @author <a href="http://www.trinea.cn" target="_blank">Trinea</a> 2013-5-16
*/
public static class CommandResult {
/** result of command **/
public int result;
/** success message of command result **/
public String successMsg;
/** error message of command result **/
public String errorMsg;
public CommandResult(int result) {
this.result = result;
}
public CommandResult(int result, String successMsg, String errorMsg) {
this.result = result;
this.successMsg = successMsg;
this.errorMsg = errorMsg;
}
}
}
文件操作类FileUtil.java
public class FileUtil {
private static FileUtil mFileUtil;
public static FileUtil getInstance(){
synchronized (FileUtil.class) {
if (mFileUtil == null){
mFileUtil = new FileUtil();
}
}
return mFileUtil;
}
/**
* InputStream to byte
* @param inStream
* @return
* @throws Exception
*/
public byte[] readInputStream(InputStream inStream) throws Exception {
byte[] buffer = new byte[1024];
int len = -1;
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
while ((len = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
byte[] data = outStream.toByteArray();
outStream.close();
inStream.close();
return data;
}
/**
* Byte to bitmap
* @param bytes
* @param opts
* @return
*/
public Bitmap getBitmapFromBytes(byte[] bytes, BitmapFactory.Options opts) {
if (bytes != null){
if (opts != null){
return BitmapFactory.decodeByteArray(bytes, 0, bytes.length,opts);
}
else{
return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
}
}
return null;
}
}
使用Base64加密传输图片BitmapUtil.java
public class BitmapUtil {
private static final String TAG = "Alin";
private static BitmapUtil mBitmapUtil;
/**
* bitmap转为base64
* @param bitmap
* @return
*/
public static BitmapUtil getInstance(){
synchronized (BitmapUtil.class) {
if (mBitmapUtil == null){
mBitmapUtil = new BitmapUtil();
}
}
return mBitmapUtil;
}
public String bitmapToBase64(Bitmap bitmap) {
Log.d(TAG, "-----bitmapToBase64-----" + bitmap);
String result = null;
ByteArrayOutputStream baos = null;
try {
if (bitmap != null) {
baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 40, baos);
baos.flush();
baos.close();
byte[] bitmapBytes = baos.toByteArray();
result = Base64.encodeToString(bitmapBytes, Base64.DEFAULT);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (baos != null) {
baos.flush();
baos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
/**
* base64转为bitmap
* @param base64Data
* @return
*/
public Bitmap base64ToBitmap(String base64Data) {
Log.d(TAG, "-----base64ToBitmap-----" + (base64Data == null));
byte[] bytes = Base64.decode(base64Data, Base64.DEFAULT);
return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
}
}
最后我是用
service服务来运行的,这里就不在贴出来了。