检查麦克风是否正在被其他应用程序使用?

时间:2018-10-06 06:28:19

标签: android mediarecorder android-mediarecorder

启动音频/屏幕录像机并打开录音机应用程序并启动服务以记录崩溃时的音频时遇到错误。
我不知道为什么会遇到此问题。< / p>

logcat的错误跟踪

E/AndroidRuntime: FATAL EXCEPTION: main
        Process: com.example.babluboro.urecorder, PID: 10632
        java.lang.RuntimeException: Unable to start service com.example.babluboro.urecorder.RecordingService@dee6d7d with Intent { cmp=com.example.babluboro.urecorder/.RecordingService }: java.lang.IllegalStateException
            at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:4145)
            at android.app.ActivityThread.access$2400(ActivityThread.java:229)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1924)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:148)
            at android.app.ActivityThread.main(ActivityThread.java:7325)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
         Caused by: java.lang.IllegalStateException
            at android.media.MediaRecorder._start(Native Method)
            at android.media.MediaRecorder.start(MediaRecorder.java:943)
            at com.example.babluboro.urecorder.RecordingService.startRecording(RecordingService.java:126)
            at com.example.babluboro.urecorder.RecordingService.onStartCommand(RecordingService.java:97)
            at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:4128)

Recording Service.java

public class RecordingService extends Service {

    private String mFileName = null;
    private String mFilePath = null;

    private static final String LOG_TAG = "RecordingService";

    private MediaRecorder mRecorder = null;
    private DBHelper mDatabase;

    private long mStartingTimeMillis = 0;
    private long mElapsedMillis = 0;

    private static final String PREF_RECORDING_KEY = "prefs_recording_channel";
    private String channelType;


    @Override
    public void onCreate() {
        super.onCreate();
        mDatabase = new DBHelper(getApplicationContext());
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        channelType = sharedPreferences.getString(PREF_RECORDING_KEY, "0");
    }

    class MyServiceBinder extends Binder{

        public RecordingService getService(){
            return RecordingService.this;
        }
    }

    private IBinder mBinder = new MyServiceBinder();

    @Override
    public void onRebind(Intent intent) {
        super.onRebind(intent);
    }


    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        Intent notificationIntent = new Intent(this, RecordingActivity.class);
        notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        notificationIntent.setAction(Intent.ACTION_MAIN);
        notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
        PendingIntent pendingIntent = PendingIntent.getActivity(this,
                0, notificationIntent, 0);

        Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
                .setContentTitle("URecorder")
                .setContentText("recording...")
                .setSmallIcon(R.drawable.microphone_icon)
                .setContentIntent(pendingIntent)
                .build();

        startForeground(1, notification);
        startRecording();

        return START_STICKY;
    }


    public void startRecording() {
        setFileNameAndPath();
        mRecorder = new MediaRecorder();
        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mRecorder.setOutputFile(mFilePath);
        mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);

        if(channelType == "Mono") {
            mRecorder.setAudioChannels(AudioFormat.CHANNEL_IN_MONO);
        }

        if(channelType == "Stereo"){
            mRecorder.setAudioChannels(AudioFormat.CHANNEL_IN_MONO);
        }

        if (MySharedPreferences.getPrefHighQuality(this)) {
            mRecorder.setAudioSamplingRate(44100);
            mRecorder.setAudioEncodingBitRate(96000);
        }

        try {
            mRecorder.prepare();
            mRecorder.start();
            mStartingTimeMillis = System.currentTimeMillis();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void setFileNameAndPath(){

        int count = 0;
        File f;

        do{
            count++;

            mFileName = "URecorder " + (mDatabase.getCount() + count)  + ".m4a";
            mFilePath = Environment.getExternalStorageDirectory().getAbsolutePath();
            mFilePath += "/URecorder/" + mFileName;

            f = new File(mFilePath);

        }while (f.exists() && !f.isDirectory());
    }

    @Override
    public void onDestroy() {
        super.onDestroy();

        if (mRecorder != null) {
            Toast.makeText(this, "Recording Canceled", Toast.LENGTH_SHORT).show();
            mRecorder.stop();
            mRecorder.release();
            File file = new File(mFilePath);
            file.delete();
            mRecorder = null;
        }
    }


    public void stopRecording() {
        mRecorder.stop();
        mElapsedMillis = (System.currentTimeMillis() - mStartingTimeMillis);
        mRecorder.release();
        mRecorder = null;
        Toast.makeText(this,"Recording Saved ", Toast.LENGTH_SHORT).show();

        try {
            mDatabase.addRecording(mFileName, mFilePath, mElapsedMillis);

        } catch (Exception e){
            Log.e(LOG_TAG, "exception", e);
        }
    }
}

