0

Android OS 2.3 以降のチャット プログラムを作成しています。私はいくつかの例に従ってきましたが、OS 2.3.x ですべての余分なベルとホイッスルで完全に動作するようになりました。

私の問題は、OS > 2.3.x、つまりハニカム、特に ICS (テスト用の ICS デバイスを持っています) で発生します。

(パケット)を送信できません。毎回エラーで落ちます。ここに示されている答えは、サービス内でスレッドを実行することのようです。

残念ながら、それは常にそうでした-メインウィンドウが別のウィンドウを開く可能性があるという事実に関係なく、余分なウィンドウを開いて、サービスがデータを取得してからメインアクティビティに戻す必要があります-チャット履歴全体に戻るとき、見逃したものすべてを含みます。

OS 4.0 (ICS) でコードが送信 (パケット) にヒットするたびにエラーを解放しないようにするために、私が何をする必要があるか教えてもらえますか?

前もって感謝します。サービスの完全なソースはこちらです。

package com.rpg.phg.themesh;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.DhcpInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;

/**
 * This class does all the work for sending and receiving broadcast packets. 
 * It has a thread that listens for incoming packets.
 */
public class TheMesh_ChatService extends Service 
{
// Debugging
private static final String TAG = "TheMesh_ChatService";
private static final boolean D = true;
private static String myIP = null;

// Member fields
private final Handler mHandler;
private ComService mConnectedService;

Context mContext ;
/**
 * Constructor. Prepares a new Broadcast service.
 * @param context  The UI Activity Context
 * @param handler  A Handler to send messages back to the UI Activity
 */
public TheMesh_ChatService(Context context, Handler handler, String ourIP) {
    //mAdapter = BluetoothAdapter.getDefaultAdapter();
    mContext = context;
    mHandler = handler;
    myIP = ourIP;
}


/**
 * Start the chat service. Specifically start ComThread to begin 
 * listening incoming broadcast packets. 
 */
public synchronized void start() {
    if (D) Log.d(TAG, "Started Service");

    mConnectedService = new ComService();
    mConnectedService.start();
}


/**
 * Stop thread
 */
public synchronized void stop() {
    if (D) Log.d(TAG, "stop");
    if (mConnectedService != null) {mConnectedService.cancel(); mConnectedService = null;}
}


public void write(byte[] out, String IP) {
    mConnectedService.write(out, IP);
}


/**
 * This thread handles all incoming and outgoing transmissions.
 * 
 * This actually needs to be turned onto the TheMesh_ChatService
 */    
private class ComService extends Thread {
    // Should we create a Thread here? 
    // It *should* stay running until the service ends...
    private static final int BCAST_PORT = 2568;
    DatagramSocket mSocket ;

    InetAddress myBcastIP, myLocalIP, myRemoteIP = null ;

    public ComService() {

        try { 
               myBcastIP    = getBroadcastAddress();
               if(D)Log.d(TAG,"my bcast ip : "+myBcastIP);

               //myLocalIP  = getLocalAddress();
               myLocalIP =  InetAddress.getByName(myIP);
               if(D)Log.d(TAG,"my local ip : "+myLocalIP);

               mSocket      = new DatagramSocket(BCAST_PORT); 
               mSocket.setBroadcast(true); 

             } catch (IOException e) { 
                 Log.e(TAG, "Could not make socket", e); 
             } 
    }


