Java tutorial
/* * Copyright (C) 2016 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.example.android.phonecallingsamplechallenge; import android.Manifest; import android.content.Intent; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.support.v4.app.ActivityCompat; import android.support.v7.app.AppCompatActivity; import android.telephony.PhoneNumberUtils; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ImageButton; import android.widget.TextView; import android.widget.Toast; /** * This app accepts a phone number and makes a phone call. * For incoming calls, the app shows the phone number of the caller. */ public class MainActivity extends AppCompatActivity { private static final String TAG = MainActivity.class.getSimpleName(); private static final int MY_PERMISSIONS_REQUEST_CALL_PHONE = 1; private TelephonyManager mTelephonyManager; private MyPhoneCallListener mListener; /** * Creates the activity, sets the view, and checks if Telephony is enabled. * Telephony enabled: * Checks for phone permission. * Sets the PhoneStateListener. * Telephony not enabled: Disables the call button and shows the Retry button. * * @param savedInstanceState Instance state */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Create a telephony manager. mTelephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); // Check to see if Telephony is enabled. if (isTelephonyEnabled()) { Log.d(TAG, getString(R.string.telephony_enabled)); // Check for phone permission. checkForPhonePermission(); // Register the PhoneStateListener to monitor phone activity. mListener = new MyPhoneCallListener(); mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_CALL_STATE); } else { Toast.makeText(this, R.string.telephony_not_enabled, Toast.LENGTH_LONG).show(); Log.d(TAG, getString(R.string.telephony_not_enabled)); // Disable the call button. disableCallButton(); } } /** * Checks whether Telephony is enabled. * * @return true if enabled, otherwise false */ private boolean isTelephonyEnabled() { if (mTelephonyManager != null) { if (mTelephonyManager.getSimState() == TelephonyManager.SIM_STATE_READY) { return true; } } return false; } /** * Checks whether the app has phone-calling permission. */ private void checkForPhonePermission() { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) { Log.d(TAG, getString(R.string.permission_not_granted)); // Permission not yet granted. Use requestPermissions(). // MY_PERMISSIONS_REQUEST_CALL_PHONE is an // app-defined int constant. The callback method gets the // result of the request. ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.CALL_PHONE }, MY_PERMISSIONS_REQUEST_CALL_PHONE); } else { // Permission already granted. Enable the call button. enableCallButton(); } } /** * Processes permission request codes. * * @param requestCode The request code passed in requestPermissions() * @param permissions The requested permissions. Never null. * @param grantResults The grant results for the corresponding permissions * which is either PERMISSION_GRANTED or PERMISSION_DENIED. Never null. */ @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { // For each permission, check if it is granted or not. switch (requestCode) { case MY_PERMISSIONS_REQUEST_CALL_PHONE: { if (permissions[0].equalsIgnoreCase(Manifest.permission.CALL_PHONE) && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // Permission was granted. Enable call button. enableCallButton(); } else { // Permission denied. // Disable the functionality that depends on this permission. Log.d(TAG, getString(R.string.failure_permission)); Toast.makeText(this, getString(R.string.failure_permission), Toast.LENGTH_SHORT).show(); // Disable the call button. disableCallButton(); } } } } /** * Uses an implicit intent to make the phone call. * Before calling, checks to see if permission is granted. * * @param view View that was clicked. */ public void callNumber(View view) { String normalizedPhoneNumber; // Find the editText_main view and assign it to editText. EditText editText = (EditText) findViewById(R.id.editText_main); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { Log.d(TAG, "Running version earlier than Lollipop. Can't normalize number."); normalizedPhoneNumber = editText.getText().toString(); } else { normalizedPhoneNumber = PhoneNumberUtils.normalizeNumber(editText.getText().toString()); } // Use format with "tel:" and phone number to create phoneNumber. String phoneNumber = String.format("tel: %s", normalizedPhoneNumber); // Log the concatenated phone number for dialing. Log.d(TAG, getString(R.string.dial_number) + phoneNumber); Toast.makeText(this, getString(R.string.dial_number) + phoneNumber, Toast.LENGTH_LONG).show(); // Create the intent. Intent callIntent = new Intent(Intent.ACTION_CALL); // Set the data for the intent as the phone number. callIntent.setData(Uri.parse(phoneNumber)); // If package resolves to an app, check for phone permission, // and send intent. if (callIntent.resolveActivity(getPackageManager()) != null) { checkForPhonePermission(); startActivity(callIntent); } else { Log.e(TAG, "Can't resolve app for ACTION_CALL Intent."); } } /** * Monitors and logs phone call activities, and shows the phone state * in a toast message. */ private class MyPhoneCallListener extends PhoneStateListener { private boolean returningFromOffHook = false; @Override public void onCallStateChanged(int state, String incomingNumber) { // Define a string for the message to use in a toast. String message = getString(R.string.phone_status); switch (state) { case TelephonyManager.CALL_STATE_RINGING: // Incoming call is ringing (not used for outgoing call). TextView incomingView = (TextView) findViewById(R.id.incoming); incomingView.setText(incomingNumber); incomingView.setVisibility(View.VISIBLE); Log.i(TAG, message); break; case TelephonyManager.CALL_STATE_OFFHOOK: // Phone call is active -- off the hook. message = message + getString(R.string.offhook); Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show(); Log.i(TAG, message); returningFromOffHook = true; break; case TelephonyManager.CALL_STATE_IDLE: // Phone is idle before and after phone call. // If running on version older than 19 (KitKat), // restart activity when phone call ends. message = message + getString(R.string.idle); Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show(); Log.i(TAG, message); if (returningFromOffHook) { // No need to do anything if >= version KitKat. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { Log.i(TAG, getString(R.string.restarting_app)); // Restart the app. Intent i = getPackageManager().getLaunchIntentForPackage(getPackageName()); i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(i); } } break; default: message = message + "Phone off"; Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show(); Log.i(TAG, message); break; } } } /** * Makes the call button (phone icon) invisible so that it can't be used, * and makes the Retry button visible. */ private void disableCallButton() { Toast.makeText(this, R.string.phone_disabled, Toast.LENGTH_LONG).show(); ImageButton callButton = (ImageButton) findViewById(R.id.phone_icon); callButton.setVisibility(View.INVISIBLE); if (isTelephonyEnabled()) { Button retryButton = (Button) findViewById(R.id.button_retry); retryButton.setVisibility(View.VISIBLE); } } /** * Makes the call button (phone icon) visible so that it can be used. */ private void enableCallButton() { ImageButton callButton = (ImageButton) findViewById(R.id.phone_icon); callButton.setVisibility(View.VISIBLE); } /** * Enables the call button, and sends an intent to start the activity. */ public void retryApp(View view) { enableCallButton(); Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName()); startActivity(intent); } @Override protected void onDestroy() { super.onDestroy(); if (isTelephonyEnabled()) { mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_NONE); } } }