SoFunction
Updated on 2025-05-04

Android 12 solution to push cannot be turned on

1. Android Compilation Command

In the past, it would not be generated by using make framework -j16 or using mm in the framework/base directory.

1.1 Compilation instructions for framework layer

make -j32 framework-minus-apex

After the compilation is passed, the output path is out\target\product\blueline\system\framework\

1.2 Replacement

adb root
adb remount
adb shell "rm -rf /system/framework/arm"
adb shell "rm -rf /system/framework/arm64"
adb push  /system/framework
adb shell sync
adb reboot

or

adb root
adb remount
adb push arm /system/framework
adb push arm64 /system/framework
adb push  /system/framework
adb shell sync
adb reboot

1.3 Compile frameworks/base/core/res

If you modify files in the frameworks/base/core/res directory, such as or other resource files, you do not need to reorganize the framework layer, you only need to single-compile in this directory.

It will be generated in out/target/product/qssi/system/framework/, and push the apk into the device directory/system/framework/ using adb.

2. Compile services

2.1 Compile commands

Execute mm in the frameworks/base/services directory

Or execute it in the Android directory

mmm frameworks/base/services -j32

or

make -j32 services

After the compilation is passed, the output path is out\target\product\blueline\system\framework\

2.2 Replacement

adb root
adb remount
adb shell "rm -rf /system/framework/arm"
adb shell "rm -rf /system/framework/arm64"
adb push  /system/framework
adb shell "rm -rf /data/dalvik-cache/arm/system@framework@@classes.* "
adb shell sync
adb reboot

3. Android 12 API Standard Specifications

3.1 Use of annotations

3.1.1 @NonNull and @Nullable

@NonNull: means that the return value, parameter, or field cannot be null. @Nullable: means that the return value, parameter, or field can be null. If there is no annotation, an exception will be reported: Missing nullability on parameter. When compiling and reporting this error, add these two annotations as needed. The Nullablility of getter/setter must be consistent.

3.1.2 @IntDef and @StringDef

To accept a limited set of public constants of int or String type, you can use these two annotations to explain this. This annotation is usually used in conjunction with @interface to create a new annotation. For example:

public final class Log {
    /** @hide */
    @IntDef({ASSERT, ERROR, WARN, INFO, DEBUG, VERBOSE})
    @Retention()
    public @interface Level {}
 
    public static final int VERBOSE = 2;
    public static final int DEBUG = 3;
    public static final int INFO = 4;
    public static final int WARN = 5;
    public static final int ERROR = 6;
    public static final int ASSERT = 7;
}

It is recommended to use the same prefix.

/** @hide */
@IntDef(prefix = { “FLAG_” }, value = {
  FLAG_USE_LOGO,
  FLAG_SHOW_HOME,
  FLAG_HOME_AS_UP,
});
@Retention()
public @interface DisplayOptions {}

3.1.3 Rules of Listener and Callback

Use Listener when there is only one callback method and there will never be other callback methods, and the registration listening method must start with add/remove, otherwise Android Lint will not be compiled.

public interface OnFooListener {
    void onFoo();
}
public void addOnFooListener(@NonNull OnFooListener listener) {}
 
public void removeOnFooListener(@NonNull OnFooListener listener) {}

Callback should be used when there are multiple callback methods, or when there are associated constants. The Callback class can be an interface or abstract class. Adding callback and removing callback should use the method that starts with register and unregister.

The method in callback should start with on-.

Use MyObjectCallback instead of MyObjectObserver. I am not sure whether this error is reported. I changed Listener to Callback and did not use Observer as the callback.

public abstract class FooCallback {
  public abstract void onStarted();
  public abstract void onStopped();
}
public void registerFooCallback(@NonNull FooCallback callback) {}
 
public void unregisterFooCallback(@NonNull FooCallback callback) {}

If the above registration method is not in an explicit thread, it is necessary to include the Executor parameter when registering. If it is not added, the default callback is in the main thread.

My register method does not add Executor, and the compiler errors are reported:

Registration methods should have overload that accepts delivery Executor: registerFooCallback [ExecutorRegistration]

Therefore, change to the following registration method:

public void registerFooCallback( @NonNull @CallbackExecutor Executor executor,
                                 @NonNull FooCallback callback)
//The unregister method does not require the addition of Executorpublic void unregisterFooCallback(@NonNull FooCallback callback) {}

Avoid using enum class enum

Using enum in the Framework layer will report an error: Enums are discouraged in Android APIs [Enum], so @intDef is generally used instead, and new annotations are used.

The above is the detailed summary of the method to solve the problem of Android 12 push that cannot be started. For more information about Android 12 push, please follow my other related articles!