android写的远程监控调用JNI的停止视频问题,如果连接远程摄像头成功后可以安全退出当前activity,如果连接摄像头不成功调用JNI中的stop方法卡死

问题:
在连接成功后可以安全退出视频查看,当正在连接时点击后退按钮,应用会出现卡死想象,请大家指教,这个问题困扰好几天了。
activity部分代码:
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setTitle("温馨提示");
builder.setMessage("确定退出视频监控吗?");
builder.setPositiveButton("确定",
new DialogInterface.OnClickListener() {

@Override
public void onClick(DialogInterface dialog, int which) {
onBackPressed();
}
});
builder.setNegativeButton("取消",
new DialogInterface.OnClickListener() {

@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.create();
builder.show();
return false;
}
public void onBackPressed() {

try {
if (this.videoView.getStatus() == 1){
videoView.logoutDevice();
this.videoView.stopVideo();
if(videoThread != null){
videoThread.interrupt();
videoThread = null;
}
}
finish();
} catch (Exception e) {
e.printStackTrace();
}

}


class VideoView extends View implements Runnable {
ByteBuffer buffer;
final int h = 288;
ImageButton ibutStop;
ImageButton ibutdown;
ImageButton ibutzoomin;
ImageButton ibutleft;
ImageButton ibutpic;
ImageButton ibutzoomout;
ImageButton ibutright;
ImageButton ibutup;
private int initial = 0;
private Bitmap mBitmap;
byte[] pixel = new byte[202752];
Bitmap resizedBitmap;
private int step = 0;
private boolean takepic = false;
Bitmap temp;
private Video video;
Bitmap videoBit = null;
final int w = 352;

static {
System.loadLibrary("Kernel");
}

public VideoView(Context paramContext, AttributeSet paramAttributeSet) {
super(paramContext, paramAttributeSet);
}

public native int status();

public native int connection(String paramString, int paramInt);

public native int loginDevice(String paramString1, String paramString2);

public native int liveVideo(int paramInt, Object paramObject);

public native int InitDecoder();

public native int UninitDecoder();

public native int changeChannel(int paramInt);

public native int connectionStatus();

public native int sendAutoPTZ(int paramInt1, int paramInt2);

public native int sendPTZCmd(int paramInt1, int paramInt2);

public native int stopVideo();

public native int logoutDevice();

public native int nextChannel(int paramInt);

public native int previousChannel(int paramInt);

public int getStatus() {
return status();
}

protected void onDraw(Canvas paramCanvas) {
try {
super.onDraw(paramCanvas);
if ((this.initial != 0) && (status() != 0)) {
videoBit = Bitmap.createBitmap(352, 288, Bitmap.Config.RGB_565);
buffer = ByteBuffer.wrap(this.pixel);
this.videoBit.copyPixelsFromBuffer(this.buffer);
if (this.takepic) {
saveBitmap2file(this.videoBit);
Toast.makeText(getContext(), "截图保存成功", 3000).show();
this.takepic = false;
}
Rect localRect1 = new Rect(0, 0, 352, 288);
Rect localRect2 = new Rect(0, 0, VideoActivity.viewWidth,
VideoActivity.viewHeight);
paramCanvas.drawBitmap(this.videoBit, localRect1, localRect2,
null);
}
int i = -10 + VideoActivity.viewHeight;
if (this.step == 0) {
Paint localPaint1 = new Paint();
localPaint1.setColor(Color.BLUE);
paramCanvas.drawText("正在连接前端设备, 请稍等..... ", 10, i, localPaint1);
}

if (this.step == 1) {
Paint localPaint2 = new Paint();
localPaint2.setColor(Color.GREEN);
paramCanvas.drawText("成功连接到前端设备 ", 10, i, localPaint2);
}
if (this.step == 2) {
Paint localPaint3 = new Paint();
localPaint3.setColor(Color.RED);
paramCanvas.drawText("连接前端设备失败 ", 10, i, localPaint3);
}
if (this.step == 3) {
Paint localPaint4 = new Paint();
localPaint4.setColor(Color.GREEN);
paramCanvas.drawText("登录前端设备成功 ", 10, i, localPaint4);
}
if (this.step == 4) {
Paint localPaint5 = new Paint();
localPaint5.setColor(Color.RED);
paramCanvas.drawText("传输实施视频失败 ", 10, i, localPaint5);
}
if (this.step == 5) {
Paint localPaint6 = new Paint();
localPaint6.setColor(Color.GREEN);
paramCanvas.drawText("正在传输实时视频", 10, i, localPaint6);
}

} catch (Exception e) {
// TODO: handle exception
}
}

public void run() {
try {
int result = -1;
result = connection(this.video.getIp(),
Integer.valueOf(this.video.getTp()));
System.out.println("connection ............" + this.video.getIp()
+ "   " + this.video.getTp());
// result = connection("192.168.1.100",6036);

System.out.println("connection ............" + result);
if (result == 0) {
this.step = 2;
updateView();
return;
}
System.out.println(this.video.getUn() + "!!!!!!!!!!!!!!!!!!!!!!!!!"
+ this.video.getPw());
result = loginDevice(this.video.getUn(), this.video.getPw());

if (result == 1) {
step = 3;
updateView();
result = liveVideo(this.video.getCh(), pixel);
if (result != 1) {
step = 4;
updateView();
stopVideo();
return;
} else {
step = 5;
updateView();
}

} else {
return;
}

} catch (Exception e) {
e.printStackTrace();
} finally {
buffer = null;
videoBit = null;
resizedBitmap = null;
temp = null;
System.gc();
}
}

boolean saveBitmap2file(Bitmap paramBitmap) {
Bitmap.CompressFormat localCompressFormat = Bitmap.CompressFormat.JPEG;
//.../storage/emulated/0/hanrun/
String str1 = Environment.getExternalStorageDirectory()
.getAbsolutePath() + File.separator + "hanrun" + File.separator;


File localFile1 = new File(str1);
if (!localFile1.exists()) {
localFile1.mkdir();
}

Date localDate = new Date();
String str2 = new SimpleDateFormat("MMddkkmmss").format(localDate);
File localFile2 = new File(str1 + this.video.getTp() + str2 + ".jpg");
FileOutputStream localFileOutputStream;
try {
localFileOutputStream = new FileOutputStream(localFile2);
boolean bool2 = paramBitmap.compress(localCompressFormat, 100,
localFileOutputStream);
return bool2;
} catch (IOException localIOException2) {
localIOException2.printStackTrace();
return false;
}
}

public void setTakepic(boolean paramBoolean) {
this.takepic = paramBoolean;
}

public void setVideo(Video paramVideo) {
this.video = paramVideo;
}

public void updateView() {
postInvalidate();
this.initial = 1;
}
}


JNI文件如下,只列出连接和退出摄像头的代码:
JNIEXPORT jint JNICALL Java_com_handlerun_view_VideoView_connection
  (JNIEnv *env, jobject thiz, jstring ip,jint port)
{



status  = 1;
m_DeviceAddr.sin_family = AF_INET;
m_DeviceAddr.sin_port = htons(port);
char *m_ip = (char*)env->GetStringUTFChars(ip, NULL);
m_DeviceAddr.sin_addr.s_addr = inet_addr(m_ip);

sk.socket = socket(AF_INET,SOCK_STREAM,0);
if(sk.socket == SOCKET_ERROR)
{
status =0;
return 0;
}

//设置为非阻塞模式
unsigned long ul = 1;
result  = ioctl(sk.socket, FIONBIO, &ul);
if(result == SOCKET_ERROR)
{
__android_log_print(ANDROID_LOG_ERROR,"Tag", "  ioctl  FIONBIO  error   :%d \n", result );
status  = 0;
return 0;
}

//连接到服务器
int error;
result =  connect(sk.socket,(struct sockaddr*)&m_DeviceAddr,sizeof(struct sockaddr));

if(result != -1 )
{
__android_log_print(ANDROID_LOG_ERROR,"Tag", "socket   connect  error   :%d \n", result );
status  = 0;
return 0;
}

//检测连接状态
if(errno != EINPROGRESS)
{
__android_log_print(ANDROID_LOG_ERROR,"Tag", "socket  earn    EINPROGRESS   :%d \n", errno );
close(sk.socket);
status  = 0;
return 0;
}
struct timeval tv;
fd_set writefds;
tv.tv_sec = 5;
tv.tv_usec = 0;
FD_ZERO(&writefds);
FD_SET(sk.socket, &writefds);
result  =  select(sk.socket+1,NULL,&writefds,NULL,&tv);
// 连接超时
if(result==0)
{
 __android_log_print(ANDROID_LOG_ERROR,"Tag", "  select    error  :%d \n", result );
close(sk.socket);
status = 0;
return 0;
}


//穿透防火墙
    int len = sizeof(int);
    result = getsockopt(sk.socket, SOL_SOCKET, SO_ERROR, &error, &len);
    if(result!=0)
    {
    __android_log_print(ANDROID_LOG_ERROR,"Tag", "  getsockopt      error  :%d \n", errno );
    close(sk.socket);
    status = 0;
    return 0;
    }


memset(buf,0,200);
result = ReceiveData(sk.socket,m_DeviceTypeInfo,64,20);

if(result != 64)
{
close(sk.socket);
status  = 0;
return 0;
}
netprotrocolver = *((unsigned long*)m_DeviceTypeInfo+3);

__android_log_write(ANDROID_LOG_ERROR,"Tag","stopVideo  ----hrsst stop over ------ ............... ");


return 1;
}

JNIEXPORT jint JNICALL Java_com_handlerun_view_VideoView_stopVideo
  (JNIEnv *env, jobject thiz)
{
memset(&dataHead,0,dataHead_Size);
memset(&packCMD,0,packCmd_Size);

dataHead.HeadFlag = '1111';
dataHead.lLen = packCmd_Size;

packCMD.cmdType = CMD_REQUEST_LOGOUT;
packCMD.dataLen = 0;

result = SendData(sk.socket,(char*)&dataHead,dataHead_Size,10);
result = SendData(sk.socket,(char*)&packCMD,packCmd_Size,10);
result  = shutdown(sk.socket,SHUT_RDWR);

close(sk.socket);

__android_log_write(ANDROID_LOG_ERROR,"Tag","stopVideo   stop over  ............... ");

status  = 0 ;
return 1;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值