0

UDP経由でAndroidアプリケーションにデータを送信しています。したがって、次のUDPReceiver-Classを作成しました。

package com.example.urowatch;

import java.net.*;
import java.nio.ByteBuffer;
import java.io.*;

public class UDPReceiver extends Thread
{
private DatagramSocket m_Socket;
private int m_BufferSize;
private Boolean m_End = false;

private int m_TotalLength;
private int m_Received;
private byte[] m_Buffer;

private byte[] m_Result;
private Boolean m_IsNewResult = false;

private float m_Progress;

private int m_ImageCount = 0;
private int m_FrameErrors = 0;

public UDPReceiver(String name, int port, int bufferSize) throws IOException
{
    super(name);

    m_Socket = new DatagramSocket(port);
    m_BufferSize = bufferSize;
    m_Socket.setBroadcast(true);
    m_Socket.setReceiveBufferSize(m_BufferSize);
}

public void run()
{
    while(!m_End)
    {
        try
        {
            byte[] buf = new byte[m_BufferSize];
            DatagramPacket packet = new DatagramPacket(buf, buf.length);
            m_Socket.receive(packet);
            ProcessData(packet);
        }
        catch (IOException e)
        {
            if (!m_Socket.isClosed())
                e.printStackTrace();
        }
    }
}

private void ProcessData(DatagramPacket packet)
{
    if (packet.getLength() == 4)
    {
        ByteBuffer bb = ByteBuffer.wrap(packet.getData());
        m_TotalLength = bb.getInt();
        if (m_Received != 0)
            m_FrameErrors++;
        m_Received = 0;
        m_Buffer = new byte[m_TotalLength];
    }
    else if (m_Buffer != null && m_Received != m_TotalLength)
    {
        int length = packet.getLength();
        System.arraycopy(packet.getData(), 0, m_Buffer, m_Received, length);
        m_Received += length;
        m_Progress = 100 * (float)m_Received/(float)m_TotalLength;

        if (m_Received == m_TotalLength)
        {
            m_Result = new byte[m_TotalLength];
            System.arraycopy(m_Buffer, 0, m_Result, 0, m_TotalLength);
            m_IsNewResult = true;
            m_ImageCount++;
            m_Received = 0;
        }
    }
}

public Boolean IsNewResult()
{
    return m_IsNewResult;
}
public byte[] GetResult()
{
    m_IsNewResult = false;
    return m_Result;
}
public float GetProgress()
{
    return m_Progress;
}
public float GetRatio()
{
    return 100 * (float)m_ImageCount / (float)m_FrameErrors;
}

public void stopServer()
{
    m_End = true;
    if (m_Socket != null)
        m_Socket.close();
}
}

そして、私はこのクラスを次のように使用しています:

package com.example.urowatch;

import java.io.IOException;
import java.text.DecimalFormat;

import android.os.*;
import android.app.Activity;
import android.app.AlertDialog;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.support.v4.app.NavUtils;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.os.Build;

public class LiveActivity extends Activity {
private static ImageView m_ImageView1;
private static TextView m_TextView1;
private static DecimalFormat m_DF;
private static Context m_Context;
private UDPReceiver m_Receiver;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_live);
    // Show the Up button in the action bar.
    setupActionBar();

    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);

    m_ImageView1 = (ImageView)findViewById(R.id.imageView1);
    m_TextView1 = (TextView)findViewById(R.id.textView1);
    m_Context = this;

    m_DF = new DecimalFormat("00.00");
}

/**
 * Set up the {@link android.app.ActionBar}, if the API is available.
 */
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void setupActionBar() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
        getActionBar().setDisplayHomeAsUpEnabled(true);
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.live, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case android.R.id.home:
        // This ID represents the Home or Up button. In the case of this
        // activity, the Up button is shown. Use NavUtils to allow users
        // to navigate up one level in the application structure. For
        // more details, see the Navigation pattern on Android Design:
        //
        // http://developer.android.com/design/patterns/navigation.html#up-vs-back
        //
        NavUtils.navigateUpFromSameTask(this);
        return true;
    }
    return super.onOptionsItemSelected(item);
}

