1. Добавление нового контакта

Скачайте и откройте заготовленный проект. В нем содержатся макеты и нужные ресурсы.

Создайте новое окно AddContactActivity (в качестве макета окна установите уже существующий макет activity_add_contact.xml.

В контроллере MainActivity.java получите ссылки на нужные элементы UI

MainActivity.java
public class MainActivity extends AppCompatActivity {

    private RecyclerView mRecyclerView;
    private FloatingActionButton mAddContactButton;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setWindow();
        
        mRecyclerView = findViewById(R.id.list);
        mAddContactButton = findViewById(R.id.fab);
    }
}

Добавьте обработчик нажатия на кнопку "+". При нажатии на кнопку открывается AddContactActivity с получением результата работы окна.

MainActivity.java
public class MainActivity extends AppCompatActivity {

    private static final int ADD_CONTACT_REQUEST_CODE = 5556;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setWindow();

        mRecyclerView = findViewById(R.id.list);

        mAddContactButton = findViewById(R.id.fab);
        mAddContactButton.setOnClickListener(v -> {
            Intent i = new Intent(this, AddContactActivity.class);
            startActivityForResult(i, ADD_CONTACT_REQUEST_CODE);
        });
    }
}

Работа с AddContactActivity

Скопируйте из MainActivity.java метод setWindow() и добавьте его в класс AddContactActivity.java. В методе create() вызовите метод setWindow().

AddContactActivity.java
public class AddContactActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add_contact);
        setWindow();
    }

    private void setWindow() {
        // Метод устанавливает StatusBar в цвет фона
        Window window = this.getWindow();
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        window.setStatusBarColor(getColor(R.color.activity_background));

        View decor = getWindow().getDecorView();
        decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
    }
}

Получите ссылки на изображение контакта, поля ввода и кнопки. Объект ImageView будет меняться при получении снимка из камеры, поэтому его необходимо сделать полем класса. Ссылки на остальные элементы UI можно сделать локальными в рамках метода onCreate().

AddContactActivity.java
public class AddContactActivity extends AppCompatActivity {

    private ImageView mContactImage;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add_contact);
        setWindow();
        
        mContactImage = findViewById(R.id.profile_image);
        
        EditText nameEditText = findViewById(R.id.name_et);
        EditText EmailEditText = findViewById(R.id.email_et);
        EditText PhoneEditText = findViewById(R.id.phone_et);

        Button addContactButton = findViewById(R.id.button_add);
        Button takePhotoButton = findViewById(R.id.button_camera);
        Button cancelButton = findViewById(R.id.button_cancel);
    }
}

Сразу реализуем сценарий, когда пользователь нажимает кнопку "Cancel" или кнопку "Назад" на телефоне. Мы помним, что в этом случае необходимо установить результат как RESULT_CANCELED.

AddContactActivity.java
public class AddContactActivity extends AppCompatActivity {

    private ImageView mContactImage;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
        ...
        
        Button cancelButton = findViewById(R.id.button_cancel);
        cancelButton.setOnClickListener(v -> onBackPressed());
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();

        setResult(RESULT_CANCELED);
    }
}

Теперь реализуем получение изображения из камеры. Реализация этого функционала аналогична прошлой лабораторной работе:

  1. запрашиваем открытие окна камеры с получением результата;

  2. при получении результата записываем миниатюру в файл;

  3. сохраняем Uri файла;

  4. меняем изображение в ImageView.

Сначала реализуем обработчик нажатия на кнопку "Take photo".

AddContactActivity.java
public class AddContactActivity extends AppCompatActivity {

    private static final int IMAGE_CAPTURE_REQUEST_CODE = 7777;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
        ...
        
        Button takePhotoButton = findViewById(R.id.button_camera);
        takePhotoButton.setOnClickListener(v -> {
            Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            try {
                startActivityForResult(takePictureIntent, IMAGE_CAPTURE_REQUEST_CODE);
            } catch (ActivityNotFoundException e) {
                Toast.makeText(this, "Error while trying to open camera app", Toast.LENGTH_SHORT).show();
            }
        });
    }
}

Далее переопределяем метод onActivityResult(), делаем нужные проверки на requestCode, resultCode и наличие данных.

AddContactActivity.java
public class AddContactActivity extends AppCompatActivity {

    private static final int IMAGE_CAPTURE_REQUEST_CODE = 7777;

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == IMAGE_CAPTURE_REQUEST_CODE && resultCode == RESULT_OK && data != null) {
            
        }
    }
}

Сохраняем пришедшее изображение в файл, меняем изображение контакта в окне и сохраняем путь к файлу. Для хранения пути к файлу создайте поле класса типа Uri.

AddContactActivity.java
public class AddContactActivity extends AppCompatActivity {

