En este momento estás viendo Cómo Crear App De Simulador De Llamadas En Android Studio

Cómo Crear App De Simulador De Llamadas En Android Studio

En esta oportunidad crearemos una App de Simulador de Llamadas para Android.

En primer lugar, nos dirigimos al archivo strings.xml, añadimos un texto que será el nombre de nuestra app.

<resources>
    <string name="app_name">Simulador</string>
</resources>

Ahora nos vamos al archivo colors.xml y añadimos los colores.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="purple_200">#FFBB86FC</color>
    <color name="purple_500">#FF6200EE</color>
    <color name="purple_700">#FF3700B3</color>
    <color name="teal_200">#FF03DAC5</color>
    <color name="teal_700">#FF018786</color>
    <color name="black">#FF000000</color>
    <color name="white">#FFFFFFFF</color>
    <color name="colorTeban">#FF420042</color>
</resources>

Una vez editado, pasamos al archivo themes.xml y hacemos referencia a los colores que agregamos.

<resources xmlns:tools="http://schemas.android.com/tools">
    <!-- Base application theme. -->
    <style name="Theme.Curso7Simulador" parent="Theme.MaterialComponents.DayNight.NoActionBar">
        <!-- Primary brand color. -->
        <item name="colorPrimary">@color/purple_500</item>
        <item name="colorPrimaryVariant">@color/purple_700</item>
        <item name="colorOnPrimary">@color/white</item>
        <!-- Secondary brand color. -->
        <item name="colorSecondary">@color/teal_200</item>
        <item name="colorSecondaryVariant">@color/teal_700</item>

        <item name="colorOnSecondary">@color/colorTeban</item>
        <!-- Status bar color. -->
        <item name="android:statusBarColor" tools:targetApi="l">?attr/colorOnSecondary</item>
        <!-- Customize your theme here. -->
    </style>
</resources>

Procedemos de la misma manera para la versión night..

Posteriormente nos dirigimos al archivo AndroidManifest.xml y agregamos los permisos para leer contactos.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mipaquete.simulador">

    <uses-permission android:name="android.permission.READ_CONTACTS"></uses-permission>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Curso7Simulador">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".CallActivity">
        </activity>
    </application>

</manifest>

Ahora nos dirigimos al archivo activity_call.xml, como se puede observar esta listo con ConstraintlLayout.

Dentro del ConstraintlLayout, creamos un TextView con su identificador, ancho, alto, margen superior, gravedad, texto, color de texto, tamaño de texto, estilo de texto y limites.

Luego creamos otro TextView, de igual manera con su identificador, ancho, alto, margen superior, gravedad, texto, color de texto y limites.

Ahora colocamos un ImageView, añadimos identificador, ancho, alto, margen superior, limites e icono.

Posteriormente creamos un TextView con identificador, ancho, alto, margen superior, texto, color de texto y limites.

Seguimos creando otro TextView con identificador, ancho, alto, margen superior, texto, color de texto y limites.

Luego creamos un imageview con su identificador, ancho, alto, margen superior, el atributo onclick, limites e icono.

Seguimos creando otro imageview con su identificador, ancho, alto, el atributo onclick, limites e icono.

Continuamos creando otro imageview con su identificador, ancho, alto, limites e icono.

Creamos el ultimo ImageView con su identificador, ancho, alto, limites e icono.

Luego creamos un TextView con su identificador, ancho, alto, texto, color de texto, limites e icono.

Creamos el ultimo TextView con su identificador, ancho, alto, texto, color de texto y limites.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".CallActivity"
    android:background="#4f5867">

    <TextView
        android:id="@+id/nameTextView"
        android:layout_width="227dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="64dp"
        android:gravity="center|center_vertical"
        android:text="Contacto"
        android:textColor="#FFF"
        android:textSize="24sp"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/timerTextView"
        android:layout_width="95dp"
        android:layout_height="32dp"
        android:layout_marginTop="24dp"
        android:gravity="center"
        android:text="Llamando"
        android:textColor="#FFF"
        app:layout_constraintEnd_toEndOf="@+id/nameTextView"
        app:layout_constraintStart_toStartOf="@+id/nameTextView"
        app:layout_constraintTop_toBottomOf="@+id/nameTextView" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="40dp"
        android:layout_height="40dp"
        app:layout_constraintStart_toStartOf="@+id/nameTextView"
        app:layout_constraintTop_toTopOf="@+id/imageView2"
        app:srcCompat="@drawable/ic_baseline_beach_access_24" />

    <ImageView
        android:id="@+id/imageView2"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_marginTop="150dp"
        app:layout_constraintEnd_toEndOf="@+id/nameTextView"
        app:layout_constraintTop_toBottomOf="@+id/timerTextView"
        app:srcCompat="@drawable/ic_baseline_message_24" />

    <TextView
        android:id="@+id/textView3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="Recuérdame más tarde"
        android:textColor="#FFF"
        app:layout_constraintEnd_toEndOf="@+id/imageView"
        app:layout_constraintHorizontal_bias="0.487"
        app:layout_constraintStart_toStartOf="@+id/imageView"
        app:layout_constraintTop_toBottomOf="@+id/imageView" />

    <TextView
        android:id="@+id/textView4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="Enviar mensaje"
        android:textColor="#FFF"
        app:layout_constraintEnd_toEndOf="@+id/imageView2"
        app:layout_constraintStart_toStartOf="@+id/imageView2"
        app:layout_constraintTop_toBottomOf="@+id/imageView2" />

    <ImageView
        android:id="@+id/imageView6"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:layout_marginTop="64dp"
        android:onClick="accept"
        app:layout_constraintEnd_toEndOf="@+id/imageView2"
        app:layout_constraintStart_toStartOf="@+id/imageView2"
        app:layout_constraintTop_toBottomOf="@+id/textView4"
        app:srcCompat="@drawable/accept" />

    <ImageView
        android:id="@+id/imageView8"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:onClick="decline"
        app:layout_constraintEnd_toEndOf="@+id/imageView"
        app:layout_constraintStart_toStartOf="@+id/imageView"
        app:layout_constraintTop_toTopOf="@+id/imageView6"
        app:srcCompat="@drawable/decline" />

    <ImageView
        android:id="@+id/imageView9"
        android:layout_width="60dp"
        android:layout_height="60dp"
        app:layout_constraintBottom_toBottomOf="@+id/imageView8"
        app:layout_constraintEnd_toEndOf="@+id/imageView8"
        app:layout_constraintStart_toStartOf="@+id/imageView8"
        app:layout_constraintTop_toTopOf="@+id/imageView8"
        app:srcCompat="@drawable/ic_baseline_call_end_24" />

    <ImageView
        android:id="@+id/imageView10"
        android:layout_width="60dp"
        android:layout_height="60dp"
        app:layout_constraintBottom_toBottomOf="@+id/imageView6"
        app:layout_constraintEnd_toEndOf="@+id/imageView6"
        app:layout_constraintStart_toStartOf="@+id/imageView6"
        app:layout_constraintTop_toTopOf="@+id/imageView6"
        app:srcCompat="@drawable/ic_baseline_call_24" />

    <TextView
        android:id="@+id/textView5"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="Colgar"
        android:textColor="#FFF"
        app:layout_constraintEnd_toEndOf="@+id/imageView8"
        app:layout_constraintStart_toStartOf="@+id/imageView8"
        app:layout_constraintTop_toBottomOf="@+id/imageView8" />

    <TextView
        android:id="@+id/textView6"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Contestar"
        android:textColor="#FFF"
        app:layout_constraintEnd_toEndOf="@+id/imageView6"
        app:layout_constraintStart_toStartOf="@+id/imageView6"
        app:layout_constraintTop_toTopOf="@+id/textView5" />

</androidx.constraintlayout.widget.ConstraintLayout>

Ahora nos dirigimos al archivo CallActivity.java, colocamos los atributos para controlar el simulador de llamadas.

