Πώς να ελέγξετε τη σύνδεση στο διαδίκτυο στο Android "Q"

Φωτογραφία από τον Matthew Henry από το Burst

Πού είναι το NetworkInfo!

Προσπαθήσατε να στοχεύσετε το πιο πρόσφατο επίπεδο API 29, ακριβώς για να δείτε τι συμβαίνει; Λοιπόν, αν είστε τυχεροί, υπάρχει μόνο μια προειδοποίηση που εμφανίζεται στη διαδικασία δημιουργίας σας και τελικά μια δόμηση επιτύχει την κοινοποίηση.

Αλλά ο φίλος μου, σίγουρα αντιμετωπίζετε κάποια απροσδόκητα προβλήματα, όπως και εγώ, ειδικά για μια συγκεκριμένη κλάση NetworkInfo, περισσότερα για αυτό μετά από λίγο περιβάλλον.

Android Q, γιατί να το στοχεύσω ούτως ή άλλως;

Το Android 10 (Q) κυκλοφόρησε επίσημα στις 3 Σεπτεμβρίου 2019, είναι ο διάδοχος του Android 9 (Pie) και είναι η τελευταία έκδοση του Android και δυστυχώς η πρώτη έκδοση που δεν ακολουθεί τα γλυκά ονόματα τάσεων.

Δεν απαντά στην ερώτηση; Λοιπόν, αν διαβάζετε αυτό είναι επειδή ίσως να αναρωτιέστε αν πραγματικά πρέπει να στοχεύσετε το επίπεδο API 29. Πάντα λέμε ότι συνιστάται να στοχεύσετε την πιο πρόσφατη έκδοση, αλλά γιατί είναι και πάλι;

Πρέπει να θυμάστε ποιος αποφασίζει τι υπαγορεύει τη διανομή της εφαρμογής μας, ναι, ο παλιός φίλος σας, το Google Play Store. Εδώ τι λέει το κατάστημα:

Απαιτήσεις επιπέδου API στόχου του Google Play.

Δείτε πού πηγαίνει αυτό; Κάθε χρόνο, η απαίτηση του Google Play πηγαίνει στην επόμενη έκδοση. Μπορεί να είναι απλώς εικασίες σε αυτό το σημείο, αλλά πιθανότατα αυτό το διάγραμμα θα έχει μια νέα γραμμή σύντομα.

Αυτό σημαίνει ότι από την 1η Αυγούστου του 2020 όλες οι νέες εφαρμογές θα πρέπει να στοχεύσουν το επίπεδο API 29 και έτσι θα έχουν όλες τις ενημερώσεις μέχρι την 1η Νοεμβρίου του 2020.

Μπορεί να έχετε τώρα λιγότερο από ένα χρόνο επικεφαλής σας για να βεβαιωθείτε ότι όλα έχουν ρυθμιστεί για εκείνη την ημερομηνία. Βεβαιωθείτε ότι δεν χρονοτριβείτε!

Πεπεισμένοι! Και εγώ, τόσο πίσω στην επιχείρηση

Πρώτα πρώτα, ας στοχεύσουμε τη νέα έκδοση και δούμε τι θα συμβεί. Για αυτό, απλά βρείτε targetSdkVersion στη διαμόρφωσή σας και χτυπήστε το στα 29, στη συνέχεια, αναδιπλώστε το έργο και ελέγξτε έξω για προειδοποιήσεις και σφάλματα κατά τη σύνταξη ....

Εδώ είναι το δείγμα των πιθανών προειδοποιήσεων που μπορείτε να πάρετε, προέρχονται από ένα πραγματικό έργο από 28 σε 29:

Η αναντιστοιχία τύπων: ο υπονοούμενος τύπος είναι το MenuItem; αλλά το MenuItem ήταν αναμενόμενο Αναντιστοιχία τύπου: συνήθης τύπος είναι Διαμόρφωση; αλλά η παράμετρος Configuration was expected Αναντιστοιχία τύπων: συνήθης τύπος είναι String; αλλά το String αναμενόταν 'setColorFilter (Int, PorterDuff.Mode): Η μονάδα' είναι παρωχημένη. Απορρίπτεται σε αναντιστοιχία τύπων Java: ο συνήθης τύπος είναι Ημερομηνία; αλλά Ημερομηνία αναμενόταν Η μη ασφαλή χρήση ενός μηδενικού δέκτη τύπου Any; Το "PreferenceManager" είναι παρωχημένο. Απορρίπτεται στην Java 'NetworkInfo' είναι απόρριψη. Αποκλεισμένος σε Java "getter για activeNetworkInfo: NetworkInfo!" είναι παρωχημένη. Απορρίπτεται στο Java 'getter για isConnectedOrConnecting: Boolean' είναι παρωχημένο. Καταργήθηκε στην Java

