Перейти к содержимому

Autofillhints android studio что это

  • автор:

Autofillhints android studio что это

Элемент EditText является подклассом класса TextView . Он также представляет текстовое поле, но теперь уже с возможностью ввода и редактирования текста. Таким образом, в EditText мы можем использовать все те же возможности, что и в TextView.

Из тех атрибутов, что не рассматривались в теме про TextView, следует отметить атрибут android:hint . Он позволяет задать текст, который будет отображаться в качестве подсказки, если элемент EditText пуст. Кроме того, мы можем использовать атрибут android:inputType , который позволяет задать клавиатуру для ввода. В частности, среди его значений можно выделить следующие:

  • text : обычная клавиатура для ввода однострочного текста
  • textMultiLine : многострочное текстовое поле
  • textEmailAddress : обычная клавиатура, на которой присутствует символ @ , ориентирована на ввод email
  • textUri : обычная клавиатура, на которой присутствует символ / , ориентирована на ввод интернет-адресов
  • textPassword : клавиатура для ввода пароля
  • textCapWords : при вводе первый введенный символ слова представляет заглавную букву, остальные — строчные
  • number : числовая клавиатура
  • phone : клавиатура в стиле обычного телефона
  • date : клавиатура для ввода даты
  • time : клавиатура для ввода времени
  • datetime : клавиатура для ввода даты и времени

Первое поле здесь обычное однострочное, а второе — многострочное. Чтобы во втором поле текст выравнивался по верху, дополнительно устанавливается атрибут android:gravity=»top» .

EditText в Java и Android

Одной из возможностей элемента EditText также является возможность обработать введенные символы по мере ввода пользователя. Для этого определим в файле activity_main.xml следующую разметку:

Предполагается, что введенные в EditText символы тут же будут отображаться в элементе TextView. И для этого также изменим код MainActivity:

package com.example.viewapp; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; import android.widget.EditText; import android.widget.TextView; public class MainActivity extends AppCompatActivity < @Override protected void onCreate(Bundle savedInstanceState) < super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); EditText editText = findViewById(R.id.editText); editText.addTextChangedListener(new TextWatcher() < public void afterTextChanged(Editable s) <>public void beforeTextChanged(CharSequence s, int start, int count, int after) < >public void onTextChanged(CharSequence s, int start, int before, int count) < TextView textView = findViewById(R.id.textView); textView.setText(s); >>); > >

С помощью метода addTextChangedListener() здесь к элементу EditText добавляется слушатель ввода текста — объект TextWatcher . Для его использования нам надо реализовать три метода, но в реальности нам хватит реализации метода onTextChanged , который вызывается при изменении текста. Введенный текст передается в этот метод в качестве параметра CharSequence. В самом методе просто передаем этот текст в элемент TextView.

В итоге при вводе в EditText все символы также будут отображаться в TextView:

В чем ошибка? Почему не запускается приложение на Android studio?

import android.annotation.SuppressLint
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.text.TextUtils
import android.view.View
import android.widget.Button
import android.widget.EditText
import android.widget.TextView

abstract class Main : AppCompatActivity(), View.OnClickListener

internal lateinit var etNum1: EditText
internal lateinit var etNum2: EditText

internal lateinit var btnDiv: Button

internal abstract var tvResult: TextView

public override fun onCreate(savedInstanceState: Bundle?) super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

// находим элементы
this.etNum1 = this.findViewById(R.id.etNum1)
this.etNum2 = findViewById(R.id.etNum2)

// прописываем обработчик
btnDiv.setOnClickListener(this)

@SuppressLint(«SetTextI18n»)
override fun onClick(v: View) val num1: Number
val num2: Number
var result = 0f

// Проверяем поля на пустоту
if (TextUtils.isEmpty(etNum1.text.toString()) || TextUtils.isEmpty(etNum2.text.toString())) return
>

// читаем EditText и заполняем переменные числами
num1 = java.lang.Float.parseFloat(etNum1.text.toString())
num2 = java.lang.Float.parseFloat(etNum2.text.toString())

// определяем нажатую кнопку и выполняем соответствующую операцию
// в oper пишем операцию, потом будем использовать в выводе
when (v.id)

result = 4 / 100 * num1 / num2
>
else -> >
>

// формируем строку вывода
tvResult.text = num1.toString() + result
>

  • Вопрос задан более трёх лет назад
  • 493 просмотра

3 комментария

Простой 3 комментария

Средства миграции данных Android и улучшение поддержки приложений

