Làm cách nào tôi có thể truy cập giá trị BuildConfig trong tệp AndroidManifest.xml của mình?


137

Có thể truy cập giá trị BuildConfig từ AndroidManifest.xml không?

Trong tệp build.gradle của tôi, tôi có:

defaultConfig {
    applicationId "com.compagny.product"
    minSdkVersion 16
    targetSdkVersion 21
    versionCode 1
    versionName "1.0"

    // Facebook app id
    buildConfigField "long", "FACEBOOK_APP_ID", FACEBOOK_APP_ID
}

FACEBOOK_APP_ID được định nghĩa trong các tập tin gradle.properies của tôi:

# Facebook identifier (app ID)
FACEBOOK_APP_ID=XXXXXXXXXX

Để sử dụng kết nối Facebook trong ứng dụng của tôi, tôi phải thêm dòng này vào AndroidManifest.xml của mình:

<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/applicationId"/> 

Tôi muốn thay thế @string/applicationIdbằng trường BuildConfig FACEBOOK_APP_IDđược xác định trong lớp, như thế này:

<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="FACEBOOK_APP_ID"/> 

Có thể sử dụng BuildConfig không? Nếu không, làm thế nào tôi có thể đạt được điều này?

Câu trả lời:


190

Thay thế

buildConfigField "long", "FACEBOOK_APP_ID", FACEBOOK_APP_ID

với

resValue "string", "FACEBOOK_APP_ID", FACEBOOK_APP_ID

sau đó xây dựng lại dự án của bạn (Android Studio -> Build -> Rebuild Project).

Cả hai lệnh đều tạo ra các giá trị được tạo - bao gồm các hằng số Java trong trường hợp đầu tiên và tài nguyên Android trong lần thứ hai - trong quá trình xây dựng dự án, nhưng phương thức thứ hai sẽ tạo ra một stringgiá trị tài nguyên có thể được truy cập bằng @string/FACEBOOK_APP_IDcú pháp. Điều này có nghĩa là nó có thể được sử dụng trong tệp kê khai cũng như trong mã.


1
Đây là mã chính xác mà tôi đang sử dụng nhưng tôi gặp phải một vấn đề: SDK Facebook đọc chuỗi dưới dạng số nguyên vì một số lý do và sau đó ném ClassCastException vì Integer không thể được chuyển thành Chuỗi. Có ai phải đối mặt với vấn đề này?
WKS

@WKS Nếu bạn xem tệp tài nguyên đã tạo, loại tài nguyên có khớp với những gì bạn mong đợi (chuỗi) ở đó không?
stbest

đó là chuỗi:<item name="facebook_app_id" type="string">15233522...</item>
WKS

13
đảm bảo bạn viết resValue "chuỗi" và KHÔNG resValue "String"
keybee

1
Nếu bạn muốn sử dụng giá trị boolean, hãy đảm bảo bạn nhập resValue "bool" thay vì "boolean" -> tanelikorri.com/tutorial/android/set-variabled-in-build-gradle
reavcn

85

Một cách khác để truy cập các giá trị Gradle Build Config từ AndroidManifest.xml của bạn là thông qua các trình giữ chỗ như thế này:

android {
    defaultConfig {
        manifestPlaceholders = [ facebookAppId:"someId..."]
    }
    productFlavors {
        flavor1 {
        }
        flavor2 {
            manifestPlaceholders = [ facebookAppId:"anotherId..." ]
        }
    }
}

và sau đó trong bảng kê khai của bạn:

<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="${facebookAppId}"/> 

Xem thêm chi tiết tại đây: https://developer.android.com/studio/build/manifest-build-variables.html

(Liên kết cũ chỉ để tham khảo: http://tools.android.com/tech-docs/new-build-system/user-guide/manifest-merger )


2
Đây là một giải pháp tuyệt vời.
BinaryShrub

2
Vâng, đây là một phương pháp hay để tiêm chuỗi chỉ hiển thị!
stbest

2
Làm thế nào bạn có thể nhận được một giá trị từ manifestPlaceholder trong java? Điều này sẽ hữu ích cho các hằng được sử dụng trong cả mã java và tệp kê khai.
Louis CAD

@LouisCAD Tôi cho rằng bạn có thể cố gắng xác định một biến trong tệp xây dựng của mình, sau đó sử dụng nó để xác định trình giữ chỗ của bạn và (ngoài ra) trường BuildConfig, để bạn có thể sử dụng nó trong mã của mình.
GregoryK

1
@LouisCAD Tôi đã không thử điều đó, nhưng bạn có thể thử các cách sau: var placeholder = 'your placeholder' (dòng mới) buildConfigField "String", "PLACEHOLDER_NAME", giữ chỗ (dòng mới) manifestPlaceholder = [placeholderName: placholder] (new dòng) Rất vui được biết nếu nó hoạt động cho bạn
GregoryK

40

lưu ý: khi bạn sử dụng resValuegiá trị có thể vô tình bị ghi đè bởi tệp tài nguyên chuỗi (ví dụ: đối với ngôn ngữ khác)

Để có được một giá trị hằng thực sự mà bạn có thể sử dụng trong tệp kê khai và mã java, hãy sử dụng cả hai manifestPlaceholdersbuildConfigField: vd

android {
    defaultConfig {
        def addConstant = {constantName, constantValue ->
            manifestPlaceholders += [ (constantName):constantValue]
            buildConfigField "String", "${constantName}", "\"${constantValue}\""
        }

        addConstant("FACEBOOK_APP_ID", "xxxxx")
    }

truy cập trong tệp kê khai:

<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="${FACEBOOK_APP_ID}"/>

từ java:

BuildConfig.FACEBOOK_APP_ID

Nếu giá trị không đổi cần phải là đặc trưng của buildType, thì trình trợ giúp addConstantcần được điều chỉnh (để làm việc với ngữ nghĩa đóng Groovy), ví dụ:

buildTypes {
    def addConstantTo = {target, constantName, constantValue ->
        target.manifestPlaceholders += [ (constantName):constantValue]
        target.buildConfigField "String", "${constantName}", "\"${constantValue}\""
    }
    debug {
        addConstantTo(owner,"FACEBOOK_APP_ID", "xxxxx-debug")
    }
    release {
        addConstantTo(owner,"FACEBOOK_APP_ID", "xxxxx-release")
    }

1
Không hoạt động, nó hiển thị id ứng dụng không hợp lệ, từ tệp kê khai, nhưng khi được đặt từ java thì nó hoạt động
Brajendra Pandey

Tôi nghĩ rằng điều này sẽ không hoạt động nếu bạn cố gắng thêm nhiều hơn một hằng số!
Greg Ennis

1
@GregEnnis Ngoài ra, nhiều hằng số hoạt động tốt hơn đối với tôi: ví dụ: tôi chỉ gọi addConstant()hai lần ( constantNamestất nhiên là khác nhau ). lỗi gì bạn nhận được?
TmTron

1
@TmTron bạn không gặp lỗi, nhưng bạn chỉ định lại toàn bộ mảng 'manifestPlaceholder' mỗi khi nó được gọi, chỉ lưu trữ giá trị cuối cùng được sử dụng.
Greg Enni

@GregEnnis bạn thật tuyệt vời! Tôi đã có một mã khác trong dự án thử nghiệm của mình. Tôi đã cập nhật câu trả lời của mình: chúng ta chỉ cần sử dụng +=toán tử như thế nàymanifestPlaceholders += [...]
TmTron

6

Truy cập các thuộc tính build.gradle trong tệp kê khai của bạn như trong ví dụ sau:

Ví dụ: bạn có một "applicationId" thuộc tính trong build.gradle của mình và bạn muốn truy cập vào AndroidManifest của mình:

nhập mô tả hình ảnh ở đây

Truy cập "applicationId" trong AndroidManifest:

<receiver
        android:name="com.google.android.gms.gcm.GcmReceiver"
        android:exported="true"
        android:permission="com.google.android.c2dm.permission.SEND">
        <intent-filter>
            <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            <category android:name="${applicationId}" />
        </intent-filter>
    </receiver>

Tương tự, chúng ta có thể tạo tài nguyên chuỗi cho các hằng số khác và truy cập chúng trong các tệp mã đơn giản như:

context.getString(R.string.GCM_SENDER_ID);

Tôi có thể định nghĩa facebookAppId: "AnotherId ..." trong tệp .properations nơi tôi sẽ lưu mật khẩu cửa hàng của mình và tất cả. Sau đó, tôi truy cập vào những người trong bảng kê khai có thể truy cập gián tiếp trong AndroidManifest.xml. Tôi có thể làm điều đó?
Aman Verma

3

@stkent là tốt nhưng quên thêm rằng bạn cần xây dựng lại dự án của bạn sau đó

Thay thế

buildConfigField "long", "FACEBOOK_APP_ID", FACEBOOK_APP_ID

với

resValue "string", "FACEBOOK_APP_ID", FACEBOOK_APP_ID

sau đó

Android Studio -> Build -> Rebuild Project

Điều này sẽ cho phép Android tạo tài nguyên chuỗi có thể truy cập thông qua

R.string.FACEBOOK_APP_ID

Không thể nhận được thuộc tính không xác định 'FACEBOOK_APP_ID' cho ProductFlavor_ ...
f.trajkovski

2

Tùy chọn khác: sử dụng tệp tài nguyên chuỗi khác để thay thế tất cả các giá trị phụ thuộc vào Hương vị:

Bước 1: Tạo thư mục mới trong thư mục "src" với tên hương vị của bạn, tôi là "giai đoạn"

Bước 2: Tạo các tệp tài nguyên cho tất cả các tệp phụ thuộc vào hương vị, ví dụ:

nhập mô tả hình ảnh ở đây

Bước 3: Tôi cũng đang sử dụng các biểu tượng khác nhau, vì vậy bạn cũng thấy các thư mục mipmap. Đối với câu hỏi này, chỉ có "chuỗi DOM" là quan trọng. Bây giờ bạn có thể ghi đè tất cả các tài nguyên chuỗi quan trọng. Bạn chỉ cần bao gồm những cái bạn muốn ghi đè, tất cả những cái khác sẽ được sử dụng từ "String.xml" chính, nó sẽ hiển thị trong Android Studio như thế này:

nhập mô tả hình ảnh ở đây

Bước 4: Sử dụng tài nguyên chuỗi trong dự án của bạn và thư giãn:

nhập mô tả hình ảnh ở đây


Một lựa chọn tốt, đặc biệt là nếu bạn có nhiều chuỗi khác, bạn cần đặt mỗi biến thể.
stbest 7/10/2015

Tôi có thể định nghĩa facebookAppId: "AnotherId ..." trong tệp .properations nơi tôi sẽ lưu mật khẩu cửa hàng của mình và tất cả. Sau đó, tôi truy cập vào những người trong bảng kê khai có thể truy cập gián tiếp trong AndroidManifest.xml. Tôi có thể làm điều đó?
Aman Verma

0

Bạn có thể sử dụng giá trị dài như dưới đây

buildConfigField 'dài', 'FLAVOR_LONG', '11500L'

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.