Dentro del método onCreate obtenemos un Intent, inicializamos MediaPlayer.

Hacemos referencia a nameTextview y colocamos el texto recibido del Intent.

Inicializamos number igual a 0, creamos el método accept para contestar la llamada falsa.

Dentro de accept, detenemos el ringtone, inicializamos handler y configuramos un nuevo temporizador.

Creamos el método decline para detener el ringtone.

mport android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import android.view.View;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

public class CallActivity extends AppCompatActivity {
    MediaPlayer mediaPlayer;
    Handler handler;
    Runnable runnable;
    TextView timeText;
    int number;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_call);
        Intent intent = getIntent();
        mediaPlayer = MediaPlayer.create(this, Settings.System.DEFAULT_RINGTONE_URI);
        mediaPlayer.setLooping(true);
        mediaPlayer.start();
        TextView name = findViewById(R.id.nameTextView);
        timeText = findViewById(R.id.timerTextView);
        name.setText(intent.getStringExtra("name"));
        number = 0;
    }

    public void accept(View view) {
        mediaPlayer.stop();
        handler = new Handler();
        runnable = new Runnable() {
            @Override
            public void run() {
                if (number < 10) {
                    timeText.setText( "00:0" + number);
                } else if (number > 10 && number < 60) {
                    timeText.setText( "00:" + number);
                } else if (number > 59 && number % 60 < 10) {
                    int second = number / 60;
                    timeText.setText( second+":0" + number % 60);
                } else {
                    int second = number / 60;
                    timeText.setText( second+":" + number % 60);
                }


                number++;
                handler.postDelayed(runnable,1000);
            }
        };
        handler.post(runnable);

    }

    public void decline(View view) {
        mediaPlayer.stop();
    }
}

Ahora nos dirigimos a la clase activity_main y colocamos un fondo al LinearLayout.

Dentro del linearlayout creamos un textview con su identiificaador, ancho, alto, margen, gravedad, texto, tamaño de texto y estilo de texto.

Luego creamos un ConstraintLayout con ancho y alto.

Dentro del constraintlayout creamos un botón flotante con su identificador, ancho, alto, márgenes, atributo clickeable activado, limites e icono.

Luego creamos un listview de igual manera con identificador, ancho, alto y limites.

Cerramos el constraint layout, cambiamos al modo diseño para ver cómo esta quedando.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/ab_gradient"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/titleTextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="10dp"
        android:layout_marginTop="10dp"
        android:layout_marginEnd="10dp"
        android:layout_marginBottom="10dp"
        android:gravity="center"
        android:text="¿Quién te gustaría que te llamara?"
        android:textSize="24sp"
        android:textStyle="bold" />

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/floatingActionButton"
            android:layout_width="55dp"
            android:layout_height="55dp"
            android:layout_marginEnd="32dp"
            android:layout_marginBottom="28dp"
            android:clickable="true"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:srcCompat="@drawable/ic_baseline_call_24" />

        <ListView
            android:id="@+id/listView"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>

</LinearLayout>

Nos dirigimos al archivo MainaActivity.java y colocamos los atributos para controlar la clase principal.

Dentro del método onCreate inicializamos un ArrayList, hacemos referencia al TextView de titulo, al botón flotante.

Colocamos texto al textview de titulo, hacemos referencia al listview.

Colocamos una condición para determinar si se tiene los permisos para leer contactos.

En caso que no se hayan otorgado permisos, se solicitaran los mismos.

En el caso que tengamos los permisos, obtenemos la lista de contactos.

Creamos un cursor y vamos recorriendo la lista de contactos.

Al terminar de recorrer, cerramos el cursor e inicializamos un adaptador para el liistview.

Colocamos el adaptador al listview.

Posteriormente actualizamos con el método notifydatasetchanged.

Colocamos una condición para determinar si el arraylist tiene elementos, en ese caso colocar texto al textview infotitle y mostrar el botón flotante.

