>>分享Android开发相关的技术 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 20252 个阅读者 刷新本主题
 * 贴子主题:  启动和运用Android VNC Server 回复文章 点赞(0)  收藏  
作者:Jacky    发表时间:2020-03-31 21:45:40     消息  查看  搜索  好友  邮件  复制  引用

    Android VNC Server

     利用shell开启VNC服务的测试版本==

     一、直接开启VNC Server

     1)下载地址

android-vnc-server:http://code.google.com/p/android-vnc-server/downloads/list

android-vnc:http://code.google.com/p/android-vnc/downloads/list

    2)参考网址

1、电脑控制手机的另一选择——android vnc server

http://bbs.gfan.com/android-116468-1-1.html

2、Android vnc server 安装

http://www.51testing.com/?uid-49689-action-viewspace-itemid-211955

    3)操作简述

     前提:机子需要是破解的,否则su不可执行。

adb push "F:/androidvncserver" /data/(放进去)

adb shell chmod 755 /data/androidvncserver(加可执行权限)

adb shell /data/androidvncserver(执行androidvncserver)

adb forward tcp:5900 tcp:5901(端口重定向,我没弄==)

           3.1)Q1:adb push

     有些机子破解后adb shell仍是$符,需要su后才是#。不能直接push进入/data/目录。

     因而可以先adb push "F:/androidvncserver" /sdcard/,之后adb shell->su->mv /sdcard/androidvncserver /data/

     /data/目录可以再建一层,为/data/local。因为如果你要用程序把androidvncserver写入的话,需要给该目录加写权限,这样涉及到的东西少些。

           3.2)Q2:chmod

     755指rwxr-xr-x,是为了增加其可执行权限。和之前一样,默认是$符需要su才#的破解机子,也只能一步步来:adb shell->su->cd data->chmod a+x androidvncserver->./fbvncserver &

     (su:变更用户身份,不指定时为root;a+x:所有用户执行权限;&:后台运行)

           3.3)Q3:关闭服务

     ps命令查看pid:ps|grep androidvnc*(这个程序里执行不过==)、ps -l androidvncserver

     kill <pid>,杀死进程,即可关闭服务。

           3.4)Q4:VNC Viewer连接不到==

1、确认android端开了VNC Server的进程

2、PC端看下能不能ping通android的ip

           二、程序执行

1)程序截图

     点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

               2)活动类(VNCServerActivity.java
  1.    /**
  2.     * @brief 利用shell开启VNC服务的测试版本
  3.     * @detail
  4.     * Question
  5.     *  
  6.     * Q1:操作设计不合理,见谅-_-!(应该一直su,不要su后执行个命令就exit)
  7.     *     另外,有些破解手机,默认是$而非#。现在这种操作方式就不适用了==
  8.     * Q2:androidvncserver这个,Google HTC开不起来==
  9.     *     纯shell操作,看到提示“cannot get ABS_X info, Invalid argument”
  10.     * Q3:fbvncserver这个,我的那个Viewer接收到的画面怎么花绿的且有挤压==
  11.     *  
  12.     * Solution
  13.     *  
  14.     * S1:先还是利用shell来开VNC服务,找下有其他的没且重新改下流程。
  15.     * S2:难道要下VNCServer源码么?要改东西?要加JNI接口?头疼T^T。
  16.     *  
  17.     * @author Join
  18.     * @date 2012-3-20
  19.     */  
  20.    public   class  VNCServerActivity  extends Activity {
  21.        private   static   final  String TAG =  "VNCServerActivity" ;
  22.        private   static   final   boolean  LOGD =  true ;
  23.        // assets目录下的VNCServer文件名  
  24.        private   static   final  String VNC_SERVER_FILENAME =  "fbvncserver" ;
  25.        private  GlobalUtil globalUtil;  // 工具类  
  26.        private  Button startBtn, stopBtn;  // 按钮  
  27.        private  TextView statusView, connectView;  // 标签  
  28.        [color=#009933]/* dialog identifiers */  
  29.        private   static   final   int  DLG_BASE =  0 ;
  30.        private   static   final   int  DLG_ROOT_FAILED = DLG_BASE +  1 ;
  31.        @Override  
  32.        public   void  onCreate(Bundle savedInstanceState) {
  33.            super .onCreate(savedInstanceState);
  34.           setContentView(R.layout.main);
  35.           startBtn = (Button) findViewById(R.id.startBtn);
  36.           stopBtn = (Button) findViewById(R.id.stopBtn);
  37.           statusView = (TextView) findViewById(R.id.statusView);
  38.           connectView = (TextView) findViewById(R.id.connectView);
  39.            // 直接获IP地址了拼接个端口了,本应该从stdout获的==  
  40.           connectView.setText(getLocalIpAddress() +  ":5901" );
  41.           globalUtil = GlobalUtil.getInstance();  // 获取工具类  
  42.            if  (initApp()) {  // 初始化应用权限  
  43.                /* 判断服务是否开启了,以改变界面 */  
  44.               changeViews(globalUtil.getPids(VNC_SERVER_FILENAME).size() >=  1 );
  45.           }
  46.       }
  47.        /** 改变界面状态 */  
  48.        private   void  changeViews( boolean  isServerOn) {
  49.           startBtn.setEnabled(!isServerOn);
  50.           stopBtn.setEnabled(isServerOn);
  51.           statusView.setText(isServerOn ? R.string.status_run
  52.                   : R.string.status_stop);
  53.       }
  54.        /** startBtn点击事件 */  
  55.        public   void  startBtn(View v) {
  56.            // 运行VNCServer文件(&:后台)  
  57.            boolean  result = globalUtil.rootCommand( "/data/"  + VNC_SERVER_FILENAME
  58.                   +  " &" );
  59.            if  (LOGD)
  60.               Log.d(TAG,  "/data/"  + VNC_SERVER_FILENAME +  " &:
    [/color]"  + result);
  61.           changeViews(result);  // 改变界面状态  
  62.           connectView.setText(getLocalIpAddress() +  ":5901" );  // 重设下IP显示  
  63.       }
  64.        /** stopBtn点击事件 */  
  65.        public   void  stopBtn(View v) {
  66.           ArrayList<String> pidArray = globalUtil.getPids(VNC_SERVER_FILENAME);
  67.            boolean  result;
  68.            for  (String pid : pidArray) {
  69.               result = globalUtil.rootCommand( "kill "  + pid);
  70.                if  (LOGD)
  71.                   Log.d(TAG,  "kill "  + pid +  ":"  + result);
  72.           }
  73.           changeViews( false );
  74.       }
  75.        /** 初始化应用权限 */  
  76.        private   boolean  initApp() {
  77.            boolean  result = globalUtil.rootCommand( "chmod 777 "  
  78.                   + getPackageCodePath());
  79.            if  (result) {
  80.               copyVNCServer();  // 检查vncserver文件  
  81.           }  else  {
  82.               showDialog(DLG_ROOT_FAILED);  // 提示退出应用  
  83.           }
  84.            return  result;
  85.       }
  86.        /** 检查VNCServer文件,不存在时复制进去 */  
  87.        private   void  copyVNCServer() {
  88.           String filePath =  "/data/"  + VNC_SERVER_FILENAME;
  89.           File file =  new  File(filePath);
  90.            /* 文件不存在时,从assets复制进去 */  
  91.            if  (!file.exists()) {
  92.                try  {
  93.                    /* /data/目录增加所有用户的写权限 */  
  94.                    boolean  result = globalUtil.rootCommand( "chmod a+w /data" );
  95.                    if  (LOGD)
  96.                       Log.d(TAG,  "==/data/目录增加写权限:"  + result +  "==" );
  97.                    if  (result) {
  98.                        /* 将VNCServer文件复制入/data/ */  
  99.                       InputStream is = getAssets().open(VNC_SERVER_FILENAME);
  100.                       FileOutputStream fos =  new  FileOutputStream(file);
  101.                        byte [] buffer =  new   byte [ 2048 ];
  102.                        int  count =  0 ;
  103.                        while  ((count = is.read(buffer)) >  0 ) {
  104.                           fos.write(buffer,  0 , count);
  105.                       }
  106.                       fos.close();
  107.                       is.close();
  108.                        if  (LOGD)
  109.                           Log.d(TAG,  "=="  + VNC_SERVER_FILENAME +  "文件写入/data/!==" );
  110.                        /* 给VNCServer文件增加所有用户的执行权限 */  
  111.                       result = globalUtil.rootCommand( "chmod a+x "  + filePath);
  112.                        if  (LOGD)
  113.                           Log.d(TAG,  "=="  + filePath +  "增加执行权限:"  + result +  "==" );
  114.                   }
  115.               }  catch  (IOException e) {
  116.                   e.printStackTrace();
  117.               }
  118.           }  else  {
  119.                if  (LOGD)
  120.                   Log.d(TAG,  "=="  + VNC_SERVER_FILENAME +  "文件已存在/data/目录下!==" );
  121.           }
  122.       }
  123.        @Override  
  124.        protected  Dialog onCreateDialog( int  id) {
  125.            switch  (id) {
  126.            case  DLG_ROOT_FAILED:
  127.                return   new  AlertDialog.Builder( this )
  128.                       .setTitle(R.string.root_title)
  129.                       .setMessage(R.string.root_failed)
  130.                       .setCancelable( false )
  131.                       .setPositiveButton(R.string.dlg_ok,
  132.                                new  DialogInterface.OnClickListener() {
  133.                                    @Override  
  134.                                    public   void  onClick(DialogInterface dialog,
  135.                                            int  which) {
  136.                                       finish();
  137.                                   }
  138.                               }).create();
  139.           }
  140.            return   super .onCreateDialog(id);
  141.       }
  142.        /** 获取IP地址 */  
  143.        public  String getLocalIpAddress() {
  144.            try  {
  145.                for  (Enumeration<NetworkInterface> en = NetworkInterface
  146.                       .getNetworkInterfaces(); en.hasMoreElements();) {
  147.                   NetworkInterface intf = en.nextElement();
  148.                    for  (Enumeration<InetAddress> enumIpAddr = intf
  149.                           .getInetAddresses(); enumIpAddr.hasMoreElements();) {
  150.                       InetAddress inetAddress = enumIpAddr.nextElement();
  151.                        if  (!inetAddress.isLoopbackAddress()) {
  152.                            return  inetAddress.getHostAddress().toString();
  153.                       }
  154.                   }
  155.               }
  156.           }  catch  (SocketException e) {
  157.               e.printStackTrace();
  158.           }
  159.            return   null ;
  160.       }
  161.   }

           3)工具类(GlobalUtil.java

    


  1.    public   final   class  GlobalUtil {
  2.        /** 内部类GlobalUtilHolder */  
  3.        static   class  GlobalUtilHolder {
  4.            static  GlobalUtil instance =  new  GlobalUtil();
  5.       }
  6.        /** 返回GlobalUtil的单例 */  
  7.        public   static  GlobalUtil getInstance() {
  8.            return  GlobalUtilHolder.instance;
  9.       }
  10.        /**
  11.         * @brief ROOT权限执行一个shell命令
  12.         * @detail 设备必须已破解,否则su不可用
  13.         *  
  14.         * @param cmd 命令
  15.         * @return 返回是否执行成功
  16.         *  
  17.         * @code
  18.         * 修改应用权限:
  19.         *   String apkRoot="chmod 777 " + getPackageCodePath();
  20.         *   GlobalUtil.getInstance().chmodCommand(apkRoot);
  21.         * @endcode
  22.         */  
  23.        public   boolean  rootCommand(String cmd) {
  24.           Process process =  null ;
  25.           DataOutputStream os =  null ;
  26.            try  {
  27.                // su变更用户身份(不指定用户时,预设root)  
  28.               process = Runtime.getRuntime().exec( "su" );
  29.                // 连接到子进程正常输入的输出流  
  30.               os =  new  DataOutputStream(process.getOutputStream());
  31.               os.writeBytes(cmd +  "
    " );
  32.               os.writeBytes( "exit
    " );
  33.               os.flush();
  34.               process.waitFor();  // 等待执行完成  
  35.           }  catch  (Exception e) {
  36.                return   false ;
  37.           }  finally  {
  38.                try  {
  39.                    if  ( null  != process) {
  40.                       process.destroy();
  41.                   }
  42.                    if  ( null  != os) {
  43.                       os.close();
  44.                   }
  45.               }  catch  (Exception e) {
  46.               }
  47.           }
  48.            return   true ;
  49.       }
  50.        [color=#009933]/**
  51.         * @brief 执行一个shell命令
  52.         *
  53.         * @param cmd 命令名称&参数组成的数组
  54.         * @param workDir 命令工作目录
  55.         * @return 命令输出结果
  56.         */  
  57.        public  String execCommand(String[] cmd, String workDir) {
  58.           StringBuffer result =  new  StringBuffer();
  59.            try  {
  60.                // 创建操作系统进程(也可以由Runtime.exec()启动)  
  61.               ProcessBuilder builder =  new  ProcessBuilder(cmd);
  62.                // 设置命令工作目录  
  63.                if  (workDir !=  null ) {
  64.                   builder.directory( new  File(workDir));
  65.               }
  66.                // 合并标准错误和标准输出  
  67.               builder.redirectErrorStream( true );
  68.                // 启动一个新进程  
  69.               Process process = builder.start();
  70.                /* 获得运行输出结果 */  
  71.               InputStream is = process.getInputStream();
  72.               BufferedReader br =  new  BufferedReader( new  InputStreamReader(is));
  73.               String line;
  74.                while  ( null  != (line = br.readLine())) {
  75.                   result.append(line);
  76.                   result.append( "
    [/color]" );
  77.               }
  78.                if  (is !=  null ) {
  79.                   is.close();
  80.                   br.close();
  81.               }
  82.           }  catch  (Exception e) {
  83.               e.printStackTrace();
  84.           }
  85.            return  result.toString();
  86.       }
  87.        /**
  88.         * @brief ps某一执行程序,获取其pid
  89.         *
  90.         * @param execFilename
  91.         * @return pid的list
  92.         */  
  93.        public  ArrayList<String> getPids(String execFilename) {
  94.           ArrayList<String> pidArray =  new  ArrayList<String>();
  95.           String result = execCommand( new  String[] {  "ps" ,  "-l" , execFilename },
  96.                    null );
  97.            if  ( null  != result && ! "" .endsWith(result)) {
  98.               String[] resultArray = result.split( "
    " );
  99.                int  len = resultArray.length;
  100.                try  {
  101.                    /* 从第二行开始遍历 */  
  102.                    for  ( int  i =  1 ; i < len; i++) {
  103.                        // 空格区分的第二个字符串  
  104.                       pidArray.add(resultArray[i].trim().split( "\\s+" )[ 1 ]);
  105.                   }
  106.               }  catch  (ArrayIndexOutOfBoundsException e) {
  107.               }
  108.           }
  109.            return  pidArray;
  110.       }
  111.   }

           三、其他参考

          1、linux权限详解

          http://blog.csdn.net/fan_zhen_hua/article/details/2050009

          2、Linux命令大全(修改版).zip

          http://vaero.blog.51cto.com/4350852/796090,附件资料。

          3、Android执行shell命令

          http://vaero.blog.51cto.com/4350852/778139,附件资料。

          4、Google Code的wiki&issues

          http://code.google.com/p/android-vnc-server/wiki/README

           四、后记

                         实现的不好,好多问题啊 T^T 。(还待完善,请多担待!)

                     ps : fastdroid-vnc 这个项目好像也不错 ^^

                   http://code.google.com/p/fastdroid-vnc/wiki/fastdroidvnc

                   1 )开启 fastdroid-vnc

          点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

                   2 )关闭 fastdroid-vnc

          点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小

        
         附件:http://down.51cto.com/data/2360106
----------------------------
原文链接:https://blog.51cto.com/vaero/812967

程序猿的技术大观园:www.javathinker.net



[这个贴子最后由 flybird 在 2020-04-08 09:01:54 重新编辑]
  Java面向对象编程-->图形用户界面(上)
  JavaWeb开发-->JSP中使用JavaBean(Ⅱ)
  JSP与Hibernate开发-->映射一对多关联关系
  Java网络编程-->RMI框架
  精通Spring-->绑定表单
  Vue3开发-->Vue CLI脚手架工具
  Android开发随想:iPhone和Android之间的对话
  Android UI学习 - Tab的学习和使用
  Android多线程及异步处理问题
  android 手势操作GestureDetector
  android异步更新UI
  Android Spinner范例
  总是听到有人说AndroidX,到底什么是AndroidX?
  Android性能优化技巧
  UI渲染优化
  UI渲染机制以及优化
  Android 服务(Service)
  Android_实现商品详情的展示页及布局
  程序员笔记|JSBridge框架解决通信问题实现移动端跨平台开发
  Android无侵入式引导提示-一键式启动
  Android中NDK的含义和作用
  更多...
 IPIP: 已设置保密
楼主      
该用户目前不在线 lililala6868 
  
威望: 0
级别: 新手上路
魅力: 100
经验: 100
现金: 992
发文章数: 2
注册时间: 0001-01-01
 消息  查看  搜索  好友  邮件  复制  引用


体彩排列5 电脑控制手机的另一选择——android vnc server北京快3
发文章时间 2021-04-07 21:34:54
 IPIP: 已设置保密 1 楼     
1页 1条记录 当前第1
发表一个新主题 开启一个新投票 回复文章


中文版权所有: JavaThinker技术网站 Copyright 2016-2026 沪ICP备16029593号-2
荟萃Java程序员智慧的结晶,分享交流Java前沿技术。  联系我们
如有技术文章涉及侵权,请与本站管理员联系。