●録音する

まずはマイクとファイルを使用する権限を取得する必要があります。
MyApplication?\app\src\main\AndroidManifest.xml
この場所にある、AndroidManifest.xmlファイルを開きます。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="jp.myapplication">
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

赤文字の部分を追加してマイクとファイル書き込みの権限をアプリに与えます。

しかし、Android6.0以降は、Dangerous Permissionのためこのままでは動きません。
アプリ起動後にユーザーに権限を許可してもらう必要があります。
対応するには下の方を見てください。


■最低限の録音をするアプリ

録音データはMPEG4形式でファイルに保存されます。

public class MainActivity extends AppCompatActivity {
    private android.media.MediaRecorder mediarec=null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    @Override
    protected void onResume() {
        super.onResume();
        if(null==mediarec) {
            startRec(android.os.Environment.getExternalStorageDirectory().getPath() + "/test.mp4");
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        android.content.Context context=getApplicationContext();
        android.os.PowerManager pm = (android.os.PowerManager) getSystemService(context.POWER_SERVICE);
        if(pm.isScreenOn()){
            //画面がONの場合はホームボタンや戻るボタンなどで終了した。
            stopRec();
        }
    }
    private void startRec(String fileName){
        mediarec = new android.media.MediaRecorder();
        mediarec.setAudioSource(android.media.MediaRecorder.AudioSource.MIC);
        mediarec.setOutputFormat(android.media.MediaRecorder.OutputFormat.MPEG_4);
        mediarec.setAudioEncoder(android.media.MediaRecorder.AudioEncoder.DEFAULT);
        mediarec.setOutputFile(fileName);
        try{
            mediarec.prepare();
            mediarec.start();
        } catch(Exception e){
            android.content.Context context = getApplicationContext();
            android.widget.Toast t=android.widget.Toast.makeText(context,e.toString(), android.widget.Toast.LENGTH_LONG);
            t.show();
        }
    }

    void stopRec(){
        mediarec.stop();
        mediarec.reset();
        mediarec.release();
        mediarec=null;
    }
}


■Dangerous Permissionに対応する

android6.0以前はインストールする段階で権限を取得できましたが、android6.0では実行時に権限を取得するように改良されました。
そのため、Android6.0以降は権限を取得するコードを書かないと例外が発生してしまい、このままでは動きません。
実行時に権限を取得するには次のようにする必要があります。

final int REQUEST_ID = 99;
void permission(String permission){
    //android version 6.0以上の場合は実行する必要がある
    if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M){
        //権限が許可されてない場合には
        if (android.support.v4.app.ActivityCompat.checkSelfPermission(this, permission)!= android.content.pm.PackageManager.PERMISSION_GRANTED){
            //権限をリクエストする
            android.support.v4.app.ActivityCompat.requestPermissions(this, new String[]{permission}, REQUEST_ID);
        }
    }
}
//権限のリクエスト結果が返ってくる
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    if (requestCode == REQUEST_ID) {
        if (grantResults[0] != android.content.pm.PackageManager.PERMISSION_GRANTED) {
            //権限が許可されなかった
            android.widget.Toast.makeText(getApplicationContext(), "権限が許可されませんでした\nアプリを終了します。", android.widget.Toast.LENGTH_LONG).show();
            //アプリを終了する
            finish();
            moveTaskToBack(true);
        }
    }
}
上の関数を追加した上で、権限を取得するタイミングで、次の関数をコールします

        //ファイル読み書きの権限をユーザーから取得する
        permission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
        //マイク使用の権限をユーザーから取得する
        permission(android.Manifest.permission.RECORD_AUDIO);

android6.0以上で関数をコールするとこのようなメッセージボックスが表示されます。



機能を使用する前に権限を取得することによりandroid6.0以降でも例外が発生しなくなります。


■録音機能を利用して作ったプログラム

▼画面の電源が消えてから10分間録音するサービス

自動起動でサービスが起動するようにしておけば、電源ボタンのON・OFFでいつでも録音できるはずです。

public class test_service extends android.app.Service
{
    private android.media.MediaRecorder mediarec=null;
    java.util.Timer timer=null;
    @Override
    public android.os.IBinder onBind(android.content.Intent intent)
    {
        return null;
    }

    @Override
    public void onCreate(){
        //サービスが作成され初期化された時に一度だけ動く部分
        getApplicationContext().registerReceiver(new android.content.BroadcastReceiver() {
            @Override
            public void onReceive(android.content.Context context, android.content.Intent intent) {
                //画面の電源ON
                stop();
            }
        }, new android.content.IntentFilter(android.content.Intent.ACTION_SCREEN_ON));

        getApplicationContext().registerReceiver(new android.content.BroadcastReceiver() {
            @Override
            public void onReceive(android.content.Context context, android.content.Intent intent) {
                //画面の電源OFF
                start();
            }
        }, new android.content.IntentFilter(android.content.Intent.ACTION_SCREEN_OFF));
    }

    @Override
    public int onStartCommand(android.content.Intent intent, int flags, int startId) {
        //startServiceでサービスを起動させた場合に毎度動く部分
        android.content.Context context=getApplicationContext();
        android.os.PowerManager pm = (android.os.PowerManager) getSystemService(context.POWER_SERVICE);

        if(!pm.isScreenOn()){
            //画面がoffの場合
            start();
        }else{
            stop();
        }

        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        //サービスが破棄される時の後始末
        stopRec();
        //再起動する
        //startService(new android.content.Intent(this, this.getClass()));
    }

    private void start(){
        if(null==mediarec) {
            java.io.File dir = new java.io.File(android.os.Environment.getExternalStorageDirectory().getPath()+"/rec");
            if (!dir.exists()){
                dir.mkdir();
            }
            java.util.Calendar calendar = java.util.Calendar.getInstance();
            startRec(android.os.Environment.getExternalStorageDirectory().getPath() + "/rec/"+ calendar.getTimeInMillis() + ".mp4");
        }
        java.util.TimerTask timertask = new java.util.TimerTask(){
            @Override
            public void run() {
                stopRec();
                timer=null;
            }
        };
        if(null!=timer){
            timer.cancel();
            timer.purge();
        }
        timer = new java.util.Timer(true);
        timer.schedule(timertask,(long)1000*60*10);
    }

    private void stop(){
        if(null!=timer){
            timer.cancel();
            timer.purge();
            timer=null;
        }
        stopRec();
    }
    private void startRec(String fileName){
        mediarec = new android.media.MediaRecorder();
        mediarec.setAudioSource(android.media.MediaRecorder.AudioSource.MIC);
        mediarec.setOutputFormat(android.media.MediaRecorder.OutputFormat.MPEG_4);
        mediarec.setAudioEncoder(android.media.MediaRecorder.AudioEncoder.DEFAULT);
        mediarec.setOutputFile(fileName);
        try{
            mediarec.prepare();
            mediarec.start();
        } catch(Exception e){
            android.content.Context context = getApplicationContext();
            android.widget.Toast t=android.widget.Toast.makeText(context,e.toString(), android.widget.Toast.LENGTH_LONG);
            t.show();
        }
    }

    void stopRec(){
        if(null!=mediarec) {
            mediarec.stop();
            mediarec.reset();
            mediarec.release();
            mediarec = null;
        }
    }
}


▲トップページ > android