Android 12. Application could not be installed. Non-existing group android.permission-group.MESSAGES

I have previously been testing an app on devices running Android 8, 10, 11 and it runs fine.
Compiled as TargetVersion 34

I have just tried to compile the app to a device that is running Android 12 and it will not install. I am seeing the following message ;

Installation failed due to: 'Failed to commit install session 558053483 with command cmd package install-commit 558053483. Error: -127: Package com.xxxxx.xxxxx.free.debug attempting to declare permission com.xxxxx.xxxxx.free.debug.permission.DELETE_MESSAGES in non-existing group android.permission-group.MESSAGES'

I tried building it as Release as well however I am getting the same message.

Manifest code is as follows ;

<permission
android:name="${applicationId}.permission.DELETE_MESSAGES"
android:description="@string/delete_messages_desc"
android:label="@string/delete_messages_label"
android:permissionGroup="android.permission-group.MESSAGES"
android:protectionLevel="dangerous"/>
<provider
    android:name="com.xxxxx.xxxxx.external.MessageProvider"
    android:authorities="${applicationId}.messageprovider"
    android:exported="false"
    android:grantUriPermissions="true"
    android:multiprocess="true"
    android:readPermission="${applicationId}.permission.READ_MESSAGES"
    android:writePermission="${applicationId}.permission.DELETE_MESSAGES"/>

Did some searching but I cannot get a grasp on how to tackle this.

Thanks

UPDATE

Code is below. Not sure how much to include so this might be overkill sorry if it is.

public class MessageProvider extends ContentProvider {
    public static String AUTHORITY = BuildConfig.APPLICATION_ID + ".messageprovider";
    public static Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);

private static final String[] DEFAULT_MESSAGE_PROJECTION = new String[] {
        MessageColumns._ID,
        MessageColumns.SEND_DATE,
        MessageColumns.SENDER,
        MessageColumns.SUBJECT,
        MessageColumns.PREVIEW,
        MessageColumns.ACCOUNT,
        MessageColumns.URI,
        MessageColumns.DELETE_URI,
        MessageColumns.SENDER_ADDRESS
};
private static final String[] DEFAULT_ACCOUNT_PROJECTION = new String[] {
        AccountColumns.ACCOUNT_NUMBER,
        AccountColumns.ACCOUNT_NAME,
};
private static final String[] UNREAD_PROJECTION = new String[] {
        UnreadColumns.ACCOUNT_NAME,
        UnreadColumns.UNREAD
};


private UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
private List<QueryHandler> queryHandlers = new ArrayList<>();

/**
 * How many simultaneous cursors we can afford to expose at once
 */
Semaphore semaphore = new Semaphore(1);

ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(1);


@Override
public boolean onCreate() {
    registerQueryHandler(new ThrottlingQueryHandler(new AccountsQueryHandler()));
    registerQueryHandler(new ThrottlingQueryHandler(new MessagesQueryHandler()));
    registerQueryHandler(new ThrottlingQueryHandler(new UnreadQueryHandler()));

    return true;
}

public static void init() {
    Timber.v("Registering content resolver notifier");

    final Context context = DI.get(Context.class);
    MessagingController messagingController = DI.get(MessagingController.class);
    messagingController.addListener(new SimpleMessagingListener() {
        @Override
        public void folderStatusChanged(Account account, String folderServerId, int unreadMessageCount) {
            context.getContentResolver().notifyChange(CONTENT_URI, null);
        }
    });
}

@Override
public String getType(Uri uri) {
    Timber.v("MessageProvider/getType: %s", uri);

    return null;
}

@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
    Timber.v("MessageProvider/query: %s", uri);

    int code = uriMatcher.match(uri);
    if (code == -1) {
        throw new IllegalStateException("Unrecognized URI: " + uri);
    }

    Cursor cursor;
    try {
        QueryHandler handler = queryHandlers.get(code);
        cursor = handler.query(uri, projection, selection, selectionArgs, sortOrder);
    } catch (Exception e) {
        Timber.e(e, "Unable to execute query for URI: %s", uri);
        return null;
    }

    return cursor;
}

@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {

    Timber.v("MessageProvider/delete: %s", uri);

    // Note: can only delete a message

    List<String> segments = uri.getPathSegments();
    int accountId = Integer.parseInt(segments.get(1));
    String folderServerId = segments.get(2);
    String msgUid = segments.get(3);

    // get account
    Account myAccount = null;
    for (Account account : Preferences.getPreferences(getContext()).getAccounts()) {
        if (account.getAccountNumber() == accountId) {
            myAccount = account;
            if (!account.isAvailable(getContext())) {
                Timber.w("not deleting messages because account is unavailable at the moment");
                return 0;
            }
        }
    }

    if (myAccount == null) {
        Timber.e("Could not find account with id %d", accountId);
    }

    if (myAccount != null) {
        MessageReference messageReference = new MessageReference(myAccount.getUuid(), folderServerId, msgUid, null);
        MessagingController controller = MessagingController.getInstance(getContext());
        controller.deleteMessage(messageReference, null);
    }

    // FIXME return the actual number of deleted messages
    return 0;
}

@Override
public Uri insert(Uri uri, ContentValues values) {
    Timber.v("MessageProvider/insert: %s", uri);

    return null;
}

@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
    Timber.v("MessageProvider/update: %s", uri);

    // TBD

    return 0;
}

/**
 * Register a {@link QueryHandler} to handle a certain {@link Uri} for
 * {@link #query(Uri, String[], String, String[], String)}
 */
protected void registerQueryHandler(QueryHandler handler) {
    if (queryHandlers.contains(handler)) {
        return;
    }
    queryHandlers.add(handler);

    int code = queryHandlers.indexOf(handler);
    uriMatcher.addURI(AUTHORITY, handler.getPath(), code);
}


public static class ReverseDateComparator implements Comparator<MessageInfoHolder> {
    @Override
    public int compare(MessageInfoHolder object2, MessageInfoHolder object1) {
        if (object1.compareDate == null) {
            return (object2.compareDate == null ? 0 : 1);
        } else if (object2.compareDate == null) {
            return -1;
        } else {
            return object1.compareDate.compareTo(object2.compareDate);
        }
    }
}

protected interface QueryHandler {
    /**
     * The path this instance is able to respond to.
     */
    String getPath();

    Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
            throws Exception;
}

/**
 * Extracts a value from an object.
 */
public interface FieldExtractor<T, K> {
    K getField(T source);
}


public static class DeleteUriExtractor implements FieldExtractor<MessageInfoHolder, String> {
    @Override
    public String getField(MessageInfoHolder source) {
        LocalMessage message = source.message;
        int accountNumber = message.getAccount().getAccountNumber();
        return CONTENT_URI.buildUpon()
                .appendPath("delete_message")
                .appendPath(Integer.toString(accountNumber))
                .appendPath(message.getFolder().getServerId())
                .appendPath(message.getUid())
                .build()
                .toString();
    }
}

2

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật