Android SIP软电话,通话录音,VoIP电话,linphone电话

各位大佬好,我又来记笔记了~~

公司又提新需求了,需要开发一个能通话(呼叫客户的手机号码)自动录音的模块。刚接触这个是蒙的,经过一番研究,可实现通话录音的方式大致有下面几种:

  方案一:点击拨号时,调用系统的拨号功能,同时应用内注册通话广播,检测通话状态,接通、挂断来决定开始录音和停止录音,录音可以使用MediaRecorder和AudioRecorder。

        优缺点:实现方式简单,开发容易。但是缺点也有,受Android系统版本影响大,每次打开应用都需要进设置页面开启“无障碍”权限才能录音(目前Android8.0的不用),录音对方的声音较小。不过适当优化下 也能用。

 方案二:刷机,获取设备root权限,把应用修改为“系统”级别应用,就可以正常录制通话(跟手机自带的通话录音一样),具体怎么刷机自行百度

         优缺点:参考手机自带的通话录音功能,效果还是非常好的,但是只能用于一些定制的设备。如正常的一些手机、pad用户就不得行了,因为客户不可能会去刷机来兼容我们的应用。

 方案三: SIP软电话,集成第三方的VoIP网络电话,实现网络通话并录音,效果也还行。如linphone框架,也是本文要讲的。

      优缺点:使用SIP软电话,前提是要有SIP服务器(网上有很多免费的SIP服务器),后面说具体的实现逻辑,通话录音还可以,双方声音都比较大。

 方案四:呼叫时,点击开启系统的录音进行录制,返回我们应用时,把系统的录音文件拿出来展示或上传服务器,哈哈 最笨的方案了,适配主流的机型(前提是手机支持通话录音,获取录音文件的路径各机型适配一下)。

      优缺点:兼容性差,不推荐了。

          

 本文主要记录的是 《方案一》 和《方案三》,下面 只介绍关键步骤,详见文末demo

   方案一:

      大致步骤:   1、权限申请

                        2、注册广播,开启服务进行录音

                        3、开始拨号 

                        4、查看通话记录,播放录音文件

                     

需要的权限,项目全部权限在这了,有的可能用不到。

<uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.RECORD_AUDIO" /><uses-permission android:name="android.permission.READ_PHONE_STATE" /><uses-permission android:name="android.permission.FOREGROUND_SERVICE" /><uses-permission android:name="android.permission.CALL_PHONE" /><uses-permission android:name="android.permission.WRITE_CALL_LOG" /><uses-permission android:name="android.permission.READ_CALL_LOG" /><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /><uses-permissionandroid:name="android.permission.MANAGE_EXTERNAL_STORAGE"tools:ignore="ScopedStorage" /><uses-permissionandroid:name="android.permission.MODIFY_PHONE_STATE"tools:ignore="ProtectedPermissions" /><uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /><uses-permissionandroid:name="android.permission.BIND_ACCESSIBILITY_SERVICE"tools:ignore="ProtectedPermissions" /><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

注册广播:

AndroidManifest文件添加 PhoneStateListener和MediaRecorderService

<receiverandroid:name=".callrecord.PhoneStateListener"android:enabled="true"android:exported="true"><intent-filter><action android:name="android.intent.action.PHONE_STATE" /></intent-filter>
</receiver><serviceandroid:name=".callrecord.MediaRecorderService"android:enabled="true"android:exported="true"android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"><intent-filter><action android:name="android.accessibilityservice.AccessibilityService" /></intent-filter><meta-dataandroid:name="android.accessibilityservice"android:resource="@xml/accessibility_service_config" /></service>

PhoneStateListener类:

