Important Announcement
PubHTML5 Scheduled Server Maintenance on (GMT) Sunday, June 26th, 2:00 am - 8:00 am.
PubHTML5 site will be inoperative during the times indicated!

Home Explore CU-MCA-SEM-VI-Advanced mobile application development-Second Draft

CU-MCA-SEM-VI-Advanced mobile application development-Second Draft

Published by Teamlease Edtech Ltd (Amita Chitroda), 2021-11-02 18:06:12

Description: CU-MCA-SEM-VI-Advanced mobile application development-Second Draft

Search

Read the Text Version

\"salary\": 56000, \"married\": true } } json array The [ (square bracket) represents the json array. [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"]  Example of android JSON parsing activity_main.xml <RelativeLayout xmlns:androclass=\"http://schemas.android.com/apk/res/android\" xmlns:tools=\"http://schemas.android.com/tools\" android:layout_width=\"match_parent\" android:layout_height=\"match_parent\" tools:context=\".MainActivity\" > <TextView android:id=\"@+id/textView1\" android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\" android:layout_alignParentLeft=\"true\" android:layout_alignParentTop=\"true\" android:layout_marginLeft=\"75dp\" android:layout_marginTop=\"46dp\" android:text=\"TextView\" /> </RelativeLayout> Activity class MainActivity.java package com.javatpoint.jsonparsing; import org.json.JSONException; import org.json.JSONObject; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; public class MainActivity extends Activity { 101 CU IDOL SELF LEARNING MATERIAL (SLM)

public static final String JSON_STRING=\"{\\\"employee\\\":{\\\"name\\\":\\\"Sachin\\\",\\\"salary\\\":56000}}\"; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView textView1=(TextView)findViewById(R.id.textView1); try{ JSONObject emp=(new JSONObject(JSON_STRING)).getJSONObject(\"employee\"); String empname=emp.getString(\"name\"); int empsalary=emp.getInt(\"salary\"); String str=\"Employee Name:\"+empname+\"\\n\"+\"Employee Salary:\"+empsalary; textView1.setText(str); }catch (Exception e) {e.printStackTrace();} } } Output: 102 CU IDOL SELF LEARNING MATERIAL (SLM)

Figure 6.3JSON parsing 6.6 SUMMARY  JSON - Parsing For parsing a JSON object, we will create an object of class JSONObject and specify a string containing JSON data to it. Its syntax is – String in;  JSON stands for JavaScript object notation. JSON has been derived from javascript, where javascript is a programming language. It was originally created to hold the structured data that could be used in javascript. JSON became so popular that it is used for data for all kinds of applications. It is the most popular way of sending the data for Web APIs.  Basic data types supported by json are: Strings: Characters that are enclosed in single or double quotation marks. Number: A number could be integer or decimal, positive or negative. Booleans: The Boolean value could be either true or false without any quotation marks. Null: Here, null means nothing without any quotation marks.  XML stands for an extensible markup language. It is like HTML, where HTML stands for Hypertext Markup language. HTML is used for creating websites, whereas XML can be used for any kind of structured data. 103 CU IDOL SELF LEARNING MATERIAL (SLM)

6.7 KEYWORDS  Parsing: analyse (a string or text) into logical syntactic components.  API:In computer programming, an application programming interface (API) is a set of subroutine definitions, protocols, and tools for building software and applications.  HTML: is the set of markup symbols or codes inserted into a file intended for display on the Internet. The markup tells web browsers how to display a web page's words and images.  ListView: Android ListView is a ViewGroup that is used to display the list of items in multiple rows and contains an adapter that automatically inserts the items into the list.  Adapters: An Adapter object acts as a bridge between an AdapterView and the underlying data for that view. The Adapter provides access to the data items. 6.8LEARNING ACTIVITY 1. Explain the components of an JSON file ___________________________________________________________________________ ___________________________________________________________________________ 2. What do you understand by JSON – Parsing? ___________________________________________________________________________ ___________________________________________________________________________ 6.9 UNIT END QUESTIONS A. Descriptive Questions Short Questions 1. What is json? What are basic data types supported by json? 2. State the similarities between the json and XML. 3. Explain how object is created using JSON 4. Write a program to create an xml file named file.xml inside the assets directory 5. State advantage of JSON over XML Long Questions 1. Explain with example SAX Xml parsing 2. Explain with example of android XMLPullParser 3. Differentiate between the json and XML 4. Explain JSON Parsing in detail. 104 CU IDOL SELF LEARNING MATERIAL (SLM)

B. Multiple Choice Questions 105 1. In JSON keys are ______ a. string b. character c. values d. data 2. JSON is faster and easier than xml for ______ applications a. JAX b. AJAX c. XML d. ARRAY 3. JSON (Javascript Object Notation) is a __________ a. DML b. DDL c. Programming Language d. Unstructured Language 4. The SAX parser cannot be used to create the XML file a. TRUE b. FALSE 5. JSON is __________ a. data-oriented. CU IDOL SELF LEARNING MATERIAL (SLM)

b. object-oriented c. structure -oriented d. All of these Answers 1-a, 2-b, 3-c, 4-a, 5-a 6.10 REFERENCES Book References  “Professional Android 4 Application Development” by Reto Meier  “Programming Android Java Programming for the New Generation of Mobile Devices” by Zigurd Mennieks  “Android Cookbook” by Ian F Darwin  “Android Programming: The Big Nerd Ranch Guide” by Bill Phillips and Chris Stewart  “Professional Android 4 Application Development” by Reto Meier  “Programming Android Java Programming for the New Generation of Mobile Devices” by Zigurd Mennieks  “Android Cookbook” by Ian F Darwin  “Android Programming: The Big Nerd Ranch Guide” by Bill Phillips and Chris Stewart E-References  Introduction to Android: http://developer.android.com/guide/index.html.  Android API: http://developer.android.com/reference/packages.html  Java 6 API: http://docs.oracle.com/javase/6/docs/API/  Android Fundamentals: http://developer.android.com/guide/components/fundamentals.html 106 CU IDOL SELF LEARNING MATERIAL (SLM)

