【android學習】多用戶發送廣播

簡介

在開發中,遇到Calling a method in the system process without a qualified user這樣的錯誤

原因:在Android 4.2以後,增加了多用戶,需要使用如下發送廣播

context.sendBroadcastAsUser(intent,UserHandle.ALL);

添加權限

<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />

 

但是會發現UserHandle獲取不到UserHandle.ALL,查看源碼

public final class UserHandle implements Parcelable {

    // NOTE: keep logic in sync with system/core/libcutils/multiuser.c

    /**
     * @hide Range of uids allocated for a user.
     */
    @UnsupportedAppUsage
    public static final int PER_USER_RANGE = 100000;

    /** @hide A user id to indicate all users on the device */
    @UnsupportedAppUsage
    public static final @UserIdInt int USER_ALL = -1;

    /** @hide A user handle to indicate all users on the device */
    @SystemApi
    @TestApi
    public static final @NonNull UserHandle ALL = new UserHandle(USER_ALL);

    /** @hide A user id to indicate the currently active user */
    @UnsupportedAppUsage
    public static final @UserIdInt int USER_CURRENT = -2;

    /** @hide A user handle to indicate the current user of the device */
    @SystemApi
    @TestApi
    public static final @NonNull UserHandle CURRENT = new UserHandle(USER_CURRENT);

    /** @hide A user id to indicate that we would like to send to the current
     *  user, but if this is calling from a user process then we will send it
     *  to the caller's user instead of failing with a security exception */
    @UnsupportedAppUsage
    public static final @UserIdInt int USER_CURRENT_OR_SELF = -3;

    /** @hide A user handle to indicate that we would like to send to the current
     *  user, but if this is calling from a user process then we will send it
     *  to the caller's user instead of failing with a security exception */
    @UnsupportedAppUsage
    public static final @NonNull UserHandle CURRENT_OR_SELF = new UserHandle(USER_CURRENT_OR_SELF);

    /** @hide An undefined user id */
    @UnsupportedAppUsage
    public static final @UserIdInt int USER_NULL = -10000;

    /**
     * @hide A user id constant to indicate the "owner" user of the device
     * @deprecated Consider using either {@link UserHandle#USER_SYSTEM} constant or
     * check the target user's flag {@link android.content.pm.UserInfo#isAdmin}.
     */
    @UnsupportedAppUsage
    @Deprecated
    public static final @UserIdInt int USER_OWNER = 0;



}

我們主要使用如下幾個

UserHandle.ALL 設備上所有用戶可接收到廣播   
UserHandle.CURRENT 設備上當前用戶可接收到廣播
UserHandle.CURRENT_OR_SELF 設備上當前用戶或者該應用所屬用戶可接收到廣播  
UserHandle.OWNER 設備所有者可接收到廣播
UserHandle.SYSTEM system用戶可以接收到廣播

由於上面都是隱藏代碼,所以我們可以使用如下方式獲得

一:反射

        Class<UserHandle> cls = UserHandle.class;
        try {
            Field field = cls.getField("ALL");
            Object allObject = field.get(null);
            sendBroadcastAsUser(intent, (UserHandle)allObject);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }


二:使用parcel

        Parcel p = Parcel.obtain();
        p.writeInt(-1);
        sendBroadcastAsUser(intent, new UserHandle(p));

三:getUserHandleForUid

sendBroadcastAsUser(intent, UserHandle.getUserHandleForUid(-1));

參考

https://blog.csdn.net/u012758497/article/details/90084618

發佈了37 篇原創文章 · 獲贊 0 · 訪問量 5157
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章