Android Nougat(API24)下无法获取IMEI的问题求助
解决Android Nougat(API24)无法获取IMEI的问题
我仔细看了你的代码和问题描述,核心问题是动态权限申请的流程处理错误,以及代码逻辑顺序颠倒导致权限未生效时就调用了敏感API,进而抛出SecurityException。下面帮你一步步梳理问题并给出正确实现:
你的代码中存在的核心问题
代码1的问题
context变量未初始化,点击事件里用context做权限检查会导致错误,应该使用当前Activity的实例(比如MainActivity.this)- 权限申请后没有处理回调:用户授予权限后,你没有在
onRequestPermissionsResult中重新执行获取IMEI的逻辑,而是在申请权限的同时直接调用getDeviceId(),这时候权限还未真正授予 - 点击事件的逻辑顺序错误:在权限未通过的分支里直接调用
getDeviceId(),这必然会失败
代码2的问题
- 逻辑完全颠倒:在权限未授予的分支里去调用
tm.getDeviceId(),这直接触发了SecurityException,正确逻辑应该是权限授予后才调用这些敏感API
正确的实现步骤与代码
首先确保AndroidManifest.xml中已经声明权限:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
然后是Activity的完整实现,包含权限检查、申请、回调处理:
public class MainActivity extends AppCompatActivity { private TextView imei_number; private Button get_imei; private TelephonyManager telephonyManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imei_number = findViewById(R.id.textView1); get_imei = findViewById(R.id.button1); telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); // 点击按钮触发IMEI获取 get_imei.setOnClickListener(v -> checkPermissionAndGetImei()); } // 检查权限并获取IMEI private void checkPermissionAndGetImei() { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { // 权限未授予,申请权限 ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, 100); } else { // 权限已授予,直接获取IMEI fetchImei(); } } // 获取IMEI并显示 private void fetchImei() { try { String imei; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // API26及以上可以获取双卡的IMEI imei = telephonyManager.getImei(0); // 如果是双卡,可以获取第二个:telephonyManager.getImei(1); } else { // API26以下用getDeviceId imei = telephonyManager.getDeviceId(); } imei_number.setText("IMEI: " + imei); } catch (SecurityException e) { e.printStackTrace(); imei_number.setText("获取IMEI失败:权限不足"); } } // 处理权限申请的回调 @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == 100) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 用户授予权限,重新获取IMEI fetchImei(); } else { // 用户拒绝权限,提示无法获取 imei_number.setText("您拒绝了权限,无法获取IMEI"); } } } }
关键注意点
- 动态权限的必要性:从Android 6.0(API23)开始,
READ_PHONE_STATE属于危险权限,必须通过requestPermissions让用户主动授予,仅在Manifest中声明是不够的 - 权限回调的处理:必须在
onRequestPermissionsResult中处理用户的权限选择,只有当权限授予后,才能调用getDeviceId()或getImei() - API版本适配:API26及以上推荐使用
getImei()代替getDeviceId(),后者在高版本中逐渐被废弃
内容的提问来源于stack exchange,提问作者Imran
相关产品推荐
相关产品推荐