UNIT - 7: ANDROID MULTIMEDIA STRUCTURE 7.0 Learning Objectives 7.1 Introduction 7.2 Recording media 7.3 Speech API 7.4 Multimedia Supported audio formats 7.5 Simple media playback 7.6 Supported video formats 7.7 Simple video playback 7.8 Summary 7.9 Keywords 7.10 Learning Activity 7.11 Unit End Questions 7.12 References 7.0 LEARNING OBJECTIVES After studying this unit, you will be able to:  Describe the method of doing media recorder.  Explain the process of interfacing speech API  Describe various multimedia audio format.  Create a simple audio and video media playback. 7.1 INTRODUCTION Today, people use cell phones for almost everything but phone calls, from chatting to surfing the web to listening to music and even to watching live streaming TV. Nowadays, a cell phone needs to support multimedia to be considered a usable device. In this Unit, we’re going to look at how you can use Android to play audio files, watch video, take pictures, and even record sound. Android supports multimedia by using the open source multimedia system called OpenCORE from PacketVideo Corporation. OpenCORE provides the foundation for Android’s media services, which Android wraps in an easy-to-use API. In addition to the OpenCORE 107 CU IDOL SELF LEARNING MATERIAL (SLM)

framework, the Android platform is migrating to a Google-written multimedia framework named Stagefright. Both frameworks are provided in version 2.2 (Froyo) and in subsequent versions of the SDK. It’s anticipated that most, if not all, of the multimedia functionality will be handled by the Stagefright code base. 7.2 RECORDING MEDIA Public class MediaRecorder Extends Object implements AudioRouting, AudioRecordingMonitor, MicrophoneDirection java.lang.Object ↳ android.media.MediaRecorder Used to record audio and video. The recording control is based on a simple state machine (see figure 7.0). 108 CU IDOL SELF LEARNING MATERIAL (SLM)

Figure 7.1 Media Recorder State Diagram  A common case of using MediaRecorder to record audio works as follows: MediaRecorder recorder = new MediaRecorder(); recorder.setAudioSource(MediaRecorder.AudioSource.MIC); recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); recorder.setOutputFile(PATH_NAME); recorder.prepare(); recorder.start(); // Recording is now started ... 109 CU IDOL SELF LEARNING MATERIAL (SLM)

