MainActivity.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. using Android.App;
  2. using Android.Graphics;
  3. using Android.OS;
  4. using Android.Views;
  5. using Android.Widget;
  6. using System;
  7. using System.IO;
  8. using System.Net.Sockets;
  9. using System.Threading.Tasks;
  10. namespace ScrExtDroid
  11. {
  12. [Activity(Label = "ScrExtDroid", MainLauncher = true, Icon = "@drawable/icon")]
  13. public class MainActivity : Activity
  14. {
  15. private FlushView _view;
  16. private bool _isRunning;
  17. private string _target;
  18. private string ConfigFilePath
  19. {
  20. get
  21. {
  22. var dataPath = Application.FilesDir.AbsolutePath;
  23. if (Directory.Exists(dataPath) == false) Directory.CreateDirectory(dataPath);
  24. return System.IO.Path.Combine(dataPath, "sxd_config.txt");
  25. }
  26. }
  27. private void AskAndConnect()
  28. {
  29. EditText et = new EditText(this);
  30. et.Text = File.Exists(ConfigFilePath) ? File.ReadAllText(ConfigFilePath) : "192.168.233.233:61234";
  31. AlertDialog.Builder ad = new AlertDialog.Builder(this);
  32. ad.SetTitle("Connect");
  33. ad.SetView(et);
  34. ad.SetPositiveButton("OK", delegate
  35. {
  36. _target = et.Text;
  37. StartDisplay();
  38. });
  39. ad.SetNegativeButton("Cancel", delegate
  40. {
  41. Finish();
  42. });
  43. ad.Show();
  44. }
  45. private void StartDisplay(bool askAgainOnFail = false)
  46. {
  47. _isRunning = true;
  48. Task.Run(() =>
  49. {
  50. var client = new Socket(SocketType.Stream, ProtocolType.Tcp);
  51. try
  52. {
  53. var parts = _target.Split(':');
  54. var port = int.Parse(parts[1]);
  55. RunOnUiThread(delegate
  56. {
  57. Toast.MakeText(this, "Connecting...", ToastLength.Short).Show();
  58. });
  59. var wait = client.BeginConnect(parts[0], port, null, null);
  60. wait.AsyncWaitHandle.WaitOne(2000, true); //等待2秒
  61. if (!wait.IsCompleted) throw new TimeoutException("Time out");
  62. RunOnUiThread(delegate
  63. {
  64. Toast.MakeText(this, "Connected", ToastLength.Short).Show();
  65. });
  66. File.WriteAllText(ConfigFilePath, _target);
  67. }
  68. catch (Exception e)
  69. {
  70. RunOnUiThread(delegate
  71. {
  72. Toast.MakeText(this, "Connect fail:" + e.Message, ToastLength.Short).Show();
  73. });
  74. RunOnUiThread(delegate
  75. {
  76. if (askAgainOnFail)
  77. {
  78. AskAndConnect();
  79. }
  80. else
  81. {
  82. System.Threading.Thread.Sleep(1000);
  83. StartDisplay(true);
  84. }
  85. });
  86. return;
  87. }
  88. client.Send(new byte[1]);
  89. client.ReceiveTimeout = 1000;
  90. var ns = new NetworkStream(client);
  91. ns.ReadTimeout = 1000;
  92. var r = new BinaryReader(ns);
  93. try
  94. {
  95. do
  96. {
  97. var l = r.ReadInt32();
  98. if (l == 0)
  99. {
  100. RunOnUiThread(() => Finish());
  101. break;
  102. }
  103. var b = r.ReadBytes(l);
  104. var ms = new MemoryStream(b);
  105. var bm = BitmapFactory.DecodeStream(ms);
  106. RunOnUiThread(() => { _view.DrawBitmap(bm); });
  107. askAgainOnFail = false;
  108. } while (_isRunning);
  109. }
  110. catch (Exception e)
  111. {
  112. RunOnUiThread(delegate
  113. {
  114. Toast.MakeText(this, "Lost Connection:" + e.Message, ToastLength.Short).Show();
  115. if (askAgainOnFail)
  116. {
  117. AskAndConnect();
  118. }
  119. else
  120. {
  121. System.Threading.Thread.Sleep(1000);
  122. StartDisplay(true);
  123. }
  124. });
  125. }
  126. client.Close();
  127. });
  128. }
  129. //
  130. protected override void OnCreate(Bundle bundle)
  131. {
  132. base.OnCreate(bundle);
  133. RequestWindowFeature(WindowFeatures.NoTitle);
  134. Window.AddFlags(WindowManagerFlags.KeepScreenOn);
  135. _view = new FlushView(this);
  136. SetContentView(_view);
  137. }
  138. protected override void OnResume()
  139. {
  140. base.OnResume();
  141. AskAndConnect();
  142. }
  143. protected override void OnPause()
  144. {
  145. base.OnPause();
  146. _isRunning = false;
  147. }
  148. private class FlushView : View
  149. {
  150. private readonly MainActivity context;
  151. private Bitmap _bmp;
  152. public FlushView(MainActivity context)
  153. : base(context)
  154. {
  155. this.context = context;
  156. }
  157. public void DrawBitmap(Bitmap bmp)
  158. {
  159. _bmp = bmp;
  160. Invalidate();
  161. }
  162. public override void Draw(Canvas canvas)
  163. {
  164. var b = _bmp;
  165. if (b != null)
  166. {
  167. canvas.DrawBitmap(b, 0, 0, new Paint());
  168. _bmp = null;
  169. b.Dispose();
  170. }
  171. }
  172. }
  173. }
  174. }