Привет, Хабр! Представляю вашему вниманию перевод статьи «Discover tools for Android data migration and improve your app retention» авторов Sean McQuillan и Prateek Tandon.

Пользователи создают учетные записи, активируют их, а затем сохраняются, когда многократно запускают приложение. Обычно пользователю не нужно повторно вводить пароль для Android-приложения в течение многих лет, то есть до тех пор, пока он не купит новый телефон.
Покупка нового телефона — это редкое событие для многих людей, может пройти несколько лет между обновлением устройств. Существует несколько инструментов, которые помогут пользователям войти в систему, когда они будут использовать приложение на новом телефоне.

Резервное копирование данных приложения

Автозагрузка должна быть настроена для каждого приложения. Эта функция автоматически создает резервные копии данных приложения. Поэтому, когда люди получают новый телефон, их данные из приложений автоматически восстанавливаются до запуска приложения.
Чтобы настроить автозагрузку приложения, вам необходимо установить правила включения и исключения:

При настройке правил include и exclude важно избегать хранения конфиденциальных пользовательских данных в Auto Backup, хотя это отличное место для хранения пользовательских настроек и другого содержимого приложения.

Чтобы реализовать отслеживание для Auto Backup, зарегистрируйте BackupAgent и прослушайте onQuotaExceeded обратный вызов. Если ваше приложение превышает предел резервной копии 25 МБ, этот обратный вызов будет уведомлением о сбое. В хорошо сконфигурированном приложении этого никогда не произойдет, поэтому вы можете отслеживать его как отчет о сбое.

Оптимизируйте вход в систему

Пользователи не хотят повторно вводить логин и пароль. Существует несколько способов для решения этой задачи:

1. Используя Google Sign-In, пользователи могут войти в систему со своей учетной записью Gmail или любым адресом электронной почты. Самое главное, им не нужно запоминать пароль. Помимо улучшения регистрации и активации, включение входа в Google также поможет с сохранением, поскольку позволяет тем, кто получает новые телефоны, активироваться с помощью одной кнопки или даже автоматически. Еще вы можете использовать Google Sign-In для входа в систему приложений iOS, Web и Android. Также если ваше приложение использует Firebase Auth для обработки входа в Google.

2. Сделайте процесс входа проще с помощью Google Smart Lock и Autofill. Эти две функции работают рука об руку, чтобы помочь людям безопасно получить доступ к своим паролям. Autofill был представлен в Android O и будет предлагать автоматически сохранять пароли пользователя в хранилище данных Smart Lock или в предпочтительном диспетчере паролей при входе в систему. Настройте подсказки автозаполнения и исключите поля, которые не должны быть заполнены Autofill.

3. Интеграция Smart Lock с API для безопасного хранения паролей. Smart Lock обратно совместим с API 9 и отлично работает на устройствах со старыми версиями Android, которые не работают с Autofill. Подобно Autofill, Smart Lock API предложит спасти пароли пользователя после входа в систему. Программный поиск Smart Lock API позволяет автоматически возвратиться к пользовательскому входу даже на новых устройствах и в Chrome. Чтобы поддержать эту функцию Smart Lock, вам нужно будет включить в приложение какой-то код; проверьте Codelab, чтобы узнать, как интегрировать Smart Lock для паролей в приложение. Также не забудьте связать свое приложение с веб-сайтом, чтобы обеспечить беспрепятственный доступ к Chrome с помощью Autofill и Smart Lock.

4. Используя API переноса учетных записей, подумайте заранее, чтобы ваше приложение могло передавать учетные данные со старого телефона на новый. Приложение использует зашифрованный bluetooth или кабель, и вы можете передавать данные с телефонов с интерфейсом API 14 или выше. Перенос учетной записи происходит, когда пользователь вашего приложения настраивает свой новый телефон в первый раз, когда ваше приложение будет повторно установлено из Google Play, учетные данные вашего приложения будут доступны при первом запуске.

Также можно настроить автозагрузку для Android Codelab и SmartLock Codelab.

Теперь вы можете облегчить миграцию данных благодаря набору инструментов: передача настроек с помощью Auto Backup, улучшение входа в систему с помощью входа в аккаунт Google, Smart Lock для паролей, автозаполнение и API перенос аккаунта.

Espresso Testing Framework – Содержание

