Search code examples
androidbroadcastreceiversecurityexceptionandroid-package-managers

Enable BroadcastReceiver of other application using PackageManager.setComponentEnabledSetting()


I want to start the BroadcastReceiver of other application installed on my android device from my app. Here is the code

ComponentName componentName  = new ComponentName("com.example.myapp","com.example.myapp.MyBroadcastReceiver");
pkgManager.setComponentEnabledSetting(componentName,
                         PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                         PackageManager.DONT_KILL_APP);

"com.example.myapp" is the package name of the other application which contains "MyBroadcastReceiver"

I referred answers given in the post Android PackageManager enable any application and Android - can't enable BroadcastReceiver but none of them seems to be working. The application continues throwing the permission denial SecurityException. Given is the logcat

05-24 11:37:38.382: E/AndroidRuntime(8746): java.lang.SecurityException: Permission Denial: attempt to change component state from pid=8746, uid=10042, package uid=10041

Solution

  • public void setComponentEnabledSetting(ComponentName componentName,  
                int newState, int flags) {  
            setEnabledSetting(componentName.getPackageName(),  
                    componentName.getClassName(), newState, flags);  
        }  
    
    public void setApplicationEnabledSetting(String appPackageName,  
                int newState, int flags) {  
            setEnabledSetting(appPackageName, null, newState, flags);  
        }  
    
    
    
    private void setEnabledSetting(  
                final String packageName, String className, int newState, final int flags) {  
            if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT  
                  || newState == COMPONENT_ENABLED_STATE_ENABLED  
                  || newState == COMPONENT_ENABLED_STATE_DISABLED)) {  
                throw new IllegalArgumentException("Invalid new component state: "  
                        + newState);  
            }  
            PackageSetting pkgSetting;  
            final int uid = Binder.getCallingUid();  
            final int permission = mContext.checkCallingPermission(  
                    android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);  
            final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);  
            boolean sendNow = false;  
            boolean isApp = (className == null);  
            String componentName = isApp ? packageName : className;  
            int packageUid = -1;  
            ArrayList<String> components;  
            synchronized (mPackages) {  
                pkgSetting = mSettings.mPackages.get(packageName);  
                if (pkgSetting == null) {  
                    if (className == null) {  
                        throw new IllegalArgumentException(  
                                "Unknown package: " + packageName);  
                    }  
                    throw new IllegalArgumentException(  
                            "Unknown component: " + packageName  
                            + "/" + className);  
                }  
                if (!allowedByPermission && (**uid != pkgSetting.userId**)) {  
                    throw new SecurityException(  
                            "Permission Denial: attempt to change component state from pid="  
                            + Binder.getCallingPid()  
                            + ", uid=" + uid + ", package uid=" + pkgSetting.userId);  
                }  
    ....  
    }  
    

    It will compare uid,so can't disable or enable other application. from: /frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java