Überblick

Fahrzeugeinstellungen ( packages/apps/Car/Settings ) werden speziell für das Android Automotive OS (AAOS) bereitgestellt. Die Autoeinstellungen unterscheiden sich von den Telefoneinstellungen ( packages/apps/Settings ). Während „Car Settings“ einige bekannte Telefoneinstellungen enthält, bietet „Car Settings“ eine an das Auto angepasste visuelle Benutzeroberfläche, Optimierungen für die Ablenkung des Fahrers und zahlreiche Einstiegspunkte für individuelle Anpassungen für OEMs.

Zusätzlich zu der unten bereitgestellten Übersicht über die Fahrzeugeinstellungen finden Sie in den folgenden verwandten Themen weitere Informationen zu den Fahrzeugeinstellungen:

Architektur und Richtlinien

Die meisten Seiten in Car Settings werden als eine Reihe von Fragmenten implementiert, die SettingsFragment erweitern, wobei jede ihre eigene Aktivität in CarSettingActivities definiert hat. Diese statischen Aktivitäten werden von BaseCarSettingsActivity erweitert. Zwar gibt es einige Ausnahmen von dieser Regel, wie etwa einige spezielle Fragmente, die BaseFragment anstelle von SettingsFragment erweitern, und einige Aktivitäten, die sich außerhalb von CarSettingActivities befinden, die jedoch alle als Ausnahmen (und nicht als zu befolgende Muster) betrachtet werden sollten.

Statische Präferenzen

Eine statische Präferenz wird in XML mithilfe des Preference- oder CarUiPreference -Tags definiert. Eine SettingsFragment Implementierung verwendet die Methode getPreferenceScreenResId() , um zu definieren, welche XML-Datei die statische Liste der anzuzeigenden Einstellungen enthält.

Dynamische Einstellungen

Dynamische Einstellungen verwenden das PreferenceGroup -Tag oder eine Implementierung von PreferenceGroup.

Innerhalb der CarSettings-App stellen dynamische Einstellungen einen normalen Satz von Einstellungen dar, die den Benutzer zu zusätzlichen Seiten innerhalb von CarSettings weiterleiten, die jedoch über den Preference Controller statt im XML hinzugefügt wurden. Ein Beispiel ist die Einstellung „Tastaturen verwalten“ unter „Sprachen und Eingabe“, die der Einstellungsseite dynamisch Eingabemethoden hinzufügt, je nachdem, ob diese Eingabemethoden zulässig sind oder nicht.

Aktionsleisten

Am oberen Rand jedes Einstellungsbildschirms befindet sich eine Aktionsleiste, die eine „Zurück“-Navigation, einen Bildschirmtitel und zusätzliche Aktions-Widgets (z. B. Schaltflächen und Schalter) enthalten kann. Diese Aktionsleisten ähneln der von Android bereitgestellten ActionBar , sind jedoch tatsächlich benutzerdefinierte Ansichten. In Android 11 und höher ist diese Symbolleiste im Basislayout des Gehäuses enthalten, das die Ansichten für die Symbolleiste und ein Framelayout für den Rest des App-Inhalts enthält.

Ergänzende Aktions-Widgets sind MenuItem-Klassen und sollten im onCreate des jeweiligen SettingsFragment oder BaseFragment erstellt werden. Eigenschaften wie Sichtbarkeit, Status usw. sollten durch Setter in der Geschäftslogik des SettingsFragment gesteuert werden.

// ExampleSettingsFragment.java
public class ExampleSettingsFragment extends SettingsFragment {

    @Override
    protected List<MenuItem> getToolbarMenuItems() {
        return Collections.singletonList(mClearConfirmButton);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        mButton = new MenuItem.Builder(getContext())
                .setTitle(R.string.text)
                .setOnClickListener(mOnClickListener)
                .setUxRestrictions(CarUxRestrictions.UX_RESTRICTIONS_NO_SETUP)
                .build();
    }

    private void updateState() {
        button.setVisible(false);
    }
}

Die Aktionsleisten unterstützen die Ablenkungsoptimierung in den Fahrzeugeinstellungen . Legen Sie die UXRestrictions im MenuItem.Builder bei der Erstellung fest.

Präferenz-Controller

Jede Einstellungsseite kann eine Reihe verschiedener Präferenzen enthalten.

Sehen Sie sich das folgende Bild an, um zu sehen, wie diese Komponenten zusammenhängen:

CarSettings-Komponenten

