• 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 移动应用开发》,杨谊 主编、喻德旷 副主编,人民邮电出版社

  • 相关阅读:
    filter与compress
    groupby,分组
    按照属性排序,使用lambda与itemgetter,attrgetter
    python3-cookbook电子书在线文档
    numpy中的向量操作
    向量Vector
    defaultdict与OrderedDict
    heapq堆队列
    (转载)SVM-基础(一)
    决策树-剪枝算法(二)
  • 原文地址:https://www.cnblogs.com/linfangnan/p/15857950.html
Copyright © 2020-2023  润新知