android截图并实时传输
最近在做android截图并实时传输的小项目,遇到些问题想请教各位高手
想请教的是:
目前我截图部分可以完成了,是读取framebuffer编码成png图片,然后使用socket传给服务端;但是实时性不强,有几秒的延时,而且不是非常的流畅。
作为刚刚接触java和android的妹纸有点伤不起啊,代码质量也不是很高下面是我的代码
public class SocketService extends Service{
//DatagramSocket socket;
InetAddress serverAddress;
DatagramPacket packet;
int port;
Socket socket = null;
OutputStream outputStream = null;
InputStream inputStream = null;
boolean is_connect = false;
byte[] shotdata = null;
byte[] data = null;
byte[] dataLen = null;
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
}
@Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
int MSG = intent.getIntExtra("MSG", 0);
if(MSG == AppConstant.Msg.CONNECT){
connect();
}else{
if(MSG == AppConstant.Msg.CLOSE){
close();
}
else if(MSG == AppConstant.Msg.SHOT){
CONNECT c = new CONNECT();
SHOT shot = new SHOT(c, 1);
SEND send = new SEND(c, 1);
shot.start();
send.start();
}
}
}
public class SHOT extends Thread {
private CONNECT connect;
private int number;
public SHOT(CONNECT c, int number) {
connect = c;
this.number = number;
}
public void run() {
while(true){
try {
shotdata = null;
startShot();//截图方式是读取framebuffer编码成png图片
shotdata = ScreenShot.getShotData();//读取图片byte[]数据
if(shotdata == null){
shotdata = ScreenShot.getShotData();
connect.put(shotdata);
}else{
connect.put(shotdata);
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
System.out.println("Shot--->" + Thread.currentThread().getId());
System.out.println("Shot #" + this.number + " put: " + shotdata);
}
}
}
public class CONNECT {
private byte[] contents;
private boolean available = false;
public synchronized byte[] get() {
while (available == false) {
try {
wait();
} catch (InterruptedException e) { }
}
available = false;
notifyAll();
return contents;
}
public synchronized void put(byte[] value) {
while (available == true) {
try {
wait();
} catch (InterruptedException e) { }
}
contents = value;
available = true;
notifyAll();
}
}
public class SEND extends Thread {
private CONNECT connect;
private int number;
public SEND(CONNECT c, int number) {
connect = c;
this.number = number;
}
public void run() {
data = null;
dataLen = null;
while(true){
try {
data = connect.get();
System.out.println("Send--->" + Thread.currentThread().getId());
System.out.println("Sendv #" + this.number + "-->get: " + data);
dataLen = new byte[4];
//一帧一帧发
dataLen[0] = (byte) (data.length & 0xff);
dataLen[1] = (byte) (data.length >> 8 & 0xff);
dataLen[2] = (byte) (data.length >> 16 & 0xff);
dataLen[3] = (byte) (data.length >> 24 & 0xff);
packet = new DatagramPacket(data,data.length,serverAddress,port);
try {
//socket.send(packet);
outputStream.write(dataLen);
outputStream.write(data,0,data.length);
outputStream.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
try {
outputStream.close();
socket.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
}
//连接
private void connect() {
// TODO Auto-generated method stub
String Ip_address = MainActivity.getIP();
String Ip_port = MainActivity.getPORT();
Ip_address.trim();
Ip_port.trim();
if(Ip_address.length()==0||Ip_port.length()==0)
System.out.println("ip_server edit is empty or port_server is empty!");
else
{
port= Integer.parseInt(Ip_port);
System.out.println("--------->IP:"+Ip_address+"----------->PORT:"+port);
try {
//创建一个Socket对象,指定服务器端的IP地址和端口号
socket = new Socket();
socket.connect(new InetSocketAddress(Ip_address, port), 1000);
if(socket.isConnected()==true){
outputStream = socket.getOutputStream();
inputStream = socket.getInputStream();
is_connect = true;
}
} catch (Exception e) {
if(e.getClass()==SocketTimeoutException.class){
System.out.println("-------------------->connect Exception!");
}
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
//断开
private void close() {
// TODO Auto-generated method stub
try{
is_connect = false;
socket.shutdownInput();
socket.shutdownOutput();
socket.close();
//socket.disconnect();
} catch (Exception e){
e.printStackTrace();
}
}
每次截图都是读取framebuffer再编码成png图片,接着将png图片先存到了SD卡上,然后socket是从SD卡上面读取的数据,我觉得可能是我截图的时间太长了,但是android好像不能直接从framebuffer读取ByteArrayOutputStream可能还有其他方法,我现在不知道了,感觉涉及的知识好多啊
还有上面代码线程部分请各位牛人看看吧~~~是不是哪里还有什么问题,现在图片传到服务端一卡一卡的真心纠结
[解决办法]
才几秒的延时,很正常啊。一般发问下,上行带宽是非常小的,不比下载文件。
[解决办法]
不需要不停的抓截图。。。
人眼 又不是机器。。。
[解决办法]
额~~~目前只能提高发送的速度了,或者在发的时候进行帧压缩,这个弄的我好纠结0.0
[解决办法]
楼主蛮强的!
[解决办法]
“每次截图都是读取framebuffer再编码成png图片,接着将png图片先存到了SD卡上,然后socket是从SD卡上面读取的数据” 你可以把截图和上传数据分为两个线程来处理,一个线程负责截图一个线程负责上传,那么整个工作流程就会比较顺畅,而不会出现互等的状态。 或者用handler的方式在SD卡上生成了该图后通知程式去上传。
[解决办法]
请问LZ,LZ的这种方法可以截到别的activity的页面吗?或者设备未启动任何程序时,截到桌面内容。。
[解决办法]
你看我的代码啊~~~我是直接放到service里面的在后台截图的
[解决办法]
我这上面代码是用的两个线程,不过使用的是线程同步的方法,但是比较java不是非常熟练,怕有的地方写的不对,求高手指点~~~~@_@
[解决办法]
试试asynctask,发送和截图分开进行,
[解决办法]
额,我之前测试过,貌似是得不到当前activity,的view。。so,以失败告终。。你的已经能成功获得到图片了嘛。。
[解决办法]
你不用包裹流?一个字节一个字节的处理图片数据?
用个缓冲流啊!
丫的字节流这么用的么?不一卡一卡的才奇怪。。。
[解决办法]
能分享一下读取framebuffer编码成png图片的源码吗 我用view.getDrawingCache();截屏Videoview的屏幕 但是截出来是黑屏
------解决方案--------------------
读写那块确实用了同步的方式了, 但是我看到你在同一个线程中进行了截图和上传的操作,那么要上传肯定要等截图存放到SD上才可以开始,而在上传的时候,你又不能去截图了,所以这个过程你可以改进一下。既是在一个线程中不要做两件事,让截图的线程不停的做直到你喊停了,而上传的线程只要检查时候有图片可以上传么,有就上传,没有就等待。
不知道这样时候对你有帮助,写得不是很好请包含。
[解决办法]
楼上的,你看到同名就认为是同一个?!
class A
{
private int a;
public A(int a)
{
this.a = a;
}
public void getInt()
{
System.out.printf("%d\n",a);
}
}
class B
{
private int a;
public B(int a)
{
this.a = a;
}
public void getInt()
{
System.out.printf("%d\n",a);
}
}
你自己测试吧!两个类中的成员,是不是在同一个地址上!
他只是最基本的问题- -,对getInputStream和getOutputStream获得的数据没有使用缓冲!
想都知道,没缓冲是个什么效果了!
[解决办法]
这方法可取,我想不需要保存成图片,而是直接吧抓到的数据直接用包裹发给服务器,让服务器去处理。
[解决办法]
楼主很强啊!刚接触就做截图这样的!顶礼膜拜啊!学习O(∩_∩)O~
[解决办法]
我有点奇怪,你既然已经是读framebuffer的数据了,为什么不直接把读出来的stream发出去,让服务器处理好了啊,在本地存成png,在去读不浪费时间吗
[解决办法]
妹子,我遇到同样的问题。我也是新手,望交流 443145442
[解决办法]
再存到SD卡上简直就是吭啊,速度太慢...直接放在内存里还是快
[解决办法]
呵呵,人家是新手,就一个绿裤衩,当然不排除他们服务器解析端只能认识文件,无法处理流的问题
[解决办法]
请问LZ startShot(); 方法具体实现了什么呢。
[解决办法]
现在对直接处理底层的stream还不是很懂的,想试试先存在手机内存,发出去的效果的@_@.....弱弱的问下android可以直接读到底层缓冲的stream吗?我现在是编译成的可执行文件的~~~~
[解决办法]
哎。。。。现在都是被蹂躏的队伍~~~天天被同事鄙视0.0
[解决办法]
该回复于2012-08-27 11:00:20被版主删除
[解决办法]
同上 求截图代码sadomt@163.com
[解决办法]
楼主,我最近也在做截屏,纠结了一周多了,能否把framebuffer截屏的代码给我发一份,谢谢!我的邮箱:lgj928@sina.com 。
------解决方案--------------------
楼下再要源码就没JJ,楼主我想问下你截图用的是什么原理
[解决办法]
跪求截图代码 skyxuyan@163.com
[解决办法]
求截图部分源码:1042783610@qq.com
多谢~
[解决办法]
楼主还在不在,求源码,475893964@qq.com
[解决办法]
大姐大,求截图部分源码:lifelee2010@163.com