Android Intent используется для открытия нового действия, либо внутреннего (открытие экрана сведений о продукте на экране списка продуктов), либо внешнего (например, открытие номеронабирателя для совершения вызова). Внутренние намерения прозрачно обрабатываются средой тестирования эспрессо и не требуют какой-либо специальной работы со стороны пользователя. Тем не менее, вызывать внешнюю активность действительно сложно, потому что она выходит за рамки нашего приложения, тестируемого приложения. Как только пользователь вызывает внешнее приложение и выходит из тестируемого приложения, вероятность того, что пользователь вернется в приложение с заранее определенной последовательностью действий, будет значительно меньше. Поэтому нам нужно принять на себя действие пользователя перед тестированием приложения. Эспрессо предоставляет две возможности справиться с этой ситуацией. Они заключаются в следующем,

предназначена

Это позволяет пользователю убедиться, что правильное намерение открыто из тестируемого приложения.

намеревающийся

Это позволяет пользователю высмеивать внешнюю активность, например снимать фотографию с камеры, набирать номер из списка контактов и т. Д., И возвращаться к приложению с предопределенным набором значений (например, предопределенное изображение с камеры вместо фактического изображения). ,

Настроить

Espresso поддерживает опцию intent через библиотеку плагинов, и ее необходимо настроить в файле gradle приложения. Вариант конфигурации заключается в следующем,

dependencies < // . androidTestImplementation 'androidx.test.espresso:espresso-intents:3.1.1' >

предназначена()

Плагин Espresso intent предоставляет специальные средства сопоставления, чтобы проверить, является ли вызванное намерение ожидаемым. Предоставленные сопоставители и их назначение заключаются в следующем:

hasAction

Это принимает действие намерения и возвращает совпадение, которое соответствует указанному намерению.

hasData

Это принимает данные и возвращает сопоставление, которое сопоставляет данные, предоставленные намерению, при его вызове.

toPackage

Это принимает имя пакета намерения и возвращает сопоставление, которое совпадает с именем пакета вызванного намерения.

Теперь давайте создадим новое приложение и протестируем приложение на внешнюю активность, используя предназначенный (), чтобы понять концепцию.

  • Запустите Android-студию.
  • Создайте новый проект, как обсуждалось ранее, и назовите его IntentSampleApp.
  • Перенесите приложение на платформу AndroidX, используя меню параметров Refactor → Migrate to AndroidX .
  • Создайте текстовое поле, кнопку, чтобы открыть список контактов, и еще одну, чтобы набрать звонок, изменив файл activity_main.xml, как показано ниже,

Создайте новый проект, как обсуждалось ранее, и назовите его IntentSampleApp.

Перенесите приложение на платформу AndroidX, используя меню параметров Refactor → Migrate to AndroidX .

Создайте текстовое поле, кнопку, чтобы открыть список контактов, и еще одну, чтобы набрать звонок, изменив файл activity_main.xml, как показано ниже,

  • Также добавьте следующий элемент в файл ресурсов strings.xml ,

Также добавьте следующий элемент в файл ресурсов strings.xml ,

Phone number Call Select from contact list 
  • Теперь добавьте приведенный ниже код в основное действие ( MainActivity.java ) в методе onCreate .

Теперь добавьте приведенный ниже код в основное действие ( MainActivity.java ) в методе onCreate .

public class MainActivity extends AppCompatActivity < @Override protected void onCreate(Bundle savedInstanceState) < // . code // Find call from contact button Button contactButton = (Button) findViewById(R.id.call_contact_button); contactButton.setOnClickListener(new View.OnClickListener() < @Override public void onClick(View view) < // Uri uri = Uri.parse("content://contacts"); Intent contactIntent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI); contactIntent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE); startActivityForResult(contactIntent, REQUEST_CODE); >>); // Find edit view final EditText phoneNumberEditView = (EditText) findViewById(R.id.edit_text_phone_number); // Find call button Button button = (Button) findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() < @Override public void onClick(View view) < if(phoneNumberEditView.getText() != null) < Uri number = Uri.parse("tel:" + phoneNumberEditView.getText()); Intent callIntent = new Intent(Intent.ACTION_DIAL, number); startActivity(callIntent); >> >); > // . code >

Здесь мы запрограммировали кнопку с идентификатором call_contact_button, чтобы открыть список контактов, и кнопку с идентификатором, кнопку, чтобы набрать звонок.

  • Добавьте статическую переменную REQUEST_CODE в класс MainActivity, как показано ниже,

Добавьте статическую переменную REQUEST_CODE в класс MainActivity, как показано ниже,

public class MainActivity extends AppCompatActivity < // . private static final int REQUEST_CODE = 1; // . >
  • Теперь добавьте метод onActivityResult в класс MainActivity, как показано ниже:

Теперь добавьте метод onActivityResult в класс MainActivity, как показано ниже:

public class MainActivity extends AppCompatActivity  // . @Override protected void onActivityResult(int requestCode, int resultCode, Intent data)  if (requestCode == REQUEST_CODE)  if (resultCode == RESULT_OK)  // Bundle extras = data.getExtras(); // String phoneNumber = extras.get("data").toString(); Uri uri = data.getData(); Log.e("ACT_RES", uri.toString()); String[] projection =  ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME >; Cursor cursor = getContentResolver().query(uri, projection, null, null, null); cursor.moveToFirst(); int numberColumnIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER); String number = cursor.getString(numberColumnIndex); int nameColumnIndex = cursor.getColumnIndex( ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME); String name = cursor.getString(nameColumnIndex); Log.d("MAIN_ACTIVITY", "Selected number : " + number +" , name : "+name); // Find edit view final EditText phoneNumberEditView = (EditText) findViewById(R.id.edit_text_phone_number); phoneNumberEditView.setText(number); > > >; // . >

Здесь onActivityResult будет вызываться, когда пользователь возвращается в приложение после открытия списка контактов с помощью кнопки call_contact_button и выбора контакта. Как только метод onActivityResult вызывается, он получает выбранный пользователем контакт, находит номер контакта и устанавливает его в текстовое поле.

  • Запустите приложение и убедитесь, что все в порядке. Окончательный вид заявки Intent приведен ниже,

Запустите приложение и убедитесь, что все в порядке. Окончательный вид заявки Intent приведен ниже,

Образец заявки

  • Теперь настройте намерение эспрессо в файле gradle приложения, как показано ниже,

Теперь настройте намерение эспрессо в файле gradle приложения, как показано ниже,

dependencies < // . androidTestImplementation 'androidx.test.espresso:espresso-intents:3.1.1' >
  • Выберите пункт меню « Синхронизировать сейчас», предоставляемый Android Studio. Это загрузит библиотеку тестирования намерений и настроит ее должным образом.
  • Откройте файл ExampleInstrumentedTest.java и добавьте IntentsTestRule вместо обычно используемого AndroidTestRule . IntentTestRule – это специальное правило для обработки намеренного тестирования.

Выберите пункт меню « Синхронизировать сейчас», предоставляемый Android Studio. Это загрузит библиотеку тестирования намерений и настроит ее должным образом.

Откройте файл ExampleInstrumentedTest.java и добавьте IntentsTestRule вместо обычно используемого AndroidTestRule . IntentTestRule – это специальное правило для обработки намеренного тестирования.

public class ExampleInstrumentedTest < // . code @Rule public IntentsTestRulemActivityRule = new IntentsTestRule<>(MainActivity.class); // . code >
  • Добавьте две локальные переменные, чтобы установить тестовый номер телефона и имя пакета номеронабирателя, как показано ниже,

Добавьте две локальные переменные, чтобы установить тестовый номер телефона и имя пакета номеронабирателя, как показано ниже,

public class ExampleInstrumentedTest < // . code private static final String PHONE_NUMBER = "1 234-567-890"; private static final String DIALER_PACKAGE_NAME = "com.google.android.dialer"; // . code >
  • Исправьте проблемы с импортом, используя опцию Alt + Enter, предоставляемую android studio, или включите нижеприведенные операторы импорта,

Исправьте проблемы с импортом, используя опцию Alt + Enter, предоставляемую android studio, или включите нижеприведенные операторы импорта,

import android.content.Context; import android.content.Intent; import androidx.test.InstrumentationRegistry; import androidx.test.espresso.intent.rule.IntentsTestRule; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import static androidx.test.espresso.Espresso.onView; import static androidx.test.espresso.action.ViewActions.click; import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard; import static androidx.test.espresso.action.ViewActions.typeText; import static androidx.test.espresso.intent.Intents.intended; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasData; import static androidx.test.espresso.intent.matcher.IntentMatchers.toPackage; import static androidx.test.espresso.matcher.ViewMatchers.withId; import static org.hamcrest.core.AllOf.allOf; import static org.junit.Assert.*;
  • Добавьте приведенный ниже контрольный пример, чтобы проверить, правильно ли вызывается номеронабиратель.

Добавьте приведенный ниже контрольный пример, чтобы проверить, правильно ли вызывается номеронабиратель.

public class ExampleInstrumentedTest  // . code @Test public void validateIntentTest()  onView(withId(R.id.edit_text_phone_number)) .perform(typeText(PHONE_NUMBER), closeSoftKeyboard()); onView(withId(R.id.button)) .perform(click()); intended(allOf( hasAction(Intent.ACTION_DIAL), hasData("tel:" + PHONE_NUMBER), toPackage(DIALER_PACKAGE_NAME))); > // . code >

