Android应用调用sentMessage、phoneCall方法崩溃,附代码求解决方案
崩溃核心原因
- 点击事件响应逻辑不匹配:如果你是在布局文件
mylayout.xml中通过android:onClick属性指定点击call、sms控件触发sentMessage和phoneCall方法,系统只会在当前宿主MainActivity中查找这两个方法,你把方法定义在Adapter里,系统找不到就会直接抛出异常崩溃。
- 点击事件响应逻辑不匹配:如果你是在布局文件
- 变量名冲突:
MainActivity中已经全局声明了TextView call,sms,myphone;,但在onCreate方法中又重新定义了同名的局部变量List<String> call=new ArrayList<>();和List<String> sms=new ArrayList<>();,会导致变量引用异常,严重时会直接崩溃。
- 变量名冲突:
- 短信Intent配置错误:发送短信匹配
smsto:URI时,应该使用Intent.ACTION_SENDTO而非Intent.ACTION_SEND,配置错误会导致找不到响应的应用,部分机型会直接崩溃。
- 短信Intent配置错误:发送短信匹配
- 启动Activity缺少必要Flag:在Adapter中使用context启动Activity时,没有添加
Intent.FLAG_ACTIVITY_NEW_TASK标记,非Activity上下文启动Activity会直接抛出异常崩溃。
- 启动Activity缺少必要Flag:在Adapter中使用context启动Activity时,没有添加
- 逻辑无对应手机号绑定:当前拨打电话逻辑写死了号码123,发短信也没有绑定对应联系人的手机号,不符合业务逻辑的同时也可能出现参数异常。
修复方案
1. 修复MainActivity变量名冲突
修改onCreate中的列表变量名,避免和全局TextView重名:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listview=findViewById(R.id.listview); List<String> name=new ArrayList<>(); List<String> phone=new ArrayList<>(); // 把原来的call、sms改名为callList、smsList,避免和全局TextView重名 List<String> callList=new ArrayList<>(); List<String> smsList=new ArrayList<>(); myphone=findViewById(R.id.phone); List<Integer> img=new ArrayList<>(); img.add(R.drawable.img1); img.add(R.drawable.img2); img.add(R.drawable.img3); name.add("Ahmad"); name.add("Ali"); name.add("Riaz"); callList.add("call"); callList.add("call"); callList.add("call"); smsList.add("sms"); smsList.add("sms"); smsList.add("sms"); phone.add("03053424234"); phone.add("03453243432"); phone.add("03348586753"); // 构造Adapter时传修改后的列表 MyAdapter adapter=new MyAdapter(this,name,callList,smsList,img,phone); listview.setAdapter(adapter); }
2. 在Adapter的getView中绑定点击事件,删除xml中的android:onClick属性
直接在item渲染时给call、sms控件绑定点击监听器,直接调用对应逻辑,同时拿到当前联系人的手机号:
@NonNull @Override public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { // 补充convertView复用逻辑优化性能 if(convertView == null){ convertView = LayoutInflater.from(context).inflate(R.layout.mylayout, parent, false); } ImageView image = convertView.findViewById(R.id.image); TextView name1 = convertView.findViewById(R.id.name); TextView call1 = convertView.findViewById(R.id.call); TextView sms1 = convertView.findViewById(R.id.sms); TextView phone1 = convertView.findViewById(R.id.phone); name1.setText(name.get(position)); call1.setText(call.get(position)); sms1.setText(sms.get(position)); String currentPhone = phone.get(position); phone1.setText(currentPhone); image.setImageResource(img.get(position)); // 绑定点击事件 call1.setOnClickListener(v -> phoneCall(currentPhone)); sms1.setOnClickListener(v -> sentMessage(currentPhone)); return convertView; }
3. 修正电话、短信的实现逻辑
修改两个方法的参数和Intent配置:
public void sentMessage(String phoneNum) { Intent intent = new Intent(Intent.ACTION_SENDTO); // 直接带入要发送的手机号 intent.setData(Uri.parse("smsto:" + phoneNum)); intent.putExtra("sms_body", ""); if (intent.resolveActivity(context.getPackageManager()) != null) { // 加FLAG_ACTIVITY_NEW_TASK适配非Activity上下文启动场景 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); } } public void phoneCall(String phoneNum) { Intent intent = new Intent(Intent.ACTION_DIAL); // 带入当前点击的联系人手机号 intent.setData(Uri.parse("tel:" + phoneNum)); if (intent.resolveActivity(context.getPackageManager()) != null) { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); } }
4. 安卓11及以上版本补充配置
在AndroidManifest.xml的manifest标签下添加 queries 声明,避免resolveActivity返回null:
<queries> <intent> <action android:name="android.intent.action.DIAL" /> <data android:scheme="tel" /> </intent> <intent> <action android:name="android.intent.action.SENDTO" /> <data android:scheme="smsto" /> </intent> </queries>
内容的提问来源于stack exchange,提问作者Mubashar Ali
相关产品推荐
相关产品推荐

