如何从任何地方获取包名?

ef2*_*011 324 android package android-context

我知道Context.getApplicationContext()View.getContext()的可用性,通过它我可以实际调用Context.getPackageName()来检索应用程序的包名.

如果我从一个View或一个Activity对象可用的方法调用它们,但是如果我想从一个完全独立的类中找到包名而没有View或者Activity,有没有办法(直接或间接)?

Joh*_*hey 462

一个想法是在主活动中有一个静态变量,实例化为包名.然后只引用该变量.

您必须在main活动的onCreate()方法中初始化它:

全球同学:

public static String PACKAGE_NAME;
Run Code Online (Sandbox Code Playgroud)

然后..

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

    PACKAGE_NAME = getApplicationContext().getPackageName();
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以通过它访问它Main.PACKAGE_NAME.

  • 这种方法不正确.例如,如果您的应用程序在执行secundary活动时进入后台,然后恢复.您的主要活动的onCreate()无法调用,而您的PACKAGE_NAME将为空!此外,如果您的应用程序有10个入口点且没有明确的"主要活动",该怎么办?您可以在此问题上查看我的答案,以获得正确的方法 (74认同)
  • 我的理解是`final`使它成为不可变的,只能在构造函数**中初始化**而**只能****.`onCreate()`不是构造函数.如果我弄错了请纠正. (12认同)
  • 这对我来说似乎是最实用的解决方案,但它确实需要我创建一个活动的子类...... +1现在. (3认同)
  • @Turbo,如果Android杀死进程,无论如何都必须再次调用`onCreate`,所以这个解决方案仍然不应该是一个问题. (3认同)
  • 确认工作 - 如果省略`final`. (2认同)
  • @JohnLeehey,如果应用程序进入后台,Android 系统可能会在某个时候终止该进程,从而导致静态变量被重置。由于这种行为,我在 Android 中遇到了一些问题,因此尝试仅使用静态变量来存储非持久性数据。 (2认同)

Bil*_*lda 252

如果您使用gradle-android-plugin构建您的应用程序,那么您可以使用

BuildConfig.APPLICATION_ID
Run Code Online (Sandbox Code Playgroud)

从任何范围检索包名称,包括 一个静态的.

  • 这是正确的方式,应该是公认的答案. (20认同)
  • 如果在库项目中使用它,请小心 - 这不起作用. (17认同)
  • 注意:对于多味道构建,这将返回(取决于用于访问BuildConfig类的导入)默认配置的包名称,而不是flavor的包名称. (4认同)
  • 如果在项目内的多个模块中使用它,请务必小心. (4认同)
  • PACKAGE_NAME实际上已停止在Android Studio 1.0中工作 (2认同)
  • @Rolfツ这是不正确的,它将返回应用程序的正确软件包名称;)也许您误以为它与Java类的软件包名称有关 (2认同)
  • @aberaud这不是正确的方法或接受的答案,因为它依赖于特定的配置,而接受的答案使用平台API。 (2认同)

Add*_*dev 68

如果使用"在任何地方"这个词你的意思是没有明确的Context(例如来自后台线程)你应该在项目中定义一个类,如:

public class MyApp extends Application {
    private static MyApp instance;

    public static MyApp getInstance() {
        return instance;
    }

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

    @Override
    public void onCreate() {
        instance = this;
        super.onCreate();
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在您manifest需要将此类添加到选项卡的Name字段中Application.或者编辑xml并放入

<application
    android:name="com.example.app.MyApp"
    android:icon="@drawable/icon"
    android:label="@string/app_name"
    .......
    <activity
        ......
Run Code Online (Sandbox Code Playgroud)

然后从你可以打电话的任何地方

String packagename= MyApp.getContext().getPackageName();
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你.

  • 根据此问题:http://code.google.com/p/android/issues/detail?id = 87227 ContentProvider对象是在Application对象之前创建的,显然与文档相反,但显然也是根据设计而定.如果在ContentProvider初始化期间调用getInstance(),则可能导致实例仍未设置. (16认同)
  • 它是线程安全的,因为对实例的引用是应用程序启动时设置的第一件事 (3认同)
  • 关于[`Application.onCreate()`](http://developer.android.com/reference/android/app/Application.html#onCreate%28%29)的文档已经更改以反映这一点:它现在特别声明"在应用程序启动时调用,在任何活动,服务或接收者对象(不包括内容提供者)之前调用". (3认同)
  • 这应该是选定的答案,因为无论正在运行什么活动,上下文都不会消亡. (2认同)

Mah*_*iya 43

如果使用gradle build,请使用以下命令:BuildConfig.APPLICATION_ID获取应用程序的包名称.

  • @Uli即便如此,即使app.gradle中的applicationId延迟到AndroidManifest.xml中的packageName,调用context.getPackageName()也会返回AndroidManifest.xml内的applicationId而不是packageName.新构建系统的目的是解耦两者,因此applicationId是Google Play及其安装设备已知的应用程序的实际程序包名称 - 部署后无法更改.我的观点是,可以使用BuildConfig.APPLICATION_ID.如果我弄错了,请告诉我(: (10认同)
  • 应用程序ID和包名称是不同的东西.应用程序ID通过gradle.build文件定义,包名称在Manifest中定义.虽然它们通常具有相同的值,但在更复杂的构建方案中它们通常也不同.可以将不同的应用程序ID分配给不同的构建配置,而包名称保持不变. (6认同)
  • @Uli对于那些想要了解更多细节的细节http://tools.android.com/tech-docs/new-build-system/applicationid-vs-packagename (3认同)
  • @kevinze完全准确!我跑了一个测试来仔细检查.谢谢你的澄清/纠正. (2认同)

use*_*104 13

对于那些使用 Gradle 的人,正如 @Billda 提到的,您可以通过以下方式获取包名称:

BuildConfig.APPLICATION_ID
Run Code Online (Sandbox Code Playgroud)

这将为您提供应用程序 gradle 中声明的包名称:

android {
    defaultConfig {
        applicationId "com.domain.www"
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您有兴趣获取 java 类使用的包名称(有时与 不同applicationId),您可以使用

BuildConfig.class.getPackage().toString()
Run Code Online (Sandbox Code Playgroud)

如果您对使用哪一个感到困惑,请阅读此处

注意:应用程序 ID 过去直接与代码的包名称关联;因此,一些 Android API 在其方法名称和参数名称中使用术语“包名称”,但这实际上是您的应用程序 ID。例如,Context.getPackageName() 方法返回您的应用程序 ID。无需在应用程序代码之外共享代码的真实包名称。


Dan*_*ark 11

只需使用此代码

val packageName = context.packageName 
Run Code Online (Sandbox Code Playgroud)


小智 5

private String getApplicationName(Context context, String data, int flag) {

   final PackageManager pckManager = context.getPackageManager();
   ApplicationInfo applicationInformation;
   try {
       applicationInformation = pckManager.getApplicationInfo(data, flag);
   } catch (PackageManager.NameNotFoundException e) {
       applicationInformation = null;
   }
   final String applicationName = (String) (applicationInformation != null ? pckManager.getApplicationLabel(applicationInformation) : "(unknown)");
   return applicationName;

}
Run Code Online (Sandbox Code Playgroud)