Android 7.0内去掉有关USB 耳机音频输入设备的对话框和Toast方法

Android 7.0 本文章可以参考解决绕过android下apk使用usb设备权限查询相应问题,自动获取usb权限,主要是在Android 7.0系统上,当插入USB 耳机或者音频输入设备的时候,就会报出如下对话框和消息提示,在我们开发的时候很不爽,需要手动去点很麻烦,如下图所示:

提示消息即Toast,当插入USB耳机或者麦时就会弹出“USB音频输入设备接入”,当拔掉时就会弹出“切换之原始的默认通道”

这个问题需要修改系统源码其位置在Android 7.0

/android/device/softwinner/common/addons/framework/audio/java/AudioManagerPolicy.java

这AudioManagerPolicy.java就是就是相关的代码源文件,而在此之前还有个xml文件来说明那就是strings_custom.xml

其实这个位置的方法很简单只要在源码目录下使用命令:

grep 'USB音频输入设备接入' ./ -Rn

就能找到strings_custom.xml,其内容如下所示:

<resources xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <!-- support the mouse mode -->
    <string name="enter_key_mouse_mode">进入鼠标模式</string>
    <string name="exit_key_mouse_mode">退出鼠标模式</string>
    <string name="title_key_mouse_mode">鼠标模式</string>
    <string name="detail_key_mouse_mode">当前处于鼠标模式</string>

    <!-- add by chenjd, message for audio -->
    <string name="usb_audio_out_plug_in_title">"USB音频输出设备接入"</string>
    <string name="usb_audio_plug_in_message">"可在‘通用设置-高级设置-提示音和通知-音频输出模式‘选择输出通道"</string>
    <string name="usb_audio_plug_out_message">"切换至原始的默认通道"</string>
    <string name="usb_audio_out_plug_out_title">"USB音频输出设备拔出"</string>
    <string name="usb_audio_in_plug_in_title">"USB音频输入设备接入"</string>
    <string name="usb_audio_in_plug_out_title">"USB音频输入设备拔出"</string>
    <string name="headphone_plug_in_title">"耳机插入"</string>
    <string name="headphone_plug_out_title">"耳机拔出"</string>
    <string name="headphone_plug_in_message">"切换至耳机"</string>
    <string name="headphone_plug_out_message">"切换至原始的默认通道"</string>
    <string name="usb_output_title">"USB音频输出选择"</string>
    <string name="usb_output_message">"USB音频输出设备已接入,请选择是否切换到USB音频设备输出,\n在 %1$s 秒后自动切换到USB音频设备"</string>
    <string name="usb_yes">"是"</string>
    <string name="usb_no">"否"</string>
    <string name="ota_title">"升级提示"</string>
    <string name="ota_accept">"确定"</string>
    <string name="ota_reject">"取消"</string>
    <string name="ota_error_title">"错误提示"</string>
</resources>

看到没有所有字符串对应的变量都列举出来了,在根据对应的字符串变量,来搜索Java源码文件:

grep 'usb_audio_in_plug_in_title' ./ -Rn

这样就找到了AudioManagerPolicy.java,其他Android系统版本也可以用这个方法去做,下面来看这个源码怎么修改,其实很简单,看字面意思就能看懂,先去掉对话框

