├── .gitattributes
├── .gitignore
├── README.md
├── Samples
├── AndroidManifest.template.xml
├── CppNetworkStateSample.cbproj
├── CppNetworkStateSample.cpp
├── CppNetworkStateSample.deployproj
├── CppNetworkStateSamplePCH1.h
├── DelphiNetworkStateSample.deployproj
├── DelphiNetworkStateSample.dpr
├── DelphiNetworkStateSample.dproj
├── Entitlement.TemplateiOS.xml
├── FForm.fmx
├── FForm.pas
├── FFormCPP.cpp
├── FFormCPP.fmx
├── FFormCPP.h
├── Samples.groupproj
├── info.plist.TemplateiOS.xml
├── libReachability.a
└── libReachability64.a
└── Source
├── Android
├── BroadcastReceiver
│ ├── UBroadcastReceiver.pas
│ └── UNetworkStateBroadcastReceiver.pas
└── UNetworkState.Android.pas
├── UNetworkState.pas
└── iOS
├── CaptiveNetwork.pas
├── SCNetworkReachability.pas
└── UNetworkState.iOS.pas
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Don't let git change default linebreaks
2 | *.xml text eol=lf
3 | .gitattributes text eol=lf
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.local
2 | *.res
3 | *.stat
4 | *.identcache
5 | *.hpp
6 |
7 | Debug/
8 | Release/
9 |
10 | __history/
11 | __recovery/
12 | __astcache/
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # firemonkey-network-state
2 | Library for managing network state in Delphi or C++ Firemonkey apps on Android and iOS.
3 |
4 | More details can be found in the accompanying article [here](https://www.code-partners.com/internet-connectivity-state-management-in-firemonkey/)
5 |
--------------------------------------------------------------------------------
/Samples/AndroidManifest.template.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
11 | <%uses-permission%>
12 |
13 |
21 |
22 | <%application-meta-data%>
23 | <%services%>
24 |
26 |
30 |
31 |
33 |
34 |
35 |
36 |
37 |
38 | <%activity%>
39 | <%receivers%>
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/Samples/CppNetworkStateSample.cpp:
--------------------------------------------------------------------------------
1 | //---------------------------------------------------------------------------
2 |
3 | #include
4 | #ifdef _WIN32
5 | #include
6 | #endif
7 | #pragma hdrstop
8 | #include
9 | //---------------------------------------------------------------------------
10 | USEFORM("FFormCPP.cpp", FormSample);
11 | //---------------------------------------------------------------------------
12 | extern "C" int FMXmain()
13 | {
14 | try
15 | {
16 | Application->Initialize();
17 | Application->CreateForm(__classid(TFormSample), &FormSample);
18 | Application->Run();
19 | }
20 | catch (Exception &exception)
21 | {
22 | Application->ShowException(&exception);
23 | }
24 | catch (...)
25 | {
26 | try
27 | {
28 | throw Exception("");
29 | }
30 | catch (Exception &exception)
31 | {
32 | Application->ShowException(&exception);
33 | }
34 | }
35 | return 0;
36 | }
37 | //---------------------------------------------------------------------------
38 |
--------------------------------------------------------------------------------
/Samples/CppNetworkStateSample.deployproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 12
5 |
6 |
7 | ad051703c071eb11e2
8 | dc398986acabb53bce25b5f6a2661fdbf3da125b
9 | dc398986acabb53bce25b5f6a2661fdbf3da125b
10 |
11 |
12 |
13 | CppNetworkStateSample.app\
14 | Default-568h@2x.png
15 | iPhone_Launch640x1136
16 | 1
17 |
18 |
19 | True
20 |
21 |
22 | CppNetworkStateSample.app\
23 | FM_ApplicationIcon_180x180.png
24 | iPhone_AppIcon180
25 | 0
26 |
27 |
28 | True
29 |
30 |
31 | CppNetworkStateSample.app\StartUp\Documents\
32 | libReachability64.a
33 | ProjectFile
34 | 0
35 |
36 |
37 | True
38 |
39 |
40 | CppNetworkStateSample.app\
41 | FM_ApplicationIcon_57x57.png
42 | iPhone_AppIcon57
43 | 0
44 |
45 |
46 | True
47 |
48 |
49 | CppNetworkStateSample.app\
50 | FM_ApplicationIcon_144x144.png
51 | iPad_AppIcon144
52 | 0
53 |
54 |
55 | True
56 |
57 |
58 | CppNetworkStateSample.app\
59 | CppNetworkStateSample
60 | ProjectOutput
61 | 1
62 |
63 |
64 | True
65 | True
66 |
67 |
68 | CppNetworkStateSample.app\
69 | FM_ApplicationIcon_60x60.png
70 | iPhone_AppIcon60
71 | 0
72 |
73 |
74 | True
75 |
76 |
77 | CppNetworkStateSample.app\
78 | Default-667h@2x.png
79 | iPhone_Launch750
80 | 0
81 |
82 |
83 | True
84 |
85 |
86 | CppNetworkStateSample.app\
87 | FM_SettingIcon_29x29.png
88 | iPad_Setting29
89 | 0
90 |
91 |
92 | True
93 |
94 |
95 | CppNetworkStateSample.app\
96 | Default@2x.png
97 | iPhone_Launch640
98 | 1
99 |
100 |
101 | True
102 |
103 |
104 | CppNetworkStateSample.app\
105 | FM_SettingIcon_58x58.png
106 | iPad_Setting58
107 | 0
108 |
109 |
110 | True
111 |
112 |
113 | CppNetworkStateSample.app\
114 | Default.png
115 | iPhone_Launch320
116 | 1
117 |
118 |
119 | True
120 |
121 |
122 | CppNetworkStateSample.app\
123 | Default-Portrait@2x.png
124 | iPad_Launch1536
125 | 1
126 |
127 |
128 | True
129 |
130 |
131 | CppNetworkStateSample.app\
132 | FM_ApplicationIcon_72x72.png
133 | iPad_AppIcon72
134 | 0
135 |
136 |
137 | True
138 |
139 |
140 | CppNetworkStateSample.app\
141 | Default-Landscape@2x.png
142 | iPad_Launch2048
143 | 1
144 |
145 |
146 | True
147 |
148 |
149 | CppNetworkStateSample.app\
150 | FM_ApplicationIcon_120x120.png
151 | iPhone_AppIcon120
152 | 0
153 |
154 |
155 | True
156 |
157 |
158 | CppNetworkStateSample.app\
159 | Default-Portrait@2x~ipad.png
160 | iPad_Launch1536x2048
161 | 0
162 |
163 |
164 | True
165 |
166 |
167 | CppNetworkStateSample.app\
168 | FM_SpotlightSearchIcon_100x100.png
169 | iPad_SpotLight100
170 | 0
171 |
172 |
173 | True
174 |
175 |
176 | CppNetworkStateSample.app\
177 | FM_SpotlightSearchIcon_58x58.png
178 | iPhone_Spotlight58
179 | 0
180 |
181 |
182 | True
183 |
184 |
185 | CppNetworkStateSample.app\
186 | ResourceRules.plist
187 | ProjectiOSDeviceResourceRules
188 | 1
189 |
190 |
191 | True
192 |
193 |
194 | CppNetworkStateSample.app\
195 | Default~ipad.png
196 | iPad_Launch768
197 | 1
198 |
199 |
200 | True
201 |
202 |
203 | CppNetworkStateSample.app\
204 | Default-Landscape-812h@3x.png
205 | iPhone_Launch2436
206 | 0
207 |
208 |
209 | True
210 |
211 |
212 | CppNetworkStateSample.app\
213 | Default-Portrait~ipad.png
214 | iPad_Launch768x1024
215 | 0
216 |
217 |
218 | True
219 |
220 |
221 | CppNetworkStateSample.app\
222 | FM_ApplicationIcon_114x114.png
223 | iPhone_AppIcon114
224 | 0
225 |
226 |
227 | True
228 |
229 |
230 | CppNetworkStateSample.app\
231 | Info.plist
232 | ProjectiOSInfoPList
233 | 1
234 |
235 |
236 | True
237 |
238 |
239 | CppNetworkStateSample.app\
240 | FM_SpotlightSearchIcon_50x50.png
241 | iPad_SpotLight50
242 | 0
243 |
244 |
245 | True
246 |
247 |
248 | CppNetworkStateSample.app\
249 | FM_ApplicationIcon_76x76.png
250 | iPad_AppIcon76
251 | 0
252 |
253 |
254 | True
255 |
256 |
257 | CppNetworkStateSample.app\..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF\
258 | CppNetworkStateSample
259 | ProjectiOSDeviceDebug
260 | 1
261 |
262 |
263 | True
264 |
265 |
266 | CppNetworkStateSample.app\
267 | FM_SpotlightSearchIcon_80x80.png
268 | iPhone_Spotlight80
269 | 0
270 |
271 |
272 | True
273 |
274 |
275 | CppNetworkStateSample.app\
276 | FM_SpotlightSearchIcon_80x80.png
277 | iPad_SpotLight80
278 | 0
279 |
280 |
281 | True
282 |
283 |
284 | CppNetworkStateSample.app\
285 | Default-Landscape-736h@3x.png
286 | iPhone_Launch2208
287 | 0
288 |
289 |
290 | True
291 |
292 |
293 | CppNetworkStateSample.app\
294 | FM_SpotlightSearchIcon_40x40.png
295 | iPhone_Spotlight40
296 | 0
297 |
298 |
299 | True
300 |
301 |
302 | CppNetworkStateSample.app\
303 | Default-736h@3x.png
304 | iPhone_Launch1242
305 | 0
306 |
307 |
308 | True
309 |
310 |
311 | CppNetworkStateSample.app\
312 | Default-812h@3x.png
313 | iPhone_Launch1125
314 | 0
315 |
316 |
317 | True
318 |
319 |
320 | CppNetworkStateSample.app\
321 | Default-Landscape.png
322 | iPad_Launch1024
323 | 1
324 |
325 |
326 | True
327 |
328 |
329 | CppNetworkStateSample.app\
330 | FM_ApplicationIcon_152x152.png
331 | iPad_AppIcon152
332 | 0
333 |
334 |
335 | True
336 |
337 |
338 | CppNetworkStateSample.app\
339 | FM_SpotlightSearchIcon_40x40.png
340 | iPad_SpotLight40
341 | 0
342 |
343 |
344 | True
345 |
346 |
347 | CppNetworkStateSample.app\
348 | FM_ApplicationIcon_87x87.png
349 | iPhone_AppIcon87
350 | 0
351 |
352 |
353 | True
354 |
355 |
356 | CppNetworkStateSample.app\
357 | FM_SpotlightSearchIcon_29x29.png
358 | iPhone_Spotlight29
359 | 0
360 |
361 |
362 | True
363 |
364 |
365 | CppNetworkStateSample.app\..\
366 | CppNetworkStateSample.entitlements
367 | ProjectiOSEntitlements
368 | 1
369 |
370 |
371 | True
372 |
373 |
374 | CppNetworkStateSample.app\
375 | Default-Landscape@2x~ipad.png
376 | iPad_Launch2048x1536
377 | 0
378 |
379 |
380 | True
381 |
382 |
383 | CppNetworkStateSample.app\
384 | Default-Landscape~ipad.png
385 | iPad_Launch1024x768
386 | 0
387 |
388 |
389 | True
390 |
391 |
392 |
393 |
394 | CppNetworkStateSample\
395 | cc64250.dll
396 | DependencyModule
397 | 0
398 |
399 |
400 | True
401 |
402 |
403 | CppNetworkStateSample\
404 | borlndmm.dll
405 | DependencyModule
406 | 0
407 |
408 |
409 | True
410 |
411 |
412 | CppNetworkStateSample\
413 | cc64250mt.dll
414 | DependencyModule
415 | 0
416 |
417 |
418 | True
419 |
420 |
421 |
422 |
423 |
424 | CppNetworkStateSample\
425 | CppNetworkStateSample.exe
426 | ProjectOutput
427 | 0
428 |
429 |
430 | True
431 | True
432 |
433 |
434 | CppNetworkStateSample\
435 | borlndmm.dll
436 | DependencyModule
437 | 0
438 |
439 |
440 | True
441 |
442 |
443 | CppNetworkStateSample\
444 | cc32250.dll
445 | DependencyModule
446 | 0
447 |
448 |
449 | True
450 |
451 |
452 | CppNetworkStateSample\
453 | cc32250mt.dll
454 | DependencyModule
455 | 0
456 |
457 |
458 | True
459 |
460 |
461 | CppNetworkStateSample\
462 | cc32c250mt.dll
463 | DependencyModule
464 | 0
465 |
466 |
467 | True
468 |
469 |
470 | CppNetworkStateSample\
471 | cc32c250.dll
472 | DependencyModule
473 | 0
474 |
475 |
476 | True
477 |
478 |
479 |
480 |
481 | CppNetworkStateSample.app\Contents\MacOS\
482 | libcgstl.dylib
483 | DependencyModule
484 | 1
485 |
486 |
487 | True
488 |
489 |
490 | CppNetworkStateSample.app\Contents\MacOS\
491 | libcgsqlite3.dylib
492 | DependencyModule
493 | 1
494 |
495 |
496 | True
497 |
498 |
499 | CppNetworkStateSample.app\Contents\MacOS\
500 | libcgunwind.1.0.dylib
501 | DependencyModule
502 | 1
503 |
504 |
505 | True
506 |
507 |
508 | CppNetworkStateSample.app\Contents\MacOS\
509 | libcgcrtl.dylib
510 | DependencyModule
511 | 1
512 |
513 |
514 | True
515 |
516 |
517 |
518 |
519 | CppNetworkStateSample\res\drawable-ldpi\
520 | ic_launcher.png
521 | Android_LauncherIcon36
522 | 1
523 |
524 |
525 | True
526 |
527 |
528 | CppNetworkStateSample\res\drawable-hdpi\
529 | ic_launcher.png
530 | Android_LauncherIcon72
531 | 1
532 |
533 |
534 | True
535 |
536 |
537 | CppNetworkStateSample\res\drawable-small\
538 | splash_image.png
539 | Android_SplashImage426
540 | 1
541 |
542 |
543 | True
544 |
545 |
546 | CppNetworkStateSample\library\lib\mips\
547 | libAndroidCppNetworkStateSample.so
548 | AndroidLibnativeMipsFile
549 | 1
550 |
551 |
552 | True
553 |
554 |
555 | CppNetworkStateSample\res\drawable-xxhdpi\
556 | ic_launcher.png
557 | Android_LauncherIcon144
558 | 1
559 |
560 |
561 | True
562 |
563 |
564 | CppNetworkStateSample\library\lib\armeabi\
565 | libAndroidCppNetworkStateSample.so
566 | AndroidLibnativeArmeabiFile
567 | 1
568 |
569 |
570 | True
571 |
572 |
573 | CppNetworkStateSample\res\values\
574 | styles.xml
575 | AndroidSplashStyles
576 | 1
577 |
578 |
579 | True
580 |
581 |
582 | CppNetworkStateSample\res\drawable-xhdpi\
583 | ic_launcher.png
584 | Android_LauncherIcon96
585 | 1
586 |
587 |
588 | True
589 |
590 |
591 | CppNetworkStateSample\
592 | AndroidManifest.xml
593 | ProjectAndroidManifest
594 | 1
595 |
596 |
597 | True
598 |
599 |
600 | CppNetworkStateSample\library\lib\armeabi-v7a\
601 | libCppNetworkStateSample.so
602 | ProjectOutput
603 | 1
604 |
605 |
606 | True
607 | True
608 |
609 |
610 | CppNetworkStateSample\res\drawable-large\
611 | splash_image.png
612 | Android_SplashImage640
613 | 1
614 |
615 |
616 | True
617 |
618 |
619 | CppNetworkStateSample\res\drawable-xlarge\
620 | splash_image.png
621 | Android_SplashImage960
622 | 1
623 |
624 |
625 | True
626 |
627 |
628 | CppNetworkStateSample\res\drawable\
629 | splash_image_def.xml
630 | AndroidSplashImageDef
631 | 1
632 |
633 |
634 | True
635 |
636 |
637 | CppNetworkStateSample\res\drawable-mdpi\
638 | ic_launcher.png
639 | Android_LauncherIcon48
640 | 1
641 |
642 |
643 | True
644 |
645 |
646 | CppNetworkStateSample\library\lib\armeabi-v7a\
647 | gdbserver
648 | AndroidGDBServer
649 | 1
650 |
651 |
652 | True
653 |
654 |
655 | CppNetworkStateSample\res\drawable-normal\
656 | splash_image.png
657 | Android_SplashImage470
658 | 1
659 |
660 |
661 | True
662 |
663 |
664 | CppNetworkStateSample\classes\
665 | classes.dex
666 | AndroidClassesDexFile
667 | 1
668 |
669 |
670 | True
671 |
672 |
673 | CppNetworkStateSample\assets\internal\
674 | libReachability64.a
675 | ProjectFile
676 | 0
677 |
678 |
679 | True
680 |
681 |
682 |
683 |
684 | CppNetworkStateSample.app\
685 | libcgunwind.1.0.dylib
686 | DependencyModule
687 | 1
688 |
689 |
690 | True
691 |
692 |
693 | CppNetworkStateSample.app\
694 | libPCRE.dylib
695 | DependencyModule
696 | 1
697 |
698 |
699 | True
700 |
701 |
702 |
703 |
--------------------------------------------------------------------------------
/Samples/CppNetworkStateSamplePCH1.h:
--------------------------------------------------------------------------------
1 | #include
2 | #ifdef _WIN32
3 | #include
4 | #endif
5 |
6 |
--------------------------------------------------------------------------------
/Samples/DelphiNetworkStateSample.deployproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 12
5 |
6 |
7 | ad051703c071eb11e2
8 | dc398986acabb53bce25b5f6a2661fdbf3da125b
9 | 03710820612b5ae95f0699fa6cdd35b5658bc656
10 | 6F516E0B-AB13-4A53-9AC0-6502F57376A6
11 |
12 |
13 |
14 | DelphiNetworkStateSample.app\
15 | Default-568h@2x.png
16 | iPhone_Launch640x1136
17 | 1
18 |
19 |
20 | True
21 |
22 |
23 | DelphiNetworkStateSample.app\
24 | FM_ApplicationIcon_144x144.png
25 | iPad_AppIcon144
26 | 0
27 |
28 |
29 | True
30 |
31 |
32 | DelphiNetworkStateSample.app\
33 | FM_ApplicationIcon_57x57.png
34 | iPhone_AppIcon57
35 | 0
36 |
37 |
38 | True
39 |
40 |
41 | DelphiNetworkStateSample.app\
42 | Default-667h@2x.png
43 | iPhone_Launch750
44 | 0
45 |
46 |
47 | True
48 |
49 |
50 | DelphiNetworkStateSample.app\
51 | Default@2x.png
52 | iPhone_Launch640
53 | 1
54 |
55 |
56 | True
57 |
58 |
59 | DelphiNetworkStateSample.app\
60 | Default-Portrait@2x.png
61 | iPad_Launch1536
62 | 1
63 |
64 |
65 | True
66 |
67 |
68 | DelphiNetworkStateSample.app\
69 | Default.png
70 | iPhone_Launch320
71 | 1
72 |
73 |
74 | True
75 |
76 |
77 | DelphiNetworkStateSample.app\
78 | FM_ApplicationIcon_120x120.png
79 | iPhone_AppIcon120
80 | 0
81 |
82 |
83 | True
84 |
85 |
86 | DelphiNetworkStateSample.app\
87 | Default~ipad.png
88 | iPad_Launch768
89 | 1
90 |
91 |
92 | True
93 |
94 |
95 | DelphiNetworkStateSample.app\
96 | FM_SpotlightSearchIcon_50x50.png
97 | iPad_SpotLight50
98 | 0
99 |
100 |
101 | True
102 |
103 |
104 | DelphiNetworkStateSample.app\
105 | FM_ApplicationIcon_76x76.png
106 | iPad_AppIcon76
107 | 0
108 |
109 |
110 | True
111 |
112 |
113 | DelphiNetworkStateSample.app\
114 | FM_SpotlightSearchIcon_80x80.png
115 | iPad_SpotLight80
116 | 0
117 |
118 |
119 | True
120 |
121 |
122 | DelphiNetworkStateSample.app\
123 | FM_SpotlightSearchIcon_40x40.png
124 | iPhone_Spotlight40
125 | 0
126 |
127 |
128 | True
129 |
130 |
131 | DelphiNetworkStateSample.app\
132 | Default-736h@3x.png
133 | iPhone_Launch1242
134 | 0
135 |
136 |
137 | True
138 |
139 |
140 | DelphiNetworkStateSample.app\
141 | FM_SpotlightSearchIcon_40x40.png
142 | iPad_SpotLight40
143 | 0
144 |
145 |
146 | True
147 |
148 |
149 | DelphiNetworkStateSample.app\
150 | FM_ApplicationIcon_180x180.png
151 | iPhone_AppIcon180
152 | 0
153 |
154 |
155 | True
156 |
157 |
158 | DelphiNetworkStateSample.app\
159 | FM_ApplicationIcon_60x60.png
160 | iPhone_AppIcon60
161 | 0
162 |
163 |
164 | True
165 |
166 |
167 | DelphiNetworkStateSample.app\
168 | FM_SettingIcon_29x29.png
169 | iPad_Setting29
170 | 0
171 |
172 |
173 | True
174 |
175 |
176 | DelphiNetworkStateSample.app\
177 | FM_SettingIcon_58x58.png
178 | iPad_Setting58
179 | 0
180 |
181 |
182 | True
183 |
184 |
185 | DelphiNetworkStateSample.app\
186 | Info.plist
187 | ProjectiOSInfoPList
188 | 1
189 |
190 |
191 | True
192 |
193 |
194 | DelphiNetworkStateSample.app\
195 | FM_ApplicationIcon_72x72.png
196 | iPad_AppIcon72
197 | 0
198 |
199 |
200 | True
201 |
202 |
203 | DelphiNetworkStateSample.app\
204 | Default-Portrait@2x~ipad.png
205 | iPad_Launch1536x2048
206 | 0
207 |
208 |
209 | True
210 |
211 |
212 | DelphiNetworkStateSample.app\
213 | Default-Landscape@2x.png
214 | iPad_Launch2048
215 | 1
216 |
217 |
218 | True
219 |
220 |
221 | DelphiNetworkStateSample.app\
222 | FM_SpotlightSearchIcon_100x100.png
223 | iPad_SpotLight100
224 | 0
225 |
226 |
227 | True
228 |
229 |
230 | DelphiNetworkStateSample.app\
231 | FM_SpotlightSearchIcon_58x58.png
232 | iPhone_Spotlight58
233 | 0
234 |
235 |
236 | True
237 |
238 |
239 | DelphiNetworkStateSample.app\..\
240 | DelphiNetworkStateSample.entitlements
241 | ProjectiOSEntitlements
242 | 1
243 |
244 |
245 | True
246 |
247 |
248 | DelphiNetworkStateSample.app\
249 | Default-Landscape-812h@3x.png
250 | iPhone_Launch2436
251 | 0
252 |
253 |
254 | True
255 |
256 |
257 | DelphiNetworkStateSample.app\
258 | Default-Portrait~ipad.png
259 | iPad_Launch768x1024
260 | 0
261 |
262 |
263 | True
264 |
265 |
266 | DelphiNetworkStateSample.app\
267 | FM_ApplicationIcon_114x114.png
268 | iPhone_AppIcon114
269 | 0
270 |
271 |
272 | True
273 |
274 |
275 | DelphiNetworkStateSample.app\
276 | DelphiNetworkStateSample
277 | ProjectOutput
278 | 1
279 |
280 |
281 | True
282 | True
283 |
284 |
285 | DelphiNetworkStateSample.app\
286 | FM_SpotlightSearchIcon_80x80.png
287 | iPhone_Spotlight80
288 | 0
289 |
290 |
291 | True
292 |
293 |
294 | DelphiNetworkStateSample.app\
295 | Default-Landscape-736h@3x.png
296 | iPhone_Launch2208
297 | 0
298 |
299 |
300 | True
301 |
302 |
303 | DelphiNetworkStateSample.app\
304 | Default-812h@3x.png
305 | iPhone_Launch1125
306 | 0
307 |
308 |
309 | True
310 |
311 |
312 | DelphiNetworkStateSample.app\
313 | Default-Landscape.png
314 | iPad_Launch1024
315 | 1
316 |
317 |
318 | True
319 |
320 |
321 | DelphiNetworkStateSample.app\..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF\
322 | DelphiNetworkStateSample
323 | ProjectiOSDeviceDebug
324 | 1
325 |
326 |
327 | True
328 |
329 |
330 | DelphiNetworkStateSample.app\
331 | FM_ApplicationIcon_152x152.png
332 | iPad_AppIcon152
333 | 0
334 |
335 |
336 | True
337 |
338 |
339 | DelphiNetworkStateSample.app\
340 | FM_ApplicationIcon_87x87.png
341 | iPhone_AppIcon87
342 | 0
343 |
344 |
345 | True
346 |
347 |
348 | DelphiNetworkStateSample.app\
349 | FM_SpotlightSearchIcon_29x29.png
350 | iPhone_Spotlight29
351 | 0
352 |
353 |
354 | True
355 |
356 |
357 | DelphiNetworkStateSample.app\
358 | ResourceRules.plist
359 | ProjectiOSDeviceResourceRules
360 | 1
361 |
362 |
363 | True
364 |
365 |
366 | DelphiNetworkStateSample.app\
367 | Default-Landscape@2x~ipad.png
368 | iPad_Launch2048x1536
369 | 0
370 |
371 |
372 | True
373 |
374 |
375 | DelphiNetworkStateSample.app\
376 | Default-Landscape~ipad.png
377 | iPad_Launch1024x768
378 | 0
379 |
380 |
381 | True
382 |
383 |
384 |
385 |
386 |
387 | DelphiNetworkStateSample.app\
388 | FM_ApplicationIcon_87x87.png
389 | iPhone_AppIcon87
390 | 0
391 |
392 |
393 | True
394 |
395 |
396 | DelphiNetworkStateSample.app\
397 | FM_ApplicationIcon_72x72.png
398 | iPad_AppIcon72
399 | 0
400 |
401 |
402 | True
403 |
404 |
405 | DelphiNetworkStateSample.app\
406 | FM_SpotlightSearchIcon_100x100.png
407 | iPad_SpotLight100
408 | 0
409 |
410 |
411 | True
412 |
413 |
414 | DelphiNetworkStateSample.app\
415 | Default-Landscape-736h@3x.png
416 | iPhone_Launch2208
417 | 0
418 |
419 |
420 | True
421 |
422 |
423 | DelphiNetworkStateSample.app\
424 | Default-Portrait@2x~ipad.png
425 | iPad_Launch1536x2048
426 | 0
427 |
428 |
429 | True
430 |
431 |
432 | DelphiNetworkStateSample.app\
433 | Default-Portrait@2x.png
434 | iPad_Launch1536
435 | 1
436 |
437 |
438 | True
439 |
440 |
441 | DelphiNetworkStateSample.app\
442 | Default.png
443 | iPhone_Launch320
444 | 1
445 |
446 |
447 | True
448 |
449 |
450 | DelphiNetworkStateSample.app\
451 | FM_SpotlightSearchIcon_80x80.png
452 | iPhone_Spotlight80
453 | 0
454 |
455 |
456 | True
457 |
458 |
459 | DelphiNetworkStateSample.app\
460 | Default~ipad.png
461 | iPad_Launch768
462 | 1
463 |
464 |
465 | True
466 |
467 |
468 | DelphiNetworkStateSample.app\..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF\
469 | DelphiNetworkStateSample
470 | ProjectiOSDeviceDebug
471 | 1
472 |
473 |
474 | True
475 |
476 |
477 | DelphiNetworkStateSample.app\
478 | Default-667h@2x.png
479 | iPhone_Launch750
480 | 0
481 |
482 |
483 | True
484 |
485 |
486 | DelphiNetworkStateSample.app\
487 | FM_ApplicationIcon_152x152.png
488 | iPad_AppIcon152
489 | 0
490 |
491 |
492 | True
493 |
494 |
495 | DelphiNetworkStateSample.app\
496 | Default-Landscape-812h@3x.png
497 | iPhone_Launch2436
498 | 0
499 |
500 |
501 | True
502 |
503 |
504 | DelphiNetworkStateSample.app\..\
505 | DelphiNetworkStateSample.entitlements
506 | ProjectiOSEntitlements
507 | 1
508 |
509 |
510 | True
511 |
512 |
513 | DelphiNetworkStateSample.app\
514 | Default-Portrait~ipad.png
515 | iPad_Launch768x1024
516 | 0
517 |
518 |
519 | True
520 |
521 |
522 | DelphiNetworkStateSample.app\
523 | Info.plist
524 | ProjectiOSInfoPList
525 | 1
526 |
527 |
528 | True
529 |
530 |
531 | DelphiNetworkStateSample.app\
532 | FM_ApplicationIcon_120x120.png
533 | iPhone_AppIcon120
534 | 0
535 |
536 |
537 | True
538 |
539 |
540 | DelphiNetworkStateSample.app\
541 | FM_SpotlightSearchIcon_40x40.png
542 | iPad_SpotLight40
543 | 0
544 |
545 |
546 | True
547 |
548 |
549 | DelphiNetworkStateSample.app\
550 | FM_SpotlightSearchIcon_80x80.png
551 | iPad_SpotLight80
552 | 0
553 |
554 |
555 | True
556 |
557 |
558 | DelphiNetworkStateSample.app\
559 | FM_ApplicationIcon_57x57.png
560 | iPhone_AppIcon57
561 | 0
562 |
563 |
564 | True
565 |
566 |
567 | DelphiNetworkStateSample.app\
568 | ResourceRules.plist
569 | ProjectiOSDeviceResourceRules
570 | 1
571 |
572 |
573 | True
574 |
575 |
576 | DelphiNetworkStateSample.app\
577 | FM_SpotlightSearchIcon_29x29.png
578 | iPhone_Spotlight29
579 | 0
580 |
581 |
582 | True
583 |
584 |
585 | DelphiNetworkStateSample.app\
586 | Default-568h@2x.png
587 | iPhone_Launch640x1136
588 | 1
589 |
590 |
591 | True
592 |
593 |
594 | DelphiNetworkStateSample.app\
595 | Default-812h@3x.png
596 | iPhone_Launch1125
597 | 0
598 |
599 |
600 | True
601 |
602 |
603 | DelphiNetworkStateSample.app\
604 | Default-Landscape@2x.png
605 | iPad_Launch2048
606 | 1
607 |
608 |
609 | True
610 |
611 |
612 | DelphiNetworkStateSample.app\
613 | FM_SpotlightSearchIcon_40x40.png
614 | iPhone_Spotlight40
615 | 0
616 |
617 |
618 | True
619 |
620 |
621 | DelphiNetworkStateSample.app\
622 | FM_SpotlightSearchIcon_50x50.png
623 | iPad_SpotLight50
624 | 0
625 |
626 |
627 | True
628 |
629 |
630 | DelphiNetworkStateSample.app\
631 | Default@2x.png
632 | iPhone_Launch640
633 | 1
634 |
635 |
636 | True
637 |
638 |
639 | DelphiNetworkStateSample.app\
640 | FM_ApplicationIcon_144x144.png
641 | iPad_AppIcon144
642 | 0
643 |
644 |
645 | True
646 |
647 |
648 | DelphiNetworkStateSample.app\
649 | Default-Landscape@2x~ipad.png
650 | iPad_Launch2048x1536
651 | 0
652 |
653 |
654 | True
655 |
656 |
657 | DelphiNetworkStateSample.app\
658 | FM_SettingIcon_58x58.png
659 | iPad_Setting58
660 | 0
661 |
662 |
663 | True
664 |
665 |
666 | DelphiNetworkStateSample.app\
667 | DelphiNetworkStateSample
668 | ProjectOutput
669 | 1
670 |
671 |
672 | True
673 | True
674 |
675 |
676 | DelphiNetworkStateSample.app\
677 | Default-736h@3x.png
678 | iPhone_Launch1242
679 | 0
680 |
681 |
682 | True
683 |
684 |
685 | DelphiNetworkStateSample.app\
686 | FM_SpotlightSearchIcon_58x58.png
687 | iPhone_Spotlight58
688 | 0
689 |
690 |
691 | True
692 |
693 |
694 | DelphiNetworkStateSample.app\
695 | FM_ApplicationIcon_114x114.png
696 | iPhone_AppIcon114
697 | 0
698 |
699 |
700 | True
701 |
702 |
703 | DelphiNetworkStateSample.app\
704 | FM_ApplicationIcon_180x180.png
705 | iPhone_AppIcon180
706 | 0
707 |
708 |
709 | True
710 |
711 |
712 | DelphiNetworkStateSample.app\
713 | FM_ApplicationIcon_60x60.png
714 | iPhone_AppIcon60
715 | 0
716 |
717 |
718 | True
719 |
720 |
721 | DelphiNetworkStateSample.app\
722 | FM_SettingIcon_29x29.png
723 | iPad_Setting29
724 | 0
725 |
726 |
727 | True
728 |
729 |
730 | DelphiNetworkStateSample.app\
731 | Default-Landscape~ipad.png
732 | iPad_Launch1024x768
733 | 0
734 |
735 |
736 | True
737 |
738 |
739 | DelphiNetworkStateSample.app\
740 | Default-Landscape.png
741 | iPad_Launch1024
742 | 1
743 |
744 |
745 | True
746 |
747 |
748 | DelphiNetworkStateSample.app\
749 | FM_ApplicationIcon_76x76.png
750 | iPad_AppIcon76
751 | 0
752 |
753 |
754 | True
755 |
756 |
757 |
758 |
759 | DelphiNetworkStateSample\
760 | DelphiNetworkStateSample.exe
761 | ProjectOutput
762 | 0
763 |
764 |
765 | True
766 | True
767 |
768 |
769 |
770 |
771 |
772 | DelphiNetworkStateSample.app\Contents\MacOS\
773 | libcgsqlite3.dylib
774 | DependencyModule
775 | 1
776 |
777 |
778 | True
779 |
780 |
781 | DelphiNetworkStateSample.app\Contents\MacOS\
782 | libcgunwind.1.0.dylib
783 | DependencyModule
784 | 1
785 |
786 |
787 | True
788 |
789 |
790 |
791 |
792 | DelphiNetworkStateSample\res\drawable-small\
793 | splash_image.png
794 | Android_SplashImage426
795 | 1
796 |
797 |
798 | True
799 |
800 |
801 | DelphiNetworkStateSample\res\drawable\
802 | splash_image_def.xml
803 | AndroidSplashImageDef
804 | 1
805 |
806 |
807 | True
808 |
809 |
810 | DelphiNetworkStateSample\library\lib\armeabi-v7a\
811 | libDelphiNetworkStateSample.so
812 | ProjectOutput
813 | 1
814 |
815 |
816 | True
817 | True
818 |
819 |
820 | DelphiNetworkStateSample\res\drawable-large\
821 | splash_image.png
822 | Android_SplashImage640
823 | 1
824 |
825 |
826 | True
827 |
828 |
829 | DelphiNetworkStateSample\res\drawable-mdpi\
830 | ic_launcher.png
831 | Android_LauncherIcon48
832 | 1
833 |
834 |
835 | True
836 |
837 |
838 | DelphiNetworkStateSample\classes\
839 | classes.dex
840 | AndroidClassesDexFile
841 | 1
842 |
843 |
844 | True
845 |
846 |
847 | DelphiNetworkStateSample\res\values\
848 | styles.xml
849 | AndroidSplashStyles
850 | 1
851 |
852 |
853 | True
854 |
855 |
856 | DelphiNetworkStateSample\res\drawable-ldpi\
857 | ic_launcher.png
858 | Android_LauncherIcon36
859 | 1
860 |
861 |
862 | True
863 |
864 |
865 | DelphiNetworkStateSample\res\drawable-hdpi\
866 | ic_launcher.png
867 | Android_LauncherIcon72
868 | 1
869 |
870 |
871 | True
872 |
873 |
874 | DelphiNetworkStateSample\library\lib\mips\
875 | libAndroidDelphiNetworkStateSample.so
876 | AndroidLibnativeMipsFile
877 | 1
878 |
879 |
880 | True
881 |
882 |
883 | DelphiNetworkStateSample\
884 | AndroidManifest.xml
885 | ProjectAndroidManifest
886 | 1
887 |
888 |
889 | True
890 |
891 |
892 | DelphiNetworkStateSample\library\lib\armeabi\
893 | libAndroidDelphiNetworkStateSample.so
894 | AndroidLibnativeArmeabiFile
895 | 1
896 |
897 |
898 | True
899 |
900 |
901 | DelphiNetworkStateSample\res\drawable-xxhdpi\
902 | ic_launcher.png
903 | Android_LauncherIcon144
904 | 1
905 |
906 |
907 | True
908 |
909 |
910 | DelphiNetworkStateSample\res\drawable-xhdpi\
911 | ic_launcher.png
912 | Android_LauncherIcon96
913 | 1
914 |
915 |
916 | True
917 |
918 |
919 | DelphiNetworkStateSample\res\drawable-xlarge\
920 | splash_image.png
921 | Android_SplashImage960
922 | 1
923 |
924 |
925 | True
926 |
927 |
928 | DelphiNetworkStateSample\library\lib\armeabi-v7a\
929 | gdbserver
930 | AndroidGDBServer
931 | 1
932 |
933 |
934 | True
935 |
936 |
937 | DelphiNetworkStateSample\res\drawable-normal\
938 | splash_image.png
939 | Android_SplashImage470
940 | 1
941 |
942 |
943 | True
944 |
945 |
946 |
947 |
948 | DelphiNetworkStateSample.app\
949 | FM_ApplicationIcon_144x144.png
950 | iPad_AppIcon144
951 | 0
952 |
953 |
954 | True
955 |
956 |
957 | DelphiNetworkStateSample.app\
958 | FM_SpotlightSearchIcon_100x100.png
959 | iPad_SpotLight100
960 | 0
961 |
962 |
963 | True
964 |
965 |
966 | DelphiNetworkStateSample.app\
967 | FM_SpotlightSearchIcon_58x58.png
968 | iPhone_Spotlight58
969 | 0
970 |
971 |
972 | True
973 |
974 |
975 | DelphiNetworkStateSample.app\
976 | FM_ApplicationIcon_114x114.png
977 | iPhone_AppIcon114
978 | 0
979 |
980 |
981 | True
982 |
983 |
984 | DelphiNetworkStateSample.app\
985 | FM_ApplicationIcon_152x152.png
986 | iPad_AppIcon152
987 | 0
988 |
989 |
990 | True
991 |
992 |
993 | DelphiNetworkStateSample.app\
994 | Default-667h@2x.png
995 | iPhone_Launch750
996 | 0
997 |
998 |
999 | True
1000 |
1001 |
1002 | DelphiNetworkStateSample.app\
1003 | FM_ApplicationIcon_72x72.png
1004 | iPad_AppIcon72
1005 | 0
1006 |
1007 |
1008 | True
1009 |
1010 |
1011 | DelphiNetworkStateSample.app\
1012 | libcgunwind.1.0.dylib
1013 | DependencyModule
1014 | 1
1015 |
1016 |
1017 | True
1018 |
1019 |
1020 | DelphiNetworkStateSample.app\
1021 | Default-Portrait~ipad.png
1022 | iPad_Launch768x1024
1023 | 0
1024 |
1025 |
1026 | True
1027 |
1028 |
1029 | DelphiNetworkStateSample.app\
1030 | Default@2x.png
1031 | iPhone_Launch640
1032 | 1
1033 |
1034 |
1035 | True
1036 |
1037 |
1038 | DelphiNetworkStateSample.app\
1039 | FM_SpotlightSearchIcon_40x40.png
1040 | iPhone_Spotlight40
1041 | 0
1042 |
1043 |
1044 | True
1045 |
1046 |
1047 | DelphiNetworkStateSample.app\
1048 | Default-Landscape-812h@3x.png
1049 | iPhone_Launch2436
1050 | 0
1051 |
1052 |
1053 | True
1054 |
1055 |
1056 | DelphiNetworkStateSample.app\
1057 | FM_ApplicationIcon_87x87.png
1058 | iPhone_AppIcon87
1059 | 0
1060 |
1061 |
1062 | True
1063 |
1064 |
1065 | DelphiNetworkStateSample.app\
1066 | Default.png
1067 | iPhone_Launch320
1068 | 1
1069 |
1070 |
1071 | True
1072 |
1073 |
1074 | DelphiNetworkStateSample.app\
1075 | FM_ApplicationIcon_180x180.png
1076 | iPhone_AppIcon180
1077 | 0
1078 |
1079 |
1080 | True
1081 |
1082 |
1083 | DelphiNetworkStateSample.app\
1084 | FM_SettingIcon_58x58.png
1085 | iPad_Setting58
1086 | 0
1087 |
1088 |
1089 | True
1090 |
1091 |
1092 | DelphiNetworkStateSample.app\
1093 | FM_SpotlightSearchIcon_80x80.png
1094 | iPhone_Spotlight80
1095 | 0
1096 |
1097 |
1098 | True
1099 |
1100 |
1101 | DelphiNetworkStateSample.app\
1102 | FM_SpotlightSearchIcon_80x80.png
1103 | iPad_SpotLight80
1104 | 0
1105 |
1106 |
1107 | True
1108 |
1109 |
1110 | DelphiNetworkStateSample.app\
1111 | Default-Portrait@2x~ipad.png
1112 | iPad_Launch1536x2048
1113 | 0
1114 |
1115 |
1116 | True
1117 |
1118 |
1119 | DelphiNetworkStateSample.app\
1120 | FM_ApplicationIcon_120x120.png
1121 | iPhone_AppIcon120
1122 | 0
1123 |
1124 |
1125 | True
1126 |
1127 |
1128 | DelphiNetworkStateSample.app\
1129 | FM_SpotlightSearchIcon_50x50.png
1130 | iPad_SpotLight50
1131 | 0
1132 |
1133 |
1134 | True
1135 |
1136 |
1137 | DelphiNetworkStateSample.app\
1138 | Default-568h@2x.png
1139 | iPhone_Launch640x1136
1140 | 1
1141 |
1142 |
1143 | True
1144 |
1145 |
1146 | DelphiNetworkStateSample.app\
1147 | Default-Landscape.png
1148 | iPad_Launch1024
1149 | 1
1150 |
1151 |
1152 | True
1153 |
1154 |
1155 | DelphiNetworkStateSample.app\
1156 | Default-812h@3x.png
1157 | iPhone_Launch1125
1158 | 0
1159 |
1160 |
1161 | True
1162 |
1163 |
1164 | DelphiNetworkStateSample.app\
1165 | FM_SpotlightSearchIcon_40x40.png
1166 | iPad_SpotLight40
1167 | 0
1168 |
1169 |
1170 | True
1171 |
1172 |
1173 | DelphiNetworkStateSample.app\
1174 | FM_ApplicationIcon_60x60.png
1175 | iPhone_AppIcon60
1176 | 0
1177 |
1178 |
1179 | True
1180 |
1181 |
1182 | DelphiNetworkStateSample.app\
1183 | Default-Portrait@2x.png
1184 | iPad_Launch1536
1185 | 1
1186 |
1187 |
1188 | True
1189 |
1190 |
1191 | DelphiNetworkStateSample.app\
1192 | Default-736h@3x.png
1193 | iPhone_Launch1242
1194 | 0
1195 |
1196 |
1197 | True
1198 |
1199 |
1200 | DelphiNetworkStateSample.app\
1201 | Default~ipad.png
1202 | iPad_Launch768
1203 | 1
1204 |
1205 |
1206 | True
1207 |
1208 |
1209 | DelphiNetworkStateSample.app\
1210 | Info.plist
1211 | ProjectiOSInfoPList
1212 | 1
1213 |
1214 |
1215 | True
1216 |
1217 |
1218 | DelphiNetworkStateSample.app\
1219 | DelphiNetworkStateSample
1220 | ProjectOutput
1221 | 1
1222 |
1223 |
1224 | True
1225 | True
1226 |
1227 |
1228 | DelphiNetworkStateSample.app\
1229 | Default-Landscape@2x~ipad.png
1230 | iPad_Launch2048x1536
1231 | 0
1232 |
1233 |
1234 | True
1235 |
1236 |
1237 | DelphiNetworkStateSample.app\
1238 | DelphiNetworkStateSample.rsm
1239 | DebugSymbols
1240 | 1
1241 |
1242 |
1243 | True
1244 |
1245 |
1246 | DelphiNetworkStateSample.app\
1247 | Default-Landscape~ipad.png
1248 | iPad_Launch1024x768
1249 | 0
1250 |
1251 |
1252 | True
1253 |
1254 |
1255 | DelphiNetworkStateSample.app\
1256 | FM_ApplicationIcon_76x76.png
1257 | iPad_AppIcon76
1258 | 0
1259 |
1260 |
1261 | True
1262 |
1263 |
1264 | DelphiNetworkStateSample.app\
1265 | libPCRE.dylib
1266 | DependencyModule
1267 | 1
1268 |
1269 |
1270 | True
1271 |
1272 |
1273 | DelphiNetworkStateSample.app\
1274 | Default-Landscape-736h@3x.png
1275 | iPhone_Launch2208
1276 | 0
1277 |
1278 |
1279 | True
1280 |
1281 |
1282 | DelphiNetworkStateSample.app\
1283 | FM_ApplicationIcon_57x57.png
1284 | iPhone_AppIcon57
1285 | 0
1286 |
1287 |
1288 | True
1289 |
1290 |
1291 | DelphiNetworkStateSample.app\
1292 | Default-Landscape@2x.png
1293 | iPad_Launch2048
1294 | 1
1295 |
1296 |
1297 | True
1298 |
1299 |
1300 | DelphiNetworkStateSample.app\
1301 | DelphiNetworkStateSample.entitlements
1302 | ProjectiOSEntitlements
1303 | 0
1304 |
1305 |
1306 | True
1307 |
1308 |
1309 | DelphiNetworkStateSample.app\
1310 | FM_SpotlightSearchIcon_29x29.png
1311 | iPhone_Spotlight29
1312 | 0
1313 |
1314 |
1315 | True
1316 |
1317 |
1318 | DelphiNetworkStateSample.app\
1319 | FM_SettingIcon_29x29.png
1320 | iPad_Setting29
1321 | 0
1322 |
1323 |
1324 | True
1325 |
1326 |
1327 |
1328 |
--------------------------------------------------------------------------------
/Samples/DelphiNetworkStateSample.dpr:
--------------------------------------------------------------------------------
1 | program DelphiNetworkStateSample;
2 |
3 | uses
4 | System.StartUpCopy,
5 | FMX.Forms,
6 | FForm in 'FForm.pas' {FormSample},
7 | UNetworkState in '..\Source\UNetworkState.pas',
8 | UBroadcastReceiver in '..\Source\Android\BroadcastReceiver\UBroadcastReceiver.pas',
9 | UNetworkStateBroadcastReceiver in '..\Source\Android\BroadcastReceiver\UNetworkStateBroadcastReceiver.pas',
10 | UNetworkState.Android in '..\Source\Android\UNetworkState.Android.pas',
11 | CaptiveNetwork in '..\Source\iOS\CaptiveNetwork.pas',
12 | SCNetworkReachability in '..\Source\iOS\SCNetworkReachability.pas',
13 | UNetworkState.iOS in '..\Source\iOS\UNetworkState.iOS.pas';
14 |
15 | {$R *.res}
16 |
17 | begin
18 | Application.Initialize;
19 | Application.CreateForm(TFormSample, FormSample);
20 | Application.Run;
21 | end.
22 |
--------------------------------------------------------------------------------
/Samples/Entitlement.TemplateiOS.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | <%getTaskAllowKey%>
6 | <%applicationIdentifier%>
7 | <%pushNotificationKey%>
8 | <%keychainAccessGroups%>
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Samples/FForm.fmx:
--------------------------------------------------------------------------------
1 | object FormSample: TFormSample
2 | Left = 0
3 | Top = 0
4 | Caption = 'Form5'
5 | ClientHeight = 480
6 | ClientWidth = 357
7 | FormFactor.Width = 320
8 | FormFactor.Height = 480
9 | FormFactor.Devices = [Desktop]
10 | OnCreate = FormCreate
11 | DesignerMasterStyle = 0
12 | object Memo1: TMemo
13 | Touch.InteractiveGestures = [Pan, LongTap, DoubleTap]
14 | DataDetectorTypes = []
15 | Align = Client
16 | Size.Width = 357.000000000000000000
17 | Size.Height = 430.000000000000000000
18 | Size.PlatformDefault = False
19 | TabOrder = 0
20 | Viewport.Width = 353.000000000000000000
21 | Viewport.Height = 426.000000000000000000
22 | end
23 | object Layout1: TLayout
24 | Align = Bottom
25 | Position.Y = 430.000000000000000000
26 | Size.Width = 357.000000000000000000
27 | Size.Height = 50.000000000000000000
28 | Size.PlatformDefault = False
29 | TabOrder = 1
30 | object Button1: TButton
31 | Align = Center
32 | Size.Width = 144.000000000000000000
33 | Size.Height = 36.000000000000000000
34 | Size.PlatformDefault = False
35 | TabOrder = 0
36 | Text = 'Get current state'
37 | OnClick = Button1Click
38 | end
39 | end
40 | end
41 |
--------------------------------------------------------------------------------
/Samples/FForm.pas:
--------------------------------------------------------------------------------
1 | unit FForm;
2 |
3 | interface
4 |
5 | uses
6 | System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
7 | FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Layouts,
8 | FMX.StdCtrls, FMX.Controls.Presentation, FMX.ScrollBox, FMX.Memo, UNetworkState;
9 |
10 | type
11 | TFormSample = class(TForm)
12 | Memo1: TMemo;
13 | Button1: TButton;
14 | Layout1: TLayout;
15 | procedure FormCreate(Sender: TObject);
16 | procedure Button1Click(Sender: TObject);
17 | private
18 | FNetworkState: TNetworkState;
19 | protected
20 | procedure DoOnChange(Sender: TObject; Value: TNetworkStateValue);
21 | public
22 |
23 | end;
24 |
25 | var
26 | FormSample: TFormSample;
27 |
28 | implementation
29 |
30 | {$R *.fmx}
31 |
32 | procedure TFormSample.FormCreate(Sender: TObject);
33 | begin
34 | self.FNetworkState := TNetworkState.Factory(self, DoOnChange);
35 |
36 | if self.FNetworkState.CurrentValue = nsConnectedWifi then
37 | self.Memo1.Lines.Add('On startup: Connected with WiFi')
38 | else if self.FNetworkState.CurrentValue = nsConnectedMobileData then
39 | self.Memo1.Lines.Add('On startup: Connected with mobile data')
40 | else if self.FNetworkState.CurrentValue = nsDisconnected then
41 | self.Memo1.Lines.Add('On startup: Disconnected')
42 | else
43 | self.Memo1.Lines.Add('On startup: Unknown');
44 | end;
45 |
46 | procedure TFormSample.DoOnChange(Sender: TObject; Value: TNetworkStateValue);
47 | begin
48 | if Value = nsConnectedWifi then
49 | self.Memo1.Lines.Add('On change: Connected with WiFi')
50 | else if Value = nsConnectedMobileData then
51 | self.Memo1.Lines.Add('On change: Connected with mobile data')
52 | else if self.FNetworkState.CurrentValue = nsDisconnected then
53 | self.Memo1.Lines.Add('On change: Disconnected')
54 | else
55 | self.Memo1.Lines.Add('On change: Unknown');
56 | end;
57 |
58 | procedure TFormSample.Button1Click(Sender: TObject);
59 | begin
60 | if self.FNetworkState.CurrentValue = nsConnectedWifi then
61 | self.Memo1.Lines.Add('Button1 Click: Connected with WiFi')
62 | else if self.FNetworkState.CurrentValue = nsConnectedMobileData then
63 | self.Memo1.Lines.Add('Button1 Click: Connected with mobile data')
64 | else if self.FNetworkState.CurrentValue = nsDisconnected then
65 | self.Memo1.Lines.Add('Button1 Click: Disconnected')
66 | else
67 | self.Memo1.Lines.Add('Button1 Click: Unknown');
68 | end;
69 |
70 | end.
71 |
--------------------------------------------------------------------------------
/Samples/FFormCPP.cpp:
--------------------------------------------------------------------------------
1 | //---------------------------------------------------------------------------
2 |
3 | #include
4 | #pragma hdrstop
5 |
6 | #include "FFormCPP.h"
7 | //---------------------------------------------------------------------------
8 | #pragma package(smart_init)
9 | #pragma resource "*.fmx"
10 | TFormSample *FormSample;
11 | //---------------------------------------------------------------------------
12 | __fastcall TFormSample::TFormSample(TComponent* Owner)
13 | : TForm(Owner)
14 | {
15 | this->FNetworkState = TNetworkState::Factory(this, this->DoOnNetworkStateChanged);
16 |
17 | if (this->FNetworkState->CurrentValue == nsConnectedWifi) {
18 | this->Memo1->Lines->Add(L"On startup: Connected with WiFi");
19 | } else if (this->FNetworkState->CurrentValue == nsConnectedMobileData) {
20 | this->Memo1->Lines->Add(L"On startup: Connected with mobile data");
21 | } else if (this->FNetworkState->CurrentValue == nsDisconnected) {
22 | this->Memo1->Lines->Add(L"On startup: Disconnected");
23 | } else {
24 | this->Memo1->Lines->Add(L"On startup: Unknown");
25 | }
26 | }
27 |
28 | void __fastcall TFormSample::Button1Click(TObject *Sender)
29 | {
30 | if (this->FNetworkState->CurrentValue == nsConnectedWifi) {
31 | this->Memo1->Lines->Add(L"Button1 Click: Connected with WiFi");
32 | } else if (this->FNetworkState->CurrentValue == nsConnectedMobileData) {
33 | this->Memo1->Lines->Add(L"Button1 Click: Connected with mobile data");
34 | } else if (this->FNetworkState->CurrentValue == nsDisconnected) {
35 | this->Memo1->Lines->Add(L"Button1 Click: Disconnected");
36 | } else {
37 | this->Memo1->Lines->Add(L"Button1 Click: Unknown");
38 | }
39 | }
40 |
41 | void __fastcall TFormSample::DoOnNetworkStateChanged(TObject* Sender, TNetworkStateValue Value)
42 | {
43 | if (this->FNetworkState->CurrentValue == nsConnectedWifi) {
44 | this->Memo1->Lines->Add(L"On change: Connected with WiFi");
45 | } else if (this->FNetworkState->CurrentValue == nsConnectedMobileData) {
46 | this->Memo1->Lines->Add(L"On change: Connected with mobile data");
47 | } else if (this->FNetworkState->CurrentValue == nsDisconnected) {
48 | this->Memo1->Lines->Add(L"On change: Disconnected");
49 | } else {
50 | this->Memo1->Lines->Add(L"On change: Unknown");
51 | }
52 | }
53 | //---------------------------------------------------------------------------
54 |
--------------------------------------------------------------------------------
/Samples/FFormCPP.fmx:
--------------------------------------------------------------------------------
1 | object FormSample: TFormSample
2 | Left = 0
3 | Top = 0
4 | Caption = 'FormSample'
5 | ClientHeight = 480
6 | ClientWidth = 368
7 | FormFactor.Width = 320
8 | FormFactor.Height = 480
9 | FormFactor.Devices = [Desktop]
10 | DesignerMasterStyle = 0
11 | object Layout1: TLayout
12 | Align = Bottom
13 | Position.Y = 430.000000000000000000
14 | Size.Width = 368.000000000000000000
15 | Size.Height = 50.000000000000000000
16 | Size.PlatformDefault = False
17 | TabOrder = 1
18 | object Button1: TButton
19 | Align = Center
20 | Size.Width = 144.000000000000000000
21 | Size.Height = 36.000000000000000000
22 | Size.PlatformDefault = False
23 | TabOrder = 0
24 | Text = 'Get current state'
25 | OnClick = Button1Click
26 | end
27 | end
28 | object Memo1: TMemo
29 | Touch.InteractiveGestures = [Pan, LongTap, DoubleTap]
30 | DataDetectorTypes = []
31 | Align = Client
32 | Size.Width = 368.000000000000000000
33 | Size.Height = 430.000000000000000000
34 | Size.PlatformDefault = False
35 | TabOrder = 0
36 | Viewport.Width = 364.000000000000000000
37 | Viewport.Height = 426.000000000000000000
38 | end
39 | end
40 |
--------------------------------------------------------------------------------
/Samples/FFormCPP.h:
--------------------------------------------------------------------------------
1 | //---------------------------------------------------------------------------
2 |
3 | #ifndef FFormCPPH
4 | #define FFormCPPH
5 | //---------------------------------------------------------------------------
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 |
16 | #include "UNetworkState.hpp"
17 | //---------------------------------------------------------------------------
18 | class TFormSample : public TForm
19 | {
20 | __published: // IDE-managed Components
21 | TLayout *Layout1;
22 | TButton *Button1;
23 | TMemo *Memo1;
24 | void __fastcall Button1Click(TObject *Sender);
25 | private: // User declarations
26 | TNetworkState *FNetworkState;
27 |
28 | protected:
29 | void __fastcall DoOnNetworkStateChanged(TObject* Sender, TNetworkStateValue Value);
30 |
31 | public: // User declarations
32 | __fastcall TFormSample(TComponent* Owner);
33 | };
34 | //---------------------------------------------------------------------------
35 | extern PACKAGE TFormSample *FormSample;
36 | //---------------------------------------------------------------------------
37 | #endif
38 |
--------------------------------------------------------------------------------
/Samples/Samples.groupproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | {D148EF59-0DAF-430B-8DAF-EFA870DE10C1}
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | Default.Personality.12
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/Samples/info.plist.TemplateiOS.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | <%VersionInfoPListKeys%>
6 | <%ExtraInfoPListKeys%>
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Samples/libReachability.a:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Partners/firemonkey-network-state/da886176ca2aeca1d62f5977f889903cf2af79c5/Samples/libReachability.a
--------------------------------------------------------------------------------
/Samples/libReachability64.a:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Partners/firemonkey-network-state/da886176ca2aeca1d62f5977f889903cf2af79c5/Samples/libReachability64.a
--------------------------------------------------------------------------------
/Source/Android/BroadcastReceiver/UBroadcastReceiver.pas:
--------------------------------------------------------------------------------
1 | {****************************************************}
2 | { }
3 | { firemonkey-network-state }
4 | { }
5 | { Copyright (C) 2018 Code Partners Pty Ltd }
6 | { }
7 | { http://www.code-partners.com }
8 | { }
9 | {****************************************************}
10 | { }
11 | { This Source Code Form is subject to the terms of }
12 | { the Mozilla Public License, v. 2.0. If a copy of }
13 | { the MPL was not distributed with this file, You }
14 | { can obtain one at }
15 | { }
16 | { http://mozilla.org/MPL/2.0/ }
17 | { }
18 | {****************************************************}
19 | unit UBroadcastReceiver;
20 |
21 | interface
22 |
23 | {$IFDEF ANDROID}
24 | uses
25 | System.SysUtils, System.Classes, Androidapi.JNIBridge, Androidapi.JNI.Embarcadero,
26 | Androidapi.JNI.GraphicsContentViewText, Androidapi.JNI.JavaTypes, Androidapi.helpers;
27 |
28 | type
29 | // based on https://github.com/ashumkin/Delphi-Android-BroadcastSample
30 |
31 | TDataReceivedEvent = procedure (Sender: TObject; Data: string) of object;
32 |
33 | TBroadcastReceiver = class;
34 |
35 | TListener = class(TJavaLocal, JFMXBroadcastReceiverListener)
36 | private
37 | fOwner: TBroadcastReceiver;
38 | fReceiver: JFMXBroadcastReceiver;
39 | public
40 | constructor Create(aOwner: TBroadcastReceiver);
41 | destructor Destroy; override;
42 | procedure onReceive(context: JContext; intent: JIntent); cdecl;
43 | end;
44 |
45 | TOnReceive = procedure (aContext: JContext; aIntent: JIntent; aResultCode: integer) of object;
46 |
47 | TBroadcastReceiver = class (TComponent)
48 | private
49 | fListener : TListener;
50 | fRegistered: boolean;
51 | fOnReceive: TOnReceive;
52 | protected
53 | procedure DoReceiveBroadcast(AContext: JContext; AIntent: JIntent; AResultCode: integer); virtual;
54 | public
55 | constructor Create(AOwner: TComponent; aOnReceiveProc: TOnReceive); reintroduce;
56 | destructor Destroy; override;
57 | procedure AddActions(const Args: array of JString);
58 | end;
59 | {$ENDIF}
60 |
61 | implementation
62 |
63 | { TBroadcastReceiver }
64 |
65 | {$IFDEF ANDROID}
66 | constructor TBroadcastReceiver.Create(AOwner: TComponent; aOnReceiveProc: TOnReceive);
67 | begin
68 | inherited Create(AOwner);
69 | fListener := TListener.Create(Self);
70 | fOnReceive := aOnReceiveProc;
71 | end;
72 |
73 | destructor TBroadcastReceiver.Destroy;
74 | begin
75 | fListener.Free;
76 | inherited;
77 | end;
78 |
79 | procedure TBroadcastReceiver.AddActions(const Args: array of JString);
80 | var
81 | vFilter: JIntentFilter;
82 | i: Integer;
83 | begin
84 | if fRegistered then
85 | TAndroidHelper.context.getApplicationContext.UnregisterReceiver(fListener.fReceiver);
86 |
87 | vFilter := TJIntentFilter.JavaClass.init;
88 | for i := 0 to High(Args) do
89 | vFilter.addAction(Args[i]);
90 |
91 | TAndroidHelper.context.getApplicationContext.registerReceiver(fListener.fReceiver, vFilter);
92 | fRegistered := true;
93 | end;
94 |
95 | //
96 |
97 | procedure TBroadcastReceiver.DoReceiveBroadcast(AContext: JContext; AIntent: JIntent; AResultCode: integer);
98 | begin
99 | //
100 | end;
101 |
102 | { TListener }
103 |
104 | constructor TListener.Create(aOwner: TBroadcastReceiver);
105 | begin
106 | inherited Create;
107 | fOwner := aOwner;
108 | fReceiver := TJFMXBroadcastReceiver.JavaClass.init(Self);
109 | end;
110 |
111 | destructor TListener.Destroy;
112 | begin
113 | TAndroidHelper.context.getApplicationContext.unregisterReceiver(fReceiver);
114 | inherited;
115 | end;
116 |
117 | // usually android call it from "UI thread" - it's not main Delphi thread
118 | procedure TListener.onReceive(context: JContext; intent: JIntent);
119 | begin
120 | if Assigned(fOwner.fOnReceive) then
121 | fOwner.fOnReceive(Context, Intent, fReceiver.getResultCode);
122 | end;
123 | {$ENDIF}
124 |
125 | end.
126 |
127 |
128 |
129 |
--------------------------------------------------------------------------------
/Source/Android/BroadcastReceiver/UNetworkStateBroadcastReceiver.pas:
--------------------------------------------------------------------------------
1 | {****************************************************}
2 | { }
3 | { firemonkey-network-state }
4 | { }
5 | { Copyright (C) 2018 Code Partners Pty Ltd }
6 | { }
7 | { http://www.code-partners.com }
8 | { }
9 | {****************************************************}
10 | { }
11 | { This Source Code Form is subject to the terms of }
12 | { the Mozilla Public License, v. 2.0. If a copy of }
13 | { the MPL was not distributed with this file, You }
14 | { can obtain one at }
15 | { }
16 | { http://mozilla.org/MPL/2.0/ }
17 | { }
18 | {****************************************************}
19 | unit UNetworkStateBroadcastReceiver;
20 |
21 | interface
22 |
23 | {$IFDEF ANDROID}
24 | uses
25 | System.SysUtils, System.Classes, Androidapi.JNI.GraphicsContentViewText,
26 | Androidapi.helpers, UBroadcastReceiver, Androidapi.JNI.Net, Androidapi.JNI.OS,
27 | Androidapi.JNI.JavaTypes;
28 |
29 | type
30 | TNetworkStateBroadcastReceiver = class (TBroadcastReceiver)
31 | private
32 | FOnConnectivityAction: TNotifyEvent;
33 | protected
34 | procedure DoReceiveBroadcast(AContext: JContext; AIntent: JIntent; AResultCode: integer); override;
35 | public
36 | constructor Create(
37 | AOwner: TComponent; AOnConnectivityAction: TNotifyEvent
38 | ); reintroduce;
39 | end;
40 | {$ENDIF}
41 |
42 | implementation
43 |
44 | {$IFDEF ANDROID}
45 | const
46 | CONNECTIVITY_ACTION = 'android.net.conn.CONNECTIVITY_CHANGE';
47 |
48 | { UNetworkStateBroadcastManager }
49 |
50 | constructor TNetworkStateBroadcastReceiver.Create(
51 | AOwner: TComponent; AOnConnectivityAction: TNotifyEvent
52 | );
53 | begin
54 | inherited Create(AOwner, self.DoReceiveBroadcast);
55 | self.FOnConnectivityAction := AOnConnectivityAction;
56 |
57 | self.AddActions([
58 | StringToJString(CONNECTIVITY_ACTION)
59 | ]);
60 | end;
61 |
62 | procedure TNetworkStateBroadcastReceiver.DoReceiveBroadcast(AContext: JContext;
63 | AIntent: JIntent; AResultCode: integer);
64 | var
65 | Action: string;
66 | begin
67 | inherited;
68 |
69 | Action := JStringToString(AIntent.getAction);
70 |
71 | if Action = CONNECTIVITY_ACTION then begin
72 | if(AIntent.getExtras() <> nil) then begin
73 | if Assigned(self.FOnConnectivityAction) then begin
74 | TThread.Synchronize(
75 | nil,
76 | procedure
77 | begin
78 | self.FOnConnectivityAction(self);
79 | end
80 | );
81 | end;
82 | end;
83 | end;
84 | end;
85 | {$ENDIF}
86 |
87 | end.
88 |
--------------------------------------------------------------------------------
/Source/Android/UNetworkState.Android.pas:
--------------------------------------------------------------------------------
1 | {****************************************************}
2 | { }
3 | { firemonkey-network-state }
4 | { }
5 | { Copyright (C) 2018 Code Partners Pty Ltd }
6 | { }
7 | { http://www.code-partners.com }
8 | { }
9 | {****************************************************}
10 | { }
11 | { This Source Code Form is subject to the terms of }
12 | { the Mozilla Public License, v. 2.0. If a copy of }
13 | { the MPL was not distributed with this file, You }
14 | { can obtain one at }
15 | { }
16 | { http://mozilla.org/MPL/2.0/ }
17 | { }
18 | {****************************************************}
19 | unit UNetworkState.Android;
20 |
21 | interface
22 |
23 | {$IFDEF ANDROID}
24 | uses
25 | System.SysUtils, System.Classes, UNetworkState, UNetworkStateBroadcastReceiver,
26 | Androidapi.JNIBridge, Androidapi.JNI.GraphicsContentViewText,
27 | Androidapi.JNI.JavaTypes, FMX.Helpers.Android, Androidapi.JNI.Net,
28 | Androidapi.Helpers;
29 |
30 | type
31 | TAndroidNetworkState = class (TNetworkState)
32 | private
33 | FBroadcastReceiver: TNetworkStateBroadcastReceiver;
34 | FConnectivityManager: JConnectivityManager;
35 |
36 | function GetConnectivityManager: JConnectivityManager;
37 | protected
38 | procedure DoOnConnectivityBroadcastAction(Sender: TObject);
39 | function GetCurrentValue: TNetworkStateValue; override;
40 | public
41 | constructor Create(AOwner: TComponent;
42 | AOnChange: TNetworkStateChangeEvent); reintroduce; override;
43 | end;
44 | {$ENDIF}
45 |
46 | implementation
47 |
48 | {$IFDEF ANDROID}
49 |
50 | { TAndroidNetworkState }
51 |
52 | constructor TAndroidNetworkState.Create(AOwner: TComponent;
53 | AOnChange: TNetworkStateChangeEvent);
54 | begin
55 | self.FConnectivityManager := self.GetConnectivityManager;
56 |
57 | self.FBroadcastReceiver := TNetworkStateBroadcastReceiver.Create(
58 | self, self.DoOnConnectivityBroadcastAction
59 | );
60 |
61 | inherited;
62 | end;
63 |
64 | function TAndroidNetworkState.GetConnectivityManager: JConnectivityManager;
65 | var
66 | ConnectivityServiceNative: JObject;
67 | begin
68 | ConnectivityServiceNative := TAndroidHelper.Context.getSystemService(
69 | TJContext.JavaClass.CONNECTIVITY_SERVICE
70 | );
71 |
72 | if not Assigned(ConnectivityServiceNative) then
73 | raise Exception.Create('Could not locate Connectivity Service');
74 |
75 | Result := TJConnectivityManager.Wrap((ConnectivityServiceNative as ILocalObject).GetObjectID);
76 |
77 | if not Assigned(Result) then
78 | raise Exception.Create('Could not access Connectivity Manager');
79 | end;
80 |
81 | procedure TAndroidNetworkState.DoOnConnectivityBroadcastAction(Sender: TObject);
82 | begin
83 | self.DoOnChange;
84 | end;
85 |
86 | function TAndroidNetworkState.GetCurrentValue: TNetworkStateValue;
87 | var
88 | ActiveNetwork: JNetworkInfo;
89 | Connected: boolean;
90 | begin
91 | ActiveNetwork := self.FConnectivityManager.getActiveNetworkInfo;
92 |
93 | Connected := Assigned(ActiveNetwork) and ActiveNetwork.isConnectedOrConnecting;
94 |
95 | if Connected then begin
96 | if ActiveNetwork.getType = TJConnectivityManager.JavaClass.TYPE_WIFI then
97 | Result := nsConnectedWifi
98 | else
99 | Result := nsConnectedMobileData;
100 | end
101 | else
102 | Result := nsDisconnected;
103 | end;
104 |
105 | {$ENDIF}
106 |
107 | end.
108 |
--------------------------------------------------------------------------------
/Source/UNetworkState.pas:
--------------------------------------------------------------------------------
1 | {****************************************************}
2 | { }
3 | { firemonkey-network-state }
4 | { }
5 | { Copyright (C) 2018 Code Partners Pty Ltd }
6 | { }
7 | { http://www.code-partners.com }
8 | { }
9 | {****************************************************}
10 | { }
11 | { This Source Code Form is subject to the terms of }
12 | { the Mozilla Public License, v. 2.0. If a copy of }
13 | { the MPL was not distributed with this file, You }
14 | { can obtain one at }
15 | { }
16 | { http://mozilla.org/MPL/2.0/ }
17 | { }
18 | {****************************************************}
19 | unit UNetworkState;
20 |
21 | interface
22 |
23 | uses
24 | System.SysUtils, System.Classes;
25 |
26 | type
27 | TNetworkStateValue = (nsUnknown = 0, nsConnectedWifi = 1, nsConnectedMobileData = 2, nsDisconnected = 3);
28 |
29 | TNetworkStateChangeEvent = procedure (Sender: TObject;
30 | Value: TNetworkStateValue) of object;
31 |
32 | TNetworkState = class (TComponent)
33 | private
34 | FCurrentValue: TNetworkStateValue;
35 | FOnChange: TNetworkStateChangeEvent;
36 | protected
37 | procedure DoOnChange;
38 | function GetCurrentValue: TNetworkStateValue; virtual;
39 |
40 | constructor Create(AOwner: TComponent;
41 | AOnChange: TNetworkStateChangeEvent); reintroduce; virtual;
42 | public
43 | class function Factory(
44 | AOwner: TComponent; AOnChange: TNetworkStateChangeEvent
45 | ): TNetworkState;
46 |
47 | property CurrentValue: TNetworkStateValue read FCurrentValue;
48 | end;
49 |
50 | implementation
51 |
52 | uses
53 | {$IF DEFINED(Android)}
54 | UNetworkState.Android;
55 | {$ELSEIF DEFINED(iOS)}
56 | UNetworkState.iOS;
57 | {$IFEND}
58 |
59 | { TNetworkState }
60 |
61 | constructor TNetworkState.Create(AOwner: TComponent;
62 | AOnChange: TNetworkStateChangeEvent);
63 | begin
64 | inherited Create(AOwner);
65 | self.FOnChange := AOnChange;
66 |
67 | self.FCurrentValue := self.GetCurrentValue;
68 | end;
69 |
70 | class function TNetworkState.Factory(AOwner: TComponent;
71 | AOnChange: TNetworkStateChangeEvent): TNetworkState;
72 | begin
73 | {$IF DEFINED(Android)}
74 | Result := TAndroidNetworkState.Create(AOwner, AOnChange);
75 | {$ELSEIF DEFINED(iOS)}
76 | {$IF DEFINED(CPUARM)} // real device
77 | Result := TiOSNetworkState.Create(AOwner, AOnChange);
78 | {$ELSEIF DEFINED(CPUX86)} // simulator
79 | Result := TNetworkState.Create(AOwner, AOnChange);
80 | {$ENDIF}
81 | {$ENDIF}
82 | end;
83 |
84 | function TNetworkState.GetCurrentValue: TNetworkStateValue;
85 | begin
86 | Result := nsUnknown;
87 | end;
88 |
89 | procedure TNetworkState.DoOnChange;
90 | var
91 | NewValue: TNetworkStateValue;
92 | begin
93 | NewValue := self.GetCurrentValue;
94 |
95 | if (self.FCurrentValue <> NewValue) then begin
96 | self.FCurrentValue := NewValue;
97 |
98 | if Assigned(self.FOnChange) then
99 | self.FOnChange(self, self.FCurrentValue);
100 | end;
101 | end;
102 |
103 | end.
104 |
--------------------------------------------------------------------------------
/Source/iOS/CaptiveNetwork.pas:
--------------------------------------------------------------------------------
1 | {****************************************************}
2 | { }
3 | { firemonkey-network-state }
4 | { }
5 | { Copyright (C) 2018 Code Partners Pty Ltd }
6 | { }
7 | { http://www.code-partners.com }
8 | { }
9 | {****************************************************}
10 | { }
11 | { This Source Code Form is subject to the terms of }
12 | { the Mozilla Public License, v. 2.0. If a copy of }
13 | { the MPL was not distributed with this file, You }
14 | { can obtain one at }
15 | { }
16 | { http://mozilla.org/MPL/2.0/ }
17 | { }
18 | {****************************************************}
19 | unit CaptiveNetwork;
20 |
21 | interface
22 |
23 | {$IFDEF IOS}
24 | uses
25 | Macapi.CoreFoundation;
26 |
27 | const
28 | libSystemConfiguration = '/System/Library/Frameworks/SystemConfiguration.framework/SystemConfiguration';
29 |
30 | function CNSetSupportedSSIDs(ssidArray: CFArrayRef): Boolean; cdecl;
31 | external libSystemConfiguration name _PU + 'CNSetSupportedSSIDs';
32 | function CNMarkPortalOnline(interfaceName: CFStringRef): Boolean; cdecl;
33 | external libSystemConfiguration name _PU + 'CNMarkPortalOnline';
34 | function CNMarkPortalOffline(interfaceName: CFStringRef): Boolean; cdecl;
35 | external libSystemConfiguration name _PU + 'CNMarkPortalOffline';
36 | function CNCopySupportedInterfaces: CFArrayRef; cdecl;
37 | external libSystemConfiguration name _PU + 'CNCopySupportedInterfaces';
38 | function CNCopyCurrentNetworkInfo(interfaceName: CFStringRef): CFDictionaryRef; cdecl;
39 | external libSystemConfiguration name _PU + 'CNCopyCurrentNetworkInfo';
40 | {$ENDIF}
41 |
42 | implementation
43 |
44 | end.
45 |
--------------------------------------------------------------------------------
/Source/iOS/SCNetworkReachability.pas:
--------------------------------------------------------------------------------
1 | {****************************************************}
2 | { }
3 | { firemonkey-network-state }
4 | { }
5 | { Copyright (C) 2018 Code Partners Pty Ltd }
6 | { }
7 | { http://www.code-partners.com }
8 | { }
9 | {****************************************************}
10 | { }
11 | { This Source Code Form is subject to the terms of }
12 | { the Mozilla Public License, v. 2.0. If a copy of }
13 | { the MPL was not distributed with this file, You }
14 | { can obtain one at }
15 | { }
16 | { http://mozilla.org/MPL/2.0/ }
17 | { }
18 | {****************************************************}
19 | unit SCNetworkReachability;
20 |
21 | interface
22 |
23 | {$IFDEF IOS}
24 | uses
25 | Macapi.CoreFoundation, Posix.SysSocket, Macapi.Dispatch;
26 |
27 | const
28 | libSystemConfiguration = '/System/Library/Frameworks/SystemConfiguration.framework/SystemConfiguration';
29 | // Stolen from Macapi.SystemConfiguration
30 | kSCNetworkFlagsConnectionAutomatic = 8;
31 | kSCNetworkFlagsConnectionRequired = 4;
32 | kSCNetworkFlagsInterventionRequired = 16;
33 | kSCNetworkFlagsIsDirect = 131072;
34 | kSCNetworkFlagsIsLocalAddress = 65536;
35 | kSCNetworkFlagsReachable = 2;
36 | kSCNetworkFlagsTransientConnection = 1;
37 | kSCNetworkReachabilityFlagsConnectionAutomatic = 8;
38 | kSCNetworkReachabilityFlagsConnectionOnDemand = 32;
39 | kSCNetworkReachabilityFlagsConnectionOnTraffic = 8;
40 | kSCNetworkReachabilityFlagsConnectionRequired = 4;
41 | kSCNetworkReachabilityFlagsInterventionRequired = 16;
42 | kSCNetworkReachabilityFlagsIsDirect = 131072;
43 | kSCNetworkReachabilityFlagsIsLocalAddress = 65536;
44 | kSCNetworkReachabilityFlagsReachable = 2;
45 | kSCNetworkReachabilityFlagsTransientConnection = 1;
46 | kSCNetworkReachabilityFlagsIsWWAN = $40000; // iOS only
47 |
48 | type
49 | SCNetworkReachabilityFlags = UInt32;
50 |
51 | SCNetworkReachabilityRef = ^__SCNetworkReachability;
52 |
53 | __SCNetworkReachability = record
54 | end;
55 |
56 | SCNetworkReachabilityContext = record
57 | version: CFIndex;
58 | info: Pointer;
59 | retain: function(info: Pointer): Pointer;
60 | release: procedure(info: Pointer);
61 | copyDescription: function(info: Pointer): CFStringRef;
62 | end;
63 |
64 | SCNetworkReachabilityContextPtr = ^SCNetworkReachabilityContext;
65 |
66 | SCNetworkReachabilityCallback = procedure(target: SCNetworkReachabilityRef;
67 | flags: SCNetworkReachabilityFlags; info: Pointer);
68 |
69 | function SCNetworkReachabilityCreateWithAddress(allocator: CFAllocatorRef; address: psockaddr): SCNetworkReachabilityRef; cdecl;
70 | external libSystemConfiguration name _PU + 'SCNetworkReachabilityCreateWithAddress';
71 | function SCNetworkReachabilityCreateWithAddressPair(allocator: CFAllocatorRef; localAddress: psockaddr;
72 | remoteAddress: psockaddr): SCNetworkReachabilityRef; cdecl;
73 | external libSystemConfiguration name _PU + 'SCNetworkReachabilityCreateWithAddressPair';
74 | function SCNetworkReachabilityCreateWithName(allocator: CFAllocatorRef; nodename: PChar): SCNetworkReachabilityRef; cdecl;
75 | external libSystemConfiguration name _PU + 'SCNetworkReachabilityCreateWithName';
76 | function SCNetworkReachabilityGetTypeID: CFTypeID; cdecl;
77 | external libSystemConfiguration name _PU + 'SCNetworkReachabilityGetTypeID';
78 | function SCNetworkReachabilityGetFlags(target: SCNetworkReachabilityRef; var flags: SCNetworkReachabilityFlags): Boolean; cdecl;
79 | external libSystemConfiguration name _PU + 'SCNetworkReachabilityGetFlags';
80 | function SCNetworkReachabilitySetCallback(target: SCNetworkReachabilityRef; callout: SCNetworkReachabilityCallback;
81 | var context: SCNetworkReachabilityContext): Boolean; cdecl;
82 | external libSystemConfiguration name _PU + 'SCNetworkReachabilitySetCallback';
83 | function SCNetworkReachabilityScheduleWithRunLoop(target: SCNetworkReachabilityRef; runLoop: CFRunLoopRef;
84 | runLoopMode: CFStringRef): Boolean; cdecl;
85 | external libSystemConfiguration name _PU + 'SCNetworkReachabilityScheduleWithRunLoop';
86 | function SCNetworkReachabilityUnscheduleFromRunLoop(target: SCNetworkReachabilityRef; runLoop: CFRunLoopRef; runLoopMode: CFStringRef): Boolean; cdecl;
87 | external libSystemConfiguration name _PU + 'SCNetworkReachabilityUnscheduleFromRunLoop';
88 | function SCNetworkReachabilitySetDispatchQueue(target: SCNetworkReachabilityRef; queue: dispatch_queue_t): Boolean; cdecl;
89 | external libSystemConfiguration name _PU + 'SCNetworkReachabilitySetDispatchQueue';
90 | {$ENDIF}
91 |
92 | implementation
93 |
94 | end.
95 |
--------------------------------------------------------------------------------
/Source/iOS/UNetworkState.iOS.pas:
--------------------------------------------------------------------------------
1 | {****************************************************}
2 | { }
3 | { firemonkey-network-state }
4 | { }
5 | { Copyright (C) 2018 Code Partners Pty Ltd }
6 | { }
7 | { http://www.code-partners.com }
8 | { }
9 | {****************************************************}
10 | { }
11 | { This Source Code Form is subject to the terms of }
12 | { the Mozilla Public License, v. 2.0. If a copy of }
13 | { the MPL was not distributed with this file, You }
14 | { can obtain one at }
15 | { }
16 | { http://mozilla.org/MPL/2.0/ }
17 | { }
18 | {****************************************************}
19 | unit UNetworkState.iOS;
20 |
21 | interface
22 |
23 | {$IFDEF IOS}
24 | uses
25 | System.SysUtils, System.Classes, UNetworkState, Macapi.ObjectiveC,
26 | Macapi.CoreFoundation, iOSApi.CocoaTypes, iOSApi.Foundation,
27 | Macapi.ObjCRuntime, Macapi.Helpers
28 | // linker will fail without these two files
29 | , SCNetworkReachability, CaptiveNetwork;
30 |
31 | type
32 | SCNetworkReachabilityFlags = UInt32;
33 |
34 | TReachability = class;
35 |
36 | Reachability = interface(NSObject)
37 | ['{B405394F-57B1-4FF1-83D9-8FBFA38FFD7B}']
38 | function startNotifier: LongBool; cdecl;
39 | procedure stopNotifier; cdecl;
40 | function isReachable: LongBool; cdecl;
41 | function isReachableViaWWAN: LongBool; cdecl;
42 | function isReachableViaWiFi: LongBool; cdecl;
43 | function isConnectionRequired: LongBool; cdecl;
44 | function connectionRequired: LongBool; cdecl;
45 | function isConnectionOnDemand: LongBool; cdecl;
46 | function isInterventionRequired: LongBool; cdecl;
47 | function currentReachabilityStatus: NSInteger; cdecl;
48 | function reachabilityFlags: SCNetworkReachabilityFlags; cdecl;
49 | function currentReachabilityString: NSString; cdecl;
50 | function currentReachabilityFlags: NSString; cdecl;
51 | end;
52 |
53 | ReachabilityClass = interface(NSObjectClass)
54 | ['{39EC0490-2787-4BB9-95EA-77BB885BFD01}']
55 | function reachabilityWithHostname(hostname: NSString): pointer; cdecl;
56 | function reachabilityForInternetConnection: pointer; cdecl;
57 | function reachabilityWithAddress: pointer; cdecl;
58 | function reachabilityForLocalWiFi: pointer; cdecl;
59 | end;
60 |
61 | TReachability = class(TOCGenericImport)
62 | end;
63 |
64 | INetworkChangeDelegate = interface(IObjectiveC)
65 | ['{BC4EABBE-F21F-4592-93B0-0C40415E4A91}']
66 | procedure handleNetworkChange(notice: NSNotification); cdecl;
67 | end;
68 |
69 | TiOSNetworkState = class;
70 |
71 | TNetworkChangeDelegate = class (TOCLocal, INetworkChangeDelegate)
72 | private
73 | FNetworkState: TiOSNetworkState;
74 | public
75 | constructor Create(ANetworkState: TiOSNetworkState);
76 |
77 | // (void) handleNetworkChange:(NSNotification *)notice
78 | procedure handleNetworkChange(notice: NSNotification); cdecl;
79 | end;
80 |
81 | TiOSNetworkState = class (TNetworkState)
82 | private
83 | FReachability: Reachability;
84 | FDelegate: TNetworkChangeDelegate;
85 | protected
86 | function GetCurrentValue: TNetworkStateValue; override;
87 | public
88 | constructor Create(AOwner: TComponent;
89 | AOnChange: TNetworkStateChangeEvent); reintroduce; override;
90 | end;
91 |
92 | {$IFDEF CPUARM}
93 | {$IF DEFINED(IOS32)}
94 | function FakeLoader: Reachability; cdecl; external 'libReachability.a' name 'OBJC_CLASS_$_Reachability';
95 | {$ELSEIF DEFINED(IOS64)}
96 | function FakeLoader: Reachability; cdecl; external 'libReachability64.a' name 'OBJC_CLASS_$_Reachability';
97 | {$ENDIF}
98 | {$ENDIF}
99 |
100 | {$ENDIF}
101 |
102 | implementation
103 |
104 | {$IFDEF IOS}
105 |
106 | { TiOSNetworkState }
107 |
108 | constructor TiOSNetworkState.Create(AOwner: TComponent;
109 | AOnChange: TNetworkStateChangeEvent);
110 | begin
111 | FDelegate := TNetworkChangeDelegate.Create(self);
112 |
113 | TNSNotificationCenter.Wrap(TNSNotificationCenter.OCClass.defaultCenter).addObserver(
114 | FDelegate.GetObjectID,
115 | sel_getUid('handleNetworkChange:'),
116 | StringToID('kReachabilityChangedNotification'),
117 | nil
118 | );
119 |
120 | FReachability := TReachability.Wrap(TReachability.OCClass.reachabilityForInternetConnection);
121 | FReachability.startNotifier;
122 |
123 | inherited;
124 | end;
125 |
126 | function TiOSNetworkState.GetCurrentValue: TNetworkStateValue;
127 | var
128 | Status: integer;
129 | begin
130 | Status := self.FReachability.currentReachabilityStatus;
131 |
132 | // 0 - disconnected, 1 - reachable via wifi, 2 - reachable via wwan
133 | if (Status = 0) then
134 | Result := nsDisconnected
135 | else if (Status = 2) then
136 | Result := nsConnectedWifi
137 | else
138 | Result := nsConnectedMobileData;
139 | end;
140 |
141 | { TNetworkChangeDelegate }
142 |
143 | constructor TNetworkChangeDelegate.Create(ANetworkState: TiOSNetworkState);
144 | begin
145 | inherited Create;
146 | self.FNetworkState := ANetworkState;
147 | end;
148 |
149 | procedure TNetworkChangeDelegate.handleNetworkChange(notice: NSNotification);
150 | begin
151 | TThread.Synchronize(
152 | nil,
153 | procedure
154 | begin
155 | self.FNetworkState.DoOnChange;
156 | end
157 | );
158 | end;
159 |
160 | {$ENDIF}
161 |
162 | initialization
163 |
164 | end.
165 |
--------------------------------------------------------------------------------