recorder.stop(); recorder.reset(); // You can reuse the object by going back to setAudioSource() step recorder.release(); // Now the object cannot be reused 7.3 SPEECH API The Android Speech API provides recognition control, background services, intents, and support for multiple languages. Again, it can look like a simple addition to the user input for your apps, but it’s a very powerful feature that makes them stand out. Imagine how helpful this feature can be for those people with disabilities using a keyboard or simply for those trying to find a way to increase productivity and improve their work flow. API Package and Device Support: Figure 7.2API Package and Device Support 110 public class ShowSupportedLanguages extends Activity { private TextView mTextView; CU IDOL SELF LEARNING MATERIAL (SLM)

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.lang); if (!SpeechRecognizer.isRecognitionAvailable(this)) { updateResults(\"nNo voice recognition support on your device!\"); } else { LanguageDetailsReceiver ldr = new LanguageDetailsReceiver(this); sendOrderedBroadcast(RecognizerIntent .getVoiceDetailsIntent(this), null, ldr, null, Activity.RESULT_OK, null, null); } } void updateResults(String s) { mTextView = (TextView)findViewById(R.id.tvlanglist); mTextView.setText(s); } } Listing 1: Display Supported Speech Languages public class LanguageDetailsReceiver extends BroadcastReceiver { List<string> mLanguages; ShowSupportedLanguages mSSL; public LanguageDetailsReceiver(ShowSupportedLanguages ssl) { 111 mSSL = ssl; mLanguages= new ArrayList<string>(); CU IDOL SELF LEARNING MATERIAL (SLM)

} @Override public void onReceive(Context context, Intent intent) { Bundle extras = getResultExtras(true); mLanguages = extras.getStringArrayList (RecognizerIntent.EXTRA_SUPPORTED_LANGUAGES); if (mLanguages == null) { mSSL.updateResults(\"No voice data found.\"); } else { String s = \"nList of language voice data:n\"; for (int i = 0; i < mLanguages.size(); i++) { s += (mLanguages.get(i) + \", \"); } s += \"n\"; mSSL.updateResults(s); } } } Listing 2: Language Details Broadcast Receiver 112 CU IDOL SELF LEARNING MATERIAL (SLM)

Figure 7.3 Language Details Broadcast Receiver 7.4 MULTIMEDIA SUPPORTED AUDIO FORMATS The table below (Table 7.1) describe the media format support built into the Android platform. YES means the format is available on handhelds and tablets running all Android versions. Where a specific Android platform is specified, the format is available on handsets and tablets running that version and all later versions. The format might also be available in earlier versions, but this is not guaranteed. On form factors other than handsets and tablets, media format support may vary. Table 7.1 Multimedia Supported audio formats Format Encoder Decoder Details File Types Container Formats YES AAC LC YES YES Support for • 3GPP (.3gp) mono/stereo/5.0/5.1 • MPEG-4 (.mp4, .m4a) HE-AACv1 Android 4.1+ content with 113 CU IDOL SELF LEARNING MATERIAL (SLM)

(AAC+) standard sampling • ADTS raw AAC (.aac, HE-AACv2 rates from 8 to 48 decode in Android 3.1+, (enhanced kHz. encode in Android 4.0+, AAC+) ADIF not supported) xHE-AAC YES Support for • MPEG-TS (.ts, not AAC ELD stereo/5.0/5.1 (enhanced seekable, Android 3.0+) low delay content with AAC) standard sampling AMR-NB AMR-WB rates from 8 to 48 FLAC kHz. Android 9+ Support for up to 8ch content with standard sampling rates from 8 to 48 kHz Android 4.1+ Android 4.1+ Support for mono/stereo content YES YES with standard Android 4.1+ sampling rates from 16 to 48 kHz YES 4.75 to 12.2 kbps • 3GPP (.3gp) sampled @ 8kHz • AMR (.amr) YES 9 rates from 6.60 kbit/s to 23.85 kbit/s sampled @ 16kHz Android 3.1+ Mono/Stereo (no • FLAC (.flac) multichannel). Sample rates up to • MPEG-4 (.mp4, .m4a, 48 kHz (but up to Android 10+) 44.1 kHz is recommended on devices with 44.1 kHz output, as the 48 to 44.1 kHz downsampler does not include a low- pass filter). 16-bit recommended; no dither applied for 114 CU IDOL SELF LEARNING MATERIAL (SLM)

24-bit. MIDI YES MIDI Type 0 and 1. • Type 0 and 1 (.mid, MP3 Opus DLS Version 1 and .xmf, .mxmf) 2. XMF and Mobile • RTTTL/RTX (.rtttl, XMF. Support for .rtx) ringtone formats RTTTL/RTX, OTA, • OTA (.ota) and iMelody • iMelody (.imy) YES Mono/Stereo 8- • MP3 (.mp3) 320Kbps constant • MPEG-4 (.mp4, .m4a, (CBR) or variable Android 10+) bit-rate (VBR) • Matroska (.mkv, Android 10+) Android 10+ Android 5.0+ • Ogg (.ogg) • Matroska (.mkv) PCM/WAVE Android 4.1+ YES 8- and 16-bit linear WAVE (.wav) Vorbis PCM (rates up to limit of hardware). Sampling rates for raw PCM recordings at 8000, 16000 and 44100 Hz. YES • Ogg (.ogg) • Matroska (.mkv, Android 4.0+) • MPEG-4 (.mp4, .m4a, Android 10+) 7.5 SIMPLE MEDIA PLAYBACK The android.media.MediaPlayer class is used to control the audio or video files. Methods of MediaPlayer class There are many methods of MediaPlayer class. Some of them are as follows: 115 CU IDOL SELF LEARNING MATERIAL (SLM)

Figure 7.4Methods of MediaPlayer class 116  Let's write the code of to play the audio file MainActivity.java package com.example.audiomediaplayer1; import android.media.MediaPlayer; import android.net.Uri; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.widget.MediaController; import android.widget.VideoView; CU IDOL SELF LEARNING MATERIAL (SLM)

public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); MediaPlayer mp=new MediaPlayer(); try{ mp.setDataSource(\"/sdcard/Music/maine.mp3\");//Write your location here mp.prepare(); mp.start(); }catch(Exception e){e.printStackTrace();} } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.activity_main, menu); return true; } } 7.6 SUPPORTED VIDEO FORMATS Table 7.2 Supported Video Formats Format Encoder Decoder Details File Types 117 CU IDOL SELF LEARNING MATERIAL (SLM)

Container Formats H.263 YES YES Support for • 3GPP (.3gp) H.263 is optional • MPEG-4 (.mp4) in Android 7.0+ • Matroska (.mkv) H.264 AVC Android 3.0+ YES • 3GPP (.3gp) Baseline Profile • MPEG-4 (.mp4) (BP) • MPEG-TS (.ts, AAC H.264 AVC Android 6.0+ YES The decoder is audio only, not Main Profile required, the seekable, Android (MP) encoder is 3.0+) recommended. • Matroska (.mkv) H.265 HEVC Android 5.0+ Main Profile • MPEG-4 (.mp4) Level 3 for • Matroska (.mkv) mobile devices and Main Profile Level 4.1 for Android TV MPEG-4 SP YES 3GPP (.3gp) VP8 Android 4.3+ Android 2.3.3+ Streamable only • WebM (.webm) in Android 4.0 • Matroska (.mkv, and above Android 4.0+) VP9 Android 4.4+ • WebM (.webm) AV1 • Matroska (.mkv) Android 10+ The decoder is • MPEG-4 (.mp4) optional. • Matroska (.mkv) 7.7SIMPLE VIDEO PLAYBACK By the help of MediaController and VideoView classes, we can play the video files in android. MediaController class The android.widget.MediaController is a view that contains media controls like play/pause, previous, next, fast-forward, rewind etc. 118 CU IDOL SELF LEARNING MATERIAL (SLM)

VideoView class The android.widget.VideoView class provides methods to play and control the video player. The commonly used methods of VideoView class are as follows: Figure 7.5Simple Video Playback  Example: File: activity_main.xml <RelativeLayout xmlns:androclass=\"http://schemas.android.com/apk/res/android\" xmlns:tools=\"http://schemas.android.com/tools\" android:layout_width=\"match_parent\" android:layout_height=\"match_parent\" tools:context=\".MainActivity\" > <VideoView android:id=\"@+id/videoView1\" android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\" android:layout_alignParentLeft=\"true\" android:layout_centerVertical=\"true\" /> </RelativeLayout> Let's write the code of to play the video file. Here, we are going to play 1.mp4 file located inside the sdcard/media directory. 119 CU IDOL SELF LEARNING MATERIAL (SLM)

File: MainActivity.java package com.example.video1; import android.net.Uri; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.widget.MediaController; import android.widget.VideoView; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); VideoView videoView =(VideoView)findViewById(R.id.videoView1); //Creating MediaController MediaController mediaController= new MediaController(this); mediaController.setAnchorView(videoView); //specify the location of media file Uri uri=Uri.parse(Environment.getExternalStorageDirectory().getPath()+\"/media/1.mp4\") ; //Setting MediaController and URI, then starting the videoView videoView.setMediaController(mediaController); videoView.setVideoURI(uri); videoView.requestFocus(); videoView.start(); } @Override 120 public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. CU IDOL SELF LEARNING MATERIAL (SLM)

getMenuInflater().inflate(R.menu.activity_main, menu); return true; } } 7.8 SUMMARY  Syntax for recording media: public class MediaRecorder extends Object implements AudioRouting, AudioRecordingMonitor, MicrophoneDirection java.lang.Object ↳ android.media.MediaRecorder  The Android Speech API provides recognition control, background services, intents, and support for multiple languages. Again, it can look like a simple addition to the user input for your apps, but it’s a very powerful feature that makes them stand out. Imagine how helpful this feature can be for those people with disabilities using a keyboard or simply for those trying to find a way to increase productivity and improve their work flow.  By the help of MediaController and VideoView classes, we can play the video files in android.  The android.media.MediaPlayer class is used to control the audio or video files. 7.9 KEYWORDS  Audio:sound, especially when recorded, transmitted, or reproduced.  Recording Media:any removable, physical audio recording medium (such as magnetic tape, optical disc or solid state memory) which can be played and copied. ... Recording media means film, video, photography, and any other media capturing or recording visual images.  API:Application programming interfaces, or APIs, simplify software development and innovation by enabling applications to exchange data and functionality easily and securely.  Multimedia:is a form of communication that combines different content forms such as text, audio, images, animations, or video into a single interactive presentation, in contrast to traditional mass media which featured little to no interaction from users, such as printed material or audio recordings. Popular examples of multimedia include video podcasts, audio slideshows and animated videos. 121 CU IDOL SELF LEARNING MATERIAL (SLM)

 Adapters: An Adapter object acts as a bridge between an AdapterView and the underlying data for that view. The Adapter provides access to the data items. 7.10 LEARNING ACTIVITY 1. Draw media recording state diagram. ___________________________________________________________________________ ___________________________________________________________________________ 3. Give example of common case of using MediaRecorder to record audio. ___________________________________________________________________________ ___________________________________________________________________________ 7.11 UNIT END QUESTIONS A. Descriptive Questions 122 Short Questions 1. List the supported video format in android. 2. Write the code of to play the audio file 3. Give the file types of the following format : a. AAC LC b. AMR-NB c. MIDI d. Opus 4. Give file type of the following video format a. H.264 AVC Baseline Profile (BP) b. H.265 HEVC c. MPEG-4 SP Long Questions 1. Explain the process of speech API. 2. State the methods of MediaPlayer Class. 3. Explain in detail simple video playback 4. List down the multimedia supported audio format. 5. Explain in detail media recorder state diagram. B. Multiple Choice Questions 1. H.264 AVC Baseline Profile (BP) encoder is supported by ________ a. Android 3.0+ CU IDOL SELF LEARNING MATERIAL (SLM)

b. Android 3.0 c. Android 2.0+ d. Android 2.0 2. The android.widget _________ is a view that contains media controls like play/pause, previous, next, fast-forward, rewind etc a. Device manager b. Media Controller c. telephony d. Audio 3. In OPUS format encoder is supported by ______ a. Android 3.0+ b. Android 3.0 c. Android 10+ d. Android 9.0 4. Android supports multimedia by using the open source multimedia system called ______ a. Main Class b. OpenClass c. OpenSource d. OpenCORE 5. Multimedia functionality will be handled by the ________ code base 123 a. Stagefright b. Binary CU IDOL SELF LEARNING MATERIAL (SLM)

c. Hexa decimal d. BCD Answers 1-a, 2-b, 3-c, 4-d, 5-a 7.12 REFERENCES Book References  “Professional Android 4 Application Development” by Reto Meier  “Programming Android Java Programming for the New Generation of Mobile Devices” by Zigurd Mennieks  “Android Cookbook” by Ian F Darwin  “Android Programming: The Big Nerd Ranch Guide” by Bill Phillips and Chris Stewart  “Professional Android 4 Application Development” by Reto Meier  “Programming Android Java Programming for the New Generation of Mobile Devices” by Zigurd Mennieks  “Android Cookbook” by Ian F Darwin  “Android Programming: The Big Nerd Ranch Guide” by Bill Phillips and Chris Stewart E-References  Introduction to Android: http://developer.android.com/guide/index.html.  Android API: http://developer.android.com/reference/packages.html  Java 6 API: http://docs.oracle.com/javase/6/docs/API/  Android Fundamentals: http://developer.android.com/guide/components/fundamentals.html 124 CU IDOL SELF LEARNING MATERIAL (SLM)

UNIT - 8: TELEPHONY API STRUCTURE 8.0 Learning Objectives 8.1 Introduction 8.2 Telephony Manager 8.3 Get Call state 8.4 Call state Broadcast Receiver 8.5 Simple caller talker 8.6 Phone call 8.7 Monitoring data connectivity and activity 8.8 Accessing phone properties and status 8.9 Summary 8.10 Keywords 8.11 Learning Activity 8.12 Unit End Questions 8.13 References 8.0 LEARNING OBJECTIVES After studying this unit, you will be able to:  Describe different application of telephone manager in android  Make call using android programmatically.  To get the location of the user  Describe how android can monitor the data connectivity.  Explain how to access phone properties. 8.1 INTRODUCTION People use Android devices to surf the web, download and store data, access networks, find location information, and use many types of applications. Android can even make phone calls. Android phones support dialing numbers, receiving calls, sending and receiving text and multimedia messages, and other related telephony services. In contrast to other smartphone platforms, all these items are accessible to developers through simple-to-use APIs and built- in applications. You can easily leverage Android’s telephony support into your own applications. 125 CU IDOL SELF LEARNING MATERIAL (SLM)

In this Unit, we’ll discuss telephony in general and cover terms related to mobile devices. We’ll move on to basic Android telephony packages, which handle calls using built-in Intent actions, and more advanced operations via the TelephonyManager and PhoneStateListener classes. The Intent actions can initiate basic phone calls in your applications. TelephonyManager doesn’t make phone calls directly but is used to retrieve all kinds of telephony-related data, such as the state of the voice network, the device’s own phone number, and other details. TelephonyManager supports adding a PhoneStateListener, which can alert you when call or phone network states change. 8.2 TELEPHONY MANAGER  Provides access to information about the telephony services on the device. Applications can use the methods in this class to determine telephony services and states, as well as to access some types of subscriber information. Applications can also register a listener to receive notification of telephony state changes.  The returned TelephonyManager will use the default subscription for all calls. To call an API for a specific subscription, use createForSubscriptionId (int). e.g. telephonyManager = defaultSubTelephonyManager.createForSubscriptionId(subId);  Note that access to some telephony information is permission-protected. Your application cannot access the protected information unless it has the appropriate permissions declared in its manifest file. Where permissions apply, they are noted in the the methods through which you access the protected information.  TelephonyManager is intended for use on devices that implement FEATURE_TELEPHONY. On devices that do not implement this feature, the behavior is not reliable.  public class TelephonyManager extends Object java.lang.Object ↳ android.telephony.TelephonyManager  The android.telephony.TelephonyManager class provides information about the telephony services such as subscriber id, sim serial number, phone network type etc. Moreover, you can determine the phone state etc.  Example: activity_main.xml <RelativeLayout xmlns:androclass=\"http://schemas.android.com/apk/res/android\" xmlns:tools=\"http://schemas.android.com/tools\" android:layout_width=\"match_parent\" android:layout_height=\"match_parent\" android:paddingBottom=\"@dimen/activity_vertical_margin\" 126 CU IDOL SELF LEARNING MATERIAL (SLM)

android:paddingLeft=\"@dimen/activity_horizontal_margin\" android:paddingRight=\"@dimen/activity_horizontal_margin\" android:paddingTop=\"@dimen/activity_vertical_margin\" tools:context=\".MainActivity\" > <TextView android:id=\"@+id/textView1\" android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\" android:layout_alignParentLeft=\"true\" android:layout_alignParentTop=\"true\" android:layout_marginLeft=\"38dp\" android:layout_marginTop=\"30dp\" android:text=\"Phone Details:\" /> </RelativeLayout> Activity class Now, write the code to display the information about the telephony services. MainActivity.java package com.javatpoint.telephonymanager; import android.os.Bundle; import android.app.Activity; import android.content.Context; import android.telephony.TelephonyManager; import android.view.Menu; import android.widget.TextView; public class MainActivity extends Activity { 127 TextView textView1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); CU IDOL SELF LEARNING MATERIAL (SLM)

textView1=(TextView)findViewById(R.id.textView1); //Get the instance of TelephonyManager TelephonyManager tm=(TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE); //Calling the methods of TelephonyManager the returns the information String IMEINumber=tm.getDeviceId(); String subscriberID=tm.getDeviceId(); String SIMSerialNumber=tm.getSimSerialNumber(); String networkCountryISO=tm.getNetworkCountryIso(); String SIMCountryISO=tm.getSimCountryIso(); String softwareVersion=tm.getDeviceSoftwareVersion(); String voiceMailNumber=tm.getVoiceMailNumber(); //Get the phone type String strphoneType=\"\"; int phoneType=tm.getPhoneType(); switch (phoneType) 128 { case (TelephonyManager.PHONE_TYPE_CDMA): strphoneType=\"CDMA\"; break; case (TelephonyManager.PHONE_TYPE_GSM): strphoneType=\"GSM\"; break; case (TelephonyManager.PHONE_TYPE_NONE): CU IDOL SELF LEARNING MATERIAL (SLM)

strphoneType=\"NONE\"; break; } //getting information if phone is in roaming boolean isRoaming=tm.isNetworkRoaming(); String info=\"Phone Details:\\n\"; info+=\"\\n IMEI Number:\"+IMEINumber; info+=\"\\n SubscriberID:\"+subscriberID; info+=\"\\n Sim Serial Number:\"+SIMSerialNumber; info+=\"\\n Network Country ISO:\"+networkCountryISO; info+=\"\\n SIM Country ISO:\"+SIMCountryISO; info+=\"\\n Software Version:\"+softwareVersion; info+=\"\\n Voice Mail Number:\"+voiceMailNumber; info+=\"\\n Phone Network Type:\"+strphoneType; info+=\"\\n In Roaming? :\"+isRoaming; textView1.setText(info);//displaying the information in the textView } } AndroidManifest.xml <?xml version=\"1.0\" encoding=\"utf-8\"?> <manifest xmlns:androclass=\"http://schemas.android.com/apk/res/android\" package=\"com.javatpoint.telephonymanager\" android:versionCode=\"1\" android:versionName=\"1.0\" > 129 CU IDOL SELF LEARNING MATERIAL (SLM)

<uses-sdk android:minSdkVersion=\"8\" android:targetSdkVersion=\"17\" /> <uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/> <application android:allowBackup=\"true\" android:icon=\"@drawable/ic_launcher\" android:label=\"@string/app_name\" android:theme=\"@style/AppTheme\" > <activity android:name=\"com.javatpoint.telephonymanager.MainActivity\" android:label=\"@string/app_name\" > <intent-filter> <action android:name=\"android.intent.action.MAIN\" /> <category android:name=\"android.intent.category.LAUNCHER\" /> </intent-filter> </activity> </application> </manifest> Output: 130 CU IDOL SELF LEARNING MATERIAL (SLM)

Figure 8.1Telephony Manager 8.3 GET CALL STATE  We can also get the information of call state using the TelephonyManager class. For this purpose, we need to call the listen method of TelephonyManager class by passing the PhonStateListener instance.  The PhoneStateListener interface must be implemented to get the call state. It provides one method onCallStateChanged().  Example MainActivity.java package com.javatpoint.callstates; import android.os.Bundle; import android.app.Activity; import android.content.Context; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.view.Menu; import android.widget.Toast; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { 131 CU IDOL SELF LEARNING MATERIAL (SLM)

super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE); PhoneStateListener callStateListener = new PhoneStateListener() { public void onCallStateChanged(int state, String incomingNumber) { if(state==TelephonyManager.CALL_STATE_RINGING){ Toast.makeText(getApplicationContext(),\"Phone Is Riging\", Toast.LENGTH_LONG).show(); } if(state==TelephonyManager.CALL_STATE_OFFHOOK){ Toast.makeText(getApplicationContext(),\"Phone is Currently in A call\", Toast.LENGTH_LONG).show(); } if(state==TelephonyManager.CALL_STATE_IDLE){ Toast.makeText(getApplicationContext(),\"phone is neither ringing nor in a call\", Toast.LENGTH_LONG).show(); } } }; telephonyManager.listen(callStateListener,PhoneStateListener.LISTEN_CALL_STA TE); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } 132 CU IDOL SELF LEARNING MATERIAL (SLM)

} AndroidManifest.xml <?xml version=\"1.0\" encoding=\"utf-8\"?> <manifest xmlns:androclass=\"http://schemas.android.com/apk/res/android\" package=\"com.javatpoint.callstates\" android:versionCode=\"1\" android:versionName=\"1.0\" > <uses-sdk android:minSdkVersion=\"8\" android:targetSdkVersion=\"17\" /> <uses-permission android:name=\"android.permission.READ_PHONE_STATE\" /> <application android:allowBackup=\"true\" android:icon=\"@drawable/ic_launcher\" android:label=\"@string/app_name\" android:theme=\"@style/AppTheme\" > <activity android:name=\"com.javatpoint.callstates.MainActivity\" android:label=\"@string/app_name\" > <intent-filter> <action android:name=\"android.intent.action.MAIN\" /> <category android:name=\"android.intent.category.LAUNCHER\" /> </intent-filter> </activity> </application> </manifest> Output: 133 CU IDOL SELF LEARNING MATERIAL (SLM)

Figure 8.2Get Call State 8.4 CALL STATE BROADCAST RECEIVER In this android example we are showing, when any new call event brodcasted ( When new call come ) then how to create receiver to read phone call states.  activity_main.xml <RelativeLayout xmlns:androclass=\"http://schemas.android.com/apk/res/android\" xmlns:tools=\"http://schemas.android.com/tools\" android:layout_width=\"match_parent\" android:layout_height=\"match_parent\" android:paddingBottom=\"@dimen/activity_vertical_margin\" android:paddingLeft=\"@dimen/activity_horizontal_margin\" android:paddingRight=\"@dimen/activity_horizontal_margin\" android:paddingTop=\"@dimen/activity_vertical_margin\" tools:context=\".MainActivity\" > <TextView android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\" android:text=\"@string/hello_world\" /> 134 CU IDOL SELF LEARNING MATERIAL (SLM)

</RelativeLayout> 135  MainActivity.java package com.example.callstatebroadcastreceiver; import android.os.Bundle; import android.app.Activity; import android.view.Menu; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }  IncommingCallReceiver.java package com.example.callstatebroadcastreceiver; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.telephony.TelephonyManager; import android.widget.Toast; public class IncommingCallReceiver extends BroadcastReceiver{ Context context; @Override public void onReceive(Context context, Intent intent){ CU IDOL SELF LEARNING MATERIAL (SLM)

try{ String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE); if(state.equals(TelephonyManager.EXTRA_STATE_RINGING)){ Toast.makeText(context, \"Phone Is Ringing\", Toast.LENGTH_LONG).show(); } if(state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){ Toast.makeText(context, \"Call Recieved\", Toast.LENGTH_LONG).show(); } if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)){ Toast.makeText(context, \"Phone Is Idle\", Toast.LENGTH_LONG).show(); } } catch(Exception e){e.printStackTrace();} } } 8.5 SIMPLE CALLER TALKER  Android provides the facility to know the incoming number and speak it by the help of android speech API and telephony manager.  Here, we are going to develop a basic android app that speaks the incoming number while phone is in ringing mode.  Example: activity_main.xml <RelativeLayout xmlns:androclass=\"http://schemas.android.com/apk/res/android\" xmlns:tools=\"http://schemas.android.com/tools\" android:layout_width=\"match_parent\" android:layout_height=\"match_parent\" android:paddingBottom=\"@dimen/activity_vertical_margin\" android:paddingLeft=\"@dimen/activity_horizontal_margin\" android:paddingRight=\"@dimen/activity_horizontal_margin\" android:paddingTop=\"@dimen/activity_vertical_margin\" tools:context=\".MainActivity\" > 136 CU IDOL SELF LEARNING MATERIAL (SLM)

<TextView android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\" android:text=\"@string/hello_world\" /> </RelativeLayout> MainActivity.java package com.example.callertalker; import java.util.Locale; import android.media.AudioManager; import android.os.Bundle; import android.app.Activity; import android.content.Context; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.util.Log; import android.widget.Toast; import android.speech.tts.TextToSpeech; public class MainActivity extends Activity implements TextToSpeech.OnInitListener { private TextToSpeech tts; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tts = new TextToSpeech(this, this); TelephonyManager telephonyManager = (TelephonyManager)getSystemService( Context.TELEPHONY_SERVICE); PhoneStateListener callStateListener = new PhoneStateListener() { public void onCallStateChanged(int state, String incomingNumber){ if(state==TelephonyManager.CALL_STATE_RINGING){ tts.speak(incomingNumber+\" calling\", TextToSpeech.QUEUE_FLUSH, null); 137 CU IDOL SELF LEARNING MATERIAL (SLM)

Toast.makeText(getApplicationContext(),\"Phone is Ringing : \"+incomingNumber, Toast.LENGTH_LONG).show(); } if(state==TelephonyManager.CALL_STATE_OFFHOOK){ Toast.makeText(getApplicationContext(),\"Phone in a call or call picked\", Toast.LENGTH_LONG).show(); } if(state==TelephonyManager.CALL_STATE_IDLE){ //phone is neither ringing nor in a call } } }; telephonyManager.listen(callStateListener,PhoneStateListener.LISTEN_CALL_STA TE); } @Override public void onInit(int status) { if (status == TextToSpeech.SUCCESS) { int result = tts.setLanguage(Locale.US); if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) { Log.e(\"TTS\", \"This Language is not supported\"); } else { } } else { Log.e(\"TTS\", \"Initilization Failed!\"); } } @Override 138 public void onDestroy() { // Don't forget to shutdown tts! if (tts != null) { tts.stop(); tts.shutdown(); } CU IDOL SELF LEARNING MATERIAL (SLM)

super.onDestroy(); } } AndroidManifest.xml <?xml version=\"1.0\" encoding=\"utf-8\"?> <manifest xmlns:androclass=\"http://schemas.android.com/apk/res/android\" package=\"com.example.callertalker\" android:versionCode=\"1\" android:versionName=\"1.0\" > <uses-sdk android:minSdkVersion=\"8\" android:targetSdkVersion=\"17\" /> <uses-permission android:name=\"android.permission.READ_PHONE_STATE\" /> <application android:allowBackup=\"true\" android:icon=\"@drawable/ic_launcher\" android:label=\"@string/app_name\" android:theme=\"@style/AppTheme\" > <activity android:name=\"com.example.callertalker.MainActivity\" android:label=\"@string/app_name\" > <intent-filter> <action android:name=\"android.intent.action.MAIN\" /> <category android:name=\"android.intent.category.LAUNCHER\" /> 139 </intent-filter> </activity> CU IDOL SELF LEARNING MATERIAL (SLM)

</application> </manifest> Output: Figure 8.3Simple Caller Talker 8.6 PHONE CALL A calling app allows users to receive or place audio or video calls on their device. Calling apps use their own user interface for the calls instead of using the default Phone app interface. An example of a calling app using its own user interface The Android framework includes the android.telecom package, which contains classes that help you build a calling app according to the telecom framework. Building your app according to the telecom framework provides the following benefits:  Your app interoperates correctly with the native telecom subsystem in the device.  Your app interoperates correctly with other calling apps that also adhere to the framework.  The framework helps your app manage audio and video routing.  The framework helps your app determine whether its calls have focus. 140 CU IDOL SELF LEARNING MATERIAL (SLM)

 activity_main.xml <RelativeLayout xmlns:androclass=\"http://schemas.android.com/apk/res/android\" xmlns:tools=\"http://schemas.android.com/tools\" android:layout_width=\"match_parent\" android:layout_height=\"match_parent\" tools:context=\".MainActivity\" > <Button android:id=\"@+id/button1\" android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\" android:layout_alignParentTop=\"true\" android:layout_centerHorizontal=\"true\" android:layout_marginTop=\"118dp\" android:text=\"Call\" /> <EditText android:id=\"@+id/editText1\" android:layout_width=\"wrap_content\" android:layout_height=\"wrap_content\" android:layout_alignParentTop=\"true\" android:layout_centerHorizontal=\"true\" android:layout_marginTop=\"25dp\" android:ems=\"10\" /> </RelativeLayout>  Write the permission code in Android-Manifest.xml file You need to write CALL_PHONE permission as given below: <uses-permission android:name=\"android.permission.CALL_PHONE\" />  Android-Manifest.xml <?xml version=\"1.0\" encoding=\"utf-8\"?> <manifest xmlns:androclass=\"http://schemas.android.com/apk/res/android\" package=\"com.example.phonecall\" android:versionCode=\"1\" android:versionName=\"1.0\" > <uses-sdk 141 android:minSdkVersion=\"8\" CU IDOL SELF LEARNING MATERIAL (SLM)

android:targetSdkVersion=\"16\" /> 142 <uses-permission android:name=\"android.permission.CALL_PHONE\" /> <application android:allowBackup=\"true\" android:icon=\"@drawable/ic_launcher\" android:label=\"@string/app_name\" android:theme=\"@style/AppTheme\" > <activity android:name=\"com.example.phonecall.MainActivity\" android:label=\"@string/app_name\" > <intent-filter> <action android:name=\"android.intent.action.MAIN\" /> <category android:name=\"android.intent.category.LAUNCHER\" /> </intent-filter> </activity> </application> </manifest>  MainActivity.java package com.example.phonecall; import android.net.Uri; import android.os.Bundle; import android.app.Activity; import android.content.Intent; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; public class MainActivity extends Activity { EditText edittext1; Button button1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); CU IDOL SELF LEARNING MATERIAL (SLM)

//Getting the edittext and button instance edittext1=(EditText)findViewById(R.id.editText1); button1=(Button)findViewById(R.id.button1); //Performing action on button click button1.setOnClickListener(new OnClickListener(){ @Override public void onClick(View arg0) { String number=edittext1.getText().toString(); Intent callIntent = new Intent(Intent.ACTION_CALL); callIntent.setData(Uri.parse(\"tel:\"+number)); startActivity(callIntent); } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.activity_main, menu); return true; } } Output: 143 CU IDOL SELF LEARNING MATERIAL (SLM)

Figure 8.4Phone Call 144 CU IDOL SELF LEARNING MATERIAL (SLM)

Figure 8.5Phone Call 8.7 MONITORING DATA CONNECTIVITY AND ACTIVITY As well as voice and service details, you can also use a Phone State Listener to monitor changes in mobile data connectivity and mobile data transfer. The Phone State Listener includes two event handlers for monitoring the device data connection. Override onDataActivity to track data transfer activity, and onDataConnectionStateChanged to request notifications for data connection state changes. Listing 12-12 shows both handlers overridden, with switch statements demonstrating each of the possible values for the state and data-flow direction parameters passed in to each event. LISTING 12-12: Monitoring data connections and transfers Available for PhoneStateListener dataStateListener = new PhoneStateListener() { Wrax°comn public void onDataActivity(int direction) { switch (direction) { case TelephonyManager.DATA_ACTIVITY_IN : break; case TelephonyManager.DATA_ACTIVITY_OUT : break; case 145 CU IDOL SELF LEARNING MATERIAL (SLM)

TelephonyManager.DATA_ACTIVITY_INOUT : break; case TelephonyManager.DATA_ACTIVITY_NONE : break; public void onDataConnectionStateChanged(int state) { switch (state) { case TelephonyManager.DATA_CONNECTED : break; case TelephonyManager.DATA_CONNECTING : break; case TelephonyManager.DATA_DISCONNECTED : break; case TelephonyManager.DATA_SUSPENDED : break; telephonyManager.listen(dataStateListener, PhoneStateListener.LISTEN_DATA_ACTIVITY | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE); 8.8 ACCESSING PHONE PROPERTIES AND STATUS The Telephony Manager also provides access to several static phone properties. You can obtain the current value of any of the phone state details described previously. The following code snippet shows how to extract the current incoming call number if the phone is ringing: String incomingCall = null; if (telephonyManager.getCallState() == TelephonyManager.CALL_STATE_RINGING) incomingCall = telephonyManager.getLine1Number(); You can also access SIM and network operator details, network information, and voice-mail details. The following code snippet shows the framework used to access the current network details: String srvcName = Context.TELEPHONY_SERVICE; TelephonyManager telephonyManager = (TelephonyManager)getSystemService(srvcName); String networkCountry = telephonyManager.getNetworkCountryIso(); String networkOperatorId = telephonyManager.getNetworkOperator(); String networkName = telephonyManager.getNetworkOperatorName(); int networkType = telephonyManager.getNetworkType(); 8.9 SUMMARY  Android phones support dialing numbers, receiving calls, sending and receiving text and multimedia messages, and other related telephony services. In contrast to other 146 CU IDOL SELF LEARNING MATERIAL (SLM)

smartphone platforms, all these items are accessible to developers through simple-to- use APIs and built-in applications. You can easily leverage Android’s telephony support into your own applications.  Telephony manger Provides access to information about the telephony services on the device. Applications can use the methods in this class to determine telephony services and states, as well as to access some types of subscriber information. Applications can also register a listener to receive notification of telephony state changes.  TelephonyManager is intended for use on devices that implement FEATURE_TELEPHONY. On devices that do not implement this feature, the behavior is not reliable.  We can also get the information of call state using the TelephonyManager class. For this purpose, we need to call the listen method of TelephonyManager class by passing the PhonStateListener instance.  Android provides the facility to know the incoming number and speak it by the help of android speech API and telephony manager. 8.10 KEYWORDS  Caller Talker:the person initiating a telephone call.  Broadcast:transmit (a programme or some information) by radio or television.  \"the announcement was broadcast live\"  Android Gallery : In Android, Gallery is a view that can show items in a center locked, horizontal scrolling list, and hence the user can able to select a view, and then the user selected view will be shown in the center of the Horizontal list.  ListView: Android ListView is a ViewGroup that is used to display the list of items in multiple rows and contains an adapter that automatically inserts the items into the list.  Adapters: An Adapter object acts as a bridge between an AdapterView and the underlying data for that view. The Adapter provides access to the data items. 8.11 LEARNING ACTIVITY 1. Explain monitoring of data connectivity ___________________________________________________________________________ ___________________________________________________________________________ 2. How is phone properties access? ___________________________________________________________________________ ___________________________________________________________________________ 147 CU IDOL SELF LEARNING MATERIAL (SLM)

8.12 UNIT END QUESTIONS A. Descriptive Questions Short Questions 1. How to extract the current incoming call number if the phone is ringing? 2. Explain all state broadcast receiver. 3. Explain the function of telephony manager. 4. Give the calling methods of telephony manager that returns the information Long Questions 1. Explain how phone call could be made with the help of program? 2. Explain Simple caller talker in detail. 3. With an appropriate program explain how to get call state? 4. Explain in brief how monitoring data connectivity happens in adroid. B. Multiple Choice Questions 1 The Telephony Manager also provides access to several _____ phone properties a. static b. dynamic c. static and dynamic d. basics 2. __________ to monitor changes in mobile data connectivity a. Phone State Reciever b. Phone State Listener c. Call State Listener d. Call State Reciever 3.Android provides the facility to know the incoming number and speak it by the help of android __________ a. Call API 148 CU IDOL SELF LEARNING MATERIAL (SLM)

b. SMS API c. Speech API d. Game API 4. We can also get the information of call state using the _______ class a. Main b. Activity c. Device Manager d. Telephony Manager 5. The _____ actions can initiate basic phone calls in your applications a. Intent b. Ring c. Dial d. All of these Answers 1-a, 2-b, 3-c, 4-d, 5-a 8.13 REFERENCES Book References  “Professional Android 4 Application Development” by Reto Meier  “Programming Android Java Programming for the New Generation of Mobile Devices” by Zigurd Mennieks  “Android Cookbook” by Ian F Darwin  “Android Programming: The Big Nerd Ranch Guide” by Bill Phillips and Chris Stewart  “Professional Android 4 Application Development” by Reto Meier  “Programming Android Java Programming for the New Generation of Mobile Devices” by Zigurd Mennieks 149 CU IDOL SELF LEARNING MATERIAL (SLM)

 “Android Cookbook” by Ian F Darwin  “Android Programming: The Big Nerd Ranch Guide” by Bill Phillips and Chris Stewart E-References  Introduction to Android: http://developer.android.com/guide/index.html.  Android API: http://developer.android.com/reference/packages.html  Java 6 API: http://docs.oracle.com/javase/6/docs/API/  Android Fundamentals: http://developer.android.com/guide/components/fundamentals.html 150 CU IDOL SELF LEARNING MATERIAL (SLM)


Like this book? You can publish your book online for free in a few minutes!
Create your own flipbook