即使应用未运行,Android服务也会始终运行

时间:2015-03-26 18:03:26

标签: android android-layout android-activity android-service

我想创建一个Android服务,它总是在后台运行,即使我们没有打开像gmail服务或whatsapp服务的应用程序,所以我们可以在应用程序关闭时收到通知(但不强制关闭)。即使应用程序关闭,我也希望获得gcm通知,就像我们从最近的应用程序中换出应用程序一样。

现在当我通过长按主页按钮关闭应用程序并交换应用程序的所有组件关闭ao我无法获得gcm通知。

我知道在强行关闭应用时,我们无法获得gcm通知。

我长期坚持这个问题。有人可以知道如何处理这个问题

public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        ComponentName comp = new ComponentName(context.getPackageName(),
                GCMNotificationIntentService.class.getName());
        startWakefulService(context, (intent.setComponent(comp)));
        setResultCode(Activity.RESULT_OK);
        }
}

清单文件

    <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="xxxx"
    android:installLocation="internalOnly">

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />


    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATUS_AND_IDENTITY" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.VIBRATE" />


    <permission
        android:name="xxxx.permission.C2D_MESSAGE"
        android:protectionLevel="signature" />

    <uses-permission android:name="xxxx.permission.C2D_MESSAGE" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />

    <application
        android:name=".MyApplication"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />

        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:screenOrientation="portrait"
            android:windowSoftInputMode="stateHidden" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>


        //it overrides WakefulBroadcastReceiver
        <receiver
            android:name=".gcm.GcmBroadcastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND" >
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />

                <category android:name="xxxx" />
            </intent-filter>
        </receiver>

        //it overrides IntentService
        <service android:name=".gcm.GCMNotificationIntentService" />

    </application>

</manifest> 

   public class GCMNotificationIntentService extends IntentService {
    // Sets an ID for the notification, so it can be updated
    public static final int notifyID = 9001;
    private static final String TAG = GCMNotificationIntentService.class.getSimpleName();

    NotificationCompat.Builder builder;

    public GCMNotificationIntentService() {
        super("GcmIntentService");
    }


    @Override
    protected void onHandleIntent(Intent intent) {
        Bundle extras = intent.getExtras();
        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
        String messageType = gcm.getMessageType(intent);
        if (!extras.isEmpty()) {
            if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR
                    .equals(messageType)) {
                sendNotification("Send error: " + extras.toString());
            } else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED
                    .equals(messageType)) {
                sendNotification("Deleted messages on server: "
                        + extras.toString());
            } else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE
                    .equals(messageType)) {

                String incomingMessage = extras.get(ApplicationConstants.MSG_KEY)+"";
                String type = identifyHeaders(incomingMessage);
                String processedString = removeHeaders(incomingMessage, type);

                if(type.equals(NOTIFICATION_MESSAGE)) {
                    sendNotification(processedString);
                }else if(type.equals(NOTIFICATION_PHONE_CHANGE)){
                }
            }
        }
        GcmBroadcastReceiver.completeWakefulIntent(intent);
    }

    //this methos is for sending notification to notification bar
    private void sendNotification(String msg) {

    }

}

更新了GCM服务代码

public class GCMNotificationIntentService extends Service {
    // Sets an ID for the notification, so it can be updated
    public static final int notifyID = 9001;
    private static final String TAG = GCMNotificationIntentService.class.getSimpleName();

    public GCMNotificationIntentService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        Log.d(TAG, "Service started");
        processIntent(intent);

        return START_STICKY;
    }

    void processIntent(Intent intent){

        Log.d(TAG, "notification received");

        Bundle extras = intent.getExtras();
        GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
        String messageType = gcm.getMessageType(intent);
        if (!extras.isEmpty()) {
            if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR
                    .equals(messageType)) {
                sendNotification("Send error: " + extras.toString());
            } else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED
                    .equals(messageType)) {
                sendNotification("Deleted messages on server: "
                        + extras.toString());
            } else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE
                    .equals(messageType)) {

                String incomingMessage = extras.get(ApplicationConstants.MSG_KEY)+"";
                String type = identifyHeaders(incomingMessage);
                String processedString = removeHeaders(incomingMessage, type);

                if(type.equals(NOTIFICATION_MESSAGE)) {
                    sendNotification(processedString);
                }else if(type.equals(NOTIFICATION_PHONE_CHANGE)){
                    updatePhoneNumber(processedString);
                }
            }
        }

        GcmBroadcastReceiver.completeWakefulIntent(intent);
    }



    private void sendNotification(String msg) {
        Intent resultIntent = new Intent(this, WelcomeScreen.class);
        resultIntent.putExtra("msg", msg);
        resultIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP| Intent.FLAG_ACTIVITY_NEW_TASK| Intent.FLAG_ACTIVITY_SINGLE_TOP);

        PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 0,
                resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        NotificationCompat.Builder mNotifyBuilder;
        NotificationManager mNotificationManager;
        mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        mNotifyBuilder = new NotificationCompat.Builder(this)
                .setContentTitle("GOODSERVICE")
                .setContentText("NEW LEAD FROM GOODSERVICE")
                .setSmallIcon(R.drawable.ic_launcher);

        mNotifyBuilder.setContentIntent(resultPendingIntent);

        // Set Vibrate, Sound and Light
        int defaults = 0;
        defaults = defaults | Notification.DEFAULT_LIGHTS;
        defaults = defaults | Notification.DEFAULT_VIBRATE;

        mNotifyBuilder.setDefaults(defaults);
        // Set the content for Notification
        mNotifyBuilder.setContentText("NEW LEAD FROM GOODSERVICE");
        // Set autocancel
        mNotifyBuilder.setAutoCancel(true);
        Uri soundTest =  Settings.System.DEFAULT_RINGTONE_URI;
        mNotifyBuilder.setSound(soundTest);
        // Post a notification
        mNotificationManager.notify(notifyID, mNotifyBuilder.build());
        Intent intentone = new Intent(this, HomeActivity.class);
        intentone.putExtra("msg", msg);
        intentone.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP| Intent.FLAG_ACTIVITY_NEW_TASK| Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
        this.startActivity(intentone);
    }

}

这就是我调用此服务的方式

    ComponentName comp = new ComponentName(context.getPackageName(),
            GCMNotificationIntentService.class.getName());
    startWakefulService(context, (intent.setComponent(comp)));
    startWakefulService(context, (intent.setComponent(comp)));
    setResultCode(Activity.RESULT_OK);

2 个答案:

答案 0 :(得分:1)

IntentService不会连续在后台运行。它们只运行一次,当它们完成时,它们将被销毁。 你应该检查一下Service。即使应用程序关闭,它们也不会被销毁。 覆盖其函数onStartCommandCheck this answer for more detailed difference

答案 1 :(得分:0)

您正在寻找WakefulBroadcastReceiverIntentService

这将有助于您https://developer.android.com/google/gcm/client.html