Colocamos un listener al botón flotante, dentro del método onclick, creamos una condición para determinar si se han otorgado permisos para leer contactos, en ese caso, obtenemos la lista de contactos.

Creamos un cursor y vamos recorriendo la lista de contactos, al terminar de recorrer, cerramos el cursor e inicializamos un adaptador para el liistview.

Colocamos el adaptador al listview, posteriormente actualizamos con el método notifydatasetchanged.

Colocamos una condición para determinar si el arraylist tiene elementos, en ese caso colocar texto al textview infotitle y mostrar el botón flotante.

En caso contrario, mostramos un snackbar de que se necesitan los permisos.

Agregamos un evento onclick al snackbar y volvemos a colocar una condición para determinar los permisos.

Finalmentee colocamos un listonar al listview, dentro del método onitemclick colocamos un intent.

Dentro del Intent pasamos el contacto e iniciamos CallActivity.

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.ContentResolver;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.Settings;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;

import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
    private ArrayList<String> contactArrayList;
    TextView infoTitle;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        contactArrayList = new ArrayList<>();
        infoTitle = findViewById(R.id.titleTextView);
        final FloatingActionButton fab = findViewById(R.id.floatingActionButton);
        infoTitle.setText("Presiona el botón de abajo para transferir tu agenda de contactos");
        final ListView listView = findViewById(R.id.listView);
        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,new String[] {Manifest.permission.READ_CONTACTS}, 1);
        } else {
            ContentResolver contentResolver = getContentResolver();
            String[] projection = {ContactsContract.Contacts.DISPLAY_NAME};
            Cursor cursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI,projection,null,null,ContactsContract.Contacts.DISPLAY_NAME);
            if (cursor != null) {
                while (cursor.moveToNext()) {
                    contactArrayList.add(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)));
                }
                cursor.close();
                ArrayAdapter adapter = new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1,contactArrayList);
                listView.setAdapter(adapter);
                adapter.notifyDataSetChanged();

                if (contactArrayList.size() > 0) {
                    infoTitle.setText("¿Quién te gustaría que te llamara?");
                    fab.setVisibility(View.INVISIBLE);
                }
            }
        }

        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {


                if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
                    ContentResolver contentResolver = getContentResolver();
                    String[] projection = {ContactsContract.Contacts.DISPLAY_NAME};
                    Cursor cursor = contentResolver.query(ContactsContract.Contacts.CONTENT_URI,projection,null,null,ContactsContract.Contacts.DISPLAY_NAME);
                    if (cursor != null) {
                        while (cursor.moveToNext()) {
                            contactArrayList.add(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)));
                        }
                        cursor.close();
                        ArrayAdapter adapter = new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1,contactArrayList);
                        listView.setAdapter(adapter);
                        adapter.notifyDataSetChanged();
                        if (contactArrayList.size() > 0) {
                            infoTitle.setText("¿Quién te gustaría que te llamara?");
                            fab.setVisibility(View.INVISIBLE);
                        }
                    }
                } else {
                    Snackbar.make(v, "Permitir extraer contactos de contactos", Snackbar.LENGTH_INDEFINITE)
                            .setAction("PERMITIR", new View.OnClickListener() {
                                @Override
                                public void onClick(View v) {
                                    if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,Manifest.permission.READ_CONTACTS)) {
                                        ActivityCompat.requestPermissions(MainActivity.this,new String[] {Manifest.permission.READ_CONTACTS}, 1);
                                    } else {
                                        Intent intent = new Intent();
                                        intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                        Uri uri = Uri.fromParts("package",MainActivity.this.getPackageName(),null);
                                        intent.setData(uri);
                                        MainActivity.this.startActivity(intent);
                                    }

                                }
                            }).show();
                }
            }
        });

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Intent intent = new Intent(MainActivity.this,CallActivity.class);
                intent.putExtra("name",contactArrayList.get(position));
                startActivity(intent);
            }
        });

    }
}

A continuación, te dejo un video con la implementación de App de Simulador de Llamadas.

Deja una respuesta