Σε αυτήν τη λίστα, εκτός από κάποιες μηδενικές ρυθμίσεις και προσθέτοντας το πακέτο androidx.preference, δεν υπήρχαν πολλά πράγματα να κάνουμε. Πολύ κάθε διόρθωση έγινε σε 20 λεπτά.

Και τότε άρχισα να εξετάζω αυτό το NetworkInfo είναι απολυμένο θέμα: ☠️

Αυτή η τάξη καταργήθηκε στο επίπεδο API 29.
Οι καλούντες θα πρέπει να χρησιμοποιήσουν το API ConnectivityManager.NetworkCallback για να μάθουν για τις αλλαγές συνδεσιμότητας ή για να χρησιμοποιήσουν το ConnectivityManager # getNetworkCapabilities ή το ConnectivityManager # getLinkProperties για να λάβουν πληροφορίες συγχρόνως ...

Ένας τρόπος για να επιλυθεί αυτό είναι να ρίξετε μια ματιά στην επίσημη οδηγία για τη μετανάστευση στον ιστότοπο του Android. Η λύση μπορεί να είναι εκεί, .

Δυστυχώς, δεν υπάρχει πολύς χρόνος εκείνη την εποχή, οπότε επιστρέφουμε για να χρησιμοποιήσουμε μερικούς μυς του εγκεφάλου για την επίλυση αυτών των προβλημάτων.

Πριν από αυτά τα κακά νέα, για να αποκτήσετε την κατάσταση συνδεσιμότητας, το μόνο που χρειάζεται να κάνετε είναι αυτό:

Αυτός ο κώδικας θα μπορούσε να καλείται από οποιοδήποτε σημείο, δεδομένου ότι έχετε πρόσβαση στο περιβάλλον εφαρμογής και θα μπορούσατε εύκολα να ελέγξετε αν η συσκευή προσθέτει αυτήν την περίοδο πρόσβαση στο δίκτυο.

Και για να λάβουμε αλλαγές συνδεσιμότητας σε μια δραστηριότητα που είχαμε βασικά μόνο για να το κάνουμε αυτό

Τώρα με το ConnectivityManager # getActiveNetworkInfo που χάσαμε, χάσαμε τον μοναδικό τρόπο για να ελέγξουμε συγχρόνως τη σύνδεση στο διαδίκτυο.

Τώρα παραμένει μόνο στο API:

  1. NetworkCallback: Αυτό το ξέρουμε και θα πρέπει να το χρησιμοποιείτε ήδη. Είναι η διεπαφή για την υλοποίηση για την λήψη συμβάντων συνδεσιμότητας.
  2. ConnectivityManager # getNetworkCapabilities: δεδομένου ενός δικτύου, παίρνετε τις δυνατότητές του όπως ο τύπος δικτύου (κινητό ή wifi), το εύρος ζώνης κ.λπ.
  3. ConnectivityManager # getLinkProperties: δεδομένου ενός δικτύου, παίρνετε τις ιδιότητες του δικτυακού συνδέσμου, δηλαδή διεπαφή δικτύου.

Εντάξει, τα # 2 και # 3 μπορεί να είναι εκεί από το επίπεδο API 21, αλλά ποτέ δεν το έχω ακούσει και φαίνεται ότι δεν μπορούν να δώσουν το ίδιο αποτέλεσμα με τον προηγούμενο κώδικα.

Για έναν εκκινητή, και οι δύο χρειάζονται ένα επιχείρημα δικτύου, το οποίο θα μπορούσατε να πάρετε με το ConnectivityManager # getActiveNetwork, αλλά στο τέλος, κανένα από αυτά δεν δίνει ισοδύναμο με το NetworkInfo # isConnected ή το NetworkInfo # isConnectedOrConencting.

Λύση ? Θα πρέπει να αποθηκεύσουμε την κατάσταση της σύνδεσης στη θέση του Android. Για να γίνει αυτό, έπρεπε να επανεξετάσουμε ορισμένα πράγματα στην εφαρμογή του NetworkCallback.

Μια εναλλακτική λύση στο NetworkInfo

