Question

I want to add some features into Browser app by start an activity from another android application. It gives me package does not exist while I make the Main Project. Notice that I see the AndroidLib is built successfully into an out/target/product/generic/data/app/AndroidLib.apk

Here are two android.mk files: AndroidLib(a normal Android App)

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_STATIC_JAVA_LIBRARIES := \
        google-ps \
        android-support-v4 \

LOCAL_SRC_FILES := \
        $(call all-java-files-under, src) \
LOCAL_MODULE := AndroidLib
LOCAL_PACKAGE_NAME := AndroidLib

LOCAL_MODULE_TAGS := tests

LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := google-ps:libs/google-play-services.jar

include $(BUILD_PACKAGE)

# additionally, build tests in sub-folders in a separate .apk
include $(call all-makefiles-under,$(LOCAL_PATH))

Browser App

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS := optional

LOCAL_STATIC_JAVA_LIBRARIES := \
        android-common \
        guava \
        android-support-v13 \
        android-support-v4 \

LOCAL_SRC_FILES := \
        $(call all-java-files-under, src) \
        src/com/android/browser/EventLogTags.logtags

LOCAL_PACKAGE_NAME := Browser

LOCAL_PROGUARD_FLAG_FILES := proguard.flags

LOCAL_EMMA_COVERAGE_FILTER := *,-com.android.common.*


# We need the sound recorder for the Media Capture API.
LOCAL_REQUIRED_MODULES := SoundRecorder, AndroidLib

include $(BUILD_PACKAGE)
# additionally, build tests in sub-folders in a separate .apk
include $(call all-makefiles-under,$(LOCAL_PATH))

Then I do:

make -j Browser

It gives me:

packages/apps/Browser/src/com/android/browser/BrowserActivity.java:36: package com.om.AndroidLib does not exist
import com.om.AndroidLib.MainActivity;
Was it helpful?

Solution

Update

Essentially your problem is that the line:

LOCAL_REQUIRED_MODULES := SoundRecorder, AndroidLib

Tells the Android build that your Browser depends on AndroidLib being built first, however it will not be linked to AndroidLib in any way. To do that you need:

LOCAL_JAVA_LIBRARIES := AndroidLib

Except that requires the AndroidLib to be a java library project, using the build type:

include $(BUILD_JAVA_LIBRARY)

And java libraries cannot include resources, unfortunately. And there is no way to link one app to another app in the Android build system.

We are working around that issue frequently, and it is frankly a bit of a mess to do so. But the only workaround we have found is to include all the resources directly in the apps that use those resources. Sorry.


How to make your AndroidLib a java library and link to it

Your android lib should probably be built as a java library, and not as a app package. So instead of:

include $(BUILD_PACKAGE)

You should probably do:

include $(BUILD_JAVA_LIBRARY)

Then you lib will be placed in out/target/product/generic/system/framework/AndroidLib.jar along with the other system libs.

Also you do not need a LOCAL_MODULE_NAME for a lib, it is only applicable for an app. So strip that.

And you should probably consider changing your LOCAL_MODULE_TAGS to:

LOCAL_MODULE_TAGS := user

tests indicates that you lib should only be built for testing, user says to build you lib for all user builds (and implicitly also for engineering builds)


In you app Android.mk you should then add a line:

LOCAL_JAVA_LIBRARIES := AndroidLib

Such that your app will be built with AndroidLib in the classpath.


In you apps AndroidManifest.xml you also need to put a uses library in the application tag:

<uses-library android:name="AndroidLib" />

And last you need to create a permissions xml file, with the following content:

<?xml version="1.0" encoding="utf-8"?>
<permissions>
    <library name="AndroidLib"
            file="/system/framework/AndroidLib.jar"/>
</permissions>

And update your product configuration file such that the xml file will be deployed to target:

PRODUCT_COPY_FILES += device/XXX/libs/AndroidLib.xml:system/etc/permissions/AndroidLib.xml

Replace device/XXX/libs/ with the path to the permissions xml file.


This is how we add and use an Android library in our Android builds. I hope it helps. :)

OTHER TIPS

I know I'm digging this out of the grave a little bit, but there was never really an answer for how to actually include an Android Library Project (or other apk with resources) within an AOSP built application.

Here is what I have done with two projects. "main" is the main application I am building the apk for. "util" is a utility library with resources I am linking against. Both of the projects reside in external/seabold/{package}:

Android.mk in seabold/

LOCAL_PATH := $(call my-dir)

UTIL_PATH := $(LOCAL_PATH)/util

UTIL_JAVA_SRC := $(call all-java-files-under, util/src)

#Filter out if the util library isn't present
UTIL_RES_DIR := $(wildcard $(UTIL_PATH)/res)

