android
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| android [2016/03/12 18:24] – external edit 127.0.0.1 | android [2022/09/03 22:42] (current) – skipidar | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| + | ==== Linux environment ==== | ||
| + | How to set up a headless build environment. | ||
| + | |||
| + | |OS|Ubuntu 20.04| | ||
| + | |Android SDK|Android 11 (API level 30) as of 26.11.2021| | ||
| + | |||
| + | |||
| + | ==== Install android-sdk on Ubuntu ==== | ||
| + | |||
| + | <sxh bash> | ||
| + | # install openjdk8 - tested android sdk and its compatible | ||
| + | sudo apt-get install openjdk-8-jdk | ||
| + | # activate the 8th version if you have multiple using: | ||
| + | # sudo update-alternatives --config java | ||
| + | |||
| + | |||
| + | # install android-sdk under / | ||
| + | sudo apt update && sudo apt install android-sdk | ||
| + | |||
| + | |||
| + | |||
| + | # download the commandlinetools and add them to sdk | ||
| + | # < | ||
| + | wget -P /tmp/ https:// | ||
| + | |||
| + | # check https:// | ||
| + | sudo mkdir -p / | ||
| + | |||
| + | sudo unzip / | ||
| + | sudo mv / | ||
| + | |||
| + | # open bashrc and modify the environment variables | ||
| + | vim ~/.bashrc | ||
| + | export ANDROID_HOME="/ | ||
| + | export PATH=$PATH: | ||
| + | |||
| + | # apply changes in bashrc | ||
| + | source ~/.bashrc | ||
| + | |||
| + | |||
| + | # setting the rights | ||
| + | sudo chown $USER:$USER $ANDROID_HOME -R | ||
| + | |||
| + | |||
| + | |||
| + | # can successfully access the sdkmanager | ||
| + | sdkmanager --version | ||
| + | |||
| + | # install the platform tools https:// | ||
| + | sdkmanager " | ||
| + | |||
| + | # install the build tools https:// | ||
| + | sdkmanager " | ||
| + | |||
| + | |||
| + | # confirm all the licenses for the android tools otherwise they wont work | ||
| + | yes | sdkmanager --licenses | ||
| + | |||
| + | |||
| + | # check for android sdk updates | ||
| + | sdkmanager --update | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | # you can build android project now | ||
| + | cd < | ||
| + | ./gradlew build | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | </ | ||
| + | |||
| + | |||
| + | |||
| + | |||
| ==== HOWTO ==== | ==== HOWTO ==== | ||
| Line 256: | Line 333: | ||
| * Before every test - the method **setUp()** is executed | * Before every test - the method **setUp()** is executed | ||
| * test methods names have to start with **" | * test methods names have to start with **" | ||
| + | |||
| + | |||
| + | === Espresso - UI tests === | ||
| + | |||
| + | <sxh java> | ||
| + | package digital.alf.geosound; | ||
| + | |||
| + | import static androidx.test.espresso.Espresso.onView; | ||
| + | import static androidx.test.espresso.assertion.ViewAssertions.matches; | ||
| + | import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; | ||
| + | import static androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility; | ||
| + | import static androidx.test.espresso.matcher.ViewMatchers.withText; | ||
| + | import static org.hamcrest.CoreMatchers.allOf; | ||
| + | |||
| + | import android.Manifest; | ||
| + | import android.app.Activity; | ||
| + | import android.os.Bundle; | ||
| + | |||
| + | import androidx.navigation.NavController; | ||
| + | import androidx.navigation.Navigation; | ||
| + | import androidx.test.espresso.action.ViewActions; | ||
| + | import androidx.test.espresso.matcher.ViewMatchers; | ||
| + | import androidx.test.ext.junit.rules.ActivityScenarioRule; | ||
| + | import androidx.test.ext.junit.runners.AndroidJUnit4; | ||
| + | import androidx.test.filters.LargeTest; | ||
| + | import androidx.test.rule.GrantPermissionRule; | ||
| + | |||
| + | import org.junit.Rule; | ||
| + | import org.junit.Test; | ||
| + | import org.junit.runner.RunWith; | ||
| + | |||
| + | @RunWith(AndroidJUnit4.class) | ||
| + | @LargeTest | ||
| + | public class JustOpenAllWindows { | ||
| + | |||
| + | @Rule | ||
| + | public ActivityScenarioRule< | ||
| + | |||
| + | @Rule | ||
| + | public GrantPermissionRule mRuntimePermissionRuleFine = GrantPermissionRule.grant(android.Manifest.permission.ACCESS_FINE_LOCATION); | ||
| + | |||
| + | @Rule | ||
| + | public GrantPermissionRule mRuntimePermissionRuleCoarse = GrantPermissionRule.grant(Manifest.permission.ACCESS_COARSE_LOCATION); | ||
| + | |||
| + | @Rule | ||
| + | public GrantPermissionRule mRuntimePermissionRuleBackground = GrantPermissionRule.grant(Manifest.permission.ACCESS_BACKGROUND_LOCATION); | ||
| + | |||
| + | |||
| + | @Test | ||
| + | public void openPreferences() { | ||
| + | |||
| + | activityRule.getScenario().onActivity(activity -> { | ||
| + | Bundle args = new Bundle(); | ||
| + | NavController navController = Navigation.findNavController(activity, | ||
| + | navController.navigate(R.id.action_fragment_maps_to_fragment_preferences, | ||
| + | }); | ||
| + | |||
| + | onView(allOf(ViewMatchers.withText(R.string.dialog_preference_label), | ||
| + | .check(matches(isDisplayed())); | ||
| + | |||
| + | onView(ViewMatchers.withText(R.string.dialog_default_onout_volume_title)) | ||
| + | .perform(ViewActions.click()); | ||
| + | |||
| + | //Click on cancel button | ||
| + | onView(ViewMatchers.withId(android.R.id.button2)) | ||
| + | .perform(ViewActions.click()); | ||
| + | |||
| + | |||
| + | onView(ViewMatchers.withText(R.string.dialog_default_onout_volume_title)) | ||
| + | .perform(ViewActions.click()); | ||
| + | |||
| + | //Click on cancel button | ||
| + | onView(ViewMatchers.withId(android.R.id.button2)) | ||
| + | .perform(ViewActions.click()); | ||
| + | |||
| + | System.out.println(" | ||
| + | } | ||
| + | |||
| + | } | ||
| + | |||
| + | </ | ||
| + | |||
| + | === Execution in CodeBuild === | ||
| + | https:// | ||
| + | |||
| + | |||
| ==== Snippets ==== | ==== Snippets ==== | ||
| Line 1110: | Line 1273: | ||
| - use Bundle.class to exchange data with the Service. It provides possibility to restore the stored values typesafe. Bundle is like a Hashmap which can store different types of values result.getString(" | - use Bundle.class to exchange data with the Service. It provides possibility to restore the stored values typesafe. Bundle is like a Hashmap which can store different types of values result.getString(" | ||
| + | |||
| + | ==== Bindings ==== | ||
| + | |||
| + | The bare minimum in code | ||
| + | <sxh java> | ||
| + | @Override | ||
| + | public View onCreateView(LayoutInflater inflater, ViewGroup container, | ||
| + | | ||
| + | |||
| + | final ViewDataBinding binding = DataBindingUtil.inflate( | ||
| + | inflater, R.layout.fragment_poidialog, | ||
| + | final View view = binding.getRoot(); | ||
| + | return view; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | The binding in xml | ||
| + | |||
| + | https:// | ||
| + | < | ||
| + | <?xml version=" | ||
| + | <layout | ||
| + | xmlns: | ||
| + | xmlns: | ||
| + | |||
| + | < | ||
| + | android: | ||
| + | android: | ||
| + | > | ||
| + | |||
| + | <include | ||
| + | layout=" | ||
| + | app: | ||
| + | /> | ||
| + | |||
| + | </ | ||
| + | </ | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | <?xml version=" | ||
| + | <layout | ||
| + | xmlns: | ||
| + | > | ||
| + | |||
| + | < | ||
| + | // declare fields | ||
| + | < | ||
| + | name=" | ||
| + | type=" | ||
| + | </ | ||
| + | |||
| + | < | ||
| + | android: | ||
| + | android: | ||
| + | android: | ||
| + | |||
| + | </ | ||
| + | |||
| + | </ | ||
| + | |||
| + | |||
| + | |||
| + | ==== Style ==== | ||
| + | |||
| + | === Styles, attributes === | ||
| + | |||
| + | {{https:// | ||
| + | |||
| + | |||
| + | === TextAppearance === | ||
| + | The text size in android is controlled by " | ||
| + | |||
| + | |||
| + | Material Design provides 13 type “styles” that are applied to all the text in your app. Each of these have a design term (eg. “Body 1”) along with a corresponding type attribute that can be overridden in your app theme (eg. textAppearanceBody1). There are default “baseline” values (text size, letter spacing, capitalization, | ||
| + | |||
| + | https:// | ||
| + | |||
| + | {{https:// | ||
| + | |||
| + | |||
| + | == Usage in your view == | ||
| + | |||
| + | At the end, | ||
| + | to express which size the text in your custom view should have | ||
| + | instead of influencing " | ||
| + | which will lead to difficulties with consistancy across app and consistancy with android native textSizes | ||
| + | |||
| + | you should set " | ||
| + | |||
| + | and the value should be one of androids own textAppearance **attributes**: | ||
| + | * textAppearanceHeadline1 | ||
| + | * textAppearanceHeadline2 | ||
| + | * textAppearanceHeadline3 | ||
| + | * textAppearanceHeadline4 | ||
| + | * textAppearanceBody1 | ||
| + | * textAppearanceBody2 | ||
| + | |||
| + | The same attributes are used by android too, so your view will be consistant with android natives | ||
| + | |||
| + | In your someAppPartLayout.xml | ||
| + | < | ||
| + | <!-- My title in my app view --> | ||
| + | < | ||
| + | android: | ||
| + | android: | ||
| + | android: | ||
| + | android: | ||
| + | </ | ||
| + | |||
| + | |||
| + | == Changing the value of attributes in AppTheme == | ||
| + | |||
| + | In your theme, maybe defined in your styles.xml | ||
| + | you can change single android attributes. | ||
| + | |||
| + | In my theme, which is defined in this style - overriding the single attributes " | ||
| + | referencing MY styles, which can interfere and override the default values for textAppearance. | ||
| + | |||
| + | **Remark: | ||
| + | Those textAppearance* attributes are also used in android native views, | ||
| + | like buttons | ||
| + | see https:// | ||
| + | So overriding those in a theme - changes the behavior also for Android native elements | ||
| + | |||
| + | THose attributes are not just strings, but are introduced as typed attributes in attrs.xml | ||
| + | with format=" | ||
| + | format=" | ||
| + | In the value-style element - the items a la android: | ||
| + | |||
| + | USAGE of attributes | ||
| + | The attribute can be USED in views, by refering to the attribute in the view | ||
| + | e.g. | ||
| + | < | ||
| + | |||
| + | In your styles.xml pointing textAppearanceHeadline1 attribute of type " | ||
| + | to my own style. | ||
| + | |||
| + | The style inherits from androids own style but I still can override some values in my inherited style. | ||
| + | |||
| + | < | ||
| + | <!-- Base application theme. --> | ||
| + | <style name=" | ||
| + | <!-- Customize your theme here. --> | ||
| + | <item name=" | ||
| + | <item name=" | ||
| + | <item name=" | ||
| + | |||
| + | |||
| + | <item name=" | ||
| + | @style/ | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | |||
| + | == Introducing own styles, to refer from overridden attributes textAppearance* == | ||
| + | |||
| + | THe value of an overridden attribute **textAppearance*** is a style | ||
| + | |||
| + | |||
| + | in your styles.xml | ||
| + | parallel to the AppTheme - introduce styles, to refer from attributes. | ||
| + | < | ||
| + | |||
| + | <!-- here I can change attributes of the STYLES. | ||
| + | by Inheriting from " | ||
| + | but get the possibility to override them here | ||
| + | --> | ||
| + | <style name=" | ||
| + | <item name=" | ||
| + | </ | ||
| + | |||
| + | <style name=" | ||
| + | <item name=" | ||
| + | </ | ||
| + | |||
| + | <style name=" | ||
| + | <item name=" | ||
| + | </ | ||
| + | |||
| + | <style name=" | ||
| + | <item name=" | ||
| + | </ | ||
| + | |||
| + | <style name=" | ||
| + | <item name=" | ||
| + | </ | ||
| + | |||
| + | <style name=" | ||
| + | <item name=" | ||
| + | </ | ||
| + | |||
| + | <style name=" | ||
| + | <item name=" | ||
| + | </ | ||
| + | |||
| + | <style name=" | ||
| + | <item name=" | ||
| + | </ | ||
| + | </ | ||
| + | |||
android.1457807067.txt.gz · Last modified: (external edit)
