为啥我要做这个东西了,是因为经常要用投影演示app ,现在有很多这样的软件可以把手机界面投到电脑上 ,但都要安装,比如说360的手机助手,我又讨厌安装,于是就自己捣鼓了下 做了这个东西,

  实现了以下简单功能

     1、屏幕获取(因为是截图方式获取的,所以有点卡顿)

   2、实现点击功能,并在点击的时候出现一个手势图标,方便用户观看

   3、实现简单的滑动功能

4、实现在界面上画图功能

5、实现拖拽安装apk功能

操作说明:鼠标左边 模拟手机点击,中键停止/开始刷新界面(画图的时候不能刷新),右键去掉画图内容

显示来看下效果图

这个就是主界面了,下面有显示手机型号

其次是在上面画图功能方便讲解

原理就是通过abd来实现的

adb shell input keyevent 26  点击power

这是截屏显示图片的代码

  private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
while (true)
{
if (isStop)
{
return;
}
//死循环截屏获取图片
var tempFileName = "1.png";
cmdAdb("shell screencap -p /sdcard/" + tempFileName);
// pictureBox1.ImageLocation = Environment.CurrentDirectory + "\\temp\\" + tempFileName;
cmdAdb("pull /sdcard/" + tempFileName);
if (System.IO.File.Exists(tempFileName))
{
//pictureBox1.BackgroundImage = new Bitmap(tempFileName);
using (var temp = Image.FromFile(tempFileName))
{ pictureBox1.Invoke(new Action(() => {
pictureBox1.Image = new Bitmap(temp);
}));
}
if (multiplierX == )
{
multiplierX = pictureBox1.Image.Width / (pictureBox1.Width + 0.00);
multiplierY = pictureBox1.Image.Height / (pictureBox1.Height + 0.00);
}
GC.Collect();
if (System.IO.File.Exists(tempFileName))
{
try
{
System.IO.File.Delete(tempFileName);
}
catch
{ }
}
Thread.Sleep(); }
}
}

这个是画图点击以及滑动的代码

  private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Right)//鼠标右键 撤销画画
{
this.Refresh();
return;
}
if (e.Button == MouseButtons.Middle)//鼠标中键按下 停止或开始更新图像
{
isStop = !isStop;
if (!isStop && HasAndroid)
{
backgroundWorker1.RunWorkerAsync();
}
return;
}
if (isDraw)
{
isDraw = false;
return;
}
if (pictureBox1.Image == null)
{
return;
}
using (Graphics g = pictureBox1.CreateGraphics())
{
g.DrawImage(ShowAndroidModel.Properties.Resources.shou, e.X - Convert.ToInt32( / multiplierX), e.Y - Convert.ToInt32( / multiplierY), Convert.ToInt32( / multiplierX), Convert.ToInt32( / multiplierY));
g.Dispose();
}
var tapx = multiplierX * e.X;//计算实际坐标
var tapy = multiplierY * e.Y;
cmdAdb(string.Format("shell input tap {0} {1}", tapx.ToString(""), tapy.ToString("")));//点击坐标
} private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
lineStartX = e.X;
lineStartY = e.Y;
StartX = e.X;
StartY = e.Y;
_MouseState = MouseState.MouseLeftDown;
return;
}
} private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
_MouseState = MouseState.None;
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
if (StartX - e.X > || StartX - e.X < - || StartY - e.Y > || StartY - e.Y < -)
{
isDraw = true;
Debug.WriteLine("执行" + isDraw);
cmdAdb(string.Format("shell input swipe {0:0} {1:0} {2:0} {3:0} 100", StartX * multiplierX, StartY * multiplierY, e.X * multiplierX, e.Y * multiplierY));
}
}
} private void pictureBox1_SizeChanged(object sender, EventArgs e)
{
multiplierX = pictureBox1.Image.Width / (pictureBox1.Width + 0.00);
multiplierY = pictureBox1.Image.Height / (pictureBox1.Height + 0.00);
} private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (_MouseState == MouseState.None)
{
return;
}
if (_MouseState == MouseState.MouseLeftDown)
{
isDraw = true;
using (Graphics g = pictureBox1.CreateGraphics())
{
g.DrawLine(new Pen(Color.Red, ), new Point(lineStartX, lineStartY), new Point(e.X, e.Y));
g.Dispose();
} lineStartX = e.X;
lineStartY = e.Y; return;
}
}

检测设备是否存在

  /// <summary>
/// 检测是否存在手机
/// </summary>
private void CheckHasAndroidModel()
{
var text = cmdAdb("shell getprop ro.product.model",false);//获取手机型号
Debug.WriteLine("检查设备:" + text+" T="+DateTime.Now);
if (text.Contains("no devices")||string.IsNullOrWhiteSpace(text))
{
HasAndroid = false;
isStop = true;
toolStripStatusLabel2.Text="未检测到设备";
}
else
{
HasAndroid = true;
isStop = false;
toolStripStatusLabel2.Text = text.Trim();
if (!backgroundWorker1.IsBusy)
{
backgroundWorker1.RunWorkerAsync();
}
}
}

重写WndProc方法监听usb设备插入

  protected override void WndProc(ref Message m)
{
if (m.Msg == 0x219)
{
Debug.WriteLine("WParam:{0} ,LParam:{1},Msg:{2},Result:{3}", m.WParam, m.LParam, m.Msg, m.Result);
if (m.WParam.ToInt32() == )//设备插入或拔出
{
CheckHasAndroidModel();
myTimer.Start();
}
}
try
{
base.WndProc(ref m);
}
catch { }
}

最后附代码  https://files.cnblogs.com/files/dotnet-org-cn/ShowAndroidModel.rar

Winfrom 简单的安卓手机屏幕获取和安卓简单操作的更多相关文章

  1. 安卓手机屏幕录像之scr

    打开SCR Screen Recorder,屏幕会显示录像控制面板,点击“开始”按钮就可以开始录像: - 停止录像的方法有两种.一种是锁屏,锁屏后等待2秒,录像文件会自动保存到SD卡,另外一种是重新打 ...

  2. 如何录制手机屏幕并转成gif

    因为上一篇博客需要展示一些软件操作过程,如果直接截图的话一来可能需要多张图,二来表达也不方便,所以特意去查了下如何录制手机屏幕操作,然后转成gif,嵌入进博客中,这样表达起来就方便多了.话不多说,总结 ...

  3. ZT 安卓手机的安全性 prepare for Q

    如何增强安卓手机的安全性?安卓的安全性太低了!!! 众所周知,安卓手机是非常容易破解的,刷过机的人都知道,不管你之前在手机怎么设置密码,只要进入recovery清空使用记录,手机就会恢复出厂设置,到时 ...

  4. MSF入侵安卓手机

    MSF是Metasploit的简称,Metasploit是一款开源的安全漏洞检测工具,非常强大,分别有Windows版和Linux版,工具里集成了许多微软公布的漏洞(0day). 我这里做测试的系统是 ...

  5. 在电脑上操作手机屏幕scrcpy工具就搞定了

    手机安卓版本:10 电脑:win64 使用步骤 电脑步骤 下载scrcpy scrcpy 是免费开源的投屏软件,支持将安卓手机屏幕投放在 Windows.macOS.GNU/Linux 上,并可直接借 ...

  6. Android安卓手机游戏开发

    成都传智播客Java培训,免费学Android安卓手机游戏开发,安卓android开发课程包括Android安卓应用开发和Android安卓游戏开发两个方向,可是偏向游戏开发. 依据"199 ...

  7. 通过 PC 远程控制 Android 的应用 -- 可以将手机屏幕投射显示到电脑上

    测试结果中的部分测试图:Mobizen手机界面: 电脑界面: 主界面 视频 全屏视频 WebKey手机界面: 电脑界面: AirMore手机界面: 电脑界面:主界面 镜像 全屏镜像 Airdroid手 ...

  8. Unity获取安卓手机运营商,电量,wifi信号强度,本地Toast,获取已安装apk,调用第三方应用,强制自动重启本应用

    一个完整的游戏项目上线需要不断的完善优化,但是到了后期的开发不再仅仅是游戏了,它的复杂度远远大于纯粹的应用开发.首先必须要考虑的就是集成第三方SDK,支付这块渠道商已经帮你我们做好了,只需要按照文档对 ...

  9. 获取手机屏幕DisplayMetrics属性方法

    转自:http://blog.csdn.net/zhangqijie001/article/details/5894872 其他参考:http://blog.sina.com.cn/s/blog_7d ...

随机推荐

  1. Java企业微信开发_07_素材管理之上传本地临时素材文件

    一.本节要点 1.临时素材有效期 media_id是可复用的,同一个media_id可用于消息的多次发送(3天内有效) 2.上传文件时的http请求里都有啥 具体原理可参看: 为什么上传文件的表单需要 ...

  2. flannel 概述 - 每天5分钟玩转 Docker 容器技术(58)

    flannel 是 CoreOS 开发的容器网络解决方案.flannel 为每个 host 分配一个 subnet,容器从此 subnet 中分配 IP,这些 IP 可以在 host 间路由,容器间无 ...

  3. Node.js之包与npm包管理工具

    Node.js之包与npm包管理工具 1.Node.js中的包 1.1在一个包中包含如下内容: package.json:对包进行描述 在bin子目录中存放二进制文件 在lib子目录中存放JavaSc ...

  4. CSS 中的rem,em,vh,vw一次说清楚

    关于css中的长度单位,我们用的最多就是px,因为他简单直接.但是当一套方案匹配不同终端时,px就会显得过于生硬,不容易变通. 然而rem,em,vh,vw就可以有效的解决这一问题.让我们来看看这些东 ...

  5. new 、 delete 、 malloc 、 free 关系

    1.new . delete . malloc . free 关系 delete 会调用对象的析构函数 , 和 new 对应, free 只会释放内存, new 调用构造函数. malloc 与 fr ...

  6. PHP迭代与递归实现无限级分类

    无限级分类是开发中常见的情况,因此本文对常见的无限极分类算法进行总结归纳. 1.循环迭代实现 $arr = [ 1=>['id'=>1,'name'=>'父1','father'=& ...

  7. C# 使用NPOI 实现Excel的简单导入导出

    private void btnImport_Click(object sender, EventArgs e) { DataSet ds = new DataSet(); DataTable dt ...

  8. Python教程百度网盘哪里有?

    Python为我们提供了非常完善的基础代码库,覆盖了网络.文件.GUI.数据库.文本等大量内容,被形象地称作"内置电池(batteries included)".带你快速入门的Py ...

  9. 详解session

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp30 一.术语session 在我的经验里,session这个词被滥用的程度 ...

  10. 【转】Spring AOP 实现之CGLIB

    详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp91    cglib(Code Generation Library)是 ...