How to add an item to Quick Settings in Android - android

I was thinking if there is a way to add an item in Quick Settings Panel in android ?
I have an app called Mirror by Koushik Dutta that does the same. It adds an item in Quick Settings panel. I decompiled the app and saw that he's moving the apk to /system/priv-app .
That's it. Nothing's related to adding an item in Quick Settings Toggle.
I know it'll require root access (just a college project). Please if anyone has any idea how it can be done, it would be really helpful.

Use the Android N tile API
Custom quick settings can be created in Android N using the tile API. Just make a class that inherits from TileService and add it to the manifest.
Here's the example given in the TileService documentation:
<service
android:name=".MyQSTileService"
android:label="#string/my_default_tile_label"
android:icon="#drawable/my_default_icon_label"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
</service>

Recent versions of CyanogenMod 12.1 support this through the CyanogenMod Platform SDK:
public void publishTile() {
if (supportsCustomTiles()) {
Intent receiver = new Intent(context, TileClickedReceiver.class);
PendingIntent clickIntent = PendingIntent.getBroadcast(
context,
0,
receiver,
PendingIntent.FLAG_CANCEL_CURRENT
);
CustomTile tile = new CustomTile.Builder(context)
.setIcon(R.drawable.tile_icon)
.setLabel("Test Tile")
.setOnClickIntent(clickIntent)
.build();
CMStatusBarManager
.getInstance(context)
.publishTile(1234, tile);
}
}
private boolean supportsCustomTiles() {
try {
Class.forName("cyanogenmod.app.CustomTile");
return true;
} catch (ClassNotFoundException e) {
return false;
}
}

The quick settings tiles in Android 4.4 are all hardcoded.
Here's a link to the source.
Even with root, the only way to change this would be patching system jars/apks.
The support for Mirror might be added by Cyanogenmod, have you tried if it works on any other ROM?
Edit: Here's a feature request for a quick settings api: https://code.google.com/p/android/issues/detail?id=42616

Koushik Dutta didn't add a new quick settings tile. The "Cast Screen"-Tile is implemented by the android system and appears sometimes. It's a shortcut to the "cast screen"-menu in system settings. Koush added new options for this menu (i don't know if there's an open api or if he needs the root permission for that) and now, the tile is always displayed because there's always content.
To answer your question: No, without system modifications with root, you can't add tiles to the android quick settings. (Edit: I haven't read that you'd also use root. So, you can't add tiles easily and the mirror application by Koushik Dutta doesn't do that, too.)
PS: It isn't because of CyanogenMod, because I use stock android and the app works, too.
Update 2019-08-08: With Android N, there's an official API to add custom quick setting tiles (see Sam's answer).

Related

Detect if Material You is present in device

So, my boss asked me to analyze how to implement Material You colors starting from Android 12. I've been researching for it and every blog of every page about "how to do it" tells you that, you need to hold down at home screen, then go to "Wallpapers & Style" and change your wallpaper. There is an issue, though.
I remember that while Android 12 was in Beta, it was supporting Material You colors. However (I assume) after the official release, this support has been removed, because I am unable to find the option. Here is what it looks like when I hold down while at home screen:
It says "Wallpapers" and when I click on it, it does not open a menu called Wallpaper & style, it just redirects to Live Wallpapers. I've unable to find the wallpaper colors option on the official Android 12 release. However, it is present on the upcoming API 32 (Android 13 I believe) emulator.
Upon researching a little bit, I've found out that the system generates the wallpaper colors under the system resources such as system_accent1_600 etc. which are available starting from API 31 (more info here). This does work when I use an API 32 emulator which is in beta, but it defaults to something else (a shade of blue on accent colors, and shades of gray on neutral, a.k.a background colors) that I haven't figured out where from on an API 31 official emulator.
Here is the question:
Is Material You colors officially supported starting from Android 12 (API 31)? If yes, then why am I not able to find it on Android's official emulator?
Also, is it possible to detect if the device supports Material You colors with different options?
I think this is what you are looking for:
public static boolean isDynamicColorAvailable()
{
return VERSION.SDK_INT >= VERSION_CODES.S && DYNAMIC_COLOR_SUPPORTED_MANUFACTURERS.contains(Build.MANUFACTURER.toLowerCase());
}
Found this in DynamicColors class in com.google.android.material.color
You can simply call it like this:
boolean isdca = DynamicColors.isDynamicColorAvailable();
I hope this answers the last part.
1. Is Material You colors officially supported starting from Android 12 (API 31)?
Yes! But it based how the ROM implements. If you using Pixel, the you can change the color via the built wallpaper app. But if you're using AOSP, sine there is not an official way in UI to user to change it.
Check out this doc: https://gist.github.com/zhaofengli/232f5a3d33113871ad61491629886084
2. If yes, then why am I not able to find it on Android's official emulator?
It looks like Google removed it from the mirror. The previous mirror had this feature.
3. Also, is it possible to detect if the device supports Material You colors?
Since Android 12 supports Material You officially, so you can just check the api version simply.
But, according to the second point, some systems still don't support it, so you can use the method com.google.android.material.color.DynamicColors#isDynamicColorAvailable. This is the definitive method used by Material Design, depending on the SDK version and phone manufacturer.
https://cs.github.com/material-components/material-components-android/blob/2ae3ca42985722900f53de9d9a1ef61c143767eb/lib/java/com/google/android/material/color/DynamicColors.java#L279-L289
4. What is the correct way to implement Material You?
XML way: Follow the official doc: https://m3.material.io/libraries/mdc-android/color-theming
Programmatically way:
Check out my app's code:
val Context.colorOnPrimary: Int
get() {
return when {
DynamicColors.isDynamicColorAvailable() -> {
getColorFromAttr(R.attr.colorOnPrimary)
}
isNight() || !supportNight() -> {
ContextCompat.getColor(this, R.color.md_theme_dark_onPrimary)
}
else -> {
ContextCompat.getColor(this, R.color.md_theme_light_onPrimary)
}
}
}
#ColorInt
fun Context.getColorFromAttr(
#AttrRes attrColor: Int,
typedValue: TypedValue = TypedValue(),
resolveRefs: Boolean = true
): Int {
theme.resolveAttribute(attrColor, typedValue, resolveRefs)
return typedValue.data
}

Taking Screenshots Using Qt C++ on Android

thanks for checking my question out!
I'm currently working on a project using Qt C++, which is designed to be multi-platform. I'm a bit of a newcoming to it, so I've been asked to set up the ability to take screenshots from within the menu structure, and I'm having issues with the Android version of the companion app.
As a quick overview, it's a bit of software that send the content of a host PC's screen to our app, and I've been able to take screenshots on the Windows version just fine, using QScreen and QPixmap, like so:
overlaywindow.cpp
{
QPixmap screenSnapData = screenGrab->currentBackground();
}
screenGrabber.cpp
{
QScreen *screen = QGuiApplication::primaryScreen();
return screen->grabWindow( QApplication::desktop()->winId() );
}
Unfortunately, Android seems to reject QScreen, and with most suggestions from past Google searches suggesting the now-deprecated QPixmap::grab(), I've gotten a little stuck.
What luck I have had is within the code for the menu itself, and QWidget, but that isn't without issue, of course!
QFile doubleCheckFile("/storage/emulated/0/Pictures/Testing/checking.png");
doubleCheckFile.open(QIODevice::ReadWrite);
QPixmap checkingPixmap = QWidget::grab();
checkingPixmap.save(&doubleCheckFile);
doubleCheckFile.close();
This code does take a screenshot, but only of the button strip currently implemented, and not for the whole screen. I've also taken a 'screenshot' of just a white box with the screen's dimensions by using:
QDesktopWidget dw;
QWidget *screen=dw.screen();
QPixmap checkingPixmap = screen->grab();
Would anyone know of whether there was an alternative to using QScreen to take a screenshot in Android, or whether there's a specific way to get it working as compared to Windows? Or would QWidget be the right track? Any help's greatly appreciated!
as i can read in Qt doc : In your screenGrabber.cpp :
QScreen *screen = QGuiApplication::primaryScreen();
return screen->grabWindow( QApplication::desktop()->winId() );
replace with :
QScreen *screen = QGuiApplication::primaryScreen();
return screen->grabWindow( 0 ); // as 0 is the id of main screen
If you want to take a screenshot of your own widget, you can use the method QWidget::render (Qt Doc):
QPixmap pixmap(widget->size());
widget->render(&pixmap);
If you want to take a screenshot of another app/widget than your app, you should use the Android API...

Using Cordova, is there a way to reference native icons?

I'm using Cordova 3.5 to build an app which contains a menu with pretty standard items in the list (home, contacts, etc.), and I want to use the native menu icons whenever possible. I believe those icons are already on the device as part of the OS, but I don't know if Cordova gives me a way to reference them.
I suppose I'd need to write a Javascript function to choose the right file name based on the platform, e.g.:
// this is pseudocode
var icon = '';
if (platform === 'android') {
icon = 'some/path/home.png';
} else {
icon = 'other/path/icon.home.png';
// or maybe a function such as the following exists:
// icon = cordova.getNativeIcon('icon.home.png');
}
$('.selector').css('background-image', icon);
Alternatively, I may be able to make do by referencing the files in CSS, e.g.:
.android .home-icon {
background-image: url('some/path/home.png');
}
.ios .home-icon {
background-image: url('other/path/icon.home.png');
}
So, how do folks handle this sort of thing in Cordova? Is there a function I can use to access native icons? Are folks just copying them into their projects? What's the best practice?
If you're working with Cordova, then you'll be working inside a web view provided by the host OS and you won't have direct access to any artwork. I've found that using icon fonts and CSS "themes" to work well enough, but that approach will replicate artwork already provided. There's extra work involved with theming for iOS 6 vs iOS 7 or 8, for example, but it's not as bad as it sounds.
IBM does have an article on partitioning your view between native and web controls, but it sounds a bit cumbersome. More details here: https://www.ibm.com/developerworks/community/blogs/worklight/entry/ios_combining_native_and_web_controls_in_cordova_based_applications

How to open device dock settings programmatically?

I have to open device dock setting through code. I searched but not got proper solution. In samsung galaxy s-3 it goes through settings->Accessory. I tried following code but didn't work
startActivityForResult(new Intent(Settings.System.getString(getContentResolver(), DOCK_SETTING)), 0);
Correct me if I'm wrong, but I believe the reason this doesn't work, (and why you weren't able to find the appropriate Activity Action in the Android Settings), is because Accessory appears to be provided by Samsung for its Galaxy devices. Therefore, you won't be able to find it in the standard Android SDK (yet?).
I'm currently trying to figure out a workaround, so I'll edit this post if I find a solution.
EDIT: Looks like JoxTraex found a way for you to edit the settings via:
Settings.System.putInt(getContentResolver(), "dock_sounds_enabled", 1);
In addition, if you need to modify these settings when the user has docked their device, you should create a BroadcastReceiver to listen for the ACTION_DOCK_EVENT broadcast.
I was able to achieve this through looking at the settings and configuring the setting programatically:
android.provider.Settings.System.putInt(getContentResolver(), "dock_sounds_enabled", 1);
You need the permission:
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
The code above will write to the settings that enables the dock sound settings on the samsung s3. However; instead of just writing it you should tell the user that the setting is disabled and you need it enabled and allow the user to confirm they want to enable it via a dialog.
On another note, I don't think its possible to go directly to the settings->accessory screen because its was a custom settings added by Samsung. This action is not provided in the Android SDK, so it would take a while to derive what is the actual action or even if it exists.
And if you want to confirm it just query it:
String where = "name = 'dock_sounds_enabled'";
Cursor c = getContentResolver().query(android.provider.Settings.System.CONTENT_URI, null, where, null, null);
Update
Steps for how to handle the dialog's response for configuring the dock setting:
Grab the setting.. if it's 0, bring up the dialog to enable it, otherwise continue with your processing
Once the dialog is up and the user confirms they want to enable it:
Confirm: Put a 1 into the dock sounds then close the dialog
Deny: Don't set the dock setting then close dialog

Android icon wrong in App Management app, but correct in Launcher

I have a simple Android app (built with Mono for Android), which has a problem with it's icon.
The icon is correct in Launcher and in Task Switcher, but
In Manage Apps and in Task Manager it's displayed a generic Android icon
I've checked the various density resources and the manifest and they all look correct.
(I'm seeing this on a Galaxy S phone and on a Nexus 7)
Most likely you set the icon property for your activities within AndroidManifest.xml, but did not set it for the application.
It occurs to me, that the app icon is somehow being cached in the app manager, so that deinstalling and reinstalling the app does not always change the icon properly. Rebooting the device could help.
Also i found this post very useful: adding application ids in gradle usually solves the problem.
Open "AndroidMenifest.xml" in the Package Explorer and click on the "Application" tab at the bottom. Look at the "icon" field and enter the location for your icon ( Ex: #drawable/iconimage). Next, go into the "AndroidManifest.xml" tab and look for android:icon=, adding the location to that as well (Ex: android:icon="#drawable/iconimage)
Make sure you have the same icon name in both locations!
Oleg and Collin are both right but for completeness - in a Mono app the icon can be set with attributes on the Application object (if you have one):
[Application(Label = "MyAppName", Icon = "#drawable/icon")]
class MyApp: Application
{ ...

Categories

Resources