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;
}
在您的 Service
的 onCreate
中,您可以检索 imei
(您也需要服务来完成其生命周期)并实例化 Runnable
,向构造函数提供 imei
我是一名开发人员,必须在许多设备上测试我们的应用程序。
我在我的新 Cagabi One 上发现了同样的问题:从我的服务读取数据时,IMEI 请求生成了一个 SecurityException。
我的应用程序在其他一些设备上正常工作,包括另一个 Cagabi One,但在新设备上却不行。
因此,我已经通过 在应用程序启动时(在主线程中)读取并保存 IMEI 号码 解决了问题,因此读取了从我的服务中保存的值。
该程序现在工作正常! ;-)
我的建议是始终从主线程读取所有硬件值,以排除冲突和安全异常。
罗伯托
我有一项为新话题加注星标的服务。我的任务是从此线程中检索 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;
}
在您的 Service
的 onCreate
中,您可以检索 imei
(您也需要服务来完成其生命周期)并实例化 Runnable
,向构造函数提供 imei
我是一名开发人员,必须在许多设备上测试我们的应用程序。
我在我的新 Cagabi One 上发现了同样的问题:从我的服务读取数据时,IMEI 请求生成了一个 SecurityException。
我的应用程序在其他一些设备上正常工作,包括另一个 Cagabi One,但在新设备上却不行。
因此,我已经通过 在应用程序启动时(在主线程中)读取并保存 IMEI 号码 解决了问题,因此读取了从我的服务中保存的值。
该程序现在工作正常! ;-)
我的建议是始终从主线程读取所有硬件值,以排除冲突和安全异常。
罗伯托