android ITelephony.aidl क्यों काम करता है?



performance android-intent (1)

दरअसल, अपनी परियोजना में ITelephony.aidl जोड़ना आवश्यक नहीं है, यह केवल एक सुविधा है। आप इसे इस तरह से भी कर सकते हैं:

TelephonyManager tm = (TelephonyManager) context
            .getSystemService(Context.TELEPHONY_SERVICE);
Class c = Class.forName(tm.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
Object telephonyService = m.invoke(tm); // Get the internal ITelephony object
c = Class.forName(telephonyService.getClass().getName()); // Get its class
m = c.getDeclaredMethod("endCall"); // Get the "endCall()" method
m.setAccessible(true); // Make it accessible
m.invoke(telephonyService); // invoke endCall()

कवर के तहत यह सभी निजी (यानी सार्वजनिक रूप से दस्तावेज नहीं) विधियों तक पहुंचने के लिए जावा प्रतिबिंब का उपयोग करके काम करता है। आप ओपन-सोर्स (यानी: सार्वजनिक रूप से उपलब्ध) एंड्रॉइड स्रोत कोड पढ़कर, वहां क्या तरीके हैं, और वे क्या करते हैं, यह पता लगा सकते हैं। एक बार जब आप जानते हैं कि वहां क्या है और यह क्या करता है, तो आप इसे पाने के लिए प्रतिबिंब का उपयोग कर सकते हैं, भले ही यह "छुपा" हो।

TelephonyManager क्लास एक दूरस्थ सेवा का उपयोग कर लागू किया गया है। यदि आप TelephonyManager से आपके लिए कुछ करने का अनुरोध करना चाहते हैं, तो आप TelephonyManager (यह सार्वजनिक रूप से प्रलेखित भाग है) पर एक विधि कॉल करते हैं और आंतरिक रूप से यह वास्तव में काम करने के लिए रिमोट टेलीफोनी सेवा को कॉल करता है। यह एआईडीएल का उपयोग करके किया जाता है, जो कि "रिमोट प्रोसेस कॉल" का एक प्रकार है। रिमोट सेवा उन चीजों को कर सकती है जो TelephonyManager क्लास के माध्यम से सार्वजनिक रूप से सामने नहीं आती हैं। आप यहां क्या कर रहे हैं getITelephony() का उपयोग कर "रिमोट getITelephony() कॉल" इंटरफ़ेस का क्लाइंट-साइड प्राप्त कर रहा है। यह ITelephony प्रकार का एक वस्तु देता है। इस श्रेणी में endCall() नामक एक विधि है। एक बार हमारे पास ITelephony टाइप करने का ऑब्जेक्ट हो ITelephony , हम इसकी क्लास ऑब्जेक्ट प्राप्त कर सकते हैं और फिर कक्षा से विधि endCall() प्राप्त कर सकते हैं। एक बार हमारे पास विधि हो जाने के बाद, हम इसे सुलभ बनाते हैं और इसे कॉल करने के बजाय। विधि endCall() दूरस्थ प्रक्रिया कॉल के क्लाइंट-साइड में है। विधि अब टेलीफ़ोनी प्रबंधक सेवा (जो रिमोट सर्वर में चल रही है) को एक संदेश भेजती है और कॉल को समाप्त करने के लिए कहती है।

चूंकि ITelephony.aidl के लिए स्रोत कोड सार्वजनिक रूप से उपलब्ध है, इसलिए आप अपने प्रोजेक्ट में सोर्स कोड डाल सकते हैं और आपका आईडीई ITelephony.java (जिसमें दूरस्थ प्रक्रिया कॉल का क्लाइंट-साइड शामिल है) उत्पन्न करेगा ITelephony.aidl । फिर आप इसे import कर सकते हैं और आपका आईडीई अब ITelephony क्लास और इसके तरीकों के बारे में ITelephony । यह आपके प्रोजेक्ट को संकलित करते समय संकलक को सही बाइट-कोड उत्पन्न करने की अनुमति देता है। जब आप एंड्रॉइड डिवाइस पर यह कोड चलाते हैं, तो आप ITelephony ऑब्जेक्ट प्राप्त करने के लिए एंड्रॉइड फ्रेमवर्क में कॉल करते हैं और फिर आप इसे com.android.internal.telephony.ITelephony डाल देते हैं। तब से, आप जेनरेट ITelephony.java गए ITelephony.java का उपयोग करके ऑब्जेक्ट के तरीकों और फ़ील्ड तक पहुंच सकते हैं जब तक कि आपके पास ITelephony लिए जावा कोड लौटाए गए ITelephony ऑब्जेक्ट की वास्तविक श्रेणी परिभाषा से मेल खाता हो। यदि कक्षा परिभाषाएं मेल नहीं खाती हैं, तो वीएम एक उचित अपवाद फेंक देगा।

हम उम्मीद करते है कि यह आपके सवाल का जवाब दे देगा। मुझे बिल्कुल यकीन नहीं था कि आप इसके बारे में कितना पहले से जानते थे, इसलिए हो सकता है कि मैंने उन चीजों का उल्लेख किया जो आप पहले ही जानते हैं। यदि हां, तो इसके बारे में खेद है। यदि यह स्पष्ट नहीं है, तो कृपया इंगित करें कि आप वास्तव में क्या समझ में नहीं आते हैं।

मैंने कुछ एसओ पोस्ट देखे जो कि एक फोन कॉल प्रोग्राम को समाप्त करने के तरीके के बारे में चर्चा करते हैं, उदाहरण के लिए, यह एक । हां, लोग नतीजे पर ध्यान केंद्रित करते हैं लेकिन कोई भी वास्तव में कारण बताता है कि यह क्यों काम करता है?

मैंने कोड की कोशिश की, यह अच्छी तरह से काम करता है। लेकिन मैं नीचे क्या हो रहा है के बारे में अधिक जानकारी जानना चाहूंगा? ITelephony.aidl बनाकर क्यों, एंड्रॉइड छुपा आंतरिक ITelephony इंटरफेस हमारी परियोजना में उजागर किया गया है? कैसे हम ITelephony.aidl और स्वचालित रूप से जेनरेट किए गए जावा (/gen/ITelephony.java) को एंड्रॉइड के ITelephony इंटरफ़ेस से लिंक करते हैं ? क्या यह केवल नाम मिलान (पैकेज नाम और सहायता फ़ाइल नाम) के कारण है?

TelephonyManager tm = (TelephonyManager) context
                .getSystemService(Context.TELEPHONY_SERVICE);

Class c = Class.forName(tm.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);

//Why does the android internal ITelephony interface is exposed after created the ITelephony.aidl?
com.android.internal.telephony.ITelephony telephonyService = (ITelephony) m.invoke(tm);
telephonyService.endCall(); 




telephonymanager