4.4.1.2 创建/使用公共服务

公共服务是应该由未指定的大量应用使用的服务。 有必要注意,它可能会收到恶意软件发送的信息(意图等)。 在使用公共服务的情况下,有必要注意,恶意软件可能会收到要发送的信息(意图等)。

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

要点(创建服务):

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

  2. 小心并安全地处理接收到的意图。

  3. 返回结果时,请勿包含敏感信息。

AndroidManifest.xml


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="org.jssec.android.service.publicservice" >
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:allowBackup="false" >
        <!-- Most standard Service -->
        <!-- *** POINT 1 *** Explicitly set the exported attribute to true. -->
        <service android:name=".PublicStartService" android:exported="true">
            <intent-filter>
                <action android:name="org.jssec.android.service.publicservice.action.startservice" />
            </intent-filter>
        </service>
        <!-- Public Service derived from IntentService class -->
        <!-- *** POINT 1 *** Explicitly set the exported attribute to true. -->
        <service android:name=".PublicIntentService" android:exported="true">
            <intent-filter>
                <action android:name="org.jssec.android.service.publicservice.action.intentservice" />
            </intent-filter>
        </service>
    </application>
</manifest>

PublicIntentService.java

package org.jssec.android.service.publicservice;

import android.app.IntentService;
import android.content.Intent;
import android.widget.Toast;

public class PublicIntentService extends IntentService{

    /**
    * Default constructor must be provided when a service extends IntentService class.
    * If it does not exist, an error occurs.
    */
    public PublicIntentService() {
        super("CreatingTypeBService");
    }
    
    // The onCreate gets called only one time when the Service starts.
    @Override
    public void onCreate() {
        super.onCreate();
        Toast.makeText(this, this.getClass().getSimpleName() + " - onCreate()", Toast.LENGTH_SHORT).show();
    }
    
    // The onHandleIntent gets called each time after the startService gets called.
    @Override
    protected void onHandleIntent(Intent intent) {
        // *** POINT 2 *** Handle intent carefully and securely.
        // Since it's public service, the intent may come from malicious application.
        // Omitted, since this is a sample. Please refer to "3.2 Handling Input Data Carefully and Securely."
        String param = intent.getStringExtra("PARAM");
        Toast.makeText(this, String.format("Recieved parameter ¥"%s¥"", param), Toast.LENGTH_LONG).show();
    }
    
    // The onDestroy gets called only one time when the service stops.
    @Override
    public void onDestroy() {
        Toast.makeText(this, this.getClass().getSimpleName() + " - onDestroy()", Toast.LENGTH_SHORT).show();
    }
}

下面是使用公共服务的活动代码:

要点(使用服务):

  1. 不要发送敏感信息。

  2. 收到结果时,小心并安全地处理结果数据。

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="org.jssec.android.service.publicserviceuser" >
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:allowBackup="false" >
        <activity
            android:name=".PublicUserActivity"
            android:label="@string/app_name"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

PublicUserActivity.java


package org.jssec.android.service.publicserviceuser;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;

public class PublicUserActivity extends Activity {

    // Using Service Info
    private static final String TARGET_PACKAGE = "org.jssec.android.service.publicservice";
    private static final String TARGET_START_CLASS = "org.jssec.android.service.publicservice.PublicStartService";
    private static final String TARGET_INTENT_CLASS = "org.jssec.android.service.publicservice.PublicIntentService";
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.publicservice_activity);
    }
    
    // --- StartService control ---
    public void onStartServiceClick(View v) {
        Intent intent = new Intent("org.jssec.android.service.publicservice.action.startservice");
        // *** POINT 4 *** Call service by Explicit Intent
        intent.setClassName(TARGET_PACKAGE, TARGET_START_CLASS);
        // *** POINT 5 *** Do not send sensitive information.
        intent.putExtra("PARAM", "Not sensitive information");
        startService(intent);
        // *** POINT 6 *** When receiving a result, handle the result data carefully and securely.
        // This sample code uses startService(), so receiving no result.
    }
    
    public void onStopServiceClick(View v) {
        doStopService();
    }
    
    // --- IntentService control ---
    public void onIntentServiceClick(View v) {
        Intent intent = new Intent("org.jssec.android.service.publicservice.action.intentservice");
        // *** POINT 4 *** Call service by Explicit Intent
        intent.setClassName(TARGET_PACKAGE, TARGET_INTENT_CLASS);
        // *** POINT 5 *** Do not send sensitive information.
        intent.putExtra("PARAM", "Not sensitive information");
        startService(intent);
    }
    
    @Override
    public void onStop(){
        super.onStop();
        // Stop service if the service is running.
        doStopService();
    }
    
    // Stop service
    private void doStopService() {
        Intent intent = new Intent("org.jssec.android.service.publicservice.action.startservice");
        // *** POINT 4 *** Call service by Explicit Intent
        intent.setClassName(TARGET_PACKAGE, TARGET_START_CLASS);
        stopService(intent);
    }
}

书籍推荐