    private static final int IMAGE_CAPTURE_REQUEST_CODE = 7777;
    private ImageView mContactImage;
    private Uri mContactImageUri;

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == IMAGE_CAPTURE_REQUEST_CODE && resultCode == RESULT_OK && data != null) {
            Bundle extras = data.getExtras();
            Bitmap imageBitmap = (Bitmap) extras.get("data");

            // Меняем ImageView с изображением контакта
            mContactImage.setImageBitmap(imageBitmap);

            String filename = "contact_" + System.currentTimeMillis() + ".png";

            File outputFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), filename);
            FileOutputStream fileOutputStream = null;
            try {
                fileOutputStream = new FileOutputStream(outputFile);
                imageBitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);

                // Сохраняем путь к файлу в формате Uri
                mContactImageUri = Uri.fromFile(outputFile);
                fileOutputStream.flush();
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

Теперь нам осталось написать обработчик для кнопки "Add". При нажатии на кнопку мы проверяем, получено ли изображение контакта, после чего упаковываем содержимое полей ввода и путь к файлу в Intent и устанавливаем результат работы окна.

AddContactActivity.java
public class AddContactActivity extends AppCompatActivity {

    private static final int IMAGE_CAPTURE_REQUEST_CODE = 7777;
    private ImageView mContactImage;
    private Uri mContactImageUri;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
        ...

        Button addContactButton = findViewById(R.id.button_add);
        addContactButton.setOnClickListener(v -> {
            if (mContactImageUri == null) {
                Toast.makeText(this, "Contact image not set!", Toast.LENGTH_SHORT).show();
                return;
            }

            String name = nameEditText.getText().toString();
            String email = EmailEditText.getText().toString();
            String phone = PhoneEditText.getText().toString();

            Intent i = new Intent();
            i.putExtra(Intent.EXTRA_USER, name);
            i.putExtra(Intent.EXTRA_EMAIL, email);
            i.putExtra(Intent.EXTRA_PHONE_NUMBER, phone);
            i.putExtra(Intent.EXTRA_ORIGINATING_URI, mContactImageUri.toString());

            setResult(RESULT_OK, i);
            finish();
        });
    }
}

Для проверки работоспособности функционала переопределим в окне MainActivity.java метод onActivityResult() и добавим вывод на экран данных, полученных из AddContactActivity.java

Ниже приведен листинг класса AddContactActivity.java

AddContactActivity.java
public class AddContactActivity extends AppCompatActivity {

    private ImageView mContactImage;
    private Uri mContactImageUri;

    private static final int IMAGE_CAPTURE_REQUEST_CODE = 7777;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add_contact);
        setWindow();

        mContactImage = findViewById(R.id.profile_image);

        EditText nameEditText = findViewById(R.id.name_et);
        EditText EmailEditText = findViewById(R.id.email_et);
        EditText PhoneEditText = findViewById(R.id.phone_et);

        Button addContactButton = findViewById(R.id.button_add);
        addContactButton.setOnClickListener(v -> {
            if (mContactImageUri == null) {
                Toast.makeText(this, "Contact image not set!", Toast.LENGTH_SHORT).show();
                return;
            }

            String name = nameEditText.getText().toString();
            String email = EmailEditText.getText().toString();
            String phone = PhoneEditText.getText().toString();

            Intent i = new Intent();
            i.putExtra(Intent.EXTRA_USER, name);
            i.putExtra(Intent.EXTRA_EMAIL, email);
            i.putExtra(Intent.EXTRA_PHONE_NUMBER, phone);
            i.putExtra(Intent.EXTRA_ORIGINATING_URI, mContactImageUri.toString());

            setResult(RESULT_OK, i);
            finish();
        });

        Button takePhotoButton = findViewById(R.id.button_camera);
        takePhotoButton.setOnClickListener(v -> {
            Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            try {
                startActivityForResult(takePictureIntent, IMAGE_CAPTURE_REQUEST_CODE);
            } catch (ActivityNotFoundException e) {
                Toast.makeText(this, "Error while trying to open camera app", Toast.LENGTH_SHORT).show();
            }
        });

        Button cancelButton = findViewById(R.id.button_cancel);
        cancelButton.setOnClickListener(v -> onBackPressed());
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == IMAGE_CAPTURE_REQUEST_CODE && resultCode == RESULT_OK && data != null) {
            Bundle extras = data.getExtras();
            Bitmap imageBitmap = (Bitmap) extras.get("data");

            // Меняем ImageView с изображением контакта
            mContactImage.setImageBitmap(imageBitmap);

            String filename = "contact_" + System.currentTimeMillis() + ".png";

            File outputFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), filename);
            FileOutputStream fileOutputStream = null;
            try {
                fileOutputStream = new FileOutputStream(outputFile);
                imageBitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);

                // Сохраняем путь к файлу в формате Uri
                mContactImageUri = Uri.fromFile(outputFile);
                fileOutputStream.flush();
                fileOutputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();

        setResult(RESULT_CANCELED);
    }

    private void setWindow() {
        // Метод устанавливает StatusBar в цвет фона
        Window window = this.getWindow();
        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
        window.setStatusBarColor(getColor(R.color.activity_background));

        View decor = getWindow().getDecorView();
        decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
    }
}

Last updated