Android:利用系统服务设置系统音量

目录

系统服务

用户编写的 Service 是后台应用服务程序,位于 Android 系统应用层。相对而言的系统服务(System Services)可以看作 Android 系统的内置软件,它是 Android 操作系统 Java 应用程序下层的,伴随操作系统启动而运行的系统后台服务程序。系统服务是 Android 系统运行的基石,它配合 binder、Dalvik 虚拟机和 Android 应用程序构成了一个多进程交互通信、交互服务的 Android 系统。
Android 的所有服务循环都建立在 System Server 之上,Service manager 是管理系统服务的进程,通过 ServerManager 的 add_service() 方法把服务加入到服务列表中,实现对服务的管理。Activity 中有一个重要的方法 getSystemService(),根据传入的 Name 来取得对应的 Object,然后转换成相应的服务对象。

public Object getSystemService(String name);

以下是常用的系统服务:

系统服务名 返回的对象 说明
WINDOW_SERVICE WindowManager 管理打开的窗口程序
LAYOUT_INFLATER_SERVICE LayoutInflater 取得 xml 里定义的 View
ACTIVITY_SERVICE ActivityManager 管理应用程序的系统状态
POWER_SERVICE PowerManger 电源服务
ALARM_SERVICE AlarmManager 闹钟服务
NOTIFICATION_SERVICE NotificationManager 状态栏服务
KEYGUARD_SERVICE KeyguardManager 键盘锁服务
LOCATION_SERVICE LocationManager 位置服务,如 GPS
SEARCH_SERVICE SearchManager 搜索服务
VIBRATOR SERVICE Vibrator手 机振动服务
CONNECTIVITY_SERVICE Connectivity 网络连接服务
WIFI_SERVICE WifiManager WiFi 服务
TELEPHONY_SERVICE TeleponyManager 电话服务

系统服务样例

程序需求

利用 Android APP 的系统服务,获取并设置系统音量。

功能设计

首先需要获取不同音量的最大值,保值音量的设置是正确的不会越界,接着再获取当前的音量作为拖动条的初始值。接着就是当用户点击“ok”的时候,根据拖动条的值使用 set 方法来设置系统音量。

代码编写

AdjustVolumeDialog.java

package com.example.yinlian;

import android.app.AlertDialog;
import android.content.Context;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.SeekBar;
import android.widget.TextView;
import androidx.annotation.NonNull;

public class AdjustVolumeDialog extends AlertDialog {

    private AudioManager audioManager;
    private SeekBar seekbar1, seekbar2, seekbar3;
    private int screenWidth;
    private TextView textView1,textView2,textView3;
    private CheckBox ch;
    private Button ok, cancel;
    private Context context;

    protected AdjustVolumeDialog(@NonNull Context context, int themeResId) {
        super(context, themeResId);
    }

    /**
     * 在onCreate方法里面 setContentView() 否则dialog的自定义view 显示不出来
     * @param savedInstanceState
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        audioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
        WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics dm = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(dm);
        screenWidth = dm.widthPixels;         // 屏幕宽度(像素)
        initView();
    }

    /**
     * 自定义dialog 的view
     * 设置 位置
     */
    private void initView() {
        View root = LayoutInflater.from(getContext()).inflate(R.layout.dialog, null);
        setContentView(root);
        seekbar1 = root.findViewById(R.id.ringseekBar);
        seekbar2 = root.findViewById(R.id.mediaseekBar);
        seekbar3 = root.findViewById(R.id.alarmseekBar);
        textView1 = (TextView) findViewById(R.id.ring);
        textView2 = (TextView) findViewById(R.id.media);
        textView3 = (TextView) findViewById(R.id.Alarm);
        ch = (CheckBox)findViewById(R.id.choose);
        ok     = (Button)findViewById(R.id.ok);
        cancel = (Button)findViewById(R.id.cancel);

        seekbar1.setMax(audioManager.getStreamMaxVolume(AudioManager.STREAM_RING));
        seekbar2.setMax(audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC));
        seekbar3.setMax(audioManager.getStreamMaxVolume(AudioManager.STREAM_ALARM));
        int ringVolume   = audioManager.getStreamVolume(AudioManager.STREAM_RING);
        int musicVolume  = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
        int alarmVolume  = audioManager.getStreamVolume(AudioManager.STREAM_ALARM);
        seekbar1.setProgress(ringVolume);
        seekbar2.setProgress(musicVolume);
        seekbar3.setProgress(alarmVolume);
        textView1.setText("铃声音量为:" + ringVolume);
        textView2.setText("媒体音量为:" + musicVolume);
        textView3.setText("闹钟音量为:" + alarmVolume);