Abbildung 1. CarSettings-Komponenten

Der PreferenceController ist eine lebenszyklusbewusste Komponente, die dabei hilft, die Geschäftslogik für bestimmte Präferenzen zu kapseln. PreferenceControllers können nur über XML an die entsprechende Präferenz angehängt werden.

// example_settings_fragment.xml
<PreferenceScreen
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:settings="http://schemas.android.com/apk/res-auto"
    android:title="@string/example_settings_title">
  <Preference
    android:key="@string/pk_example_preference_key"
    android:title="@string/example_preference_title"
    settings:controller="com.android.car.settings.example.ExamplePreferenceController"/>
</PreferenceScreen>

Car Settings verhindert explizit die Erstellung von PreferenceController durch Code, um die Änderung der Einstellungshierarchie mit minimalen Änderungen am Java-Code zu erleichtern.

Es ist möglich, dass ein PreferenceController einige dynamische Daten benötigt, um ordnungsgemäß zu funktionieren. Beispielsweise muss ein PreferenceController , der Benachrichtigungen für eine App deaktiviert, wissen, auf welche App er reagieren soll. Da PreferenceControllers immer in XML definiert werden, gibt es keine Möglichkeit, zusätzliche Konstruktorargumente bereitzustellen. Stattdessen werden diese zusätzlichen Werte über öffentliche Setter auf dem PreferenceController bereitgestellt und mithilfe der use(...) Methode von SettingsFragment festgelegt.

// ExamplePreferenceController.java
public class ExamplePreferenceContorller extends PreferenceController<Preference> {

  private ExampleArg mExampleArg;

  public ExamplePreferenceController(...) {
    ...
  }

  public void setExampleArg(ExampleArg exampleArg) {
    mExampleArg = exampleArg;
  }
}

// ExampleSettingsFragment.java
public class ExampleSettingsFragment extends SettingsFragment {

  @Override
  @XmlRes
  protected int getPreferenceScreenResId() {
    Return R.xml.example_settings_fragment;
  }

  @Override
  public void onAttach(Context context) {
    ExampleArg arg = (ExampleArg) getArguments().getSerializeable(ARG_KEY);
    ExamplePreferenceController controller =
        use(ExamplePreferenceController.class, R.string.pk_example_preference_key);
    controller.setExampleArg(arg);
  }
}

Je häufiger die Methode use(...) verwendet wird, desto schwieriger wird es, das ursprüngliche Ziel beizubehalten, die Einstellungshierarchie mit minimalen Änderungen am Java-Code neu anordnen zu können, da große Abschnitte des vorhandenen Fragmentcodes geändert werden müssen in das neu erstellte Fragment kopiert. Eine Möglichkeit, die Schwierigkeit dabei zu minimieren, besteht darin:

  • Minimieren Sie Ihren Einsatz von use(...) .
  • Versuchen Sie, jeden Aufruf von use(...) an einer Stelle im Fragment aufzubewahren (z. B. in der Methode onAttach() ).

Absichtsbehandlung

Alle Absichten , die von der App „Autoeinstellungen“ verarbeitet werden sollen, sind in der Manifestdatei definiert. Absichten werden im Allgemeinen wie die meisten Standard-Android-Apps definiert und gehandhabt, wobei alle Aktivitäten und Absichtsfilter im Manifest definiert sind.

Ändern Sie das Root-Fragment

Bei Bedarf kann das Exit-Symbol mit config_show_settings_root_exit_icon angezeigt oder ausgeblendet werden.

Passen Sie das Thema an

Passen Sie andere Attribute und Ressourcen an

Die Car Settings-App verwendet hauptsächlich CarSettingTheme , eine Erweiterung von Theme.CarUi . Dieses Thema wird verwendet, um das Erscheinungsbild von System-Apps zu standardisieren und so die Konsistenz im System sicherzustellen.

Passen Sie die Einstellungen an

Das Anpassen der Einstellungen umfasst die folgenden zusätzlichen Standorte:

  • Das Layout einiger Basispräferenzklassen wird in car_preference definiert und für Fahrzeugaufbauten überlagert . Alle Anpassungslayouts für die Basispräferenzklassen können hier ersetzt werden.
  • Die Autoeinstellungen verwenden einige benutzerdefinierte Einstellungen, die hauptsächlich im common Paket definiert sind. Diese sollten innerhalb des Fahrzeugeinstellungen-Moduls getrennt von den Basispräferenzklassen überlagert werden.