436 Stimmen

Wie kann man den Paketnamen von überall bekommen?

Ich bin mir der Verfügbarkeit von Context.getApplicationContext() und View.getContext() bewusst, durch die ich tatsächlich Context.getPackageName() aufrufen kann, um den Paketnamen einer Anwendung abzurufen.

Sie funktionieren, wenn ich von einer Methode aus aufrufe, zu der ein View oder ein Activity-Objekt verfügbar ist, aber wenn ich den Paketnamen von einer völlig unabhängigen Klasse ohne View oder Activity finden möchte, gibt es einen Weg, das zu tun (direkt oder indirekt)?

7 Stimmen

Die akzeptierte Antwort wird dazu führen, dass Ihre Anwendung gelegentlich ABSTÜRZT - lesen Sie die Kommentare von AddDev & Turbo und danken Sie beiden für die vorgeschlagenen Lösungen.

1 Stimmen

Es könnte sein, dass du keine andere Möglichkeit hast, aber aus Gründen bewährter Praxis würde ich sagen, es ist besser, dies auf irgendeine Weise in die Klasse zu übergeben, in der du es benötigst, ausgehend von deinem letzten Kontextpunkt. Du greifst auf Laufzeitkontextinformationen in einer Klasse zu, die nichts über Kontexte auf eine statische Weise weiß - das stört mich. Ein anderer Ansatz wäre, es irgendwo fest codiert einzufügen.

574voto

John Leehey Punkte 21626

Eine Idee besteht darin, eine statische Variable in Ihrer Hauptaktivität zu haben, die instanziiert ist, um der Paketname zu sein. Verweisen Sie dann einfach auf diese Variable.

Sie müssen es in der onCreate()-Methode der Hauptaktivität initialisieren:

Global für die Klasse:

public static String PACKAGE_NAME;

Dann..

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    PACKAGE_NAME = getApplicationContext().getPackageName();
}

Sie können dann darauf zugreifen über Main.PACKAGE_NAME.

3 Stimmen

Das scheint für mich im Moment die praktischste Lösung zu sein, erfordert aber das Erstellen einer Unterklasse der Aktivität... +1 für jetzt.

1 Stimmen

Gerade einen ähnlichen Verweis gefunden: stackoverflow.com/questions/2002288/…

14 Stimmen

Mein Verständnis ist, dass final es unveränderlich macht, initialisierbar nur in einem Konstruktor und nur einmal. onCreate() ist kein Konstruktor. Bitte korrigieren Sie mich, wenn ich falsch liege.

377voto

Billda Punkte 5607

Wenn Sie das gradle-android-Plugin zum Erstellen Ihrer App verwenden, können Sie

BuildConfig.APPLICATION_ID

verwenden, um den Paketnamen aus jedem Bereich abzurufen, einschließlich eines statischen Bereichs.

34 Stimmen

Das ist der richtige Weg, die richtige Antwort sein sollte.

7 Stimmen

Hinweis: Bei Multi-Flavor-Builds wird (je nach dem verwendeten Import zum Zugriff auf die BuildConfig-Klasse) mit diesem Befehl der Paketname der Standardkonfiguration zurückgegeben und nicht der Paketname des Geschmacks.

2 Stimmen

@Rolf Das ist nicht wahr, es wird den richtigen Paketnamen der Anwendung zurückgeben ;) Vielleicht verwechseln Sie es mit dem Paketnamen Ihrer Java-Klassen

71voto

Addev Punkte 30523

Wenn Sie mit dem Wort "überall" meinen, ohne einen expliziten Kontext zu haben (zum Beispiel von einem Hintergrundthread aus), sollten Sie in Ihrem Projekt eine Klasse definieren, wie zum Beispiel:

public class MyApp extends Application {
    private static MyApp instance;

    public static MyApp getInstance() {
        return instance;
    }

    public static Context getContext(){
        return instance;
        // oder return instance.getApplicationContext();
    }

    @Override
    public void onCreate() {
        instance = this;
        super.onCreate();
    }
}

