[Android Apps and Games] daxgirl:
General tips and tricks

Some tips and tricks

Running app and debugging:

Android studio provides you with built in logcat. Not only that you can debug the app you're working on, you can debug any app you're modding too. Just need to specify the filter for the logcat and the package name. Dig in and you will find some cool features.

You need to have unknown souces enabled and usb debugging enabled to run your compiled app directly on your device.

1. You can install and run this app as user app. It does not need to be system app. For now no features require it. You can of course include it as system app in your rom. We recommend pulling the base.apk from data folder and pushing to /system/priv-app

2. You do not need USB cable to debug and run your app from studio. There is anifty app I am using. You can download it here https://play.google.com/store/apps/details?id=com.ttxapps.wifiadb&hl=en. All you need to do is open the command line on your pc and type adb connect <ip number of your phone in the network>:5555. The app will provide you with an IP number.

Now studio will recognize your device as USB debugging device even though it's not connected with usb cable. I just hate cables.......

Including key specific functions:

For now all our work is done automatically for us. You click a preference and the work is done. But what if you have a key that you want to do alittle more with than just write into database? I will give you an example.

We have a SwitchPreference in our app that enables/disables call recording. That mod requires restart of InCallUI.apk. Now you can of course restart it by creating a Script Running PreferenceScreen item called Reboot InCallUI and it will be fine. That's what you have been doing so far. But let me show you what you can do now that you own your source code.

We have two ways to kill that app. Silently (without user knowing - very cool) or informing the user. Let me show you how it would be done.

Let's say you create a preference for call recording:

<[COLOR="red"]SwitchPreference[/COLOR]
android:defaultValue="true"
android:key="[COLOR="Red"]toggle_call_recording[/COLOR]"
android:summaryOff="Call recording is disabled"
android:summaryOn="Call recording is enabled"
android:title="Enable/Disable Call Recording" />

The two things we need to know is the key and the class instance of preference - which is SwitchPreference.

Let us go to the java class HandlePreferenceFragments and find a method called public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key){}}. In android studio you can search through class by pressing ctrl+f.

In that method we have switch by the preference class name (INSTANCE). So we have this case:

case "SwitchPreference":
SwitchPreference s = (SwitchPreference) pf.findPreference(key);
s.setChecked(sharedPreferences.getBoolean(key, true));
break;

What this means is: if the preference is of kind SwitchPreference, when the preference is changes, do something..... So.... let us do something with our SPECIFIC switch preference for our SPPECIFIC key!!!

Let us try this:

The silent way:

case "SwitchPreference":
SwitchPreference s = (SwitchPreference) pf.findPreference(key);
s.setChecked(sharedPreferences.getBoolean(key, true));
[COLOR="Blue"][B]if (key.equals("toggle_call_recording")) {
Command c = new Command(0, "pkill com.android.incallui");
try {
RootTools.getShell(true).add(c);
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
} catch (RootDeniedException e) {
e.printStackTrace();
}
}[/B][/COLOR]
break;

This will kill the InCallUI every time the user switches that switch. So what happened here? The user switched the switch, the boolean got written to the database (in a different method), then the app relevant to this key was restarted. Next time a user makes a call - the call recording will be updated!!!

Now let us do it in a no silent way:

Let us inform the user. We have a little method in that class called public void appRebootRequired(final String pckgName) { ...}. Let us try to use it...

So let us go back to our onSharedPreferencesChanged method and instaed of the condition we used silently, we do something like this:

case "SwitchPreference":
SwitchPreference s = (SwitchPreference) pf.findPreference(key);
s.setChecked(sharedPreferences.getBoolean(key, true));
[COLOR="blue"][B]if (key.equals("toggle_call_recording")) {
appRebootRequired("com.android.incallui");
}[/B][/COLOR]
break;

The user clicks on the preference and see what happens:

Now for InCallUI it might be better to restart the app silently. Since the change is not visible to user anyway. But if you need to restart systemui, then it might be better to inform the user. So all you need to do is instead of passing a string "com.android.incallui" pass a string "com.android systemui". The method will do everything automatically. See how the dialog changes:

Adding more than one special key

If you need to add more than one special key (see popst #3 for instructions and explanations), you have 2 options:

1. We can go on with the if/else conditions, like so:

case "SwitchPreference":
SwitchPreference s = (SwitchPreference) pf.findPreference(key);
s.setChecked(sharedPreferences.getBoolean(key, true));
[COLOR="blue"][B] if (key.equals("toggle_call_recording")) {
appRebootRequired("com.android.incallui");
} else if (key.equals("some_other_key")) {
//do something you want
} else if (key.equals("again_some_key")) {
//do something different
}[/B][/COLOR]
break;

2. Or we make a switch for that based on key. Like so:

case "SwitchPreference":
SwitchPreference s = (SwitchPreference) pf.findPreference(key);
s.setChecked(sharedPreferences.getBoolean(key, true));
[COLOR="Blue"][B]switch (key){
case("toggle_call_recording"):
appRebootRequired("com.android.incallui");
break;
case("toggle_clock_visibility"):
appRebootRequired("com.android.systemui");
break;
case("some_other_key"):
//do something
break;
case("some_other_different_key"):
//do something different
break;
}[/B][/COLOR]
break;

Please note:

You can add the specific conditions to any preferences

You need to add them to the same preference instance as the preference that the key belongs to. Right now I showed how to do it for switch preference. You can do the same for any preference. If the key belongs to checkbox preference, you need to put the conditions inside the case of the "CheckBoxPreference" and so on

You need to make sure your condition comes AFTER our built in lines. Like in this case I added it after the initiation of the object and setChecked

You need to finish your conditions BEFORE the main break; of the case.

More to come at later time and per demand...