From 1a571684ca26c3945eab72c7857dca9b434a76a7 Mon Sep 17 00:00:00 2001 From: ZhanGSKen Date: Sat, 29 Mar 2025 09:13:14 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=B1=BB=E5=BA=93=E7=89=88?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contacts/build.gradle | 14 ++-- contacts/build.properties | 6 +- contacts/src/main/AndroidManifest.xml | 3 + .../java/cc/winboll/studio/contacts/App.java | 4 +- .../winboll/studio/contacts/MainActivity.java | 37 +++------ .../contacts/activities/SettingsActivity.java | 36 ++------- .../adapters/PhoneConnectRuleAdapter.java | 9 +-- .../phonecallui/PhoneCallService.java | 78 +++++++++++++++++++ 8 files changed, 114 insertions(+), 73 deletions(-) diff --git a/contacts/build.gradle b/contacts/build.gradle index d1614c5..547e522 100644 --- a/contacts/build.gradle +++ b/contacts/build.gradle @@ -18,18 +18,18 @@ def genVersionName(def versionName){ } android { - compileSdkVersion 30 - buildToolsVersion "30.0.3" + compileSdkVersion 32 + buildToolsVersion "32.0.0" defaultConfig { applicationId "cc.winboll.studio.contacts" - minSdkVersion 26 + minSdkVersion 24 targetSdkVersion 29 versionCode 1 // versionName 更新后需要手动设置 // 项目模块目录的 build.gradle 文件的 stageCount=0 // Gradle编译环境下合起来的 versionName 就是 "${versionName}.0" - versionName "1.0" + versionName "15.2" if(true) { versionName = genVersionName("${versionName}") } @@ -75,7 +75,7 @@ dependencies { implementation 'androidx.fragment:fragment:1.1.0' implementation 'com.google.android.material:material:1.4.0' - implementation 'cc.winboll.studio:libappbase:2.1.5' - implementation 'cc.winboll.studio:libapputils:9.4.4' - implementation 'cc.winboll.studio:libaes:7.6.12' + implementation 'cc.winboll.studio:libappbase:15.2.0' + implementation 'cc.winboll.studio:libapputils:15.2.0' + implementation 'cc.winboll.studio:libaes:15.2.0' } diff --git a/contacts/build.properties b/contacts/build.properties index ce3c44e..7e535ea 100644 --- a/contacts/build.properties +++ b/contacts/build.properties @@ -1,8 +1,8 @@ #Created by .winboll/winboll_app_build.gradle -#Wed Mar 19 11:09:14 HKT 2025 +#Sat Mar 29 01:09:07 GMT 2025 stageCount=22 libraryProject= -baseVersion=1.0 +baseVersion=15.2 publishVersion=1.0.21 -buildCount=0 +buildCount=5 baseBetaVersion=1.0.22 diff --git a/contacts/src/main/AndroidManifest.xml b/contacts/src/main/AndroidManifest.xml index f92009a..156e436 100644 --- a/contacts/src/main/AndroidManifest.xml +++ b/contacts/src/main/AndroidManifest.xml @@ -33,6 +33,9 @@ + + + ruleList; - @Override - public APPInfo getAppInfo() { - return null; - } - @Override public AppCompatActivity getActivity() { return this; @@ -82,21 +77,6 @@ public class SettingsActivity extends AppCompatActivity implements IWinBollActiv return TAG; } - @Override - public Toolbar initToolBar() { - return findViewById(R.id.activitymainToolbar1); - } - - @Override - public boolean isAddWinBollToolBar() { - return true; - } - - @Override - public boolean isEnableDisplayHomeAsUp() { - return false; - } - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -105,10 +85,8 @@ public class SettingsActivity extends AppCompatActivity implements IWinBollActiv // 初始化工具栏 mToolbar = findViewById(R.id.activitymainToolbar1); setSupportActionBar(mToolbar); - if (isEnableDisplayHomeAsUp()) { - // 显示后退按钮 - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - } + // 显示后退按钮 + getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setSubtitle(getTag()); mswMainService = findViewById(R.id.sw_mainservice); @@ -232,7 +210,7 @@ public class SettingsActivity extends AppCompatActivity implements IWinBollActiv Intent intent = new Intent(this, UnitTestActivity.class); startActivity(intent); } - + public void onAddNewConnectionRule(View view) { Rules.getInstance(this).getPhoneBlacRuleBeanList().add(new PhoneConnectRuleModel()); Rules.getInstance(this).saveRules(); @@ -267,8 +245,8 @@ public class SettingsActivity extends AppCompatActivity implements IWinBollActiv } }).start(); } - - + + public void onSearchBoBullToonPhone(View view) { TomCat tomCat = TomCat.getInstance(this); diff --git a/contacts/src/main/java/cc/winboll/studio/contacts/adapters/PhoneConnectRuleAdapter.java b/contacts/src/main/java/cc/winboll/studio/contacts/adapters/PhoneConnectRuleAdapter.java index f225c36..8483c55 100644 --- a/contacts/src/main/java/cc/winboll/studio/contacts/adapters/PhoneConnectRuleAdapter.java +++ b/contacts/src/main/java/cc/winboll/studio/contacts/adapters/PhoneConnectRuleAdapter.java @@ -19,14 +19,11 @@ import androidx.recyclerview.widget.RecyclerView; import cc.winboll.studio.contacts.R; import cc.winboll.studio.contacts.beans.PhoneConnectRuleModel; import cc.winboll.studio.contacts.dun.Rules; +import cc.winboll.studio.contacts.views.LeftScrollView; +import cc.winboll.studio.libappbase.dialogs.YesNoAlertDialog; +import com.hjq.toast.ToastUtils; import java.util.ArrayList; import java.util.List; -import android.widget.LinearLayout; -import android.view.MotionEvent; -import android.widget.HorizontalScrollView; -import cc.winboll.studio.contacts.views.LeftScrollView; -import com.hjq.toast.ToastUtils; -import cc.winboll.studio.libapputils.view.YesNoAlertDialog; public class PhoneConnectRuleAdapter extends RecyclerView.Adapter { diff --git a/contacts/src/main/java/cc/winboll/studio/contacts/phonecallui/PhoneCallService.java b/contacts/src/main/java/cc/winboll/studio/contacts/phonecallui/PhoneCallService.java index 3786899..27b76d3 100644 --- a/contacts/src/main/java/cc/winboll/studio/contacts/phonecallui/PhoneCallService.java +++ b/contacts/src/main/java/cc/winboll/studio/contacts/phonecallui/PhoneCallService.java @@ -7,26 +7,52 @@ package cc.winboll.studio.contacts.phonecallui; * @see PhoneCallActivity * @see android.telecom.InCallService */ +import android.content.ContentResolver; +import android.database.Cursor; import android.media.AudioManager; +import android.media.MediaRecorder; +import android.net.Uri; import android.os.Build; +import android.provider.CallLog; import android.telecom.Call; import android.telecom.InCallService; +import android.telephony.TelephonyManager; import androidx.annotation.RequiresApi; import cc.winboll.studio.contacts.ActivityStack; import cc.winboll.studio.contacts.beans.RingTongBean; import cc.winboll.studio.contacts.dun.Rules; import cc.winboll.studio.libappbase.LogUtils; +import java.io.File; +import java.io.IOException; @RequiresApi(api = Build.VERSION_CODES.M) public class PhoneCallService extends InCallService { public static final String TAG = "PhoneCallService"; + MediaRecorder mediaRecorder; + private final Call.Callback callback = new Call.Callback() { @Override public void onStateChanged(Call call, int state) { super.onStateChanged(call, state); switch (state) { + case TelephonyManager.CALL_STATE_OFFHOOK: + { + long callId = getCurrentCallId(); + if (callId != -1) { + // 在这里可以对获取到的通话记录ID进行处理 + //System.out.println("当前通话记录ID: " + callId); + + // 电话接通,开始录音 + startRecording(callId); + } + break; + } + case TelephonyManager.CALL_STATE_IDLE: + // 电话挂断,停止录音 + stopRecording(); + break; case Call.STATE_ACTIVE: { break; } @@ -127,4 +153,56 @@ public class PhoneCallService extends InCallService { CALL_IN, CALL_OUT, } + + + private void startRecording(long callId) { + LogUtils.d(TAG, "startRecording(...)"); + mediaRecorder = new MediaRecorder(); + mediaRecorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL); + mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + mediaRecorder.setOutputFile(getOutputFilePath(callId)); + try { + mediaRecorder.prepare(); + mediaRecorder.start(); + } catch (IOException e) { + LogUtils.d(TAG, e, Thread.currentThread().getStackTrace()); + } + } + + private String getOutputFilePath(long callId) { + LogUtils.d(TAG, "getOutputFilePath(...)"); + // 设置录音文件的保存路径 + File file = new File(getExternalFilesDir(TAG), String.format("call_%d.mp4", callId)); + return file.getAbsolutePath(); + } + + private void stopRecording() { + LogUtils.d(TAG, "stopRecording()"); + if (mediaRecorder != null) { + mediaRecorder.stop(); + mediaRecorder.release(); + mediaRecorder = null; + } + } + + private long getCurrentCallId() { + LogUtils.d(TAG, "getCurrentCallId()"); + ContentResolver contentResolver = getApplicationContext().getContentResolver(); + Uri callLogUri = Uri.parse("content://call_log/calls"); + String[] projection = {"_id", "number", "call_type", "date"}; + String selection = "call_type = " + CallLog.Calls.OUTGOING_TYPE + " OR call_type = " + CallLog.Calls.INCOMING_TYPE; + String sortOrder = "date DESC"; + + try { + Cursor cursor = contentResolver.query(callLogUri, projection, selection, null, sortOrder); + if (cursor != null && cursor.moveToFirst()) { + return cursor.getLong(cursor.getColumnIndex("_id")); + } + } catch (Exception e) { + LogUtils.d(TAG, e, Thread.currentThread().getStackTrace()); + } + + return -1; + } }