include $(call all-subdir-makefiles)



Android.mk in seabold/main/

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_PACKAGE_NAME := main

LOCAL_MODULE_TAGS := optional

LOCAL_SRC_FILES := $(call all-java-files-under, src)

#Since the BUILD_PACKAGE makefile expects java files to be relative paths,
#we need to add the ../ in front of each file (which is stored as relative
#to seabold/
LOCAL_SRC_FILES += $(patsubst %.java,../%.java,$(UTIL_JAVA_SRC))

#Make sure both packages' resources are included
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res $(UTIL_RES_DIR)

#Since we are including resouces for two packages (This app and the util lib),
#we need to tell aapt to generate an R.java for the util package as well
LOCAL_AAPT_FLAGS := --generate-dependencies --extra-packages com.seabold.util --auto-add-overlay

include $(BUILD_PACKAGE)

Be careful here to make sure you fiddle with the filenames correctly. For me, the files defined in UTIL_JAVA_SRC are in the form of util/src/com/seabold/util/*.java. Since, the build script for the main app expects java files to be relative paths to the location of Android.mk, I'm adding a ../ to properly get to the util library's path.

The key for resources is the LOCAL_AAPT_FLAGS. This tells the resource packager to make sure it generates an R.java for the package in the utility library. Without this, all of the utility's resources will get put into the main applications R.java, and the utility classes will fail to compile because its R.java will be missing.

To add a pre-build jar file to the framework I did that:

  1. Locate a folder with the jar and the Android.mk file under

    prebuilds/misc/common/

Android.mk:

LOCAL_PATH := $(call my-dir) 
include $(CLEAR_VARS) 

LOCAL_MODULE := <jar name> 
LOCAL_MODULE_TAGS := optional 
LOCAL_SRC_FILES := <jar name>.jar 
LOCAL_MODULE_CLASS := JAVA_LIBRARIES 
LOCAL_MODULE_SUFFIX := $(COMMON_JAVA_PACKAGE_SUFFIX) 

include $(BUILD_PREBUILT) 
  1. Run make on the Android.mk file: make prebuilds/misc/common/Android.mk

  2. Add the jar file to the frameworks/base/services/Android.mk:

LOCAL_STATIC_JAVA_LIBRARIES := $(addprefix services.,$(services)) jar-name

I've stumbled over a solution, on how a java library can access resources. The resources are build as a separate apk. The jar-lib can be used from any app that says so in its Manifest. The java-library-code has the R.java of the resources-apk and uses createPackageContext() to gain access to the actual resources. createPackageContext() gets the app-context as parameter which each app must provide whenever it uses a java-lib-function that needs access to the resources.

I'm not that deep into the AOSP-build-system yet, so I'm hoping what I document here makes sense. It's not my solution either, I just improoved on something that some other developer created here at my job so I don't know where he got the approach from.

for the resource-only-apk we have:

Android.mk

include $(CLEAR_VARS)

LOCAL_PATH := $(call my-dir)
LOCAL_PACKAGE_NAME := shared-resources
LOCAL_MODULE_TAGS :=  optional
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_APPS)
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res 

include $(BUILD_PACKAGE)

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
                package="my.company.common.resources">
<application android:hasCode="false"/>
</manifest>

For the jar-lib we have:

Android.mk

LOCAL_PATH:= $(call my-dir)

####################
# compile the jar  #
include $(CLEAR_VARS)
LOCAL_MODULE := helper-lib
LOCAL_SRC_FILES := $(call all-java-files-under, src)

# add package-context-ressources
resource-intermediates := $(call intermediates-dir-for,APPS,shared-resources,,common)
shared_res := $(resource-intermediates)/src/my/company/common/resources/R.java
$(shared_res): $(resource-intermediates)/src/R.stamp
LOCAL_GENERATED_SOURCES := $(shared_res)

LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_JAVA_LIBRARIES)
LOCAL_ADDITIONAL_DEPENDENCIES := helper-lib.xml
include $(BUILD_JAVA_LIBRARY)

######################
# deliver permisions #
include $(CLEAR_VARS)
LOCAL_MODULE := helper-lib.xml
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/permissions
LOCAL_SRC_FILES := helper-lib.xml
include $(BUILD_PREBUILT)

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="my.company.helper">
    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
    <uses-permission android:name="android.permission.MANAGE_USERS" />
    <application />
</manifest>

helper-lib.xml

<?xml version="1.0" encoding="utf-8"?>
<permissions>
    <library name="helper-lib" file="/vendor/framework/helper-lib.jar" />
</permissions>

Last but not least here is how we declare them in that over-all-makefile that says what all to include -> base_packages.mk

PRODUCT_PACKAGES += \
    my.company.common \
    shared-resources \
    helper-lib
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top