This is my Receiver Class where i'm getting phone state of both incoming and outgoing calls

public class MyBroadcastReceiver extends BroadcastReceiver {

    private static final String TAG = "MyBroadcastReceiver";
    //The receiver will be recreated whenever android feels like it.  We need a static variable to remember data between instantiations

    private String phoneIncomingNumber = "";
    private String PhoneState = "";
    private String Message = "";
    private MediaRecorder recorder;

    Context context;

    //Call Recording varibales
    private static final String AUDIO_RECORDER_FILE_EXT_3GP = ".3gp";
    private static final String AUDIO_RECORDER_FILE_EXT_MP4 = ".mp3";
    private static final String AUDIO_RECORDER_FOLDER = "Recordings";

    Uri audiouri;
    ParcelFileDescriptor file;
    AudioManager audioManager;
    private int currentFormat = 0;
    private int output_formats[] = { MediaRecorder.OutputFormat.MPEG_4,
            MediaRecorder.OutputFormat.THREE_GPP };
    private String file_exts[] = { AUDIO_RECORDER_FILE_EXT_MP4,
            AUDIO_RECORDER_FILE_EXT_3GP };

    //The receiver will be recreated whenever android feels like it.  We need a static variable to remember data between instantiations
    private static int lastState = TelephonyManager.CALL_STATE_IDLE;
    private static Date callStartTime;
    private static boolean isIncoming;
    private static String savedNumber;  //because the passed incoming is only valid in ringing


    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO: This method is called when the BroadcastReceiver is receiving
//        Registering service
        context.startService(new Intent(context, MyService.class));

//      Getting Call Details
        String stateStr = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
        phoneIncomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);

        Log.d("Call Status1", "Number1: " + phoneIncomingNumber + ":STATE : " + stateStr);

        if (intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL")) {
            savedNumber = intent.getStringExtra("android.intent.extra.PHONE_NUMBER");
        } else {
            phoneIncomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
            int state = 0;
            if (stateStr.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
                state = TelephonyManager.CALL_STATE_IDLE;
            } else if (stateStr.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
                state = TelephonyManager.CALL_STATE_OFFHOOK;
                startRecording(getRecordFileName(phoneIncomingNumber), context);
            } else if (stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
                state = TelephonyManager.CALL_STATE_RINGING;
            }
            onCallStateChanged(context, state, phoneIncomingNumber);
        }
    }

    //Derived classes should override these to respond to specific events of interest
    protected void onIncomingCallStarted(Context ctx, String number, Date start) {

        Message = "Call from : \"+number+\" on DATE \"+start+\" started";
        Log.d("Call Status", "INCOMING CALL STARTED");

    }

    protected void onOutgoingCallStarted(Context ctx, String number, Date start) {
        Message = "Call to : \"+number+\" on DATE \"+start+\" started";
        Log.d("Call Status", "OUTGOING CALL STARTED to :" + number);
        PhoneState = "OFFHOOK";

    }

    protected void onIncomingCallEnded(Context ctx, String number, Date start, Date end) {
        Log.d("Call Status", "INCOMING CALL ENDED");
        Message = "Call from : \"+number+\" on DATE \"+start+\" ended";
        stopRecording();
    }

    protected void onOutgoingCallEnded(Context ctx, String number, Date start, Date end) {
        Message = "Call to : \"+number+\" on DATE \"+start+\" ended";
        Log.d("Call Status", "OUTGOING CALL ENDED");
        stopRecording();
    }

    protected void onMissedCall(Context ctx, String number, Date start) {
        Message = "Missed call : \"+number+\" on DATE \"+start+\"";
        Log.d("Call Status", "MISSED CALL");
      
    }

    //Deals with actual events

    //Incoming call-  goes from IDLE to RINGING when it rings, to OFFHOOK when it's answered, to IDLE when its hung up
    //Outgoing call-  goes from IDLE to OFFHOOK when it dials out, to IDLE when hung up
    public void onCallStateChanged(Context context, int state, String number) {
        Log.d("Call", "Number: " + number);
        if (lastState == state) {
            //No change, debounce extras
            return;
        }
        switch (state) {
            case TelephonyManager.CALL_STATE_RINGING:
                isIncoming = true;
                callStartTime = new Date();
                savedNumber = number;
                PhoneState = "RINGING";
                onIncomingCallStarted(context, number, callStartTime);
                break;
            case TelephonyManager.CALL_STATE_OFFHOOK:
                //Transition of ringing->offhook are pickups of incoming calls.  Nothing done on them
                if (lastState != TelephonyManager.CALL_STATE_RINGING) {
                    isIncoming = false;
                    callStartTime = new Date();
                    PhoneState = "OFFHOOK";
                    onOutgoingCallStarted(context, phoneIncomingNumber, callStartTime);
                }
                break;
            case TelephonyManager.CALL_STATE_IDLE:
                //Went to idle-  this is the end of a call.  What type depends on previous state(s)
                if (lastState == TelephonyManager.CALL_STATE_RINGING) {
                    //Ring but no pickup-  a miss
                    PhoneState = "IDLE";
                    onMissedCall(context, phoneIncomingNumber, callStartTime);
                } else if (isIncoming) {
                    PhoneState = "INCOMING CALL ENDED";
                    onIncomingCallEnded(context, phoneIncomingNumber, callStartTime, new Date());
                } else {
                    PhoneState = "OUTGOING CALL ENDED";
                    onOutgoingCallEnded(context, phoneIncomingNumber, callStartTime, new Date());
                }
                break;
        }
        lastState = state;
    }

 

    private MediaRecorder.OnErrorListener errorListener = new MediaRecorder.OnErrorListener() {
        @Override
        public void onError(MediaRecorder mr, int what, int extra) {
            Toast.makeText(context,
                    "Error: " + what + ", " + extra, Toast.LENGTH_SHORT).show();
        }
    };

    private MediaRecorder.OnInfoListener infoListener = new MediaRecorder.OnInfoListener() {
        @Override
        public void onInfo(MediaRecorder mr, int what, int extra) {
            Toast.makeText(context,
                            "Warning: " + what + ", " + extra, Toast.LENGTH_SHORT)
                    .show();
        }
    };


    //    Recording Audio
    private void startRecording(String fileName, Context ctx) {
        Log.d("Call Status", "Inside");
        ContentValues values = new ContentValues(4);
        values.put(MediaStore.Audio.Media.TITLE, fileName);
        values.put(MediaStore.Audio.Media.DATE_ADDED, (int) (System.currentTimeMillis() / 1000));
        values.put(MediaStore.Audio.Media.MIME_TYPE, "audio/mpeg");
        values.put(MediaStore.Audio.Media.RELATIVE_PATH, "Music/Recordings/");

        audiouri = ctx.getContentResolver().insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, values);
        Log.d("Call Status", "Call Status: "+audiouri);
        try {
            file = ctx.getContentResolver().openFileDescriptor(audiouri, "w");
        } catch (Exception e) {
            Log.d("Call Status", "File Error"+e);
        }


        audioManager = (AudioManager) ctx.getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
        audioManager.setMode(AudioManager.MODE_IN_CALL);