/*** @ClassName PhoneStateListener* @Description TODO* @Author HK.W   通话录音广播* @Date 2022/10/15 22:13*/
public class PhoneStateListener extends BroadcastReceiver {private static final String TAG = "通话状态监听";static boolean incoming_flag;private Context mContext;@Overridepublic void onReceive(Context ctx, Intent intent) {mContext = ctx;String event = intent.getStringExtra(TelephonyManager.EXTRA_STATE);Log.d(TAG, "通话状态:state:" + event);if (event.equals(TelephonyManager.EXTRA_STATE_RINGING)) {Log.d(TAG, "-->RINGING--正在响铃");incoming_flag = true;} else if (event.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {Log.d(TAG, "-->EXTRA_STATE_OFFHOOK--正在通话");startService(ctx, intent);} else if (event.equals(TelephonyManager.EXTRA_STATE_IDLE)) {Log.d(TAG, "-->EXTRA_STATE_IDLE--电话挂断--空闲");ctx.stopService(new Intent(ctx, MediaRecorderService.class));//AudioRecordUtil.getInstance().stopRecording();AudioRecorder.getInstance().stopRecord();}}private void startService(Context context, Intent intent) {Log.d(TAG, "-->startService--打开服务-检查权限");String[] PERMISSIONS = {Manifest.permission.RECORD_AUDIO,Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};if (hasPermissions(context, PERMISSIONS)) {Log.d(TAG, "-->startService--打开服务-权限已打开");intent.setClass(context, MediaRecorderService.class);intent.putExtra("incoming_flag", incoming_flag);if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {context.startForegroundService(intent);} else {context.startService(intent);}} else {Log.d(TAG, "-->startService--打开服务-权限未打开");}}public static boolean hasPermissions(Context context, String... permissions) {if (context != null && permissions != null) {for (String permission : permissions) {if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {return false;}}}return true;}
}

MediaRecorderService类:

public class MediaRecorderService extends AccessibilityService {private static final String TAG = "通话状态监听";NotificationManagerCompat notificationManager;private boolean incoming_flag;private String number;@Overridepublic void onInterrupt() {}@Overridepublic void onAccessibilityEvent(AccessibilityEvent accessibilityEvent) {}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {if (intent != null) {Log.d(TAG, "-->startService--进入录音服务");number = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);incoming_flag = intent.getBooleanExtra("incoming_flag", false);String phone = SpUtils.getInstance().getString(this, "phone", "Unknown");AudioRecorder.getInstance().createDefaultAudio(phone);AudioRecorder.getInstance().startRecord(new RecordStreamListener() {@Overridepublic void recordOfByte(byte[] data, int begin, int end) {Log.d(TAG, "data:" + data);}});notificationBuilder();}return START_STICKY;}private void notificationBuilder() {Log.d(TAG, "-->startService--录音服务--打开通知栏,让服务进入前台,避免被杀掉");if (Build.VERSION.SDK_INT >= 26) {String CHANNEL_ID = "my_channel_01";NotificationChannel channel = new NotificationChannel(CHANNEL_ID, "Channel title",NotificationManager.IMPORTANCE_DEFAULT);((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID).setContentTitle("").setContentText("").build();startForeground(1, notification);} else {NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "CHANNEL_ID").setSmallIcon(R.mipmap.ic_launcher).setContentTitle("Recording").setPriority(NotificationCompat.PRIORITY_DEFAULT).setOngoing(true);notificationManager = NotificationManagerCompat.from(this);notificationManager.notify(1, builder.build());}}@Overridepublic void onDestroy() {super.onDestroy();Log.d(TAG, "-->startService--录音服务--服务被销毁---onDestroy()");stopRecording();}private void stopRecording() {Log.d(TAG, "-->startService--录音服务--停止录音");if (Build.VERSION.SDK_INT >= 26) {stopForeground(true);} else {NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);notificationManager.cancel(1);}}
}

功能相关页面截图:

 拨号:

 private void callPhone(String phoneNumber) {Intent intentPhone = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + phoneEt.getText().toString()));startActivity(intentPhone);}

 开始录音

 @Overridepublic int onStartCommand(Intent intent, int flags, int startId) {if (intent != null) {Log.d(TAG, "-->startService--进入录音服务");number = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);incoming_flag = intent.getBooleanExtra("incoming_flag", false);String phone = SpUtils.getInstance().getString(this, "phone", "Unknown");//开始录音AudioRecorder.getInstance().createDefaultAudio(phone);AudioRecorder.getInstance().startRecord(new RecordStreamListener() {@Overridepublic void recordOfByte(byte[] data, int begin, int end) {Log.d(TAG, "data:" + data);}});notificationBuilder();}return START_STICKY;}

停止录音:

public class PhoneStateListener extends BroadcastReceiver {private static final String TAG = "通话状态监听";static boolean incoming_flag;private Context mContext;@Overridepublic void onReceive(Context ctx, Intent intent) {mContext = ctx;String event = intent.getStringExtra(TelephonyManager.EXTRA_STATE);Log.d(TAG, "通话状态:state:" + event);if (event.equals(TelephonyManager.EXTRA_STATE_RINGING)) {Log.d(TAG, "-->RINGING--正在响铃");incoming_flag = true;} else if (event.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {Log.d(TAG, "-->EXTRA_STATE_OFFHOOK--正在通话");startService(ctx, intent);} else if (event.equals(TelephonyManager.EXTRA_STATE_IDLE)) {Log.d(TAG, "-->EXTRA_STATE_IDLE--电话挂断--空闲");ctx.stopService(new Intent(ctx, MediaRecorderService.class));//AudioRecordUtil.getInstance().stopRecording();//为什么不在服务里面停止录音?有的机型挂断电话后没有马上销毁服务,所以在状态这里直接停止录音AudioRecorder.getInstance().stopRecord();}}

本文demo 录音文件保存在根目录anyi.phone/record 文件下。

获取通话记录对应的录音文件:

 /*** 获取录音文件路径 --通话记录*/private List<RecordBean> getLocalRecord() {List<ContactsBean> contacts = readContacts();List<RecordBean> list = new ArrayList<>();JSONArray allFiles = getAllFiles("", "wav");//Log.d("allFiles", "allFiles:" + allFiles.toString());if (null != allFiles) {for (int i = 0; i < allFiles.length(); i++) {try {JSONObject jsonObject = allFiles.getJSONObject(i);String name = jsonObject.getString("name");String path = jsonObject.getString("path");String[] split1 = name.split("-");if (split1.length > 0) {RecordBean recordBean = new RecordBean();recordBean.setNumber(split1[0]);recordBean.setPath(path);recordBean.setDate(new SimpleDateFormat("HH:mm").format(new Date(Long.parseLong(split1[1]))));if (contacts.size() > 0) {for (ContactsBean b : contacts) {if (split1[0].equals(b.getNumber())) {recordBean.setCachedName(b.getName());}}} else {recordBean.setCachedName("未知");}list.add(recordBean);}} catch (JSONException e) {e.printStackTrace();}}Collections.reverse(list);return list;}return list;}public static JSONArray getAllFiles(String dirPath, String _type) {dirPath = "/storage/emulated/0/anyi.phone/record/";File f = new File(dirPath);if (!f.exists()) {//判断路径是否存在return null;}File[] files = f.listFiles();if (files == null) {//判断权限return null;}JSONArray fileList = new JSONArray();for (File _file : files) {//遍历目录if (_file.isFile() && (_file.getName().endsWith("amr")||_file.getName().endsWith("wav"))) {String _name = _file.getName();String filePath = _file.getAbsolutePath();//获取文件路径String fileName = _file.getName().substring(0, _name.length() - 4);//获取文件名try {JSONObject _fInfo = new JSONObject();_fInfo.put("name", fileName);_fInfo.put("path", filePath);fileList.put(_fInfo);} catch (Exception e) {}} else if (_file.isDirectory()) {//查询子目录//getAllFiles(_file.getAbsolutePath(), _type);} else {}}return fileList;}

播放:

 private void initPlay() {mediaPlayer = new MediaPlayer();}private void startPlay(String path) {if (TextUtils.isEmpty(path)) {Toast.makeText(this, "文件路径不存在", Toast.LENGTH_LONG).show();return;}mediaPlayer.reset(); //清空里面的其他歌曲try {mediaPlayer.setDataSource(path);mediaPlayer.prepare(); //准备就绪mediaPlayer.start(); //开始唱歌} catch (IOException e) {e.printStackTrace();}}

方案三,SIP通话录音,linphone 为例,只调试了音频通话,视频通话未调试

 前提准备

准备一个SIP服务器地址和一个账号密码。可以自己搭建SIP服务器或者网上找一个SIP服务器注册 一个账号密码。下面是网上找的资源,没试过。因为我们公司是购买的有SIP话机服务器的。

免费sip账号注册地址 http://serweb.iptel.org/user/reg/index.php
免费sip服务器   iptel.org
免费sip客户端 http://www.fring.com

        

正文:

1、把linphone-sdk-android-4.3.0-beta.aar包放在项目libs,提取码: nq6q。

2、配置文件注册服务:

 <serviceandroid:name=".linphone.LinphoneService"android:enabled="true"android:exported="true"android:label="@string/app_name" />

3.在启动页 启动SIP相关服务,

启动页:

public class LauncherActivity extends AppCompatActivity {private static final String TAG = "XXPermissions";private Handler mHandler;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_launcher);mHandler = new Handler();}@Overrideprotected void onStart() {super.onStart();getPermission();}private void getPermission() {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {XXPermissions.with(this).permission(allPermission).request(new OnPermissionCallback() {@Overridepublic void onGranted(List<String> permissions, boolean all) {if (all) {if (LinphoneService.isReady()) {onServiceReady();} else {startService(new Intent().setClass(LauncherActivity.this, LinphoneService.class));new ServiceWaitThread().start();}}}@Overridepublic void onDenied(List<String> permissions, boolean never) {if (never) {Log.e(TAG, "onDenied:被永久拒绝授权,请手动授予权限 ");} else {Log.e(TAG, "onDenied: 权限获取失败");}}});} else {if (LinphoneService.isReady()) {onServiceReady();} else {startService(new Intent().setClass(LauncherActivity.this, LinphoneService.class));new ServiceWaitThread().start();}}}private void onServiceReady() {Intent intent = new Intent();intent.setClass(LauncherActivity.this, MainActivity.class);if (getIntent() != null && getIntent().getExtras() != null) {intent.putExtras(getIntent().getExtras());}intent.setAction(getIntent().getAction());intent.setType(getIntent().getType());startActivity(intent);}private class ServiceWaitThread extends Thread {public void run() {while (!LinphoneService.isReady()) {try {sleep(30);} catch (InterruptedException e) {throw new RuntimeException("waiting thread sleep() has been interrupted");}}mHandler.post(new Runnable() {@Overridepublic void run() {onServiceReady();}});}}
}

首页activity  onResume()方法中检测 账号是否注册,未注册跳转到注册页面:

@Overrideprotected void onResume() {super.onResume();Log.d(TAG, "onResume()");LinphoneService.getCore().addListener(mCoreListener);ProxyConfig proxyConfig = LinphoneService.getCore().getDefaultProxyConfig();if (proxyConfig != null) {updateLed(proxyConfig.getState());} else {startActivity(new Intent(this, ConfigureAccountActivity.class));}}

注册:

/*** 注册*/private void configureAccount() {mAccountCreator.setUsername(mUsername.getText().toString());mAccountCreator.setDomain(mDomain.getText().toString());mAccountCreator.setPassword(mPassword.getText().toString());switch (mTransport.getCheckedRadioButtonId()) {case R.id.transport_udp:mAccountCreator.setTransport(TransportType.Udp);break;case R.id.transport_tcp:mAccountCreator.setTransport(TransportType.Tcp);break;case R.id.transport_tls:mAccountCreator.setTransport(TransportType.Tls);break;}ProxyConfig cfg = mAccountCreator.createProxyConfig();LinphoneService.getCore().setDefaultProxyConfig(cfg);}public void listener(){
mCoreListener = new CoreListenerStub() {/*** 监听注册是否成功* @param core* @param cfg* @param state* @param message*/@Overridepublic void onRegistrationStateChanged(Core core, ProxyConfig cfg, RegistrationState state, String message) {registerPr.setVisibility(View.GONE);if (state == RegistrationState.Ok) {finish();} else if (state == RegistrationState.Failed) {Toast.makeText(ConfigureAccountActivity.this, "Failure: " + message, Toast.LENGTH_LONG).show();}}};
}

注册成功开始通话:

 private void sipCallIng() {Core core = LinphoneService.getCore();Address addressToCall = core.interpretUrl(phoneEt.getText().toString());CallParams params = core.createCallParams(null);params.enableVideo(false);if (addressToCall != null) {String filePath = AudioRecordUtil.getInstance().getFilename(phoneEt.getText().toString(), ".wav");android.util.Log.d("linPhone--", "开始呼叫--号码--filePath = " + filePath);//重要:通话前需要设置录音文件,要不不会录音,params.setRecordFile(filePath);core.inviteAddressWithParams(addressToCall, params);Intent intent = new Intent(getActivity(), CallActivity.class);intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);startActivity(intent);}}

开始录音:

/*** ---通话接通--开始录音*/private void startRecord() {android.util.Log.d("linPhone--", "接通或者拒绝");android.util.Log.d("linPhone--", "开始录音:录音地址:" + core.getRecordFile());call.startRecording();}

停止录音:

 /*** ---通话挂断--停止录音--销毁页面*/private void stopRecord() {android.util.Log.d("linPhone--", "挂断,未接");android.util.Log.d("linPhone--", "停止录音");call.stopRecording();//停止录音finish();//挂断电话-销毁页面}

后面就是拿到录音文件播放,-----具体就不说了,

研究SIP也用了大量时间和下载了很多大佬的资源,也花费了很多积分,

so  想要demo的朋友们也希望支持一下,

demo需要积分下载,具体多少由平台分配。

本文demo成功实现了两种主流的通话录音方式,应该是能满足你们的业务需求的,

demo传送门---

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/52344.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GB28181语音对讲

GB28181语音对讲 前段时间将音频对讲功能集成我们国标平台&#xff0c;踩些坑记录下来&#xff0c;方便后来人。 GB28181-2016语音对讲没有明确规定流程&#xff0c;各厂家按自己的理解进行实现。先说海康的&#xff0c;毕竟海康 是这个行业的龙头老大。海康摄像机接收音频的…

基于sip的语音对讲 Demo

SipVoice 项目地址&#xff1a;SipVoice 该 demo 基于https://github.com/VoiSmart/pjsip-android 项目实现语音对讲对讲功能。 还有很多关于 pjsip 的功能和 API 请移步 pjsip-android。 正常运行该 Demo &#xff0c;需要已有 Sip 服务端&#xff0c;Constants 中配置 ip …

讯飞星火认知大模型可以内测了

以ChatGPT为代表的AI产品层出不穷&#xff0c;每天在社交媒体都可以看到AI领域的新成果&#xff0c;写文章、写代码、绘画&#xff0c;各种功能让人大呼神奇。 4月24日&#xff0c;讯飞星火认知大模型来了。只需一个指令“懂你所言&#xff0c;答你所问&#xff0c;创你所需&a…

tabBar不显示

微信小程序tabBar不显示 在尝试小程序开发时&#xff0c;tabBar这个是个非常常见的组件&#xff0c;但是今天在进行开发时&#xff0c;设置了TabBarb并没有显示&#xff0c;被这个问题困扰了近半小时&#xff0c;现在将排查问题后所得到的经验记录下来。 首先 如果tabBar不显示…

微信小程序底部导航栏tabBar及不显示问题解决记录

1&#xff0c;首先需要新建一个目录images来保存相关导航图标&#xff0c;如下图&#xff1a; 2&#xff0c;在app.json文件中对tabBar进行配置&#xff08;注意字母大小写不要写错&#xff0c;图片路径不要写错&#xff09; "tabBar": {"color": "…

来自一个曾经200斤现在140斤程序员的减肥成功经验(包含个人认为相对安全的饮食法推荐)

一、何为减肥 作为名词&#xff1a;减去体内蓄积的脂肪 作为动词&#xff1a;控制日常饮食摄入&#xff0c;搭配好日常饮食结构&#xff0c;打开热量赤字&#xff08;缺口&#xff09;&#xff0c;持续一定时间后达到减少体内脂肪&#xff0c;降低体脂率的效果。 二、吃与动 …

基于Android的健康食谱菜谱app

《[含文档PPT源码等]精品基于UniappSSM实现的Android的健康食谱交流app[包运行成功]》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程等 软件开发环境及开发工具&#xff1a; 开发语言&#xff1a;Java 框架&#xff1a;ssm JDK版本&#xff1a;JDK…

菜谱分享APP/基于android菜谱分享系统

摘 要 随着现代生活水平的不断提升&#xff0c;人们越来越关注健康,关注美食,大部分人都希望吃得美味的同时也要吃得健康,所以,有的人喜欢在家自己动手制作美食,但是却缺少这方面的资讯来源。菜谱分享APP是一个使用Hbuildex作为手机客户端和后台服务系统的开发环境, MySQL作为后…

03 做毕业设计,前端部分你需要掌握的6个核心技能

其实前端新手如果想要自己实现一套毕业设计项目并非简单的事,因为之前很多人一直还停留在知识点的阶段,而且管理系统和C端网站都需要开发,但现在需要点连成线了。所以在启动项目开发之前呢,针对前端部分,我列举一些非常必要的前端核心技能,希望你已掌握。 《Vue + Sprin…

ChatGPT引领AI新浪潮,AIGC商业化启

ChatGPT引领AI技术新一轮热潮&#xff0c;预示着NLP技术有望迅速进入平民化应用时代。ChatGPT引领AI新浪潮&#xff0c;AIGC商业化启_up.pdf: https://url39.ctfile.com/f/2501739-805099732-b78420?p2096 (访问密码: 2096) 参考文献&#xff1a; [1]ChatGPT引领AI新浪潮&…

躺不平了?600万青年人失业,这届年轻人该何去何从?(文末附招聘岗位)

“中国主要的问题不是就业数量&#xff0c;而是就业的质量问题&#xff0c;即就业率高而工资收入低&#xff0c;普遍存在工作中‘穷人’的问题。” 一、青年失业率持续走高 6月15日上午&#xff0c;国新办举行新闻发布会&#xff0c;国家统计局新闻发言人、国民经济综合统计司…

散户交易潮流不火了?国际券商希望零售热潮将永久持续下去

今年 1 月&#xff0c;33 岁的 KlipC 用户 Miki Lok 在新加坡以500美元的价格在Robinhood券商上买入了游戏零售商GameStop和影院连锁AMC的股票&#xff0c;在今年早些时候的社区交易狂潮中&#xff0c;投机性购买狂潮使不受欢迎的股票飙升至创纪录高点。 Lok 女士回忆说&#x…

上海亚商投顾: 沪指冲高回落 高景气赛道股回归

前言&#xff1a;无惧大盘大跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 市场情绪 沪指今日横盘震荡&#xff0c;创业板指低开高走&#xff0c;盘中涨超1.7%&#xff0c;科创50一度涨近3%&#xff0c;赛道股持续…

锦秋基金臧天宇:大模型时代,AI创业者如何掘金

“2011年, A16Z 创始合伙人 Marc Andreesse 提出Software is eating the world,在我们步入 AI新时代的节点&#xff0c;或许我们可以说, AI is eating the world。” 在火山引擎和锦秋基金联合主办的「2023 AI逐梦者计划」活动中&#xff0c;锦秋基金执行董事臧天宇表示。 在…

查理芒格语录

要点 要有逆向思维 客观分析 每天读书 但要给每天读书要个固定的时间段&#xff0c;让自己不受打扰&#xff0c;高效的读书 如果你想要获得你要的东西&#xff0c;那就让自己配得上它。信任、成功和钦佩都是靠努力获得的 联系&#xff1a;怎样找到好的伴侣&#xff1f; 提升…

巴菲特、芒格的傲慢与偏见

(图片来源于网络) 5月1号&#xff0c;伯克希尔哈撒韦公司股东会&#xff0c;巴菲特和芒格出席。会上有人通过主持人提问&#xff0c;说现在加密货币市场市值已经突破2万亿美元&#xff0c;问巴菲特和芒格二位是否仍然认为加密货币是“无用的人造黄金”&#xff1f;巴菲特耍了个…

计算机读书笔记1500,《罗辑思维》读书笔记1500字

《罗辑思维》像一扇打开新世界的大门&#xff0c;能不断刷新我对世界的理解。 罗胖总是反向提出事情的别样观点&#xff0c;乍看之下&#xff0c;违背常识&#xff0c;仔细一琢磨&#xff0c;还真的有几份道理&#xff01; 读完《罗辑思维》认知篇&#xff0c;想和大家分析下书…

如何读书和选书?

上面这个公号「涩郎」&#xff0c;是我的一个备用号&#xff0c;为了防止万一哪天大号失联&#xff0c;平时一周我也会发三篇左右的我的思考&#xff0c;读书笔记&#xff0c;认知感悟等文章&#xff0c;带领大家一起探索精神与财务自由之路。 前几天我在年终总结的时候&#x…

查理芒格思维模型 —— 费马帕斯卡系统

前言 查理元思维模型最早的提倡者&#xff0c;他说这样的好晶体&#xff0c;至少能数出一百个&#xff0c;它们都来自「重要学科的重要结论」 查理芒格提 在《穷查理宝典》中提到了有100多个思维模型&#xff0c; 他尤其强调了&#xff1a; 数学&#xff1a;复利原理、排列组…

《查理·芒格的智慧:投资的格栅理论》读书笔记

Charles Munger查理芒格是一位思考者&#xff0c;把自己的深度思考和投资相结合&#xff0c;取得了非凡的成就。幸运的是&#xff0c;他把自己的思考方式告诉大家&#xff0c;同时也分享了他自己的格栅模型。学习那些基础学科的基础理论&#xff0c;并将它们应用到自己的实践中…