java.lang.RuntimeException:启动失败

Posted

技术标签:

【中文标题】java.lang.RuntimeException:启动失败【英文标题】:java.lang.RuntimeException: start failed 【发布时间】:2014-11-17 12:59:47 【问题描述】:

我正在尝试使用 MediaRecorder 在我的一项活动中录制音频。部分代码如下所示。

File file = new File(AppConstants.MSGS_DIR, filename);
MediaRecorder recorder = new MediaRecorder();
recorder.setAudiosource(AudioSource.MIC);
recorder.setOutputFormat(OutputFormat.THREE_GPP);
recorder.setAudioEncoder(AudioEncoder.AMR_WB);
recorder.setOutputFile(file.getAbsolutePath());
try 
    recorder.prepare();
    recorder.start();
 catch (IOException e) 
    System.out.println("Exception: " + e.getMessage());

我在清单文件中授予了以下权限。

<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />

但在 recorder.start() 行我得到了运行时异常。 Logcat 显示以下错误消息。

09-23 15:47:54.462: E/AndroidRuntime(8697): FATAL EXCEPTION: main
09-23 15:47:54.462: E/AndroidRuntime(8697): java.lang.RuntimeException: Unable to start activity ComponentInfocom.mypackage/com.mypackage.RecordingActivity: java.lang.RuntimeException: start failed.
09-23 15:47:54.462: E/AndroidRuntime(8697):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2250)
09-23 15:47:54.462: E/AndroidRuntime(8697):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2300)
09-23 15:47:54.462: E/AndroidRuntime(8697):     at android.app.ActivityThread.access$600(ActivityThread.java:144)
09-23 15:47:54.462: E/AndroidRuntime(8697):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1295)
09-23 15:47:54.462: E/AndroidRuntime(8697):     at android.os.Handler.dispatchMessage(Handler.java:99)
09-23 15:47:54.462: E/AndroidRuntime(8697):     at android.os.Looper.loop(Looper.java:150)
09-23 15:47:54.462: E/AndroidRuntime(8697):     at android.app.ActivityThread.main(ActivityThread.java:5162)
09-23 15:47:54.462: E/AndroidRuntime(8697):     at java.lang.reflect.Method.invokeNative(Native Method)
09-23 15:47:54.462: E/AndroidRuntime(8697):     at java.lang.reflect.Method.invoke(Method.java:525)
09-23 15:47:54.462: E/AndroidRuntime(8697):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:744)
09-23 15:47:54.462: E/AndroidRuntime(8697):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
09-23 15:47:54.462: E/AndroidRuntime(8697):     at dalvik.system.NativeStart.main(Native Method)
09-23 15:47:54.462: E/AndroidRuntime(8697): Caused by: java.lang.RuntimeException: start failed.
09-23 15:47:54.462: E/AndroidRuntime(8697):     at android.media.MediaRecorder.start(Native Method)
09-23 15:47:54.462: E/AndroidRuntime(8697):     at com.mypackage.RecordingActivity.startRecording(RecordingActivity.java:169)
09-23 15:47:54.462: E/AndroidRuntime(8697):     at com.mypackage.RecordingActivity.onCreate(RecordingActivity.java:107)
09-23 15:47:54.462: E/AndroidRuntime(8697):     at android.app.Activity.performCreate(Activity.java:5288)
09-23 15:47:54.462: E/AndroidRuntime(8697):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
09-23 15:47:54.462: E/AndroidRuntime(8697):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2214)

尝试了与 *** 中的错误相对应的问题,但无法从中得出有效的答案。请检查这个并帮助我在代码中出了什么问题。

仅供参考>这段代码仅在特定设备中失败。我是否缺少任何其他权限?

【问题讨论】:

