精华内容
下载资源
问答
  • 一个简单的例子,将手机屏幕录下来传到电脑即时显示,方便演示项目。
  • asm:共享安卓手机屏幕及使用说明,方便手机屏幕在电脑上的同步查看
  • 该篇主要讲解安卓与安卓之间如何截图传输,属于安卓屏幕共享的入门篇。适用场景:安卓屏幕共享工具类应用。 效果图 效果图 demo界面 前言 目前安卓屏幕共享的方式有很多种软件已经实现,究其根源,无非就是采集-...

    Android屏幕共享-传输图片

    该篇主要讲解安卓与安卓之间如何截图传输,属于安卓屏幕共享的入门篇。适用场景:安卓屏幕共享工具类应用。

    效果图

    效果图

    效果图
    demo界面

    Demo

    前言

    目前安卓屏幕共享的方式有很多种软件已经实现,究其根源,无非就是采集-传输-播放的过程,而安卓端无论是截图传输还是硬解码,也一定离不开核心类MediaProjection,它就是Google开放了视频录制的接口(屏幕采集的接口)。

    比较优秀的软件举例:

    • TeamViewer
    • 向日葵
    • Vysor

    其中Vysor就是通过adb实现无root静默截图,然后传输,实现电脑控制手机。在整个屏幕共享的过程中,重点在于如何采集,采集到画质清晰内存又小的技术成为核心。

    常用的安卓端采集技术有:

    • MediaProjection 实现截图
    • MediaProjection 硬解码
    • ffmpeg 软解码
    • adb 实现无root截图

    功能点

    1. android5.0及以上免root截图
    2. 安卓屏幕变化的时候采集
    3. 多端共享拓展简单
    4. socket传输字节数组
    5. 尽可能都使用原生代码实现

    功能讲解

    截图

    随着安卓系统的不断升级,权限也越来越收紧,无root并且不连接数据线做不到静默截图,这里指截取不属于该app的区域。

    • 在允许连接数据线的情况下,可以通过adb shell push 事先编译好的 dex 文件到手机中,实现静默截图。
    • 在没有链接数据线无root的情况下,只能显式的让用户有感知的进行截取。本篇截图使用的是 MediaProjection, 如下图:

    在这里插入图片描述

    MediaProjection 是Android 5.0 开放的屏幕截图与录制视频的接口,是一个系统级的服务,在使用前需要动态申请权限,并在onActivityResult进行处理。
    eg:

         /**
         * 申请截屏权限
         */
        private void tryStartScreenShot() {
            MediaProjectionManager mProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
            if (mProjectionManager != null) {
                startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_MEDIA_PROJECTION);
            }
        }
        
    
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            if (requestCode == REQUEST_MEDIA_PROJECTION && data != null) {
                if (resultCode == RESULT_OK) {
                    // 截屏的回调
                    ScreenShotHelper screenShotHelper = new ScreenShotHelper(this, resultCode, data, this);
                    screenShotHelper.startScreenShot();
                } else if (resultCode == RESULT_CANCELED) {
                    LogWrapper.d(TAG, "用户取消");
                }
            }
        }
    
    

    在屏幕共享时,一直截图就会很费性能,如果在屏幕改变时进行截图就好了。
    刚好,在ImageReader中有setOnImageAvailableListener可以让我们方便的拿到屏幕变化的数据。eg:

         /**
         * 屏幕发生变化时截取
         */
        private class ImageAvailableListener implements ImageReader.OnImageAvailableListener {
            @Override
            public void onImageAvailable(ImageReader reader) {
                try (Image image = reader.acquireLatestImage()) {
                    if (image != null) {
                      // todo 
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    
    

    图片处理

    图片格式:

    • png:无损压缩图片格式,支持Alpha通道
    • jpeg:有损压缩图片格式,不支持背景透明
    • webp:“WebP 是 Android 4.2.1(API 级别 17)支持的较新图片格式。这种格式可为网络上的图片提供出色的无损压缩和有损压缩效果。使用 WebP,开发者可以创建更小、更丰富的图片。WebP 无损图片文件比 PNG 平均缩小了 26%。这些图片文件还支持透明度(也称为 Alpha 通道),只需增加 22% 的字节。
      WebP 有损图片比采用等效 SSIM 质量指标的同等 JPG 图片缩小 25-34%。对于可以接受有损 RGB 压缩的情况,有损 WebP 也支持透明度,生成的文件大小通常比 PNG 小 3 倍。” – 出自谷歌官方文档

    笔者曾尝试过webp格式的编码,大小确实降低了50%左右,但是编码耗时却长了100%,相当于用CPU换网速。这样看来webp并不适用该场景。

    图片压缩:

    • 压缩大小
    • 压缩图片质量

    该Demo的代码中是将bitmap压缩到固定的大小

    Server:

    /**
         * 压缩图片 (压缩后不代表实际大小,有差异)
         *
         * @param bitmap    被压缩的图片
         * @param sizeLimit 大小限制  单位 k
         * @return 压缩后的图片
         */
        public static Bitmap compressBitmap(Bitmap bitmap, long sizeLimit) {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            int quality = 90;
            bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);
            // 循环判断压缩后图片是否超过限制大小
            while (baos.toByteArray().length / 1024 > sizeLimit) {
                baos.reset();
                bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);
                quality -= 10;
            }
            return BitmapFactory.decodeStream(new ByteArrayInputStream(baos.toByteArray()), null, null);
        }
    
    

    socket传输

    原生socket在发送大量数据时,会进行分包,接收的时候也就必须要合包;
    有一些第三方socket框架会帮助我们处理合包的操作,websocket则是在它的协议标准中处理了这个问题。
    所以该demo中选用了websocket进行通讯。拿到的截图的数据放进去就可以了。

    
    import com.talon.screen.quick.util.LogWrapper;
    import org.java_websocket.WebSocket;
    import org.java_websocket.handshake.ClientHandshake;
    import org.java_websocket.server.WebSocketServer;
    
    import java.net.InetSocketAddress;
    
    /**
     * @author by Talon, Date on 2020-04-13.
     * note: websocket 服务端
     */
    public class MWebSocketServer extends WebSocketServer {
    
        private final String TAG = "MWebSocketServer";
    
        private WebSocket mWebSocket;
        private boolean mIsStarted = false;
        private CallBack mCallBack;
    
        public MWebSocketServer(int port, CallBack callBack) {
            super(new InetSocketAddress(port));
            this.mCallBack = callBack;
            setReuseAddr(true);
            setConnectionLostTimeout(5 * 1000);
        }
    
        @Override
        public void onOpen(WebSocket webSocket, ClientHandshake handshake) {
            LogWrapper.d(TAG, "有用户链接");
            mWebSocket = webSocket;
        }
    
        @Override
        public void onClose(WebSocket conn, int code, String reason, boolean remote) {
            LogWrapper.d(TAG, "有用户离开");
        }
    
        @Override
        public void onMessage(WebSocket conn, String message) {
            LogWrapper.e(TAG, "接收到消息:" + message);
        }
    
        @Override
        public void onError(WebSocket conn, Exception ex) {
            LogWrapper.e(TAG, "发生error:" + ex.toString());
        }
    
        @Override
        public void onStart() {
            updateServerStatus(true);
        }
    
        /**
         * 停止服务器
         */
        public void socketStop() {
            try {
                super.stop(100);
                updateServerStatus(false);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 发送二进制
         *
         * @param bytes
         */
        public void sendBytes(byte[] bytes) {
            if (mWebSocket != null)
                mWebSocket.send(bytes);
        }
    
        private void updateServerStatus(boolean isStarted) {
            mIsStarted = isStarted;
            LogWrapper.e(TAG, "mIsStarted:" + mIsStarted);
            // 回调
            if (mCallBack != null)
                mCallBack.onServerStatus(isStarted);
        }
    
        public boolean isStarted() {
            LogWrapper.e(TAG, "mIsStarted:" + mIsStarted);
            return mIsStarted;
        }
    
        public interface CallBack {
            void onServerStatus(boolean isStarted);
        }
    
    }
    
    

    Client:

    import com.talon.screen.quick.util.BitmapUtils;
    import com.talon.screen.quick.util.LogWrapper;
    
    import org.java_websocket.client.WebSocketClient;
    import org.java_websocket.handshake.ServerHandshake;
    
    import java.net.SocketException;
    import java.net.URI;
    import java.nio.ByteBuffer;
    
    /**
     * @author by Talon, Date on 2020-04-13.
     * note: websocket 客户端
     */
    public class MWebSocketClient extends WebSocketClient {
    
        private final String TAG = "MWebSocketClient";
    
        private boolean mIsConnected = false;
        private CallBack mCallBack;
    
        public MWebSocketClient(URI serverUri, CallBack callBack) {
            super(serverUri);
            this.mCallBack = callBack;
        }
    
        @Override
        public void onOpen(ServerHandshake handshakeData) {
            LogWrapper.e(TAG, "onOpen");
            updateClientStatus(true);
    
            try {
                getSocket().setReceiveBufferSize(5 * 1024 * 1024);
            } catch (SocketException e) {
                e.printStackTrace();
            }
    
    
        }
    
        @Override
        public void onMessage(String message) {
    
        }
    
        @Override
        public void onMessage(ByteBuffer bytes) {
            byte[] buf = new byte[bytes.remaining()];
            bytes.get(buf);
            if (mCallBack != null)
                mCallBack.onBitmapReceived(BitmapUtils.decodeImg(buf));
        }
    
        @Override
        public void onClose(int code, String reason, boolean remote) {
            updateClientStatus(false);
        }
    
        @Override
        public void onError(Exception ex) {
            updateClientStatus(false);
        }
    
        private void updateClientStatus(boolean isConnected) {
    
            mIsConnected = isConnected;
            LogWrapper.d(TAG, "mIsConnected:" + mIsConnected);
            // 回调
            if (mCallBack != null)
                mCallBack.onClientStatus(isConnected);
        }
    
        public boolean isConnected() {
            LogWrapper.d(TAG, "mIsConnected:" + mIsConnected);
            return mIsConnected;
        }
    
        public interface CallBack {
            void onClientStatus(boolean isConnected);
    
            void onBitmapReceived(Bitmap bitmap);
        }
    
    
    }
    

    Demo下载

    demo下载(github)
    demo下载(CSDN)

    展开全文
  • 过去为了方便的把手机屏幕投射到电脑上,使用过Teamviewer,ApowerMirror等软件,但是速度和质量均不理想,也不是我想要的官方形式。 这里我要推荐的是Andoird系统自带的无线显示功能 ,通过它我们可以很高效得将...

    过去为了方便的把手机屏幕投射到电脑上,使用过Teamviewer,ApowerMirror等软件,但是速度和质量均不理想,也不是我想要的官方形式。

    这里我要推荐的是Andoird系统自带的无线显示功能 ,通过它我们可以很高效得将手机屏幕投到显示器上。

    测试环境:

    • Windows 10
    • Android 7.1.1 MIUI 9

    步骤:

    1. 在Windows 10 系统设置中,选择“系统”设置,如下图

      这里写图片描述

    2. 在“投影到此电脑”中做如下2设置

      这里写图片描述

    3. 进入到手机设置中,找到无线设置,MIUI在“更多连接方式中”,其它手机如果无此设置,可以去“显示”设置项中找到,如下图
      这里写图片描述

      进入设置开启无线显示,如下图

      这里写图片描述

    4. 保持和电脑在同一个局域网中,如果手机需要连接到vpn,请在开启vpn进行此连接,连接后切换会导致中断!同时,电脑如果开启了热点并连接到了路由器,请以连接到路由器网段为准

    5. 做完以上操作,我们只需要等待搜索,搜索到之后,点击PC设备,PC会弹出通知,询问是否允许其连接,允许之后便可以投屏了。
      这里写图片描述

      手机切换横竖屏的时候,PC显示会始终保持正确的方向,非常人性化,在此,你可以畅游流畅且高质量的屏幕投射了。


    全剧终

    展开全文
  • 有时候为了方便演示一个手机app,需要把手机屏幕显示到PC或Mac上。这里提供一个方法 — 使用Vysor达到此功能。 Vysor的吸引力在于3个方面: 它适用于Windows、Linux或Mac。 USB数据线分享的屏幕几乎是实时的,而...

    有时候为了方便演示一个手机app,需要把手机屏幕显示到PC或Mac上。这里提供一个方法 — 使用Vysor达到此功能。

     

    Vysor的吸引力在于3个方面:

     

    它适用于Windows、Linux或Mac。

     

     

    USB数据线分享的屏幕几乎是实时的,而某些无线解决方案有明显的滞后。Vysor仍然有轻微的延迟,但它的速度远远超过了无线方式。

     

     

    你可以通过你的电脑和手机屏幕进行交互。

    工具/原料

    • 一台Android设备(经测试,需要安卓5.0及以上系统)
    • USB数据线
    • 安装有Chrome浏览器的PC或Mac

    在Android设备上开启USB调试

    1. 1

      一般在"设置-开发者选项-USB调试",打开此开关(也有些国产手机在"设置-辅助功能-开发人员工具-USB调试"等)

       

      大部分手机可能默认并没有开发者选项(开发人员工具)的入口,需要按如下步骤开启:

      进入"设置-关于设备",连续点击7次"内部版本号",会提示开发者模式已启用,返回上一级菜单即可看到开发者选项。

      将你的安卓手机屏幕共享到PC或Mac上
      将你的安卓手机屏幕共享到PC或Mac上
      END

    开启Chrome浏览器的WebGL渲染

    1. 1

      Chrome地址栏输入chrome://gpu/,回车,会看到如图画面。

      其中最后一行"WebGL: Unavailable",说明WebGL不可用

      将你的安卓手机屏幕共享到PC或Mac上
    2. 2

      Chrome地址栏输入chrome://flags,找到"覆盖软件渲染列表",点击"启用",如图

      将你的安卓手机屏幕共享到PC或Mac上
    3. 3

      然后Chrome底部会提示让你重新启动,点击重新启动。或者你手动关闭Chrome浏览器,然后确保没有chrome.exe进程

      (可以任务管理器找到chrome.exe全部干掉,或cmd执行"taskkill /F /IM chrome.exe")

    4. 4

      再次查看chrome://gpu/,如图WebGL已经开启

      将你的安卓手机屏幕共享到PC或Mac上
      END

    在线Chrome浏览器上安装Vysor扩展

    共享手机屏幕到pc或mac上

    1.  

      Android设备通过USB连上电脑

    2.  

      Chrome打开"更多工具-扩展程序",找到之前安装的"Vysor",点击"启用",如图

      将你的安卓手机屏幕共享到PC或Mac上
    3.  

      在打开的对话框中,点击"Find Devices",如图

      将你的安卓手机屏幕共享到PC或Mac上
    4.  

      选择你的Android设备

      将你的安卓手机屏幕共享到PC或Mac上
    5.  

      然后会打开一个窗口,显示提示"Installing Vysor APK",会在你的Android设备上自动安装一个Vysor的app,如图

      将你的安卓手机屏幕共享到PC或Mac上
    6.  

      然后就可以了(测试了Android 4.2、4.4和5.1的,只有5.1可以),如图(左边是原生Android 5.1.1的小米2s,右边是基于Android 5.1的魅蓝note)

      将你的安卓手机屏幕共享到PC或Mac上
      END

    注意事项

    • 手机如果连不上电脑的话,可以用各种手机助手之类的安装下手机驱动
    分类: Android Pro
    本文转自demoblog博客园博客,原文链接http://www.cnblogs.com/0616--ataozhijia/p/5169023.html如需转载请自行联系原作者

    demoblog
    展开全文
  • 展开全部题主可以去试试2113看用向5261日葵远程控制,...先来看个手机控制手机的效果图感受下题主只需要共享屏幕的话点桌面观看就可以了。应用市场里搜向日葵远程控制,注意有两个APP一个是主控端——用于控制,另...

    展开全部

    题主可以去试试2113看用向5261日葵远程控制,里面有手机4102控制手机的功能1653,也有观看屏幕的功能,不过由于苹果系统的强大,苹果手机不能被控制以及被观看,但是苹果手机可以控制和观看安卓的。当然安卓设备之间可以互相控制和观看。

    先来看个手机控制手机的效果图感受下

    0626122af6ff1a865c14c568fc9c78a2.gif

    题主只需要共享屏幕的话点桌面观看就可以了。

    f5107e3568aab141c24d39c9ffd4e0a9.png

    应用市场里搜向日葵远程控制,注意有两个APP一个是主控端——用于控制,另一个是客户端——用于被控制。

    举例说明,题主想把自己手中的小米6的屏幕分享给朋友的Iphone7,那么小米6就要安装客户端,Iphone7要安装主控端。两边都登录同一个账号(账号去官网注册下即可),这样Iphone7上的主控端能识别出小米的被控端,进行几步连接的操作后,点桌面观看就可以了。

    需要注意两点:

    1、如果需要用到控制手机的功能,被控制的手机要被root过才可以,客户端上有root的帮助指引。

    2、包括观看桌面在内,被控设备是手机的话是向日葵的付费功能,不过有比较丰富的渠道免费试用,APP里有阳光小店,他们的微信公众号也有机会获得控制手机的授权。

    展开全文
  • spacedesk之Windows扩展屏幕安卓设备 一、安装 软件下载地址:https://gitee.com/xiaoha1234/soft-ware/blob/master/spacedesk.zip 包含一个.msi文件 安装在Windows10端 包含一个.apk文件 安装在安卓手机或平板...
  • 虽然安卓和苹果系统的使用体验是不一样的,但是安装后技术参数都是一样的,也就是说微信本身有的功能不论是什么系统都是有的,即使更换了手机也是可以进行匹配。 最后总结来说,虽然现在抖音可以说是人人必备,但是...
  • 安卓开发中,使用手机来展示自己的作品要比模拟器效果更好,但是有时候人比较多,手机太小不方便展示,我们可以通过asm.jar这个文件来将手机屏幕显示在电脑上。 asm.jar下载地址:...
  • 树莓派一个安卓智能手机一部USB数据线一条(USB网络共享模式需要,热点模式不需要)软件需要用到的有:JuiceSSHTermuxVNC Viewer首先在手机上安装JuiceSSH和androidVNC还有VNC Viewer,这个直接下载进行安装就可以了。...
  • 这种简单的编辑器可以让用户快速完成屏幕截图的编辑,把不需要的内容或不能公开的内容遮挡再共享给其他人。同时谷歌最近还更新谷歌相册应用带来类似的编辑器,这些编辑器的目的都是让用户不需要依靠专门的编辑软件。...
  • 开源的安卓投屏工具,可用来共享安卓手机的屏幕,亲测好用 开源的安卓投屏工具,可用来共享安卓手机的屏幕,亲测好用
  • 我是这样做的,有更好的方法记得共享喔!谢谢! 这里有一个很重要的概念就是锚点(Anchor)。屏幕的自适应主要是通过它实现的。 看如下图: 这样的话,通过锚点固定UI,不同的分辨率的设备就会自动拉伸对位,实现了...
  • 安卓音视频SDK包

    2019-04-17 09:58:40
    安卓音视频SDK包,远程网络视频会议-在线远程教育-屏幕共享-电子白板-影音共享-直播等等都可以用
  • Android 显示过程可以简单概括为:应用层负责绘制,系统层负责渲染,通过进程间通信把应用层需要绘制的数据传递到系统层服务,系统层服务通过刷新机制把数据更新到屏幕上。 详细过程如下: 首先每一个应用程序都会...
  • 背景 随着近年来移动游戏应用的发展,安卓...2.设备性能,安卓模拟器本质是虚拟设备,可以实现PC硬件的性能共享,性能数据远超手机 3.视觉效果,由于PC硬件的性能共享,可以开启高分辨率等画质。 4.解决电量网速等问
  • 手机在生活中的作用显而易见,大家可能是不是的需要将手机屏幕共享到电脑,进行会议,直播,及其他一些操作展示。那么,我们要怎样将安卓手机投屏到电脑呢?下面介绍一个投屏神器-ApowerMirror。它是一款能够将安卓...
  • 近期买了一部东风日产轩逸2016版,自带智能互联功能,但一直不能用,好好研究下,终于成功了,现分享...打开“无线显示”(我的是OPPO手机,其他的可能显示的是屏幕共享或者其他的东西)。 步骤四:在车载智能互联...
  • 纵观这几年,手机功能和设计向前推动完全靠着安卓手机,比如:屏下指纹识别、屏下摄像头、TOf镜头等新鲜好玩的功能,都是安卓手机在稳扎稳打的推进。根据目前媒体透露消息来看,即将发布的iPhone12依然是稳扎稳打,...
  • 关注安卓版OneNote的主要功能一直以来,安卓版的OneNote功能少得可怜,有时候,我只把它当成一个文档阅读器,我们先来看看它有哪些功能吧:创建笔记本和分区。与 OneNote 共享 Web 内容、文章、图像、视频和文件。...
  • ApkIDE——安卓反编译

    2014-10-19 10:52:47
    小米人APK改之理是一款可视化的用于修改安卓Apk程序文件的工具,集成了ApkTool、Dex2jar、JD-GUI等Apk修改工具,集Apk反编译、Apk打包、Apk签名,支持语法高亮的代码编辑器,基于文件内容的关键字(支持单行代码或...
  • 多屏共享

    2017-01-21 12:01:00
    安卓手机需在手机设置中,查看有无以下功能之一:无线显示/屏幕共享/多屏互动/WLANDisplay/Screen Mirroring/All share CAST 投射屏幕 屏幕投影等。 华为是多屏互动。 镜像技术(Mirroring Technolo...
  • 4.会议录制:共享屏幕、声音、聊天记录、设置保存路径 5.用户列表:显示用户名、显示用户状态 6.绘图工具:画笔、可选择颜色 7.支持终端:台式机、笔记本、安卓系统的智能机、IOS系统的智能机、电话 8.会议安排:...
  • 使用GitHub移动版,你可以在任何地方查看代码,合并更改并共享反馈。由于移动版GitHub是作为原生本机应用程序构建的,因此它甚至可以根据你的系统偏好在暗黑模式下自动适应不同的屏幕尺寸。与团队一起,你可以在...
  • 如今这年代手机、平板电脑进入了每个人的生活,时...1、首先确保你的环境满足以上2点要求,本经验主要侧重于设置pc,正确设置好了,用安卓设备访问pc的共享目录很简单,设置pc按下win+r或者点选屏幕左下角的开始图标...
  • 一款可以隐藏录像的app是一款专业的屏幕录制软件,一款可以隐藏录像的app可以帮助用户方便又快捷的录制屏幕视频,一款可以隐藏录像的app还提供悬浮窗功能,能够自由控制软件开始录屏和结束录屏。软件介绍一款可以...
  • 1,可以使 ViewModel 以及 ViewModel 中的数据在屏幕旋转或配置更改引起的 Activity 重建时存活下来, 重建后数据可继续使用 2,可以帮助开发者轻易实现 Fragment 与 Fragment 之间, Activity 与 Fragment 之间的...

空空如也

空空如也

1 2 3 4 5
收藏数 83
精华内容 33
关键字:

安卓屏幕共享