1.在代码的527行有段方法:private void chooseUsbAudioDeviceDialog(final ArrayList<String> usb_device)这个方法就是弹出的对话框,下面来分析以下这个对话框:

 private void chooseUsbAudioDeviceDialog(final ArrayList<String> usb_device)
    {
        String str = mCtx.getResources().getString(com.android.internal.R.string.usb_output_message);
//获取对话框的内容,也就是在上面那个xml内usb_output_message对应的:USB音频输出设备已接入,请选择是否切换到USB音频设备输出,\n在 %1$s 秒后自动切换到USB音频设备
        alertDialog = new AlertDialog.Builder(mCtx).//创建对话框
                setTitle(com.android.internal.R.string.usb_output_title).//设置对话框的标题为"USB音频输出选择"
                setMessage(String.format(str, Integer.toString(USB_TOAST_TIME))).
                setPositiveButton(com.android.internal.R.string.usb_yes, new DialogInterface.OnClickListener() {//设置当点击“是”按钮的监听时间
                     @Override
                     public void onClick(DialogInterface dialog, int which) {
                           // TODO Auto-generated method stub
                           mAudioManagerEx.setAudioDeviceActive(usb_device, AudioManagerEx.AUDIO_OUTPUT_ACTIVE);//设置为usb为音频输入设备
                     }
                }).
                setNegativeButton(com.android.internal.R.string.usb_no, new DialogInterface.OnClickListener() {/设置当点击“否”按钮的监听时间
                     @Override
                     public void onClick(DialogInterface dialog, int which) {
                           // TODO Auto-generated method stub
                           //Log.v(TAG, "setNegativeButton ");
                           String message = mCtx.getResources().getString(R.string.usb_audio_plug_in_message);
                           toastPlugInNotification(message, AUDIO_OUT_NOTIFY);
//点击“否”,弹出提示消息:"可在‘通用设置-高级设置-提示音和通知-音频输出模式‘选择输出通道"
                     }
                }).
                create();
        alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
        alertDialog.show();//喷出对话框
        new AsyncTask() {
            @Override
            protected Object doInBackground(Object... arg0) {
                int time = USB_TOAST_TIME;//设置10秒等待时间
                while(time >= 0 && alertDialog != null && alertDialog.isShowing()){
                    publishProgress(time);
                    try {
                        Thread.sleep(1000);
                    } catch(Exception e) {
                        // do nothing
                    }
                    time--;
                }
                return null;
            }
            @Override
            protected void onPostExecute(Object result) {//当超过10秒没有点击时触发
                super.onPostExecute(result);
                if (alertDialog != null && alertDialog.isShowing()) {
                    alertDialog.dismiss();
                    mAudioManagerEx.setAudioDeviceActive(usb_device, AudioManagerEx.AUDIO_OUTPUT_ACTIVE);//设置为USB 设备为输入设备,这个逻辑很关键,是默认的情况,当去掉对话框时这个陆机要保留
                    alertDialog = null;
                }
            }
            @Override
            protected void onProgressUpdate(Object... values) {
                super.onProgressUpdate(values);
                int time = (Integer)values[0];
                String str = mCtx.getResources().getString(com.android.internal.R.string.usb_output_message);
                if(alertDialog != null)
                    alertDialog.setMessage(String.format(str, Integer.toString(time)));
            }
       }.execute();
    }

根据上面的对话框的代码,我们知道,对话框是默认点击“是”按钮的因此,我们需要在代码中也要保持这个逻辑:

那么这个对话框方法调用的位置在方法handleExternalDevice内,这个代码看着很长,但很简单,我就不分析了,把主要的贴出来,在634行调用了这个方法因此只要注释掉并添加一行:

 //chooseUsbAudioDeviceDialog(audio_out);
mAudioManagerEx.setAudioDeviceActive(audio_out, AudioManagerEx.AUDIO_OUTPUT_ACTIVE);

添加的就是跳过对话框而直接设置usb音频设备为输入设备

2.去掉相关的提示信息

在上面去掉对话框是就已经去掉了 

<string name="usb_audio_plug_in_message">"可在‘通用设置-高级设置-提示音和通知-音频输出模式‘选择输出通道"</string>

对方法handleExternalDevice分析可知,每一个对应的消息都会调用方法 toastPlugInNotification和toastPlugOutNotification

这两个方法从字面意思就知道是:挂在消息通知和挂出消息通知,源码如下:

private void toastPlugOutNotification(String title,String mng, int id){

        NotificationManager notificationManager = (NotificationManager) mCtx
            .getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.cancel(id);
        handleToastMessage(mng);
    }

    private void toastPlugInNotification(String title, int id){
        Notification notification = new Notification(com.android.internal.R.drawable.stat_sys_data_usb,
                title,System.currentTimeMillis());
        String contentTitle = title;
        String contextText = title;
        notification.setLatestEventInfo(mCtx, contentTitle, contextText, null);

        notification.defaults &= ~Notification.DEFAULT_SOUND;
        notification.flags = Notification.FLAG_AUTO_CANCEL;

        NotificationManager notificationManager = (NotificationManager) mCtx
            .getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(id, notification);

        handleToastMessage(title);
    }

其实到这里解决消息通知的方法就有很多了,你可以在AudioManagerPolicy.java搜索这两个方法,只要调用了这两个方法,就统统注释了就可以了,但是我在此的 做法是去研究这段代码,这两个代码内都有方法handleToastMessage,而这个方法如下:

 private void handleToastMessage(String message){
        if(mHandler == null) return;
        Message mng = mHandler.obtainMessage();
        mng.obj = message;
        mHandler.sendMessage(mng);//发送消息
    }

然后去找mHandler如下:

private void toastMessage(String message){//产生Toast,并喷发出来
        Toast.makeText(mCtx, message, Toast.LENGTH_LONG).show();
    }
 private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg){
            String message = (String)msg.obj;
            //toastMessage(message);//屏蔽这个Toast的喷发
        }
    };

因此我们就可以找到着个最内层的一句话,Toast.makeText(mCtx, message, Toast.LENGTH_LONG).show(); 屏蔽掉,所有的相关音频输入的消息通知都没有了

猜你喜欢

转载自blog.csdn.net/hubbybob1/article/details/81203425