इस फेरी की सवारी करने के लिए आपको 64-बिट होना चाहिए
Pixel 7 के लिए अपडेटेड NY Waterway ऐप को रिवर्स इंजीनियरिंग करें
टीएलडीआर : यदि आपके पास एक नया एंड्रॉइड डिवाइस है जो आपको एनवाई वाटरवे स्थापित नहीं करने देगा, तो आप एप्लिकेशन के मेरे संशोधित संस्करण को डाउनलोड कर सकते हैं । आपको हमेशा रैंडम एप्लिकेशन इंस्टॉल करने में सावधानी बरतनी चाहिए, विशेष रूप से आधिकारिक Play Store के अलावा अन्य स्रोतों से - जैसे किसी रैंडम व्यक्ति द्वारा यह मीडियम पोस्ट जिसके बारे में आपने कभी नहीं सुना होगा। यदि आप अतिरिक्त सतर्क रहना चाहते हैं, तो आप यह देखने के लिए आगे पढ़ सकते हैं कि एपीके को कैसे संशोधित किया गया था (और यदि आप चाहें तो स्वयं चरणों को दोहरा सकते हैं)।
2019 में, Google ने Play Store में सभी नए और अपडेट किए गए एप्लिकेशन के लिए 64-बिट समर्थन आवश्यक कर दिया। अगस्त 2021 से, 64-बिट आर्किटेक्चर का समर्थन नहीं करने वाले एप्लिकेशन 64-बिट सक्षम उपकरणों के लिए Play Store में अनुपलब्ध हो गए। विशेष रूप से, नया पिक्सेल 7 और पिक्सेल 7 प्रो केवल 32-बिट एप्लिकेशन इंस्टॉल करने का समर्थन नहीं करते हैं ।
हडसन रिवर फेरी की सवारी करने वाले न्यू यॉर्कर्स के लिए, यह काफी असुविधाजनक है क्योंकि आपके फोन, एनवाई वाटरवे पर इलेक्ट्रॉनिक टिकट प्रदान करने वाला एप्लिकेशन वास्तव में पुराना है । इसे अंतिम बार जून 2018 में प्रकाशित किया गया था, और इसमें केवल 32-बिट आर्किटेक्चर के लिए मूल पुस्तकालय शामिल हैं... इसलिए, नए पिक्सेल उपकरणों के उपयोगकर्ताओं के लिए, आपके लिए हडसन रिवर फेरी पर कोई इलेक्ट्रॉनिक टिकट नहीं है!
मैंने अब से कई साल पहले iPhone पर स्विच किया था, लेकिन जब मैं एक Android उपयोगकर्ता था, तो मैं OS और एप्लिकेशन के साथ हैक करता था - कस्टम रोम स्थापित करना और एप्लिकेशन को डिकंपाइल करना। मेरे एक करीबी दोस्त को नया पिक्सेल 7 प्रो मिला और वह हर समय हडसन रिवर फेरी लेता है, इसलिए उसने मजाक में मुझे उसके लिए इस ऐप को ठीक करने के लिए कहा। ये रहा!
आवेदन में झाँकना
आइए एनवाई वाटरवे एप्लिकेशन का निरीक्षण करके उन हिस्सों की पहचान करना शुरू करें जो केवल 32-बिट हैं, जो इसे स्थापित होने से रोक रहे हैं। का उपयोग करके apktool
, हम Android एप्लिकेशन को निकाल सकते हैं और उसके कोड का निरीक्षण कर सकते हैं।
$ apktool d ./NYWaterway.apk
I: Using Apktool 2.6.1 on NYWaterway.apk
I: Loading resource table...
I: Decoding AndroidManifest.xml with resources...
I: Loading resource table from file: /Users/joeywatts/Library/apktool/framework/1.apk
I: Regular manifest package...
I: Decoding file-resources...
I: Decoding values */* XMLs...
I: Baksmaling classes.dex...
I: Copying assets and libs...
I: Copying unknown files...
I: Copying original files...
$ cd ./NYWaterway
$ ls -l
total 72
-rw-r--r-- 1 joeywatts staff 8797 Nov 21 18:37 AndroidManifest.xml
-rw-r--r-- 1 joeywatts staff 21382 Nov 21 18:37 apktool.yml
drwxr-xr-x 14 joeywatts staff 448 Nov 21 18:37 assets
drwxr-xr-x 5 joeywatts staff 160 Nov 21 18:37 lib
drwxr-xr-x 4 joeywatts staff 128 Nov 21 18:37 original
drwxr-xr-x 178 joeywatts staff 5696 Nov 21 18:37 res
drwxr-xr-x 10 joeywatts staff 320 Nov 21 18:37 smali
drwxr-xr-x 10 joeywatts staff 320 Nov 21 18:37 unknown
64-बिट संगतता और मूल पुस्तकालय
एंड्रॉइड एप्लिकेशन आमतौर पर जावा या कोटलिन में लिखे जाते हैं, दोनों भाषाएं जावा वर्चुअल मशीन को लक्षित करती हैं, जो एक उच्च-स्तरीय अमूर्तता है जो आम तौर पर आपको प्लेटफ़ॉर्म-विशिष्ट संगतता के बारे में चिंताओं से बचाती है। हालाँकि, आप मूल, प्लेटफ़ॉर्म-विशिष्ट कोड (आमतौर पर निम्न-स्तरीय भाषाओं जैसे C या C++ से संकलित) को कॉल करने के लिए जावा नेटिव इंटरफ़ेस (JNI) का उपयोग कर सकते हैं। यदि हम libs
निर्देशिका को देखते हैं, तो हम NY जलमार्ग ऐप में शामिल देशी पुस्तकालयों को देख सकते हैं।
$ ls -lR lib/*
lib/armeabi:
total 8352
-rw-r--r-- 1 joeywatts staff 177900 Nov 21 18:37 libdatabase_sqlcipher.so
-rw-r--r-- 1 joeywatts staff 1369284 Nov 21 18:37 libsqlcipher.so
-rw-r--r-- 1 joeywatts staff 2314540 Nov 21 18:37 libsqlcipher_android.so
-rw-r--r-- 1 joeywatts staff 402604 Nov 21 18:37 libstlport_shared.so
lib/armeabi-v7a:
total 2552
-rw-r--r-- 1 joeywatts staff 1303788 Nov 21 18:37 libsqlcipher.so
lib/x86:
total 14616
-rw-r--r-- 1 joeywatts staff 1476500 Nov 21 18:37 libdatabase_sqlcipher.so
-rw-r--r-- 1 joeywatts staff 2246448 Nov 21 18:37 libsqlcipher.so
-rw-r--r-- 1 joeywatts staff 3294132 Nov 21 18:37 libsqlcipher_android.so
-rw-r--r-- 1 joeywatts staff 455740 Nov 21 18:37 libstlport_shared.so
यहाँ एक और अवलोकन यह है कि armeabi
और x86
चार पुस्तकालय हैं जबकि armeabi-v7a
केवल एक है। एंड्रॉइड ऐप द्वारा लाइब्रेरी को लोड करने के लिए, उसे java.lang.System.loadLibrary
या में कॉल करना होगा java.lang.Runtime.loadLibrary
। "लोडलाइब्रेरी" के लिए स्माली कोड की खोज करने से केवल एक ही स्थान का पता चलता है जहां यह देशी पुस्तकालयों को लोड कर रहा है।
$ grep -r loadLibrary smali/
smali//net/sqlcipher/database/SQLiteDatabase.smali: invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
$ grep loadLibrary -A 2 -B 3 smali/net/sqlcipher/database/SQLiteDatabase.smali
:try_start_0
const-string v0, "sqlcipher"
invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V
:try_end_0
.catchall {:try_start_0 .. :try_end_0} :catchall_0
एप्लिकेशन को नए पिक्सेल उपकरणों के साथ संगत बनाने के लिए libsqlcipher.so
हमें 64-बिट एआरएम बिल्ड की आवश्यकता है। lib/arm64-v8a
आसानी से, SQLCipher एक ओपन सोर्स लाइब्रेरी है । देशी sqlcipher पुस्तकालय के साथ बातचीत के लिए उच्च-स्तरीय गोंद कोड को देखते हुए, हम उस पुस्तकालय के संस्करण को देख सकते हैं जिसका उपयोग किया गया था।
$ grep -ri version smali/net/sqlcipher
smali/net/sqlcipher/database/SQLiteDatabase.smali:.field public static final SQLCIPHER_ANDROID_VERSION:Ljava/lang/String; = "3.5.4"
SQLCipher को v3.5.5 में अपग्रेड करना
अपग्रेड करने की प्रक्रिया में नए संस्करण से कोड के साथ SQLCipher Smali कोड और देशी लाइब्रेरी को बदलना शामिल होगा। यदि SQLCipher की सार्वजनिक API सतह महत्वपूर्ण रूप से बदल जाती है, तो यह समस्याएँ पैदा करेगा (उदाहरण के लिए, यदि NY जलमार्ग द्वारा उपयोग किए जाने वाले सार्वजनिक फ़ंक्शन ने या तो हस्ताक्षर बदल दिए हैं या हटा दिए गए हैं, तो इसे नए संस्करण के साथ बदलने से समस्याएँ पैदा होंगी)। v3.5.4 से v3.5.5 में परिवर्तनों का त्वरित स्कैन करना, ऐसा नहीं लगता कि यह कोई समस्या है जो यहां दिखाई देगी। मैंने SQLCipher v3.5.5 के लिए AAR फ़ाइल डाउनलोड की और फिर unzip
इसे निकालने के लिए इस्तेमाल किया।
$ mkdir ../sqlcipher && cd ../sqlcipher
$ unzip ~/Downloads/android-database-sqlcipher-3.5.5.aar
Archive: /Users/joeywatts/Downloads/android-database-sqlcipher-3.5.5.aar
inflating: AndroidManifest.xml
creating: res/
inflating: classes.jar
creating: jni/
creating: jni/arm64-v8a/
creating: jni/armeabi/
creating: jni/armeabi-v7a/
creating: jni/x86/
creating: jni/x86_64/
inflating: jni/arm64-v8a/libsqlcipher.so
inflating: jni/armeabi/libsqlcipher.so
inflating: jni/armeabi-v7a/libsqlcipher.so
inflating: jni/x86/libsqlcipher.so
inflating: jni/x86_64/libsqlcipher.so
एंड्रॉइड एसडीके एक कमांड लाइन टूल प्रदान करता है जिसे एंड्रॉइड बाइट कोड ( फ़ाइल) d8
में फ़ाइल संकलित कर सकता है । फिर वहाँ एक और उपकरण कहा जाता है जो फ़ाइलों को डीकंपाइल कर सकता है । चरणों को एक साथ जोड़ना:jar
classes.dex
baksmali
dex
smali
$ export ANDROID_HOME=/Users/joeywatts/Library/Android/sdk
$ $ANDROID_HOME/build-tools/33.0.0/d8 classes.jar \
--lib $ANDROID_HOME/platforms/android-31/android.jar
$ java -jar ../baksmali.jar dis ./classes.dex
$ rm -r ../NYWaterway/smali/net/sqlcipher ../NYWaterway/lib
$ mv out/net/sqlcipher ../NYWaterway/smali/net/sqlcipher
$ mv jni ../NYWaterway/lib
अब, हम एप्लिकेशन को फिर से बना सकते हैं और उस पर हस्ताक्षर कर सकते हैं, इसलिए इसे डिवाइस पर इंस्टॉल किया जा सकता है!
$ cd ../NYWaterway
$ apktool b .
$ keytool -genkey -v -keystore my-release-key.keystore -alias alias_name \
-keyalg RSA -keysize 2048 -validity 10000
$ $ANDROID_HOME/build-tools/33.0.0/apksigner sign \
--ks my-release-key.keystore ./dist/NYWaterway.apk
लक्ष्य SDK संस्करण बढ़ाना
इस पॉपअप से छुटकारा पाने के लिए यह दर्शाता है कि एप्लिकेशन Android के पुराने संस्करण के लिए बनाया गया था, हमें लक्ष्य SDK संस्करण को apktool.yml
. एसडीके संस्करण <31 को लक्षित करने वाले एप्लिकेशन अब प्ले स्टोर में स्वीकार नहीं किए जाते हैं, इसलिए मैंने इसे उस तक बढ़ाना चुना।
एंड्रॉइड एसडीके के एक नए संस्करण को लक्षित करने के लिए कोड परिवर्तन की आवश्यकता हो सकती है क्योंकि बहिष्कृत एपीआई नए एसडीके संस्करणों में अनुपलब्ध हो जाते हैं। NY जलमार्ग को SDK v31 को लक्षित करने के लिए कई परिवर्तनों की आवश्यकता है।
सुरक्षित घटक निर्यात
यदि आपका ऐप Android 12 या उच्चतर को लक्षित करता है और इसमें गतिविधियाँ, सेवाएँ या प्रसारण रिसीवर शामिल हैं जो इंटेंट फ़िल्टर का उपयोग करते हैं, तो आपको android:exported
इन ऐप घटकों के लिए स्पष्ट रूप से विशेषता घोषित करनी होगी।
ऐसी कुछ गतिविधियां और एक रिसीवर हैं जिनमें <intent-filter>
एस है और इसमें जोड़ने के लिए एक android:exported="true"
विशेषता की आवश्यकता है AndroidManifest.xml
।
लंबित इरादे परिवर्तनशीलता
यदि आपका ऐप Android 12 को लक्षित करता है, तो आपको अपने ऐप द्वारा बनाए जाने वाले प्रत्येक ऑब्जेक्ट की परिवर्तनशीलता को निर्दिष्ट करना होगा । PendingIntent
यह अतिरिक्त आवश्यकता आपके ऐप की सुरक्षा को बेहतर बनाती है।
यह एक पेचीदा है, क्योंकि इसके लिए हमें वास्तविक कोड को बदलने की आवश्यकता है (प्रोजेक्ट कॉन्फ़िगरेशन या लाइब्रेरी के उन्नत संस्करण की प्रतिलिपि बनाने के विपरीत)।
जब भी कोई PendingIntent
वस्तु बनाई जाती है, उसे स्पष्ट रूप से FLAG_MUTABLE
या निर्दिष्ट करने की आवश्यकता होती है FLAG_IMMUTABLE
। पूर्व एसडीके संस्करणों में, FLAG_MUTABLE
डिफ़ॉल्ट था यदि कोई ध्वज निर्दिष्ट नहीं किया गया था। PendingIntent
ऑब्जेक्ट वर्ग पर स्थिर विधियों के एक सेट द्वारा बनाए जाते हैं: getActivity
, getActivities
, getBroadcast
, या getService
। हम उन कार्यों के आह्वान की खोज करके शुरू कर सकते हैं।
$ grep -r -E "PendingIntent;->(getActivity|getActivities|getBroadcast|getService)" smali
smali/android/support/v4/f/a/ac.smali: invoke-static {p1, v2, v0, v2}, Landroid/app/PendingIntent;->getBroadcast(Landroid/content/Context;ILandroid/content/Intent;I)Landroid/app/PendingIntent;
smali/com/google/firebase/iid/r.smali: invoke-static {p0, p1, v0, p4}, Landroid/app/PendingIntent;->getBroadcast(Landroid/content/Context;ILandroid/content/Intent;I)Landroid/app/PendingIntent;
smali/com/google/firebase/iid/m.smali: invoke-static {p0, v2, v0, v3}, Landroid/app/PendingIntent;->getBroadcast(Landroid/content/Context;ILandroid/content/Intent;I)Landroid/app/PendingIntent;
smali/com/google/firebase/messaging/c.smali: invoke-static {v0, v2, v1, v3}, Landroid/app/PendingIntent;->getActivity(Landroid/content/Context;ILandroid/content/Intent;I)Landroid/app/PendingIntent;
smali/com/google/android/gms/common/m.smali: invoke-static {p1, p3, v0, v1}, Landroid/app/PendingIntent;->getActivity(Landroid/content/Context;ILandroid/content/Intent;I)Landroid/app/PendingIntent;
smali/com/google/android/gms/common/api/GoogleApiActivity.smali: invoke-static {p0, v0, v1, v2}, Landroid/app/PendingIntent;->getActivity(Landroid/content/Context;ILandroid/content/Intent;I)Landroid/app/PendingIntent;
smali/com/google/android/gms/c/cbx.smali: invoke-static {v1, v2, v0, v3}, Landroid/app/PendingIntent;->getActivity(Landroid/content/Context;ILandroid/content/Intent;I)Landroid/app/PendingIntent;
smali/com/google/android/gms/c/cbx.smali: invoke-static {v2, v7, v1, v7}, Landroid/app/PendingIntent;->getBroadcast(Landroid/content/Context;ILandroid/content/Intent;I)Landroid/app/PendingIntent;
smali/com/google/android/gms/c/v.smali: invoke-static {v0, v1, v2, v3}, Landroid/app/PendingIntent;->getActivity(Landroid/content/Context;ILandroid/content/Intent;I)Landroid/app/PendingIntent;
smali/com/google/android/gms/c/bj.smali: invoke-static {v1, p2, v0, v2}, Landroid/app/PendingIntent;->getActivity(Landroid/content/Context;ILandroid/content/Intent;I)Landroid/app/PendingIntent;
smali/com/google/android/gms/c/byd.smali: invoke-static {v1, v4, v0, v4}, Landroid/app/PendingIntent;->getBroadcast(Landroid/content/Context;ILandroid/content/Intent;I)Landroid/app/PendingIntent;
smali/com/google/android/gms/c/mr.smali: invoke-static {v1, v3, v0, v3}, Landroid/app/PendingIntent;->getBroadcast(Landroid/content/Context;ILandroid/content/Intent;I)Landroid/app/PendingIntent;
स्माली को समझना
बाइट कोड निर्देश स्थिर फ़ंक्शन में पैरामीटर के रूप में पारित होने वाले रजिस्टरों की invoke-static
एक सूची लेता है। स्थिर फ़ंक्शन का प्रतीक ऐसा दिखता है Landroid/app/PendingIntent;->getBroadcast(Landroid/content/Context;ILandroid/content/Intent;I)Landroid/app/PendingIntent;
जो पूरी तरह से योग्य वर्ग के नाम और फ़ंक्शन के हस्ताक्षर से सीधा अनुवाद है। यह वर्ग के नाम Landroid/app/PendingIntent;
(या android.app.PendingIntent
सामान्य जावा सिंटैक्स में) से शुरू होता है। फिर फ़ंक्शन का नाम ( ->getBroadcast
) पैरामीटर और रिटर्न प्रकार के साथ। Landroid/content/Context;ILandroid/content/Intent;I
पैरामीटर हैं, जिन्हें चार पैरामीटर में विभाजित किया जा सकता है: Landroid/content/Context;
( android.content.Context
), I
( int
), Landroid/content/Intent;
( android.content.Intent
), और I
( int
)। अंत में, समापन कोष्ठक के बाद रिटर्न प्रकार है Landroid/app/PendingIntent;
:।
इसलिए, invoke-static {v1, v2, v3, v4}
ऊपर दिए गए फ़ंक्शन v1
में से Context
, v2
पहले int
के v3
रूप में , के रूप में Intent
, और v4
के रूप में पास होगा int
। इन PendingIntent
एपीआई के लिए, flags
हमेशा अंतिम पैरामीटर ( int
) होते हैं, इसलिए हमें केवल यह सुनिश्चित करने की आवश्यकता है कि मान में हमेशा FLAG_MUTABLE
या तो FLAG_IMMUTABLE
सेट हो। Android SDK प्रलेखनFLAG_MUTABLE
से पता चलता है कि is 0x02000000
और FLAG_IMMUTABLE
is का मान है 0x04000000
। ज्यादातर मामलों में, अंतिम पैरामीटर को एक स्थानीय चर रजिस्टर ( v#
) के रूप में निर्दिष्ट किया जाता है जिसे एक स्थिर मान (जैसे const/high16 v3, 0x8000000
या const/4 v4, 0x0
) के साथ आरंभ किया गया था। इन मामलों में, हम तुच्छ रूप से जाँच सकते हैं कि क्या FLAG_MUTABLE
याFLAG_IMMUTABLE
सेट है और यदि यह नहीं है तो स्थिरांक को अपडेट करें।
- const/high16 v3, 0x8000000
+ const/high16 v3, 0xA000000
invoke-static {v1, v2, v0, v3}, Landroid/app/PendingIntent;->getActivity(Landroid/content/Context;ILandroid/content/Intent;I)Landroid/app/PendingIntent;
# you may need to change from const/4 to const/high16 to specify the flag
# const/4 is a loading a signed 4-bit integer (seen used to load 0x0).
# const/high16 loads the high 16-bits from a value (the low 16-bits must be 0)
- const/4 v4, 0x0
+ const/high16 v4, 0x2000000
.method private static a(Landroid/content/Context;ILjava/lang/String;Landroid/content/Intent;I)Landroid/app/PendingIntent;
.locals 2
new-instance v0, Landroid/content/Intent;
const-class v1, Lcom/google/firebase/iid/FirebaseInstanceIdInternalReceiver;
invoke-direct {v0, p0, v1}, Landroid/content/Intent;-><init>(Landroid/content/Context;Ljava/lang/Class;)V
invoke-virtual {v0, p2}, Landroid/content/Intent;->setAction(Ljava/lang/String;)Landroid/content/Intent;
const-string v1, "wrapped_intent"
invoke-virtual {v0, v1, p3}, Landroid/content/Intent;->putExtra(Ljava/lang/String;Landroid/os/Parcelable;)Landroid/content/Intent;
invoke-static {p0, p1, v0, p4}, Landroid/app/PendingIntent;->getBroadcast(Landroid/content/Context;ILandroid/content/Intent;I)Landroid/app/PendingIntent;
move-result-object v0
return-object v0
.end method
if (p4 & (FLAG_IMMUTABLE | FLAG_MUTABLE) == 0) {
p4 |= FLAG_MUTABLE;
}
const/high16 v3, 0x6000000 # v3 = FLAG_IMMUTABLE | FLAG_MUTABLE
and-int v2, p4, v3 # v2 = p4 & v3
if-nez v2, :cond_0 # if (v2 != 0) { goto :cond_0; }
const/high16 v3, 0x2000000 # v3 = FLAG_MUTABLE
or-int p4, p4, v3 # p4 = p4 | v3
:cond_0
फ़ाइल सिस्टम अनुमति परिवर्तन
निजी फ़ाइलों की फ़ाइल अनुमतियों को अब स्वामी द्वारा शिथिल नहीं किया जाना चाहिए, और MODE_WORLD_READABLE
और/या का उपयोग करके ऐसा करने का प्रयास एक MODE_WORLD_WRITEABLE
को ट्रिगर करेगा SecurityException
।
कुछ SharedPreferences
एपीआई उपयोग था जो में उपयोग कर रहा MODE_WORLD_READABLE
था com/google/android/gms/ads/identifier/AdvertisingIdClient.smali
। इसे ठीक करना बहुत आसान था, क्योंकि यह ( ) से ( ) स्विच करने MODE_WORLD_READABLE
की 0x1
बात MODE_PRIVATE
थी 0x0
।
--- a/smali/com/google/android/gms/ads/identifier/AdvertisingIdClient.smali
+++ b/smali/com/google/android/gms/ads/identifier/AdvertisingIdClient.smali
@@ -93,7 +93,7 @@
const-string v4, "google_ads_flags"
- const/4 v5, 0x1
+ const/4 v5, 0x0
invoke-virtual {v2, v4, v5}, Landroid/content/Context;->getSharedPreferences(Ljava/lang/String;I)Landroid/content/SharedPreferences;
Android 6.0 के साथ, हमने Apache HTTP क्लाइंट के लिए समर्थन हटा दिया है। एंड्रॉइड 9 से शुरू होकर, वह लाइब्रेरी बूटक्लासपाथ से हटा दी गई है और डिफ़ॉल्ट रूप से ऐप्स के लिए उपलब्ध नहीं है।
एनवाई वाटरवे अपाचे एचटीटीपी क्लाइंट के एंड्रॉइड संस्करण का उपयोग कर रहा था, लेकिन इसके लिए फिक्स बहुत आसान है - AndroidManifest.xml
.
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 1490d73..39ccbf3 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -16,6 +16,7 @@
<permission android:name="co.bytemark.nywaterway.permission.C2D_MESSAGE" android:protectionLevel="signature"/>
<uses-permission android:name="co.bytemark.nywaterway.permission.C2D_MESSAGE"/>
<application android:allowBackup="false" android:icon="@drawable/icon" android:label="@string/app_name" android:name="co.bytemark.nywaterway2.core.NYWWApp" android:theme="@style/AppTheme">
+ <uses-library android:name="org.apache.http.legacy" android:required="false" />
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version"/>
<receiver android:exported="false" android:label="NetworkConnection" android:name="co.bytemark.android.sdk.BytemarkSDK$ConnectionChangeReceiver">
<intent-filter>
यदि आपका ऐप Android 9 या उच्चतर को लक्षित करता है, तो isCleartextTrafficPermitted()
विधि false
डिफ़ॉल्ट रूप से वापस आ जाती है। यदि आपके ऐप को विशिष्ट डोमेन के लिए क्लियरटेक्स्ट को सक्षम करने की आवश्यकता है, तो आपको अपने ऐप के नेटवर्क सुरक्षा कॉन्फ़िगरेशन में उन डोमेन के लिए स्पष्ट रूप से सेट cleartextTrafficPermitted
करना होगा।true
इस नई सुरक्षा सुविधा के कारण नेटवर्क अनुरोध विफल हो रहे थे। एप्लिकेशन को संगत बनाने का सबसे सरल तरीका विशेषता AndroidManifest.xml
जोड़ने के लिए केवल एक और परिवर्तन था।android:usesCleartextTraffic="true"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 39ccbf3..69b4aa7 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -15,7 +15,7 @@
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
<permission android:name="co.bytemark.nywaterway.permission.C2D_MESSAGE" android:protectionLevel="signature"/>
<uses-permission android:name="co.bytemark.nywaterway.permission.C2D_MESSAGE"/>
- <application android:allowBackup="false" android:icon="@drawable/icon" android:label="@string/app_name" android:name="co.bytemark.nywaterway2.core.NYWWApp" android:theme="@style/AppTheme">
+ <application android:allowBackup="false" android:icon="@drawable/icon" android:label="@string/app_name" android:name="co.bytemark.nywaterway2.core.NYWWApp" android:theme="@style/AppTheme" android:usesCleartextTraffic="true">
<uses-library android:name="org.apache.http.legacy" android:required="false" />
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version"/>
<receiver android:exported="false" android:label="NetworkConnection" android:name="co.bytemark.android.sdk.BytemarkSDK$ConnectionChangeReceiver">
उपरोक्त सभी परिवर्तन करने के बाद, एप्लिकेशन बिना किसी परेशान पॉपअप के सफलतापूर्वक चलता है कि इसे एंड्रॉइड के पुराने संस्करण के लिए बनाया गया था!
कुछ हद तक अप्रत्याशित रूप से, इसे नए लक्ष्य एसडीके संस्करण के साथ काम करना वास्तव में 64-बिट समस्या को ठीक करने की तुलना में बहुत अधिक शामिल था, लेकिन दिन के अंत में, सब कुछ सिर्फ कोड है और कोड से डरने की कोई बात नहीं है ...
कनेक्ट करना चाहते हैं? मुझे ट्विटर या लिंक्डइन पर एक संदेश भेजें !