{"record":{"id":"998b139fd773bcac","repo":"MuntashirAkon/AppManager","slug":"openpgpservice-could-not-be-bound","errorCode":null,"errorMessage":"OpenPGPService could not be bound.","messagePattern":"OpenPGPService could not be bound\\.","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/io/github/muntashirakon/AppManager/crypto/OpenPGPCrypto.java","lineNumber":253,"sourceCode":"        IntentFilter filter = new IntentFilter(ACTION_OPEN_PGP_INTERACTION_BEGIN);\n        filter.addAction(ACTION_OPEN_PGP_INTERACTION_END);\n        ContextCompat.registerReceiver(mContext, mReceiver, filter, ContextCompat.RECEIVER_NOT_EXPORTED);\n    }\n\n    @WorkerThread\n    private void waitForServiceBound() throws IOException {\n        int i = 0;\n        while (mService.getService() == null) {\n            if (i % 20 == 0) {\n                Log.i(TAG, \"Waiting for openpgp-api service to be bound\");\n            }\n            SystemClock.sleep(100);\n            if (i > 1000)\n                break;\n            i++;\n        }\n        if (mService.getService() == null) {\n            throw new IOException(\"OpenPGPService could not be bound.\");\n        }\n    }\n\n    @WorkerThread\n    private void waitForResult() {\n        int i = 0;\n        while (!mSuccessFlag && !mErrorFlag) {\n            if (i % 200 == 0) Log.i(TAG, \"Waiting for user interaction\");\n            SystemClock.sleep(100);\n            if (i > 1000)\n                break;\n            i++;\n        }\n    }\n\n    @UiThread\n    private void handleResult(@NonNull Intent result) {\n        mSuccessFlag = false;","sourceCodeStart":235,"sourceCodeEnd":271,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/AppManager/crypto/OpenPGPCrypto.java#L235-L271","documentation":"OpenPGPCrypto binds to the external OpenPGP provider app (e.g. OpenKeychain) via OpenPgpServiceConnection. waitForServiceBound polls up to ~100 seconds; if mService.getService() is still null, binding never succeeded and an IOException is thrown.","triggerScenarios":"Calling handleFiles/handleStreams when the OpenPGP provider app is not installed, the provider package name (mProvider) is wrong, the user denied the bind/connect dialog, or binding didn't complete within the timeout.","commonSituations":"OpenKeychain not installed on the device; user cancels the authorization prompt for this app; wrong provider package passed to the crypto options; provider app crashed or disabled.","solutions":["Install/enable the OpenPGP provider app (e.g. OpenKeychain) matching the provider package name","Verify the provider package passed to OpenPGPCrypto/options is correct (org.sufficientlysecure.keychain for OpenKeychain)","Approve the app's access request in the OpenPGP provider","Retry the operation to give binding more time if the device was slow"],"exampleFix":"// before\ncryptoOptions.setProvider(\"com.example.wrongkeychain\");\n// after\ncryptoOptions.setProvider(\"org.sufficientlysecure.keychain\"); // OpenKeychain installed & enabled","handlingStrategy":"retry","validationCode":"// ensure the provider app exists before attempting\nPackageManager pm = context.getPackageManager();\ntry {\n    pm.getPackageInfo(\"org.sufficientlysecure.keychain\", 0);\n} catch (PackageManager.NameNotFoundException e) {\n    throw new IllegalStateException(\"OpenPGP provider (OpenKeychain) is not installed\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    crypto.doAction(Crypto.OPEN_ENCRYPT, in, out);\n} catch (IOException e) {\n    if (e.getMessage().contains(\"could not be bound\")) {\n        // retry once, or prompt the user to install/open OpenKeychain\n    }\n}","preventionTips":["Check the provider package is installed and enabled before crypto operations","Use the canonical provider package name (org.sufficientlysecure.keychain)","Prompt the user to authorize the app in OpenKeychain on first use"],"tags":["openpgp","android","binding","service-connection"],"backgroundTag":"connection-refused","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}