RecordingActivity

    toolbar_main = (android.support.v7.widget.Toolbar) findViewById(R.id.toolbar_main);

        setSupportActionBar(toolbar_main);

        folderBtn = (ImageView) findViewById(R.id.folder_button);

        waveHeader = (MultiWaveHeader) findViewById(R.id.waveHeader);
        circleSpinner = (ImageView) findViewById(R.id.circleSpinner);
        pulsator = (PulsatorLayout) findViewById(R.id.pulsator);
        recordBtn = (ImageButton) findViewById(R.id.recordBtn);
        chronometer_id = (Chronometer) findViewById(R.id.chronometer_id);

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

                Intent intent = new Intent(RecordingActivity.this, AllRecordsActivity.class);
                startActivity(intent);
                chronometer_id.setBase(SystemClock.elapsedRealtime());

            }
        });

        recordBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                onRecord(uStartRecording);
                uStartRecording = !uStartRecording;
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.settings_popup, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.settings:

                Intent intent = new Intent(RecordingActivity.this, SettingsActivity.class);
                startActivity(intent);
                return true;

            default:
                return super.onOptionsItemSelected(item);
        }
    }


    private void onRecord(boolean start) {

        serviceIntent = new Intent(this, RecordingService.class);
        recordBtn.setImageResource(R.drawable.save_icon);

        if (start) {

            bindService();
            folderBtn.setVisibility(View.GONE);
            pulsator.setCount(2);
            pulsator.start();

            File folder = new File(Environment.getExternalStorageDirectory() + "/URecorder");
            if (!folder.exists()) {
                folder.mkdir();
            }

            startService(serviceIntent);
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

            rotation = AnimationUtils.loadAnimation(this, R.anim.rotate);
            rotation.setFillAfter(true);
            circleSpinner.startAnimation(rotation);

            chronometer_id.setBase(SystemClock.elapsedRealtime());
            chronometer_id.start();

        } else {
            folderBtn.setVisibility(View.VISIBLE);
            recordingService.stopRecording();
            unbindService(serviceConnection);
            isServiceBound = false;
            stopService(serviceIntent);
            recordBtn.setImageResource(R.drawable.microphone_icon);
            timeWhenPaused = chronometer_id.getBase() - SystemClock.elapsedRealtime();
            circleSpinner.clearAnimation();
            pulsator.stop();
            chronometer_id.stop();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
            getPermissionToRecordAudio();
        }
    }

    public void getPermissionToRecordAudio() {

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED
                || ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
                || ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){

            if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)
                    || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE)
                    || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {

                AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setMessage("Record, Read & Write External Storage permissions are required to do the task.");
                builder.setTitle("Please grant those permissions");
                builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        ActivityCompat.requestPermissions(
                                RecordingActivity.this,
                                new String[]{
                                        Manifest.permission.RECORD_AUDIO,
                                        Manifest.permission.READ_EXTERNAL_STORAGE,
                                        Manifest.permission.WRITE_EXTERNAL_STORAGE
                                },
                                RECORD_AUDIO_REQUEST_CODE
                        );
                    }
                });
                builder.setNeutralButton("Cancel",null);
                AlertDialog dialog = builder.create();
                dialog.show();

            }else{

                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

                    requestPermissions(new String[]{Manifest.permission.RECORD_AUDIO,
                                    Manifest.permission.READ_EXTERNAL_STORAGE,
                                    Manifest.permission.WRITE_EXTERNAL_STORAGE},
                                    RECORD_AUDIO_REQUEST_CODE);
                }
            }
        }
    }

    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        if (requestCode == RECORD_AUDIO_REQUEST_CODE) {
            if (grantResults.length == 3 &&
                    grantResults[0] == PackageManager.PERMISSION_GRANTED
                    && grantResults[1] == PackageManager.PERMISSION_GRANTED
                    && grantResults[2] == PackageManager.PERMISSION_GRANTED){

                Toast.makeText(this, "Permissions granted.", Toast.LENGTH_SHORT).show();
            }
        } else {

            Toast.makeText(this,"Permissions denied.",Toast.LENGTH_SHORT).show();

        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        if(isServiceBound != false) {
            unbindService(serviceConnection);
            isServiceBound = false;
            stopService(serviceIntent);
        }
    }

    private void bindService(){

        if(serviceConnection == null){
            serviceConnection = new ServiceConnection() {
                @Override
                public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
                    RecordingService.MyServiceBinder myServiceBinder=(RecordingService.MyServiceBinder)iBinder;
                    recordingService = myServiceBinder.getService();
                    isServiceBound = true;
                }

                @Override
                public void onServiceDisconnected(ComponentName componentName) {
                    isServiceBound=false;
                }
            };
        }

        bindService(serviceIntent ,serviceConnection, Context.BIND_AUTO_CREATE);

    }
}

当我尝试在我的应用中开始记录时,会发生这种情况。
链接如下。

showing my app crash

2 个答案:

答案 0 :(得分:0)

我认为您没有使用麦克风的权限。 尝试将其添加到清单文件中。

这是权限:

<uses-permission android:name="android.permission.RECORD_AUDIO" />

按如下所示将其放置在应用程序块之外:

...
    </application>

    <uses-permission android:name="android.permission.RECORD_AUDIO" /> 
</manifest>

然后,您可以使用this code检查麦克风是否正在使用:

private boolean validateMicAvailability(){
    Boolean available = true;
    AudioRecord recorder =
            new AudioRecord(MediaRecorder.AudioSource.MIC, 44100,
                    AudioFormat.CHANNEL_IN_MONO,
                    AudioFormat.ENCODING_DEFAULT, 44100);
    try{
        if(recorder.getRecordingState() != AudioRecord.RECORDSTATE_STOPPED ){
            available = false;

        }

        recorder.startRecording();
        if(recorder.getRecordingState() != AudioRecord.RECORDSTATE_RECORDING){
            recorder.stop();
            available = false;

        }
        recorder.stop();
    } finally{
        recorder.release();
        recorder = null;
    }

    return available;
}

答案 1 :(得分:0)

这是怎么做的

AudioManager am = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);

if(am.getMode()==AudioManager.MODE_IN_COMMUNICATION){
   //Mic is in use
}

MODE_NORMAL -> You good to go. Mic not in use
MODE_RINGTONE -> Incoming call. The phone is ringing
MODE_IN_CALL -> A phone call is in progress
MODE_IN_COMMUNICATION -> The Mic is being used by another application