Здесь, hasAction , hasData и toPackage используются вместе с allOf matcher для достижения успеха, только если все сопоставления пройдены.

  • Теперь запустите ExampleInstrumentedTest через меню контента в Android-студии.

Теперь запустите ExampleInstrumentedTest через меню контента в Android-студии.

намереваясь ()

Эспрессо предоставляет специальный метод – намерение (), чтобы высмеивать действие внешнего намерения. intending () принимает имя пакета намерения, которое должно быть смоделировано, и предоставляет метод responseWith, чтобы установить, как смоделированное намерение должно отвечать, как указано ниже,

intending(toPackage("com.android.contacts")).respondWith(result);

Здесь responseWith () принимает намеренный результат типа Instrumentation.ActivityResult . Мы можем создать новое намерение заглушки и вручную установить результат, как указано ниже,

// Stub intent Intent intent = new Intent(); intent.setData(Uri.parse("content://com.android.contacts/data/1")); Instrumentation.ActivityResult result = new Instrumentation.ActivityResult(Activity.RESULT_OK, intent);

Полный код для проверки правильности открытия контактного приложения:

@Test public void stubIntentTest() < // Stub intent Intent intent = new Intent(); intent.setData(Uri.parse("content://com.android.contacts/data/1")); Instrumentation.ActivityResult result = new Instrumentation.ActivityResult(Activity.RESULT_OK, intent); intending(toPackage("com.android.contacts")).respondWith(result); // find the button and perform click action onView(withId(R.id.call_contact_button)).perform(click()); // get context Context targetContext2 = InstrumentationRegistry.getInstrumentation().getTargetContext(); // get phone number String[] projection = < ContactsContract.CommonDataKinds.Phone.NUMBER, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME >; Cursor cursor = targetContext2.getContentResolver().query(Uri.parse("content://com.android.cont acts/data/1"), projection, null, null, null); cursor.moveToFirst(); int numberColumnIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER); String number = cursor.getString(numberColumnIndex); // now, check the data onView(withId(R.id.edit_text_phone_number)) .check(matches(withText(number))); >

Здесь мы создали новое намерение и установили возвращаемое значение (при вызове намерения) в качестве первой записи списка контактов, содержимое: //com.android.contacts/data/1 . Затем мы установили метод intending, чтобы смоделировать вновь созданное намерение вместо списка контактов. Он устанавливает и вызывает наше вновь созданное намерение, когда вызывается пакет com.android.contacts и возвращается первая запись списка по умолчанию. Затем мы запустили действие click (), чтобы запустить фиктивное намерение и, наконец, проверили, совпадают ли телефонный номер из вызывающего фиктивного намерения и номер первой записи в списке контактов.

Если есть проблема с отсутствующим импортом, исправьте эти проблемы с помощью опции Alt + Enter, предоставляемой android studio, или включите приведенные ниже операторы импорта,

import android.app.Activity; import android.app.Instrumentation; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.provider.ContactsContract; import androidx.test.InstrumentationRegistry; import androidx.test.espresso.ViewInteraction; import androidx.test.espresso.intent.rule.IntentsTestRule; import androidx.test.runner.AndroidJUnit4; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import static androidx.test.espresso.Espresso.onView; import static androidx.test.espresso.action.ViewActions.click; import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard; import static androidx.test.espresso.action.ViewActions.typeText; import static androidx.test.espresso.assertion.ViewAssertions.matches; import static androidx.test.espresso.intent.Intents.intended; import static androidx.test.espresso.intent.Intents.intending; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasAction; import static androidx.test.espresso.intent.matcher.IntentMatchers.hasData; import static androidx.test.espresso.intent.matcher.IntentMatchers.toPackage; import static androidx.test.espresso.matcher.ViewMatchers.withId; import static androidx.test.espresso.matcher.ViewMatchers.withText; import static org.hamcrest.core.AllOf.allOf; import static org.junit.Assert.*;

Добавьте приведенное ниже правило в тестовый класс, чтобы предоставить разрешение на чтение списка контактов.

@Rule public GrantPermissionRule permissionRule = GrantPermissionRule.grant(Manifest.permission.READ_CONTACTS);

Добавьте указанную ниже опцию в файл манифеста приложения, AndroidManifest.xml

Теперь убедитесь, что в списке контактов есть хотя бы одна запись, а затем запустите тест с помощью контекстного меню Android Studio.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *