[Android General] daxgirl:
Run!

Installing and running your builds in Android Studio:

First of all - data or system app?

The simple answer is SYSTEM. And not just system - we need some high level permissions, so definitely /system/priv-app. Why?

So for that we dig deeper into android permission system.

1. Writing settings into settings storage database:

This permission was revoked from data apps on Marshmallow. Meaning, THEORETICALLY, that only system apps can write into Settings.System. So how come we can write when the app is installed as data app? Oh, this is where THEORETICALLY part comes in. Permission to write system settings is declaired in framework in such a way, that it allows data apps to write there if they target sdk lower than 23 in their build. That permission level is called "pre23". That is why in our gradle we have a somewhat peculiar sdk division for building. Let's look at the image:

As you can see, target sdk is set to 22. This is not by mistake. This is by design so if you want to test the basic functionality of the app by installing debug version in data, it will not crash every time you flip a switch.

This is the definition of pre23, we target sdk 22 so the pre MM permissions can be achieved by running the app in data.

Although all of you will be including this app in your roms in system priv-app, you will be working with it quite alot as you build it. We want you to be able to run it from data if you wish so. if we target sdk 23 and up it will never run from data, unless installed also in system.

You are free to change this to 23 or 24. But NEVER run it while installed only in data then. It will crash like a drunken monkey.

Also, changing it to 23 or 24 for TARGET sdk is meaningless. It's not better because it's a higher number. For target sdk it makes no difference.​

2. Running reboot

We run reboot functions in a proper android shutdown sequence. Any of you that are familiar enough with linux kernel based platforms KNOW the system should not be shut down by killing it's process.

Therefore all reboot functionality in our app is native android reboot. For THAT we absolutely need the app to have an initial copy in priv-app. If the app is only installed in data, clicking on any reboot option, either from reboot menu or from reboot dialogs, will result in FC in your face. the following permissions cannot be obtained by data apps NEVER EVER.

<uses-permission android:name="android.permission.REBOOT"
tools:ignore="ProtectedPermissions"/>
<uses-permission android:name="android.permission.DEVICE_POWER"
tools:ignore="ProtectedPermissions"/>
<uses-permission android:name="android.permission.RECOVERY"/>

3. But we have root permissions? Isn't it enough?

So here is the thing you should remember:

Android doesn't give a damn about root permissions. When we run command under su we talk to the linux kernel through shell. We do not run it on android level. Android is NOT linux. There is NO android permission which is compiant with su.​

When we are talking about android application permissions, we are talking about PackageManager, which is android framework system service, that grants the permissions to perform certain action. Package manager does not know su. It is not part of linux platform. It is android. Android is not designed to have root access. Not on any level. it does not recognize unix commands by default.

So when we execute your scripts, android doesn't do it. Our application code doesn't do it. We just pass it to the kernel as runtime command. Remember that, when you come complaining that your scripts don't run. We can't help it. If the kernel refuses to execute them, something is WRONG in the script syntax or structure.
​

4. So data or system? The answer is - when you build and test run your app - BOTH

Can you run apps from android studio while one of the copies is installed in system? Absolutely. As any system app, app is allowed to have an update.

The most important thing is for that update to have same signature and same package as the app in system. Once the app is installed in priv-app it has privileged permissions. You can after that, as oyu build, install updates in data, so you don't have to push every single test build into system and reboot, and all privileged permissions will work.​

​

Gradle, baby!

Gradle is a build tool. You can read on history of gradle online. It was not developed with any relation with android. Google decided to adopt gradle as their primary build tool for their primary development environment for android and hence, android gradle plugin was born.

Build tool is a way to "put things together in orderly fashion". In essence, android application is a bunch of files in folders. Making it into a running product is a matter of some complexity. Connecting java to resources, signing, packaging, updating manifest, setting primary configs and build related configs, compiling java, compiling dependencies, including multiple modules, being able to have several builds and flavors in one project - this is what gradle does for us.

If you wish to learn more about gradle for android, please watch this amazing video https://www.youtube.com/watch?v=jJ9j7MvGPkU.

Gradle, in a manner of speaking, is a bunch of tasks. Tasks are executed in specific order. Files are being copied, deleted, compiled and packaged as result of single button click.

Android gradle plugin comes with specific predifined tasks. We can also write our own tasks, which we usually do, for our own usage. We will talk about OUR specific tasks later on in the advanced section.

For now we will talk about basic android gradle tasks, such as assembleRelease, assembleDebug, installRelease, installDebug and so on.

1. Clicking RUN button

If you have a look on the top panel of android studio you have this green "play" button next to a selection box which, usually, says "app". Like this:

This is what will appear on the run menu when you first open the project and it's done syncing with gradle. If the "app" selection box has a red "X" on it, means gradle is syncing now or has failed to sync and you need to find out WHY and fix it. Once there is no red "x" current configuration is ready to run.

When you click the green run button, it will run whatever task is in the selection box. When it says "app" in the selection box and you click run, it will do the following:

1. Compile debug build

2. Install it on your connected device

3. Run it​

So what is "app"? App is the main of the module we want to run. It is the only module in our project. So by running "app", we run the RomControl application on a device in DEBUG mode.

Why is it good to run in debug mode? For 2 reasons:

1. Run "app" configuration supports instant run. You can read more on instant run here. This will push the code changes into your running app on device and apply immediately. It's very handy if you add a preference or 2 and want to test how it looks or works. If instant run is impossible for your current build tools, android studio will tell you and it will tell you why. It usually means that you need to upgrade android gradle plugin. This can be done with ease.

2. Running app module in debug mode will give you full stack trace if there is an error. It will be easier for you to copy the log here for us to have a look at and debug. Or debug yourselves.​

The downside of running debug mode?

1. It's somewhat slow. Meaning the app on the device is a little slow in debug mode (although now it's not as slow as it used to be)

2. Debug mode by definition runs from data. So none of the reboot options will work. So if you want to test actual changes that require reboot from our app, you need to have a system priv-app version installed. You can have a debug version installed in priv-app and then you can use instant run, like we spoke before.​

2. So how do we make a release version?

1. Generating signing key

For that we need a signing key. We already made a full prepared platform for you to run release build in our app gradle build file. All you need to do is create a signature and make some little edits. So, let's roll.

To create a signature please follow these instructions

Please remember or write down the following:

1. Path where you create the signature

2. Key password

3. Store password

4. Key alias​

You do not need to generate the release build just yet. Just finish creating your own keystore and remember where you put it.

Now go to the parent folder where your rom control project sits. For example if you put it in AndroidStudioProjects folder, in the same folder create a folder called "keys" (no caps, just "keys"). Copy your keystore there. Or originally create it there.

Now go back to android studio. to the left project panel (provided it is in project view, like we asked you to make it) and scroll down... You will see at the very bottom some singleton files, like gradlew, gradlew.bat, gradle.properties and so on. One of the files there is called key.properties. Double click on it to open.

Inside you will see 4 strings. Like this:

Out in your actual key information. The one you used to create your key. you need to make changes to all 4 fields.

for example:

As you can see we used relative path to the keystore. Which is why it's supposed to be in the parent folder of your folder containing your project in direcroty called "keys".​

2. Telling gradle to use our signing key for release builds

On the left project panel look inside the "app" module folder. On the bottom of it, after the AndroidManifest.xml file, you will see a builg.gradle file. Double click to open it.

This is a gradle file for building our app module. You will see there are alot of configurations related to android build there. It will look something like this:

You need to un-comment the sections pointed to with red arrows. To comment or un-comment the section in android studio, select the section and click "ctrl + /"

Now you should be ready to build the release version. Let's test that:

1. On the right upper corner of the studio window you will see little vertical "gradle" tab. Like this

Click on it. A side window till open with gradle tasks. Like this:

2. Open app > tasks > build

3. Find a task called assembleRelease and double click on it.

4. Wait for it to finish. You will see tons of things running in the gradle console window on the bottom. Provided you didn't mess up any of the previous steps, it will work fine.

5. Once it's done, check that you did now have errors and that build was successfull.

6. If all is good, open in file manager your project folder > app > build > outputs > apk. There you should see your freshly compiled release version. Release version is called simply RomControl.apk. it is already zipaligned and signed. You can go ahead and use it in your rom, push it into priv-app and test. So on.

​

3. So every time I need to run assembleRelease and push the apk into priv-app and reboot?

NO!!!

1. Once you run your first assembleRelease, take that apk and push it into system priv-app. Reboot your device.

2. Now look again into the app > tasks in the gradle window on the right. You also have there "install" tasks. Open it and find "installRelease". Connect your device with app installed already in priv-app and double click on installRelease. This will install the release as UPDATE in the DATA apps. This is so you don't need to push the app to device as you're building and testing. You can make code changes, install release as data and run it FULLY. Becasue you have the original sitting in the system, it will have all the premissions for the reboots. So you can build and test from data.

3. Please remember that as you build and test only the data version of your app is updated. So once you are done testing and the build is final, run assembleRelease and take the final apk from the outpute/apk folder to include in your rom.​

4. Do I need to go to the gradle menu on the right all the time to run installRelease?

NO!!!

After you run a task from the gradle menu have a look at the run button on the top panel. Surprise! It doesn't have "app" selected anymore. it has the latest task you ran!!! Look:

Now if you click the "run" button it will run the selected task. If you want to select another task from the tasks you used in the past, Just select from the selection box menu and click run.​

So which build to run and when?

1. If you're building and testing continuously, we recommend keeping the app as debug in data only and NOT TO USE the reboot options.

For adding preferences and building your ui you don't need to use reboot options. Just click LATER on reboot dialogs if you include reboot options.

So you can use instant run, switch to "app" configuration and keep running in debug mode from data as you build.
​

2. When you go further into preference testing, we recommend uninstaling the debug version. creating signed release version and push into priv-app. From this point on run installRelease task to instal release update in data as you build and correct and test scripts and reboot options.

3. When ready to go final release with your rom, use task assembleRelease to build your final version and include it in your rom zip

4. Commit latest changes to your github repository​

Uploading sources to git

1. Provided you followed our instructions and forked the project source code and then cloned it to studio, it is now connected to your forked git project.

2. Any new file you add will ask if you want to add it to git. And will turn it's color to green if added. Any file that is not added will have brown color.

3. To add brown colored file to github, right click it, choose git > add

4. You should have the following available on the top panel:

The green arrow is for commiting and pushing changes to github. Once you push it the following window will open:

​

5. Check what files you would like to commit. For example, never commit key.properties file which contains your key password.

6. Write description of your commit and choose from the blue button selector box commit and push.

7. Make a habit of committing your work daily or at least on a new feature basis. It easier to follow for you and also serves as backup.​

We would be happy to talk more about gradle and various tasks, but this post had a specific purpose. To teach you how to manipulate build types and use it to you advantage. Please ask us specific questions about gradle tasks related to your build.