Dann müssen Sie in Ihrem Manifest diese Klasse im Feld Name im Reiter Anwendung hinzufügen. Oder bearbeiten Sie das XML und fügen Sie hinzu

`

und dann können Sie von überall aus folgendermaßen aufrufen:

String packagename= MyApp.getContext().getPackageName();

Hoffe, es hilft.

`

0 Stimmen

Dies ist nicht thread-sicher, aber Sie können wahrscheinlich damit davonkommen, wenn der Hintergrundthread später von dieser Aktivität gestartet wird.

3 Stimmen

Es ist threadsicher, da die Referenz auf die Instanz das erste ist, was gesetzt wird, wenn die App gestartet wird.

18 Stimmen

Entsprechend dieses Problems: code.google.com/p/android/issues/detail?id=8727 ContentProvider-Objekte werden vor dem Application-Objekt erstellt, anscheinend im Widerspruch zur Dokumentation, aber offensichtlich auch nach und gemäß dem Design. Dies könnte dazu führen, dass Ihre Instanz immer noch nicht gesetzt ist, wenn getInstance() während der Initialisierung eines ContentProviders aufgerufen wird.

46voto

Mahendra Liya Punkte 11992

Wenn Sie gradle build verwenden, verwenden Sie dies: BuildConfig.APPLICATION_ID, um den Paketnamen der Anwendung zu erhalten.

7 Stimmen

Anwendungs-ID und Paketname sind unterschiedliche Dinge. Die Anwendungs-ID wird über die `gradle.build`-Datei definiert, und der Paketname wird im Manifest definiert. Obwohl sie häufig den gleichen Wert haben, unterscheiden sie sich in komplexeren Build-Szenarien oft. Man kann verschiedenen Build-Konfigurationen verschiedene Anwendungs-IDs zuweisen, während der Paketname gleich bleibt.

3 Stimmen

@Uli Für diejenigen, die die Feinheiten etwas genauer wissen möchten tools.android.com/tech-docs/new-build-system/…

11 Stimmen

@ Uli Das gesagt, auch wenn die applicationId in der app.gradle von der packageName in der AndroidManifest.xml abweicht, liefert der Aufruf von context.getPackageName() die applicationId und nicht die packageName in der AndroidManifest.xml zurück. Der Zweck des neuen Build-Systems war es, beide zu entkoppeln, sodass applicationId der tatsächliche Paketname der App ist, der Google Play und dem auf dem Gerät installierten Paket bekannt ist - er kann nach der Bereitstellung nicht mehr geändert werden. Meine Meinung ist, es ist in Ordnung, BuildConfig.APPLICATION_ID zu verwenden. Lassen Sie mich wissen, wenn ich mich irre (:

13voto

user1506104 Punkte 5678

Für diejenigen, die Gradle verwenden, können Sie wie @Billda erwähnt den Paketnamen über Folgendes erhalten:

BuildConfig.APPLICATION_ID

Dies gibt Ihnen den im App-Gradle deklarierten Paketnamen:

android {
    defaultConfig {
        applicationId "com.domain.www"
    }
}

Wenn Sie den Paketnamen Ihrer Java-Klassen erhalten möchten (der manchmal von applicationId unterschiedlich ist), können Sie Folgendes verwenden:

BuildConfig.class.getPackage().toString()

Wenn Sie verwirrt sind, welchen Sie verwenden sollen, lesen Sie hier:

Anmerkung: Die Anwendungs-ID war früher direkt mit dem Paketnamen Ihres Codes verbunden; daher verwenden einige Android-APIs den Begriff "Paketname" in ihren Methodennamen und Parameterbezeichnungen, aber dies ist tatsächlich Ihre Anwendungs-ID. Beispielsweise gibt die Methode Context.getPackageName() Ihre Anwendungs-ID zurück. Es ist nicht erforderlich, den wahren Paketnamen Ihres Codes außerhalb Ihres App-Codes weiterzugeben.

0 Stimmen

Welchen Code haben Sie verwendet? Bitte geben Sie den genauen Fehler an, den Sie erhalten haben.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X