用JNI实现调节win7系统音量

时间:2022-02-12 23:19:22

这是我大三时写的,现在把它传到博客园给大家分享.

github地址:https://github.com/silicon621600/SiliconJNIProject/tree/master/JavaControlVolumeOfWin7

一编写包含native方法的Java类文件:

使用了异常处理机制

com.guwei,volume.VolumeControl.java文件

package com.guwei.volume;

/**

* 该类设计为单例模式

* 提供控制win7系统音量的方法

* @author guwei

*

*/

public class VolumeControl {

     static

     {

         System.out.println(System.getProperty("java.library.path"));

     System.loadLibrary("VolumeControlDLL");

     }

        private static VolumeControl uniqueInstance = null;

 

        private VolumeControl() throws OperationFailedException

        {            

            init();

        }            

        /**

         * 单例模式

         * @return 唯一的VolumeControl 有可能为null

         */

        public static VolumeControl getInstance() {

            if (uniqueInstance == null) {

                try {

                    uniqueInstance = new VolumeControl();

                }catch (OperationFailedException e)

                {

                    e.printStackTrace();

                    return null;

                }

            }

            return uniqueInstance;

        }             

        /**

         * cpp本地一些初始化

         * @return

         */

        private native void init() throws OperationFailedException;

        /**

         * 设置音量大小0~100

         * @param num

         * @return 操作是否成功

         */

     public native void setMasterVolume(int num) throws OperationFailedException;

     /**

     *

     * @return 当前音量大小1-100

     */

        public native int getMasterVolume() throws OperationFailedException;

        /**

         * 设置是否静音 true-是 false-否

         * @param bMute

         * @return

         */

        public native void setMute(boolean bMute) throws OperationFailedException;

        /**

         * 得到当前静音状态 true-是 false-否

         * @return

         */

        public native boolean getMute() throws OperationFailedException;

        /**

         * cpp本地释放指针等操作

         * @return

         */

        private native void finished();        

        @Override

        public void finalize()

        {

            finished();

        }

}

com.guwei,volume.OperationFailedException.java文件

package com.guwei.volume;

public class OperationFailedException extends Exception

{

    public OperationFailedException()

    {}

    public OperationFailedException(String message)

    {

        super(message);

    }

}

一.编译,然后用javah命令生成相应cpp头文件

编译可用命令行javac或eclipse自动编译(javac 注意用-encoding utf8参数)

在完整.class文件位置(不是class文件的存放目录,考虑包名)使用javah命令

javah -jni com.guwei.volume.VolumeControl

也可以用-classpath指明类路径

注意要输入完整的类名,更多参数输入javah查看

命令运行完成后,会出现一个com_guwei_volume_VolumeControl.h文件

生成的头文件内容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */

#include <jni.h>

/* Header for class com_guwei_volume_VolumeControl */

#ifndef _Included_com_guwei_volume_VolumeControl

#define _Included_com_guwei_volume_VolumeControl

#ifdef __cplusplus

extern "C" {

#endif

/*

* Class: com_guwei_volume_VolumeControl

* Method: init

* Signature: ()V

*/

JNIEXPORT void JNICALL Java_com_guwei_volume_VolumeControl_init

(JNIEnv *, jobject);

/*

* Class: com_guwei_volume_VolumeControl

* Method: setMasterVolume

* Signature: (I)V

*/

JNIEXPORT void JNICALL Java_com_guwei_volume_VolumeControl_setMasterVolume

(JNIEnv *, jobject, jint);

/*

* Class: com_guwei_volume_VolumeControl

* Method: getMasterVolume

* Signature: ()I

*/

JNIEXPORT jint JNICALL Java_com_guwei_volume_VolumeControl_getMasterVolume

(JNIEnv *, jobject);

/*

* Class: com_guwei_volume_VolumeControl

* Method: setMute

* Signature: (Z)V

*/

JNIEXPORT void JNICALL Java_com_guwei_volume_VolumeControl_setMute

(JNIEnv *, jobject, jboolean);

/*

* Class: com_guwei_volume_VolumeControl

* Method: getMute

* Signature: ()Z

*/

JNIEXPORT jboolean JNICALL Java_com_guwei_volume_VolumeControl_getMute

(JNIEnv *, jobject);

/*

* Class: com_guwei_volume_VolumeControl

* Method: finished

* Signature: ()V

*/

JNIEXPORT void JNICALL Java_com_guwei_volume_VolumeControl_finished

(JNIEnv *, jobject);

#ifdef __cplusplus

}

#endif

#endif

二.查询MSDN中调节wen7系统音量的方法

https://msdn.microsoft.com/zh-cn/library/windows/desktop/dd370839(v=vs.85).aspx

该网址提供一个样例VC++的win32工程显示调节系统音量,

将网页文档读懂即可编写自己的dll,,其中用到了COM组件相关知识

该工程运行效果如下:

三.编写dll文件(用到了COM相关)

使用VS2010建立名为VolumeControlDLL的win32控制台工程

点下一步后 选择dll 和空项目

将jni.h和之前生成的com_guwei_volume_VolumeControl.h加入工程

jni.h在jdk目录的include目录下:

可以在VS的环境变量中加入该目录

此处我用的是直接把文件拷到当前工程,所以相应com_guwei_volume_VolumeControl.h文件中的 include <jni.h> 改为 include "jni.h"

注意头文件中的extern C 是必要的,否则会报找不到的错,这是因为CPP支持函数重载,会将函数名XX映射

另外,jdk1.7只需jni.h文件,jdk1.8还需要jni_md.h文件(include/win32目录下)根据编译信息来即可

Epvolume.cpp文件实现com_guwei_volume_VolumeControl.h的方法(根据MSDN工程中的改写)

// Epvolume.cpp -- WinMain and dialog box functions

#include "Epvolume.h"

#include "com_guwei_volume_VolumeControl.h"

GUID g_guidMyContext = GUID_NULL;

static IAudioEndpointVolume *g_pEndptVol = NULL;

IMMDeviceEnumerator *pEnumerator = NULL;

IMMDevice *pDevice = NULL;