Developing Android applications that are intended to be pre-installed into a device ROM can be a bit of a chore. One of the strengths of the Android development environment is the ability to immediately deploy you code to a device for testing and demonstration. However, for signed apps in an Android ROM, the Android security model blocks this by default (if anyone could install signature-unmatched applications, it would render a lot of Android's security meaningless).
Attempting to do this by default will show a window like the one below. For pre-installed apps, the instructions often aren't accurate (Android Studio will fail when trying to uninstall the existing application, since the app isn't allowed to be uninstalled).
This can be frustrating. Developers shouldn't have to loose the convenient 'one-click deploy' workflow, even when developing pre-installed ROM apps. And we still want to retain an application's full platform / shared / media permissions when developing and testing those apps.
Luckily, there is a workaround. Here's one method for resolving these code-signing issues :
Assumptions :
Start by finding your ROM's Android Source root directory. Then run `ls build/target/product/security`. You should see a list of two files (a *.pk8 and a *.x509.pem) for each of the keys for the various levels of permissions in Android (eight in total).
Typically, one of these is the key your app is signed with. If you don't know which key your using, check your source package directory for your application's Android.mk. In my case, that's running `cat packages/apps/MyAppName/Android.mk`. In this file, you may find a line that reads someting like 'LOCAL_CERTIFICATE := platform', which would tell you the key to use.
If your Android.mk file doesn't specify a key, your probably using the testkey (it's the default). If your packages app directory contains an APK, in some cases the application may be presigned (in which case, you'll need to find the key used to sign it from the source of the APK).
If you didn't generate these keys yourself (or if someone from your company / organization did not generate these keys) then you might be using default/test ones provided by an OEM or other vendor. Now might be a good time to generate your own. If these keys are missing from the directory entirely, that's another sign to generate your own.
If necessary, you can generate your own keys by running commands like the following below (change the description as necessary to suit your needs)
`./development/tools/make_key build/target/product/security/media '/C=US/ST=Michigan/L=Grand Rapids/O=My Company/OU=My Product Name/CN=Android/emailAddress=hello@example.com'`
Note that you'll want to repeat this for each key (the above is for 'media', you'll probably want a 'platform', 'shared', and 'testkey' too to get your ROM source to compile properly). You'll also want to make sure you either don't use a password, or remember any key passwords you set.
Now we have a key/certificate pair from the Android device source code. But Android Studio expects to work with a Java keystore -- not a key/certificate directly. We can work around this by creating a new Java keystore and adding our key/certificate to it, by using 'keytool-importkeypair'
Inside your app, open your (Module: app) build.gradle file and add a definition under android to contain your new signing configuration. Then, add or modify your build types for debug to include signing using these new keys. (See image below)
Then, run a gradle sync (or clean and rebuild the project) and then attempt to deploy it to a connected Android device. (Shift + F10, in Android Studio)
That should be it. Your app should start up on the connected device. No more dreaded "application can't be installed" messages. And, your app should still have all of the permissions the keys specified.