2013-02-20 6 views
15

私は当初、サーバにデータを送信する自分のアクティビティで非同期タスクを実装しました。しかし、私が活動を変えたとき、そのつながりは失われました。この私のアプローチを回避するために、ネットワーク運用を一元化し、データをサーバーに送信し、このサービスのコードはRotator.javaが、私はこのサービスにバインド私の活動であるアクティビティの変更やサーバーへのデータの送信時にもアンドロイドクライアントをサーバーに接続しておく方法はありますか?

import java.io.BufferedWriter; 
import java.io.OutputStreamWriter; 
import java.io.PrintWriter; 
import java.net.InetAddress; 
import java.net.Socket; 

import android.app.Service; 
import android.content.Intent; 
import android.os.Binder; 
import android.os.IBinder; 
import android.util.Log; 
import android.widget.Toast; 

public class SocketService extends Service { 
    public static final String SERVERIP = ""; //your computer IP address should be written here 
    public static final int SERVERPORT = 5000; 
    PrintWriter out; 
    Socket socket; 
    InetAddress serverAddr; 

@Override 
public IBinder onBind(Intent intent) { 
    // TODO Auto-generated method stub 
    System.out.println("I am in Ibinder onBind method"); 
     return myBinder; 
} 

    private final IBinder myBinder = new LocalBinder(); 
    TCPClient mTcpClient = new TCPClient(); 

    public class LocalBinder extends Binder { 
     public SocketService getService() { 
      System.out.println("I am in Localbinder "); 
      return SocketService.this; 

     } 
    } 

    @Override 
    public void onCreate() { 
     super.onCreate(); 
     System.out.println("I am in on create");  
    } 

    public void IsBoundable(){ 
     Toast.makeText(this,"I bind like butter", Toast.LENGTH_LONG).show(); 
    } 

    public void sendMessage(String message){ 
     if (out != null && !out.checkError()) { 
      System.out.println("in sendMessage"+message); 
      out.println(message); 
      out.flush(); 
     } 
    } 

    @Override 
    public int onStartCommand(Intent intent,int flags, int startId){ 
     super.onStartCommand(intent, flags, startId); 
     System.out.println("I am in on start"); 
     // Toast.makeText(this,"Service created ...", Toast.LENGTH_LONG).show(); 
     Runnable connect = new connectSocket(); 
     new Thread(connect).start(); 
     return START_STICKY; 
    } 


    class connectSocket implements Runnable { 

     @Override 
     public void run() { 


      try { 
       //here you must put your computer's IP address. 
       serverAddr = InetAddress.getByName(SERVERIP); 
       Log.e("TCP Client", "C: Connecting..."); 
       //create a socket to make the connection with the server 

       socket = new Socket(serverAddr, SERVERPORT); 

       try { 


        //send the message to the server 
        out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true); 


        Log.e("TCP Client", "C: Sent."); 

        Log.e("TCP Client", "C: Done."); 


        } 
       catch (Exception e) { 

        Log.e("TCP", "S: Error", e); 

       } 
      } catch (Exception e) { 

       Log.e("TCP", "C: Error", e); 

      } 

     } 

    } 


    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
      try { 
       socket.close(); 
      } catch (Exception e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      socket = null; 
     } 


    } 

の下に与えられているサービスを実装することでした。以下は私の活動のコードです。このサービスはバックグラウンドで実行されて私は私が使用してサーバーにいくつかのデータを送信したい場合は、サービスがActivityにバインドされている場合は

private ServiceConnection mConnection = new ServiceConnection() { 
      //EDITED PART 
    @Override 
    public void onServiceConnected(ComponentName name, IBinder service) { 
     // TODO Auto-generated method stub 
     mBoundService = ((SocketService.LocalBinder)service).getService(); 

    } 

    @Override 
    public void onServiceDisconnected(ComponentName name) { 
     // TODO Auto-generated method stub 
     mBoundService = null; 
    } 

    }; 


    private void doBindService() { 
     bindService(new Intent(Rotator.this, SocketService.class), mConnection, Context.BIND_AUTO_CREATE); 
     mIsBound = true; 
     if(mBoundService!=null){ 
     mBoundService.IsBoundable(); 
     } 
    } 


    private void doUnbindService() { 
     if (mIsBound) { 
      // Detach our existing connection. 
      unbindService(mConnection); 
      mIsBound = false; 
     } 
    } 

@Override 
public void onCreate(Bundle savedInstanceState) 
{ 
     super.onCreate(savedInstanceState); 
     gestureDetector = new GestureDetector(this, new GestureListener()); 
     setContentView(R.layout.activity_rotator); 


     //Binding the activity to the service to perform client-server operations 
     //start service on create 
     startService(new Intent(Rotator.this,SocketService.class)); 
     doBindService(); 
        ........... 
        ........... 
} 


@Override 
protected void onDestroy() { 
    super.onDestroy(); 
    doUnbindService(); 
} 

は今、次

if(mBoundService!=null) 
{ 
    mBoundService.sendMessage("right"); 
} 

答えて

5

コードが正しいです。唯一間違っていたのは、onServiceConnected()メソッドとonCreate()メソッドで2回サービスを開始しようとしていたことです。

ランチャーアクティビティでonCreate()メソッドでのみサービスを開始するようにコードを変更しました。残りのアクティビティはdoBindService()メソッドを使用してサービスに直接バインドします

+0

あなたは自分の時間を保存しました。 – BSKANIA

+0

上記のコードは完璧ですか、上記のコードでサービスを2回開始しましたか?あなたは上記のコードを変更しましたか? startserviceメソッドを使用して1回、doBindserviceメソッドを使用して1回開始することがわかります。正しいようにしてください。私はこれを読んだ後のconnfuse –

+0

@sam_k私はサービスを開始するmainactivityでstartServiceメソッドを使用しました。残りのアクティビティは、onCreateでdoBindService()メソッドを使用するだけです。上記のコードは、正しいコードで編集されています。私はあなたの混乱を理解していない – Giz

2

、それは時に殺されますアクティビティは停止されます。そのようなサービスは、Activityのバックグラウンドサービスのようです。したがって、実行するには、ServiceクラスにonStartCommand()メソッドを実装し、this.START_STICKYを返します。この方法でサービスを管理してください。

+0

私はすでにサービスコードでそれを行っています。しかし、非同期タスクにデータを送信してサーバーに送信する方法はわかりません。 – Giz

+0

アクティビティでは、mTcpClientは常にnullです。 – Giz

+0

いいえ、 'Service'のアンドロイドのドキュメントをチェックし、' Binder'を使って 'Activity'にバインドしている場合は自動的に閉じます。それを 'Binder'から削除し、代わりにonStartCommand()で試してみてください。それが私の言うことです。 – AbdulHannan

関連する問題