Ας αρχίσουμε να δημιουργούμε ένα εναλλακτικό NetworkInfo, το οποίο θα επαναφέρει έναν σύγχρονο τρόπο για να πάρει εάν η κατάσταση συνδεσιμότητας δικτύου. Ακολουθεί ένα παράδειγμα διεπαφής για αυτό:

Τώρα πρέπει να εφαρμόσουμε αυτή τη διεπαφή και να διασφαλίσουμε ότι οι τιμές της αντανακλούν τη συνδεσιμότητα της συσκευής. Εντάξει, ας δώσουμε ένα πρώτο πλάνο:

Τώρα μπορούμε να χρησιμοποιήσουμε αυτή την υλοποίηση μέσα σε ένα NetworkCallback, αποθηκεύοντας την κατάσταση δικτύου και ενημερώνοντάς την κάθε φορά που αλλάζει η συνδεσιμότητα:

Εγινε ! Τι, λείπει κάτι; Ναι, τρία μικρά πράγματα.

  1. Το πρώτο είναι πώς να κάνουμε μια παρουσία του NetworkState προσβάσιμη παντού στην εφαρμογή, όχι σε NetworkStateImp, θέλουμε ένα αντικείμενο μόνο για ανάγνωση.
  2. Το δεύτερο είναι πώς αφήνουμε κάθε ενδιαφερόμενο να γνωρίζει ότι οι αξίες του άλλαξαν.
  3. Τέλος, το τρίτο είναι πώς συνδέεται όλο το δίκτυο με το NetworkCallback.

Το πρώτο και το τρίτο σημείο μπορούν να έχουν αρκετές λύσεις, μερικοί θα επιλέξουν να χρησιμοποιήσουν το δοχείο DI που έχει ήδη εγκατασταθεί εκεί, αλλά για να το κρατήσουμε αυτό απλό, ας χρησιμοποιήσουμε λίγο μαγείρεμα του Kotlin εδώ:

Ας σπάσουμε λίγο

  • το αντικείμενο είναι συντακτική ζάχαρη για να ρυθμίσετε το πρότυπο singleton
  • Το NetworkStateHolder είναι μια παρουσία του NetworkState αλλά οι τιμές αποθηκεύονται στον κάτοχο ιδιοκτησίας. ο κάτοχος είναι ένα NetworkStateImp και είναι επεξεργάσιμο, αλλά είναι ιδιωτικό, επιλύοντας το πρώτο σημείο.
  • registerConnectivityBroadcaster είναι μια επέκταση εφαρμογής που συνδέει τη θήκη με την επανάκληση, επιλύοντας το τρίτο σημείο.

Για να ρυθμίσετε όλη αυτή την αρχιτεκτονική παρακολούθησης, πρέπει απλώς να καλέσετε registerConnectivityBroadcaster όπως αυτό:

Τώρα παραμένει μόνο το δεύτερο σημείο, δηλαδή η μετάδοση των αλλαγών του δικτύου. Ο παλιός τρόπος θα ήταν να χρησιμοποιήσετε κάποιον Broadcaster -> Intent -> Receiver -> πρότυπο λειτουργίας για να λάβετε τα γεγονότα στις δραστηριότητες.

Αλλά δεν είμαστε εδώ για να κολλήσουμε με το παρελθόν, πρέπει να αρχίσουμε να χρησιμοποιούμε τα αρχεία Android Jetpack εδώ, θέλουμε να χρησιμοποιήσουμε τα Αρχιτεκτονικά Στοιχεία!

Ας χρησιμοποιήσουμε κάποια LiveData

Με την εισαγωγή του LiveData εδώ, θα λύσουμε το δεύτερο σημείο που ανακοινώθηκε προηγουμένως, δηλαδή πώς θα μεταδώσουμε τα συμβάντα συνδεσιμότητας στην υπόλοιπη εφαρμογή.

Πρέπει πρώτα να ορίσουμε κάποια γεγονότα, ας χρησιμοποιήσουμε για άλλη μια φορά κάποια μαγεία από το Kotlin εδώ:

