Call Recording in Android 10 is not working without using Accessibility Service ,So here i define you how it is working.
First you have to add permissions in Menifest.xml file like below.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.dv_callrecording_android10">
<uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
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>
<service
android:name=".MyService"
android:label="@string/app_name"
android:enabled="true"
android:exported="true"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data android:name="android.accessibilityservice" android:resource="@xml/accessibility_service_config" />
</service>
</application>
</manifest>
Then make xml folder under res folder name is accessibility_service_config.xml
<?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:packageNames="test.demo.com.tests"
android:accessibilityEventTypes="typeAllMask"
android:accessibilityFlags="flagRetrieveInteractiveWindows|flagReportViewIds|flagIncludeNotImportantViews"
android:accessibilityFeedbackType="feedbackAllMask"
android:notificationTimeout="100"
android:canRetrieveWindowContent="true"
/>
Then Make MyService.java for Accessibility Service like below , Also define your service in Menifest.xml file
import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.media.AudioDeviceInfo;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Build;
import android.os.Handler;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.widget.FrameLayout;
import java.io.IOException;
import androidx.core.app.NotificationCompat;
import static com.dv_callrecording_android10.MainActivity.fileName;
import static com.dv_callrecording_android10.MainActivity.recorder;
public class MyService extends AccessibilityService {
public static final String LOG_TAG_S = "MyService:";
WindowManager windowManager;
@SuppressLint("RtlHardcoded")
@Override
public void onCreate() {
super.onCreate();
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
Log.i("start Myservice","MyService");
startForegroundService();
}
@Override
public void onAccessibilityEvent(AccessibilityEvent event) {
Log.e(LOG_TAG_S, "Event :"+event.getEventType());
}
@Override
public void onInterrupt() {
}
@Override
protected void onServiceConnected() {
System.out.println("onServiceConnected");
//==============================Record Audio while Call received===============//
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
FrameLayout layout = new FrameLayout(this);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE| WindowManager.LayoutParams.FLAG_FULLSCREEN |
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE|
WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS|
WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP;
windowManager.addView(layout, params);
layout.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.e(LOG_TAG_S, "Window view touched........:");
return true;
}
});
//==============To Record Audio wile Call received=================
AccessibilityServiceInfo info = new AccessibilityServiceInfo();
info.eventTypes = AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED;
info.eventTypes= AccessibilityEvent.TYPES_ALL_MASK;
info.feedbackType = AccessibilityServiceInfo.FEEDBACK_ALL_MASK;
info.notificationTimeout = 100;
info.packageNames = null;
setServiceInfo(info);
try {
startRecordingA();
} catch (Exception e) {
e.printStackTrace();
}
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// This method will be executed once the timer is over
//stopRecording();
stopRecordingA();
}
}, 30000);
}
private void startRecordingA() {
recorder = new MediaRecorder();
// This must be needed sourcea
recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_RECOGNITION);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setOutputFile(fileName);
//recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.HE_AAC);
recorder.setAudioEncodingBitRate(48000);
} else {
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
recorder.setAudioEncodingBitRate(64000);
}
recorder.setAudioSamplingRate(16000);
try {
recorder.prepare();
} catch (IOException e) {
Log.e(LOG_TAG_S, "prepare() failed");
}
recorder.start();
}
private void stopRecordingA() {
Log.e(LOG_TAG_S, "stop recording");
recorder.stop();
recorder.release();
recorder = null;
}
public static final String CHANNEL_ID = "MyAccessibilityService";
private void startForegroundService() {
createNotificationChannel();
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("recording Service")
.setContentText("Start")
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel serviceChannel = new NotificationChannel(
CHANNEL_ID,
"Recording Service Channel",
NotificationManager.IMPORTANCE_DEFAULT
);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(serviceChannel);
}
}
}
And then in MainActivity.java like below ,
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.Toast;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
public static final String LOG_TAG = "AudioRecordTest";
private static final int REQUEST_RECORD_AUDIO_PERMISSION = 200;
public static String fileName = null;
private RecordButton recordButton = null;
public static MediaRecorder recorder = null;
private PlayButton playButton = null;
public static MediaPlayer player = null;
// Requesting permission to RECORD_AUDIO
private boolean permissionToRecordAccepted = false;
private String [] permissions = {Manifest.permission.RECORD_AUDIO};
Context mContext;
boolean isbbTrue = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fileName = getExternalCacheDir().getAbsolutePath();
fileName += "/dv_recodringaudio.3gp";
ActivityCompat.requestPermissions(MainActivity.this, permissions, REQUEST_RECORD_AUDIO_PERMISSION);
mContext = MainActivity.this;
Intent openSettings = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
LinearLayout ll = new LinearLayout(this);
recordButton = new RecordButton(MainActivity.this);
ll.addView(recordButton,
new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
0));
playButton = new PlayButton(MainActivity.this);
ll.addView(playButton,
new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT,
0));
setContentView(ll);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case REQUEST_RECORD_AUDIO_PERMISSION:
permissionToRecordAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
break;
}
if (!permissionToRecordAccepted ) finish();
}
private void onRecord(boolean start) {
if (start) {
startserviceD();
} else {
}
}
private void onPlay(boolean start) {
if (start) {
startPlaying();
} else {
stopPlaying();
}
}
private void startPlaying() {
player = new MediaPlayer();
try {
player.setDataSource(fileName);
player.prepare();
player.start();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}
}
private void stopPlaying() {
player.release();
player = null;
}
class RecordButton extends androidx.appcompat.widget.AppCompatButton {
boolean mStartRecording = true;
OnClickListener clicker = new OnClickListener() {
public void onClick(View v) {
/* Toast.makeText(mContext,"Click....",Toast.LENGTH_SHORT).show();
try {
isbbTrue = MyService.isAccessibilitySettingsOn(mContext);
} catch (Exception e) {
e.printStackTrace();
}
Toast.makeText(mContext,"Service :"+isbbTrue,Toast.LENGTH_SHORT).show();*/
onRecord(mStartRecording);
if (mStartRecording) {
setText("Stop recording");
} else {
setText("Start recording");
}
mStartRecording = !mStartRecording;
}
};
public RecordButton(Context ctx) {
super(ctx);
setText("Start recording");
setOnClickListener(clicker);
}
}
class PlayButton extends androidx.appcompat.widget.AppCompatButton {
boolean mStartPlaying = true;
OnClickListener clicker = new OnClickListener() {
public void onClick(View v) {
onPlay(mStartPlaying);
if (mStartPlaying) {
setText("Stop playing");
} else {
setText("Start playing");
}
mStartPlaying = !mStartPlaying;
}
};
public PlayButton(Context ctx) {
super(ctx);
setText("Start playing");
setOnClickListener(clicker);
}
}
@Override
public void onStop() {
super.onStop();
}
public void startserviceD(){
// Permission for Manifest.permission.SYSTEM_ALERT_WINDOW in Android M
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(getApplicationContext())) {
Intent openSettings = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
openSettings.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(openSettings);
}
}
// Code to start the Service
startService(new Intent(getApplication(), MyService.class));
Toast.makeText(MainActivity.this,"Enable allow Service from Accessbility,Trye,and 30 Sec Recording will Start....",Toast.LENGTH_SHORT).show();
Toast.makeText(MainActivity.this,"After 30 Sec Play Recording File, you can make Call between it",Toast.LENGTH_SHORT).show();
}
}
And run this app . Audio recording file is found you in your mobile's Internel Storage/Android/data/your app package name/audio.mp3
This is the call recording in Android 10 Q version with Accessibility Service.
Android Call Recording in Android 10 Q
Good and valuable job! Thanks!
ReplyDeleteThank you.
Delete