0

Я хочу создать службу андроида, которая всегда работает в фоновом режиме, даже если мы не открыли приложение, такое как служба gmail или службу whatsapp, чтобы мы могли получать уведомления, когда приложение закрыто (но не принудительно закрыть). Я хочу получить gcm-уведомление, даже когда приложение закрыто, как мы поменяли приложение из последних приложений.Служба Android всегда работает, даже когда приложение не работает

Прямо сейчас, когда я закрываю приложение, долго нажимаю на кнопку «домой» и меняю местами все компоненты приложения close 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); 
+0

Ваш сервис разрушен, потому что вы уничтожаете процесс (долгое нажатие на кнопку), в котором создается ваше обслуживание. Я надеюсь, что ваша служба не связана с вашей деятельностью, но поскольку ваш процесс убит, так это ваша служба. В идеале Android должен перезапустить все такие разрушенные службы, но они начнутся с нуля. – Kay

+0

Используйте START_STICKY http://developer.android.com/reference/android/app/Service.html#START_STICKY или используйте startForeground (int, Notification), но это будет показывать уведомление пользователю, и я не думаю, что это идеально для gcm – Kay

+0

Я добавил изображение, в котором приложения всегда работают на переднем плане. Вы пробовали делать что-нибудь подобное? Я уже пробовал эти параметры, но служба останавливается, когда я долгое время закрываю – user3265443

ответ

0

Вы ищете WakefulBroadcastReceiver и IntentService

Вот это поможет https://developer.android.com/google/gcm/client.html

+0

Я уже реализовал его, но проблема в том, что когда я делаю длинное нажатие, я прекратил получать уведомления, так как все компоненты моего приложения закрыты. Я думаю о способе открытия компонента приложения, чтобы я мог получать уведомления GCM. – user3265443

+0

Это не сработает, так как когда вы закроете приложение, его фоновые службы также будут закрыты. Попробуйте принудительно закрыть gmail и whatsapp, вы также не получите их уведомления. – Ryan

+0

, но это не принудительно закрыть. Я поменял whatsapp из последних приложений, кроме того, что получаю уведомления. Принудительное закрытие, когда я перехожу к настройкам-> Приложения-> Принудительное закрытие – user3265443

1

IntentService не будет работать в фоновом режиме постоянно. Они будут работать только один раз, и когда они закончатся, они будут уничтожены. Вы должны проверить Service. Они не уничтожаются, даже если приложение закрыто. Отменить его функцию onStartCommand. Check this answer for more detailed difference.

+0

* Они не уничтожаются, даже если приложение закрыто * О, они есть. Но разница в том, что они могут перезапустить себя –

Смежные вопросы