Με αυτόν τον απλό κώδικα, ορίσαμε διάφορα πρότυπα:

  • Καταμέτρηση: η σφραγισμένη κλάση επιτρέπει περιορισμένο σύνολο τύπων με βάση το συμβάν, με όλα αυτά να είναι ένθετα στο Event, πολύ εύκολο να το διαβάσετε!
  • Πολυμορφισμός: Κάθε περίπτωση του συμβάντος διατηρεί την κατάσταση του δικτύου, αλλά και ορισμένα συγκεκριμένα δεδομένα που σχετίζονται με την αλλαγή που συνέβη.
  • Αφαίρεση: Εάν δεν χρειάζονται δεδομένα, μπορείτε να χρησιμοποιήσετε τον τύπο για να χειριστείτε το συμβάν, ακριβώς όπως το χειρισμό Εκτέλεσης. Είναι η περίπτωση των ConnectivityLost και ConnectivityAvailable, και επιπλέον, είναι αντικείμενο / singletons για μεγαλύτερη απλότητα χρήσης.

Είστε έτοιμοι για την εντατική χρήση ζωντανών δεδομένων; Ορίστε :

Αυτό είναι όλο ? Ναί !

  • Το NetworkEvents είναι ένα LiveData και χρησιμοποιώντας το NetworkEvents.observe (ιδιοκτήτης ζωής, παρατηρητής) μπορείτε να το παρατηρήσετε από οποιονδήποτε LifeCycleOwner (Δραστηριότητα, Θραύσμα, ...) όχι μόνο αλλά και οποιαδήποτε άλλη θέση με το NetworkEvents.observeForever (παρατηρητής)
  • η ειδοποίηση είναι η λειτουργία που θα χρησιμοποιηθεί για την προώθηση νέων συμβάντων.
  • Στο προηγουμένως παρουσιαζόμενο NetworkHolderImp με την προσθήκη ενός ρυθμιστή στην ιδιότητα του που καλεί το NetworkEvents.notify είναι το μόνο που πρέπει να ειδοποιήσουμε όλους τους παρατηρητές ότι κάτι άλλαξε

Ένας σύνδεσμος για βοήθεια

Δεν θέλετε να το κάνετε μόνοι σας; Ή ίσως πρέπει να δείτε τα πάντα μαζί στο ίδιο μέρος για να το καταλάβετε καλύτερα; Ρίξτε μια ματιά σε αυτό το αποθετήριο. Εκεί θα βρείτε μια εφαρμογή Android που υλοποιεί όλα όσα παρουσιάζονται εδώ και πολλά άλλα:

Μια μικρή σημείωση σχετικά με την ορατότητα

Μπορεί να έχετε παρατηρήσει εδώ και εκεί τις εσωτερικές λέξεις-κλειδιά, μπροστά σε ορισμένες κατηγορίες και ιδιότητες. FYI, αυτή η λέξη-κλειδί σημαίνει "μόνο ορατή μέσα από μια ενότητα".

Μεγάλη ιστορία σύντομη, βάζοντας τον κωδικό σας στη δική του ενότητα (Δημιουργία βιβλιοθήκης Android), μπορείτε να περιορίσετε την προβολή των τάξεων σας. Θέλετε περισσότερες πληροφορίες, είναι ο καλεσμένος μου:

Δείτε επίσης

Πώς δημιουργείτε έναν ιστότοπο για την επιχείρησή σας; Προσπαθώ να πουλήσω στο διαδίκτυο, καθώς το κατάστημά μου δεν κάνει πολλά χρήματα και είναι στη χειρότερη περιοχή. Δεν γνωρίζω τίποτα πολύ για τους υπολογιστές και τον προγραμματισμό;Πώς μπορώ να εξασφαλίσω κατά την ανάπτυξη μιας ιστοσελίδας που χρησιμοποιεί το WordPress; Μπορείτε να πληρώσετε για να λάβετε θετικές κριτικές στο κατάστημα εφαρμογών; Ποιες εταιρείες παρέχουν αυτές τις υπηρεσίες;Θέλω να κάνω μια εφαρμογή που θα μπορούσαν να χρησιμοποιηθούν από τους μαθητές για ένα συγκεκριμένο θέμα. Δεν ξέρω πώς να κωδικοποιήσω. Τι πρέπει να κάνω? Πού πρέπει να ξεκινήσω;Πώς μπορώ να μάθω C ++ σε μία νύχτα; Ξέρω ότι είναι δυνατό.πώς να ρωτήσετε κάποιον μέσω emailΠώς μπορώ να αποκτήσω δίκτυο πελατών για την εταιρεία σχεδιασμού ιστοσελίδων μου; Πώς αποκτάτε πρόσβαση στη μεταβλητή περιόδου σύνδεσης από άλλη σελίδα με PHP;