    public void run() {

        try {

            byte[] buf = new byte[1024]; 

            //Listen on socket to receive messages 
            while (true) { 
                DatagramPacket packet = new DatagramPacket(buf, buf.length); 
                mSocket.receive(packet); 

                InetAddress remoteIP = packet.getAddress();
                if(remoteIP.equals(myLocalIP))
                    continue;

                String s = new String(packet.getData(), 0, packet.getLength()); 
                if(D)Log.d(TAG, "Received response " + s); 

                // Send the obtained bytes to the UI Activity
                mHandler.obtainMessage(TheMesh_PAN.MESSAGE_READ,-1,-1, s)
                .sendToTarget();
            } 
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
      * Write broadcast packet.
      */
    public void write(byte[] buffer, String IP) {

        try {
            String data = new String (buffer);
            if (IP.equalsIgnoreCase("ALL"))
            {
                DatagramPacket packet = new DatagramPacket(data.getBytes(), data.length(), 
                    myBcastIP, BCAST_PORT);
                mSocket.send(packet); // logcat shows crash here!
            } else
            {
                myRemoteIP = InetAddress.getByName(IP); // Will this generate Exceptions if lookup fails?
                DatagramPacket packet = new DatagramPacket(data.getBytes(), data.length(), 
                        myRemoteIP, BCAST_PORT);
                mSocket.send(packet); // and logcat shows crash here.
            }
            // Share the sent message back to the UI Activity
            mHandler.obtainMessage(TheMesh_PAN.MESSAGE_WRITE, -1, -1, data)
                    .sendToTarget();
        } catch (Exception e) {
            Log.e(TAG, "Exception during write", e);
        }
    }


    /** 
     * Calculate the broadcast IP we need to send the packet along. 
     */ 
    private InetAddress getBroadcastAddress() throws IOException {
      WifiManager mWifi = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);

      WifiInfo info = mWifi.getConnectionInfo();
      if(D)Log.d(TAG,"\n\nWiFi Status: " + info.toString());

      // DhcpInfo  is a simple object for retrieving the results of a DHCP request
      DhcpInfo dhcp = mWifi.getDhcpInfo(); 
      if (dhcp == null) { 
        Log.d(TAG, "Could not get dhcp info"); 
        return null; 
      } 

      int broadcast = (dhcp.ipAddress & dhcp.netmask) | ~dhcp.netmask; 
      byte[] quads = new byte[4]; 
      for (int k = 0; k < 4; k++) 
        quads[k] = (byte) ((broadcast >> k * 8) & 0xFF);

      return InetAddress.getByAddress(quads); // The high order byte is quads[0].
    }  

    public void cancel() {
        try {
            mSocket.close();
        } catch (Exception e) {
            Log.e(TAG, "close() of connect socket failed", e);
        }
    }
}

@Override
public IBinder onBind(Intent arg0) {
    // TODO Auto-generated method stub
    return null;
}
}

これはすべてそのまま機能します。プログラムのほとんどは「broadcastchat4」から取られています (どのウェブサイトから入手したか忘れてしまいました)。特に呼び出しプログラムに追加しました。

send が write 関数内から呼び出されるとすぐに (これは run() が実行されている間に呼び出され、書き込みが発信トラフィックを処理している間に着信トラフィックを監視します)、logcat で次のようになります。

09-22 19:32:24.959: E/TheMesh_ChatService(17320): Exception during write
09-22 19:32:24.959: E/TheMesh_ChatService(17320): android.os.NetworkOnMainThreadException
09-22 19:32:24.959: E/TheMesh_ChatService(17320):   at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099)
09-22 19:32:24.959: E/TheMesh_ChatService(17320):   at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:175)
09-22 19:32:24.959: E/TheMesh_ChatService(17320):   at libcore.io.IoBridge.sendto(IoBridge.java:463)
09-22 19:32:24.959: E/TheMesh_ChatService(17320):   at java.net.PlainDatagramSocketImpl.send(PlainDatagramSocketImpl.java:182)
09-22 19:32:24.959: E/TheMesh_ChatService(17320):   at java.net.DatagramSocket.send(DatagramSocket.java:287)
09-22 19:32:24.959: E/TheMesh_ChatService(17320):   at com.rpg.phg.themesh.TheMesh_ChatService$ComService.write(TheMesh_ChatService.java:146)
09-22 19:32:24.959: E/TheMesh_ChatService(17320):   at com.rpg.phg.themesh.TheMesh_ChatService.write(TheMesh_ChatService.java:69)
09-22 19:32:24.959: E/TheMesh_ChatService(17320):   at com.rpg.phg.themesh.TheMesh_PAN.sendMessage(TheMesh_PAN.java:513)
09-22 19:32:24.959: E/TheMesh_ChatService(17320):   at com.rpg.phg.themesh.TheMesh_PAN.access$11(TheMesh_PAN.java:494)
09-22 19:32:24.959: E/TheMesh_ChatService(17320):   at com.rpg.phg.themesh.TheMesh_PAN$3.onKey(TheMesh_PAN.java:264)
09-22 19:32:24.959: E/TheMesh_ChatService(17320):   at android.view.View.dispatchKeyEvent(View.java:5495)
09-22 19:32:24.959: E/TheMesh_ChatService(17320):   at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1246)
09-22 19:32:24.959: E/TheMesh_ChatService(17320):   at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1246)
09-22 19:32:24.959: E/TheMesh_ChatService(17320):   at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1246)
09-22 19:32:24.959: E/TheMesh_ChatService(17320):   at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1246)
09-22 19:32:24.959: E/TheMesh_ChatService(17320):   at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1246)
09-22 19:32:24.959: E/TheMesh_ChatService(17320):   at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1246)
09-22 19:32:24.959: E/TheMesh_ChatService(17320):   at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1879)
09-22 19:32:24.959: E/TheMesh_ChatService(17320):   at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1361)
09-22 19:32:24.959: E/TheMesh_ChatService(17320):   at android.app.Activity.dispatchKeyEvent(Activity.java:2324)
09-22 19:32:24.959: E/TheMesh_ChatService(17320):   at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1806)
09-22 19:32:24.959: E/TheMesh_ChatService(17320):   at android.view.ViewRootImpl.deliverKeyEventPostIme(ViewRootImpl.java:3327)
09-22 19:32:24.959: E/TheMesh_ChatService(17320):   at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2597)
09-22 19:32:24.959: E/TheMesh_ChatService(17320):   at android.os.Handler.dispatchMessage(Handler.java:99)
09-22 19:32:24.959: E/TheMesh_ChatService(17320):   at android.os.Looper.loop(Looper.java:137)
09-22 19:32:24.959: E/TheMesh_ChatService(17320):   at android.app.ActivityThread.main(ActivityThread.java:4424)
09-22 19:32:24.959: E/TheMesh_ChatService(17320):   at java.lang.reflect.Method.invokeNative(Native Method)
09-22 19:32:24.959: E/TheMesh_ChatService(17320):   at java.lang.reflect.Method.invoke(Method.java:511)
09-22 19:32:24.959: E/TheMesh_ChatService(17320):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
09-22 19:32:24.959: E/TheMesh_ChatService(17320):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
09-22 19:32:24.959: E/TheMesh_ChatService(17320):   at dalvik.system.NativeStart.main(Native Method)

この ICS を機能させる方法についてのアイデアはありますか (実際には、ネットワークの変更が v3+ に組み込まれているように見えるため、ハニカム以上では機能しないと思われます)。

4

2 に答える 2

1

スタックトレースがないため、100%確実ではありませんが:

のコンストラクターはComServiceメイン スレッド ( new ComService()) で実行され、既にネットワーキングを行っています。私の知る限り、ほとんどのInetAddressメソッドは名前の解決を試み、すでに「ネットワーキング」として認定されている dns ルックアップを行う可能性があるためです。キャッチする必要があることも、そのIOException強力な指標です。

コードをコンストラクターからrun()メソッドに移動してみてください。既に機能している可能性があります。

ところで:実際には、コンストラクターでネットワークや長時間実行されるタスクを実行しないでください。簡単な課題ばかり。

于 2012-09-21T12:07:41.230 に答える
-1

ここで同様の質問にすでに回答しましたが、とにかく、次のコードを oncreate() に追加すれば問題ありません

        if (android.os.Build.VERSION.SDK_INT > 9)
         {
            StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
            StrictMode.setThreadPolicy(policy);
          }
于 2012-09-21T11:59:50.440 に答える