Are Android system widgets within app configurable?

别说谁变了你拦得住时间么 提交于 2021-01-22 04:59:34

问题


When I press one of the volume hardware buttons, Android's system is shown a depicted. Naturally this also happens when I press whithin my app.

Is it possible to configure the style of these Android system stuff like volume? Or at least when I open these system stuff in my app?

EDIT: As recommended in the comments, I've overwritten onKeyDown, but the adjustStreamVolume switches between 0 and 1 only.

override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
    when (event?.keyCode) {
        KeyEvent.KEYCODE_VOLUME_UP -> {
            audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_RAISE, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE)
            return true
        }
        KeyEvent.KEYCODE_VOLUME_DOWN -> {
            audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_LOWER, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE)
            return true
        }
        else -> {
            return super.onKeyDown(keyCode, event)
        }
    }
}

The streamVolume does not increase well. Unfortunately, when I press continuously Volume_up, the 'getStreamVolume()' value remains t 1


回答1:


Volume dialog

For the volume, it is very easy to replace the volume dialog with a custom one, from android-hide-volume-change-bar-from-device you can replace it with something simple such as a progressbar in your activity, because Android provide an interface for it.

Notification dialog

You can also (if you are very motivated) have a custom display for the incoming notifications. You will need to have a service implementing NotificationListenerService running, it will have to intercepts the notifications, and send them to the main activity to display them the way you want.

Other dialogs

Others, such as the power menu will not be changeable for obvious reasons.

Conclusion

You cannot modify the style of the android system without root permission, because it is encoded in the system app.

Android offers you different way to change its behavior but it has its limitations.

Here is an example for the volume:

main_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ProgressBar
        android:id="@+id/progress_horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toTopOf="parent"
        style="@style/Widget.AppCompat.ProgressBar.Horizontal"/>

</androidx.constraintlayout.widget.ConstraintLayout> 

MainActivity.java

public class MainActivity extends AppCompatActivity {

    AudioManager manager;
    ProgressBar progressBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        manager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        progressBar = findViewById(R.id.progress_horizontal);
        updateVolume();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        switch (event.getKeyCode()) {
            case KeyEvent.KEYCODE_VOLUME_UP:
                updateVolume();
                manager.adjustStreamVolume(AudioManager.STREAM_MUSIC,
                        AudioManager.ADJUST_RAISE,
                        AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
                return true;
            case KeyEvent.KEYCODE_VOLUME_DOWN:
                updateVolume();
                manager.adjustStreamVolume(AudioManager.STREAM_MUSIC,
                        AudioManager.ADJUST_LOWER,
                        AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
                return true;

            default:
                return super.onKeyDown(keyCode, event);
        }
    }

    private void updateVolume()
    {
        int currentVolume = manager.getStreamVolume(AudioManager.STREAM_MUSIC);
        int maxVolume = manager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);

        progressBar.setProgress((int) ((float) currentVolume/maxVolume*100));
    }
}

Edit

Some people said the original volume bar is still visible. I directly tried the code I provided on my S10 Android 10 (Samsung framework) and the default volume bar is not visible. Therefore I also tried it on my S4 running LineageOS 10, and same result. No volume bar appear.

About the adjustStreamVolume or adjustVolume they both allow you to change volume channel but the adjustStreamVolume allow you to change a specific one for example, media, call etc. In my example it is only editing the media.




回答2:


At application Level yes you can do anything because every action has an event, you can create your own actions with UI of your own choice on the events of your choosing, e.g hiding the STOCK VOLUME DIALOG and showing CUSTOM DIALOG, but at OS level no you can't.

Reason

Android Framework and any other architectural Component work on the basics of events, like in Android OS if you do something, an event is initialized and a broadcast is sent to all the framework and it can be read by any application having right PERMISSIONS and IDS for those Broadcasts, by using BROADCAST RECEIVERS and SERVICES in case of Notifications for special broadcasts.

How can you achieve your goals

I will not tell you every function and method for what you want to do but will tell you the recipe for achieving it, with the help of Andoird's Official DOCs and with great people at Stackoverflow

For all the events you can you this overriding method

 @Override
public boolean onKey**`YourKeyEvent`**(int keyCode, KeyEvent event) {
    switch (event.getKeyCode()) {
        case KeyEvent.Your_Event_One:
            //your actions (perform code on some keyEvent)

            break;

        case KeyEvent.Your_Event_Two:
           //your actions (perform code on some keyEvent)

        break;
    }
}

above code is great for most of the events but for some, you will be needing Broadcast Reciever aswell

LIST OF KEY_EVENTS (Android's Docs)

List Of Key Codes (Android's Code)

EDIT For volume change please have a look at This post, by using this post you can create a callback on volume rocker action, and then hide the stock dialog, and show your own, by using the service on the home screen.

NOTE: I've never been exposed to hiding the stock UI components in past so I am not sure about that part.



来源:https://stackoverflow.com/questions/64552085/are-android-system-widgets-within-app-configurable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!