//        audioManager.setSpeakerphoneOn(true);

        recorder = new MediaRecorder();
        recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION);
        recorder.setOutputFormat(output_formats[currentFormat]);
        //recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        recorder.setOutputFile(file.getFileDescriptor());
        recorder.setOnErrorListener(errorListener);
        recorder.setOnInfoListener(infoListener);

        try {
            recorder.prepare();
            recorder.start();
        } catch (IllegalStateException e) {
            Log.e("REDORDING :: ",e.getMessage());
            e.printStackTrace();
        } catch (IOException e) {
            Log.e("REDORDING :: ",e.getMessage());
            e.printStackTrace();
        }
         }

    private void stopRecording() {
//        audioManager.setSpeakerphoneOn(false);

        try{
            if (null != recorder) {
                recorder.stop();
                recorder.reset();
                recorder.release();

                recorder = null;
            }
        }catch(Exception stopException){
            Log.d("Exce",stopException+"");
        }
    }

    private String getRecordFileName(String phoneNumber) {
        // Generate a unique file name based on the phone number and the current time
        String timeStamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        return phoneNumber + "_" + timeStamp + ".wav";
    }

}

My Service Class to run receiver as a forground service

public class MyService extends Service {

private static final int SERVICE_NOTIFICATION_ID =2 ;
private static final String CHANNEL_ID = "PhoneStateModule";

public MyService() {
}

private Handler handler = new Handler();
private Runnable runnableCode = new Runnable() {
    @Override
    public void run() {
        try{
            handler.postDelayed(this, 2000);
        }catch (Exception ex){
            Log.d("Error",ex+"");
        }

    }
};

private void createNotificationChannel() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        int importance = NotificationManager.IMPORTANCE_DEFAULT;
        NotificationChannel channel = new NotificationChannel(CHANNEL_ID, "PhoneStateModule", importance);
        channel.setDescription("CHANEL DESCRIPTION");
        NotificationManager notificationManager = getSystemService(NotificationManager.class);
        notificationManager.createNotificationChannel(channel);
    }
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    this.handler.post(this.runnableCode); // Starting the interval
    // Turning into a foreground service
    createNotificationChannel(); // Creating channel for API 26+
    Intent notificationIntent = new Intent(this, MainActivity.class);
    PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT|PendingIntent.FLAG_MUTABLE);
    Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("Phone Recording Service")
            .setContentText("Running…")
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentIntent(contentIntent)
            .setOngoing(true)
            .build();
    startForeground(SERVICE_NOTIFICATION_ID, notification);
    return START_STICKY;
}

@Override
public IBinder onBind(Intent intent) {
    // TODO: Return the communication channel to the service.
   return null;
}

}

Can anyone help me with the issue facing, I am using device with android 10 and am not getting the recordings, even if the recording is saved inside folder I'm not getting any audio.

0

There are 0 best solutions below