问题
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