4.4.1.1 创建/使用私有服务

私有服务是不能由其他应用启动的服务,因此它是最安全的服务。 当使用仅在应用中使用的私有服务时,只要您对该类使用显式意图,那么您就不必担心意外将它发送到任何其他应用。

下面展示了如何使用startService类型服务的示例代码。

要点(创建服务):

  1. 将导出属性显式设置为false

  2. 小心并安全地处理收到的意图,即使意图从相同应用发送。

  3. 由于请求应用在同一应用中,所以可以发送敏感信息。

AndroidManifest.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="org.jssec.android.service.privateservice" >
  4. <application
  5. android:icon="@drawable/ic_launcher"
  6. android:label="@string/app_name"
  7. android:allowBackup="false" >
  8. <activity
  9. android:name=".PrivateUserActivity"
  10. android:label="@string/app_name"
  11. android:exported="true" >
  12. <intent-filter>
  13. <action android:name="android.intent.action.MAIN" />
  14. <category android:name="android.intent.category.LAUNCHER" />
  15. </intent-filter>
  16. </activity>
  17. <!-- Private Service derived from Service class -->
  18. <!-- *** POINT 1 *** Explicitly set the exported attribute to false. -->
  19. <service android:name=".PrivateStartService" android:exported="false"/>
  20. <!-- Private Service derived from IntentService class -->
  21. <!-- *** POINT 1 *** Explicitly set the exported attribute to false. -->
  22. <service android:name=".PrivateIntentService" android:exported="false"/>
  23. </application>
  24. </manifest>

PrivateStartService.java

  1. package org.jssec.android.service.privateservice;
  2. import android.app.Service;
  3. import android.content.Intent;
  4. import android.os.IBinder;
  5. import android.widget.Toast;
  6. public class PrivateStartService extends Service {
  7. // The onCreate gets called only one time when the service starts.
  8. @Override
  9. public void onCreate() {
  10. Toast.makeText(this, "PrivateStartService - onCreate()", Toast.LENGTH_SHORT).show();
  11. }
  12. // The onStartCommand gets called each time after the startService gets called.
  13. @Override
  14. public int onStartCommand(Intent intent, int flags, int startId) {
  15. // *** POINT 2 *** Handle the received intent carefully and securely,
  16. // even though the intent was sent from the same application.
  17. // Omitted, since this is a sample. Please refer to "3.2 Handling Input Data Carefully and Securely."
  18. String param = intent.getStringExtra("PARAM");
  19. Toast.makeText(this,
  20. String.format("PrivateStartService¥nReceived param: ¥"%s¥"", param),
  21. Toast.LENGTH_LONG).show();
  22. return Service.START_NOT_STICKY;
  23. }
  24. // The onDestroy gets called only one time when the service stops.
  25. @Override
  26. public void onDestroy() {
  27. Toast.makeText(this, "PrivateStartService - onDestroy()", Toast.LENGTH_SHORT).show();
  28. }
  29. @Override
  30. public IBinder onBind(Intent intent) {
  31. // This service does not provide binding, so return null
  32. return null;
  33. }
  34. }

下面是使用私有服务的活动代码:

要点(使用服务):

  1. 使用指定类的显式意图,调用同一应用程序的服务。

  2. 由于目标服务位于同一应用中,因此可以发送敏感信息。

  3. 即使数据来自同一应用中的服务,也要小心并安全地处理收到的结果数据。

PrivateUserActivity.java

  1. package org.jssec.android.service.privateservice;
  2. import android.app.Activity;
  3. import android.content.Intent;
  4. import android.os.Bundle;
  5. import android.view.View;
  6. public class PrivateUserActivity extends Activity {
  7. @Override
  8. public void onCreate(Bundle savedInstanceState) {
  9. super.onCreate(savedInstanceState);
  10. setContentView(R.layout.privateservice_activity);
  11. }
  12. // --- StartService control ---
  13. public void onStartServiceClick(View v) {
  14. // *** POINT 4 *** Use the explicit intent with class specified to call a service in the same application.
  15. Intent intent = new Intent(this, PrivateStartService.class);
  16. // *** POINT 5 *** Sensitive information can be sent since the destination service is in the same application.
  17. intent.putExtra("PARAM", "Sensitive information");
  18. startService(intent);
  19. }
  20. public void onStopServiceClick(View v) {
  21. doStopService();
  22. }
  23. @Override
  24. public void onStop() {
  25. super.onStop();
  26. // Stop service if the service is running.
  27. doStopService();
  28. }
  29. private void doStopService() {
  30. // *** POINT 4 *** Use the explicit intent with class specified to call a service in the same application.
  31. Intent intent = new Intent(this, PrivateStartService.class);
  32. stopService(intent);
  33. }
  34. // --- IntentService control ---
  35. public void onIntentServiceClick(View v) {
  36. // *** POINT 4 *** Use the explicit intent with class specified to call a service in the same application.
  37. Intent intent = new Intent(this, PrivateIntentService.class);
  38. // *** POINT 5 *** Sensitive information can be sent since the destination service is in the same application.
  39. intent.putExtra("PARAM", "Sensitive information");
  40. startService(intent);
  41. }
  42. }