        /* 设置SeekBar 监听setOnSeekBarChangeListener */
        seekbar1.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            /*拖动条停止拖动时调用 */
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
            }
            /*拖动条开始拖动时调用*/
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }
            /* 拖动条进度改变时调用*/
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                textView1.setText("铃声音量为:" + progress);
            }
        });

        seekbar2.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
            }
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                textView2.setText("媒体音量为:" + progress);
            }
        });

        seekbar3.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
            }
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                textView3.setText("闹钟音量为:" + progress);
            }
        });

        ok.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                int ringVolume = seekbar1.getProgress();
                if(ch.isChecked()) {
                    audioManager.setStreamVolume(AudioManager.STREAM_RING, seekbar1.getProgress(), AudioManager.FLAG_PLAY_SOUND);
                    audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, seekbar1.getProgress(), AudioManager.FLAG_PLAY_SOUND);
                    seekbar2.setProgress(ringVolume);
                    textView2.setText("媒体音量为:" + ringVolume);
                    audioManager.setStreamVolume(AudioManager.STREAM_ALARM, seekbar1.getProgress(), AudioManager.FLAG_PLAY_SOUND);
                    seekbar3.setProgress(ringVolume);
                    textView3.setText("闹钟音量为:" + ringVolume);
                }
                else {
                    audioManager.setStreamVolume(AudioManager.STREAM_RING, seekbar1.getProgress(), AudioManager.FLAG_PLAY_SOUND);
                    audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, seekbar2.getProgress(), AudioManager.FLAG_PLAY_SOUND);
                    audioManager.setStreamVolume(AudioManager.STREAM_ALARM, seekbar3.getProgress(), AudioManager.FLAG_PLAY_SOUND);
                }
            }
        });

        cancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                dismiss();
            }
        });

        // 设置dialog中view的位置
        Window window = getWindow();
        WindowManager.LayoutParams lp = window.getAttributes();
        lp.gravity = Gravity.CENTER;    //居中
        window.setAttributes(lp);
    }

    /**
     * dialog显示时回调
     * 广播注册
     */
    @Override
    public void show() {
        super.show();
        IntentFilter filter = new IntentFilter() ;
        filter.addAction("android.media.VOLUME_CHANGED_ACTION") ;
    }

    /**
     * dialog消失时回调
     * 广播反注册
     */
    @Override
    public void dismiss() {
        super.dismiss();
    }
}

Diglog.xml

接着就设置一个弹窗来实现这个功能即可。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/parentLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">

    <LinearLayout
        android:id="@+id/seekLayout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:orientation="vertical">

        <TextView
            android:id="@+id/volume"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:text="Volume"
            android:textSize="40dp"></TextView>

        <TextView
            android:id="@+id/ring"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:text="Ringtone"
            android:textSize="20dp">
        </TextView>

        <SeekBar
            android:id="@+id/ringseekBar"
            android:layout_width="250dp"
            android:layout_height="wrap_content"
            android:maxHeight="20dp"
            android:paddingStart="15dp"
            android:paddingEnd="15dp"
            android:progressDrawable="@drawable/po_seekbar"
            android:thumb="@drawable/seekbar_thumb" />

        <TextView
            android:id="@+id/media"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:text="Media"
            android:textSize="20dp"></TextView>

        <SeekBar
            android:id="@+id/mediaseekBar"
            android:layout_width="250dp"
            android:layout_height="wrap_content"
            android:maxHeight="20dp"
            android:paddingStart="15dp"
            android:paddingEnd="15dp"
            android:progressDrawable="@drawable/po_seekbar"
            android:thumb="@drawable/seekbar_thumb" />

        <TextView
            android:id="@+id/Alarm"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:text="Alarm"
            android:textSize="20dp"></TextView>

        <SeekBar
            android:id="@+id/alarmseekBar"
            android:layout_width="250dp"
            android:layout_height="wrap_content"
            android:maxHeight="20dp"
            android:paddingStart="15dp"
            android:paddingEnd="15dp"
            android:progressDrawable="@drawable/po_seekbar"
            android:thumb="@drawable/seekbar_thumb" />

        <CheckBox
            android:id="@+id/choose"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="使用来电铃音音量进行通知"></CheckBox>

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <Button
                android:id="@+id/ok"
                android:layout_width="114.0dip"
                android:layout_height="40.0dip"
                android:gravity="center"
                android:text="ok" />

            <Button
                android:id="@+id/cancel"
                android:layout_width="114.0dip"
                android:layout_height="40.0dip"
                android:layout_marginLeft="20.0dip"
                android:gravity="center"
                android:text="cancel" />

        </LinearLayout>
    </LinearLayout>
</LinearLayout>

MainActivity

package com.example.yinlian;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

    Button btn;
    AdjustVolumeDialog adjustVolumeDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 需要为 dialog 设置一个 style
        adjustVolumeDialog = new AdjustVolumeDialog(this, R.style.Theme_Yinlian);
        btn = findViewById(R.id.btn);
        // 点击按钮弹出对话框
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                adjustVolumeDialog.show();
            }
        });
    }

    @Override
    protected void onDestroy() {
        if(adjustVolumeDialog!=null && adjustVolumeDialog.isShowing()) {
            adjustVolumeDialog.dismiss();
        }
        super.onDestroy();
    }
}

Activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.yinlian.MainActivity"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="音量调节"
        android:layout_marginTop="50dp"
        android:layout_gravity="center"
        android:textSize="20dp"/>

    <Button
        android:id="@+id/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:layout_gravity="center"
        android:textSize="20dp"
        android:text="调节">
    </Button>

</LinearLayout>

运行效果

打开弹窗。
Android:利用系统服务设置系统音量
设置新的音量。
Android:利用系统服务设置系统音量
使用来电音量来设置,媒体音量和闹钟音量会设置为来电音量。
Android:利用系统服务设置系统音量

参考资料

《Android 移动应用开发》,杨谊 主编、喻德旷 副主编,人民邮电出版社

上一篇:Java Socket基础(三)


下一篇:eclipse下的tomcat启动失败(Server Tomcat v7.0 Server at localhost failed to start.)