private static Handler MyHandler = new Handler()
{
    @Override
    public void handleMessage(Message msg)
    {
        if (msg.what == 100)
        {
            float[] infos = (float[])msg.obj;
            m_TextView1.setText("Empfange Bild: " + m_DF.format(infos[0]) + "% (FrameErrors: " + m_DF.format(infos[1]) + "%)");
        }
        else if (msg.what == 101)
        {
            byte[] b = (byte[])msg.obj;
            m_TextView1.setText("Empfange Bild: 100,00%");
            m_ImageView1.setImageBitmap(BitmapFactory.decodeByteArray(b, 0, b.length));
        }
        else if (msg.what == 102)
        {
            AlertDialog.Builder b = new AlertDialog.Builder(m_Context);
            b.setTitle("Fehler");
            b.setMessage("Es ist folgende Exception aufgetreten:\n" + (Exception)msg.obj);
            b.setNeutralButton("OK", null);
            b.show();
        }
    }
};

@Override
public void onBackPressed() {
    super.onBackPressed();
    if (m_Receiver != null)
        m_Receiver.stopServer();
    finish();
}

@Override
public void onPause()
{
    m_Receiver.stopServer();
    super.onPause();
}

@Override
protected void onResume()
{
    try {
        m_Receiver = new UDPReceiver("UDPReceiver", 5678, 1024);
        m_Receiver.start();
    } catch (IOException e1)
    {
        // TODO Auto-generated catch block
        e1.printStackTrace();

        AlertDialog.Builder b = new AlertDialog.Builder(this);
        b.setTitle("Fehler");
        b.setMessage("Es ist folgende Exception aufgetreten:\n" + e1);
        b.setNeutralButton("OK", null);
        b.show();
    }

//      Thread thread = new Thread()
//      {
//          @Override
//          public void run()
//          {
//              while(true)
//              {
//                  try {
                    //sleep(250);
                    Toast.makeText(getBaseContext(), "Runing Thread", Toast.LENGTH_SHORT).show();
                    Update();


//                  } catch (InterruptedException e) {
//                      // TODO Auto-generated catch block
//                      e.printStackTrace();
//                      MyHandler.sendMessage(MyHandler.obtainMessage(102, e));
//                  }

//              }
//          }
//      };
//      thread.start();
    super.onResume();
}

public void buttonClick(View v)
{
    Update();
}

private void Update()
{
    if (m_Receiver != null)
    {                               
        if (m_Receiver.IsNewResult())
        {
            byte[] b = m_Receiver.GetResult();
            MyHandler.sendMessage(MyHandler.obtainMessage(101, b));
        }
        else
        {
            float[] infos = new float[2];
            infos[0] = m_Receiver.GetProgress();
            infos[1] = m_Receiver.GetRatio();
            MyHandler.sendMessage(MyHandler.obtainMessage(100, infos));
        }
    }
}
}

ご覧のとおり、UDPReceiver-Objectのステータス(新しい完全なbyte []の準備はできていますか?)をスレッドで確認したいと思います。GUIを更新するには、スレッドはGUIを更新するメッセージをMyHandlerに送信する必要があります。

現時点では、buttonClick-Eventを上げるためにボタンをクリックする必要があります。後で、コメント付きのスレッド構造でこれを実行したいと思います。

さて、これが私の問題です。アクティビティを開始すると、すべてが正常に機能します。次に、UDP-Senderを使用して1つのパケットを手動で送信し始めています(これは機能します。C#-UDP-Receiverで検証しました)。最初のパケットは正常に受信されます。次に、受信した2番目のパケットも送信します。しかし、これからは、m_Socket.receive(packet);のブレークポイントになります。もうヒットしません!

この動作が何を引き起こすのか私にはわかりません。このアプリケーションを機能させることは私にとって非常に重要です。何かアイデアや推測があれば教えてください。

4

0 に答える 0