あるAPKで動的登録BroadcastReceiverが使用する、LauncherでこのAPKを動的にロードするjavaが現れる.lang.SecurityException異常の解決方法


あるAPKでは、次の方法でBroadcastReceiverが動的に登録されています.コードリファレンスは次のとおりです.
    @Override
    protected void onAttachedToWindow()
    {
        super.onAttachedToWindow();
        
        /* monitor time ticks, time changed, timezone */
        
        if (mIntentReceiver == null)
        {
            mIntentReceiver = new TimeChangedReceiver(this);
            IntentFilter filter = new IntentFilter();
            filter.addAction(Intent.ACTION_TIME_TICK);
            filter.addAction(Intent.ACTION_TIME_CHANGED);
            filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
            getContext().registerReceiver(mIntentReceiver, filter);

LauncherはこのAPKを動的にロードする(APKを動的にロードする目的と実現構想、私のこの文章を参照:Launcherの中で他のAPKの中でActivityの問題解決構想を動的にロードする
),
次のような異常が発生しました.
09-05 19:05:55.033: E/AndroidRuntime(28637): java.lang.SecurityException: Given caller package com.zhao3546.time is not running in process ProcessRecord{41e74e50 28637:com.zhao3546.launcher/u0a10142}

検索してみると、多くの人がこのような問題に遭遇したことがあるが、解決策を提案していないので、自分で解決するしかないようだ.
ダイナミックロードはできませんAndroidManifestですxmlはBroadcastReceiverを静的にロードしてみてもいいですか?
他のBroadcastRecevierの場合はOKであることが確認されましたがandroid.content.Intent.ACTION_TIME_TICKというダメなのは、Androidのコメントで明確に説明されています.
String android.content.Intent.ACTION_TIME_TICK = "android.intent.action.TIME_TICK"

Broadcast Action: The current time has changed. Sent every minute. You can not receive this through components declared in manifests, only by exlicitly registering for it with Context.registerReceiver(). 

This is a protected intent that can only be sent by the system.

本当に解決策がないのだろうか.
手元にAndroidソースがあり、「Given caller package」と「is not running in process Process Record」の2つのキーワードの全文検索に基づいて、
この異常なコードがどこで作られたのか見てみたいです.cpp,*.c*,*.JAvaで検索しても見つからないので、まずこの方法を放棄しましょう.
 
後でこの異常を分析します
09-05 19:05:55.033: E/AndroidRuntime(28637): java.lang.SecurityException: Given caller package com.zhao3546.time is not running in process ProcessRecord{41e74e50 28637:com.zhao3546.launcher/u0a10142}

サードパーティAPKに登録されているBroadcastReceiverです.このAPKはAndroidManifestにあります.xmlで宣言されたパケット名はちょうど「com.zhao 3546.time」であり、最終的にはLauncherと同じプロセスで実行され、このプロセスに対応するパケット名は「com.zhao 3546.launcher」であり、Launcherが先に実行され、APKが動的にロードされるためである.
それは私がBroadcastReceiver対応のパッケージ名を登録すれば「com.zhao 3546.launcher」であれば、問題を解決できるのではないでしょうか.
Launcherでは、LauncherとサードパーティAPKのAndroidManifestを動的にロードする問題の解決策について説明しています.xmlでandroid:sharedUserIdプロパティ宣言が一致しました.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.zhao3546.time"
    android:sharedUserId="zhao3546.launcher"

だからLauncherとサードパーティのAPKは実際に同じプロセスで実行されています.それはLauncherのcontextオブジェクトをこのAPKに渡すだけで、このAPKはLauncherのcontextを使ってBroadcastReceiverを登録すれば、問題を解決することができますか?
サードパーティAPKのcom.zhao3546.timeパッケージには、次のクラスが追加され、public static void setContext(Context context)という静的メソッドが実装されています.
package com.zhao3546.time;

import android.content.Context;

public class ContextHolder
{
    private static Context context = null;
    
    public static void setContext(Context context)
    {
        System.out.println("com.zhao3546.time.ContextHolder setContext");
        
        ContextHolder.context = context;
    }
    
    public static Context getContext()
    {
        System.out.println("com.zhao3546.time.ContextHolder getContext() context="
                + context);
        
        return context;
    }
}

Launcherコードでは、launcherのcontextオブジェクトを反射機構により動的にcomに伝達する.zhao3546.time.ContextHolderでは、
    private void setContext2Plugin(ClassLoader pluginClassLoader,
            String pluginPackageName, Context launcherContext)
    {
        String className = pluginPackageName + ".ContextHolder";
        try
        {
            Method m = pluginClassLoader.loadClass(className)
                    .getMethod("setContext", Context.class);
            m.invoke(null, launcherContext);
        }
        catch (Exception e)
        {
            Log.w(TAG, "Fail to loadClass " + className + ", skip it", e);
        }
    }

以前にBroadcastReceiverを登録していた場所を変更し、ContextHolder()でBroadcastReceiverを登録し、APKを再配置して検証し、問題を解決します.
 
解決できないように見える問題は、実は別の方法を試してみる必要がある場合があり、予想外の効果を得る可能性があります.