Android: 无法从主题获取 IMEI

Android: Can't get Imei from a Thread

我有一项为新话题加注星标的服务。我的任务是从此线程中检索 IMEI。我试过这样的事情:

主要:

public class MainActivity extends AppCompatActivity {
String imei;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    TelephonyManager mg=(TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
    imei = mg.getDeviceId();


    Intent intent = new Intent();
    startService(new Intent(getBaseContext(), MyService.class));

}

public String getIMEI(){
    Log.d("THIS IS THE IMEI", imei);
    return imei;
}

这是我的服务Class:

public class MyService extends Service {
Connection con = new Connection();
@Nullable
@Override
public IBinder onBind(Intent intent) {

    return null;
}

@Override
public void onCreate(){

    Thread t = new Thread(con);
    t.start();
}

这是我的 Runnable class:

public class Connection implements Runnable {
MainActivity app = new MainActivity();

@Override
public void run() {
   String imei = app.getIMEI();
}

但是当我的代码达到 String imei = app.getIMEI() 时,我的应用程序崩溃并抛出异常。

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.asder.vediamo/com.asder.vediamo.MainActivity}: java.lang.SecurityException: getDeviceId: Neither user 10057 nor current process has android.permission.READ_PHONE_STATE.

在我的 android 清单中:

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    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"/>
</application>

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

问题是您正在自己创建 Activity,您永远不应该这样做:

MainActivity app = new MainActivity();

如果您需要上下文,请使用 Application class,并从中获取上下文。活动总是通过 startActivity 命令创建 OS。

然后尝试使用该上下文获取 TelephonyManager 和 IMEI...

MainActivity app = new MainActivity();

不要在扩展 Activity 的 class 上使用 new 运算符。在你的情况下,你正在初始化 imei,但你的 Activity 没有经历生命周期,因为你使用 new 来实例化它。如果可用,服务有可能访问 TelephonyManager。如果你需要在你的 Thread 中使用 imei,你可以在它的构造函数中提供它。例如

public class Connection implements Runnable {

    final String imei;
    public Connection(String i) {
      imei = i;
    }

在您的 ServiceonCreate 中,您可以检索 imei(您也需要服务来完成其生命周期)并实例化 Runnable,向构造函数提供 imei

我是一名开发人员,必须在许多设备上测试我们的应用程序。
我在我的新 Cagabi One 上发现了同样的问题:从我的服务读取数据时,IMEI 请求生成了一个 SecurityException。
我的应用程序在其他一些设备上正常工作,包括另一个 Cagabi One,但在新设备上却不行。
因此,我已经通过 在应用程序启动时(在主线程中)读取并保存 IMEI 号码 解决了问题,因此读取了从我的服务中保存的值。
该程序现在工作正常! ;-)
我的建议是始终从主线程读取所有硬件值,以排除冲突和安全异常。
罗伯托