***.com/a/10497885/1777090 @MysticMagic 我正在寻找与宽度和高度无关的录音。您提出的答案是用于视频录制:) 这段代码仅在特定设备中失败 - 您可能希望包含有关这些设备的更多详细信息。比如,它们的平台版本是什么? AudioEncoder.AMR_WB 仅适用于 API10。 @shoerat:代码在设备中不起作用: 索尼爱立信 4.0.3 版,华硕 Genfone 4.3 版。代码在 Moto-g 4.4.4 中运行良好,操作系统版本 4.4.2 的注 2。 @shoerat AppConstants.MSGS_DIR = Environment.getExternalStorageDirectory().getPath() + "/MYAppFolder/";文件名是一些随机字符串。我能够创建文件夹和文件(该文件夹中的 fileName0 成功但无法向其中写入任何数据。 【参考方案1】:

很少有设备不支持,因为它们不支持 3GP 格式以及 AudioEncoder.AMR_WB 编码。点击here查看支持的格式。

请使用下面的代码来支持最大数量的设备。

recorder.setOutputFormat(OutputFormat.MPEG_4);
recorder.setAudioEncoder(AudioEncoder.AAC);

【讨论】:

安卓2.2怎么样? 安卓M怎么样?? 是否会使其默认适用于所有设备?像下面的 recorder.setOutputFormat(OutputFormat.DEFAULT); recorder.setAudioEncoder(AudioEncoder.DEFAULT);【参考方案2】:

如果您使用的是 Api 23,请先授予权限,然后开始录制

     private boolean checkAndRequestPermissions() 
            int permissionSendMessage = ContextCompat.checkSelfPermission(this,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE);
            int locationPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO);
            List<String> listPermissionsNeeded = new ArrayList<>();
            if (locationPermission != PackageManager.PERMISSION_GRANTED) 
                listPermissionsNeeded.add(Manifest.permission.RECORD_AUDIO);
            
            if (permissionSendMessage != PackageManager.PERMISSION_GRANTED) 
                listPermissionsNeeded.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
            
            if (!listPermissionsNeeded.isEmpty()) 
                ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]),REQUEST_ID_MULTIPLE_PERMISSIONS);
                return false;
            
            return true;
        
      @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) 
        Log.d("TAG", "Permission callback called-------");
        switch (requestCode) 
            case REQUEST_ID_MULTIPLE_PERMISSIONS: 

                Map<String, Integer> perms = new HashMap<>();
                // Initialize the map with both permissions
                perms.put(Manifest.permission.WRITE_EXTERNAL_STORAGE, PackageManager.PERMISSION_GRANTED);
                perms.put(Manifest.permission.RECORD_AUDIO, PackageManager.PERMISSION_GRANTED);
                // Fill with actual results from user
                if (grantResults.length > 0) 
                    for (int i = 0; i < permissions.length; i++)
                        perms.put(permissions[i], grantResults[i]);
                    // Check for both permissions
                    if (perms.get(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
                            && perms.get(Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED) 
                        Log.d("TAG", "sms & location services permission granted");
                        // process the normal flow

                        pager = (ViewPager) findViewById(R.id.pager);
                        pager.setAdapter(new MyAdapter(getSupportFragmentManager()));
                        tabs = (PagerSlidingTabStrip) findViewById(R.id.tabs);
                        tabs.setViewPager(pager);
                        //else any one or both the permissions are not granted
                     else 
                        Log.d("TAG", "Some permissions are not granted ask again ");
                        //permission is denied (this is the first time, when "never ask again" is not checked) so ask again explaining the usage of permission
//                        // shouldShowRequestPermissionRationale will return true
                        //show the dialog or snackbar saying its necessary and try again otherwise proceed with setup.
                        if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) ||
                                ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) 
                            showDialogOK("SMS and Location Services Permission required for this app",
                                    new DialogInterface.OnClickListener() 
                                        @Override
                                        public void onClick(DialogInterface dialog, int which) 
                                            switch (which) 
                                                case DialogInterface.BUTTON_POSITIVE:
                                                    checkAndRequestPermissions();
                                                    break;
                                                case DialogInterface.BUTTON_NEGATIVE:
                                                    // proceed with logic by disabling the related features or quit the app.
                                                    break;
                                            
                                        
                                    );
                        
                        //permission is denied (and never ask again is  checked)
                        //shouldShowRequestPermissionRationale will return false
                        else 
                            Toast.makeText(this, "Go to settings and enable permissions", Toast.LENGTH_LONG)
                                    .show();
                            //                            //proceed with logic by disabling the related features or quit the app.
                        
                    
                
            
        

    

    private void showDialogOK(String message, DialogInterface.OnClickListener okListener) 
        new AlertDialog.Builder(this)
                .setMessage(message)
                .setPositiveButton("OK", okListener)
                .setNegativeButton("Cancel", okListener)
                .create()
                .show();
    

【讨论】:

以上是关于java.lang.RuntimeException:启动失败的主要内容,如果未能解决你的问题,请参考以下文章

Android Studio 按钮导致崩溃

添加 ImageView 时应用程序崩溃?