0

in meiner App starte ich einen Dienst, um Benachrichtigungen zu erhalten, während die App im Hintergrund ist - dieser Dienst zwingt meine App automatisch zu starten, nachdem ich es zu stoppen. Ich habe versucht, das Problem zu lösen, indem ich ausstehende Absicht verwendete, aber es geschieht immer noch.Android-Dienst startet App automatisch

Hier ist meine Absicht, den Dienst zu starten:

Intent messageReceivingIntent = new Intent(this, MessageReceivingService.class); 
messageReceivingIntent.putExtra("myUserId", myUserId); 
Pending Inten messagePendingIntent = PendingIntent.getService(this, 0, messageReceivingIntent, PendingIntent.FLAG_UPDATE_CURRENT); 

    try { 
     // Perform the operation associated with our pendingIntent 
     messagePendingIntent.send(); 
    } catch (PendingIntent.CanceledException e) { 
     e.printStackTrace(); 
    } 

, wenn ich Dienst über externalreceiver nennen bekomme ich eine Nullpointer. irgendeine Idee warum?

das ist mein BroadcastReceiver Aufruf:

messageReceivingIntent = new Intent(this, MessageReceivingService.class); 
messageReceivingIntent.putExtra("myUserId", myUserId); 
messageReceivingIntent.setAction("com.example.androidtest"); 
sendBroadcast(messageReceivingIntent); 

Hier ist meine Rundfunkempfänger:

public class ExternalReceiver extends BroadcastReceiver { 

@Override 
public void onReceive(Context context, Intent intent) { 
    if(intent!=null){ 
     Bundle extras = intent.getExtras(); 
     if(!MapsActivity.inBackground){ 
      MessageReceivingService.sendToApp(extras, context); 
     } 
     else{ 
      MessageReceivingService.saveToLog(extras, context); 
     } 
    } 
} 

}

und das ist MessageReceivingService

public class MessageReceivingService extends Service { 
private GoogleCloudMessaging gcm; 
public static SharedPreferences savedValues; 

public static final String INSTANCE_ID_SCOPE = "GCM"; 
final String BASE_URL = "http://www.example.com/"; 

public String myUserId; 
public String registeredUserId; 
public String token; 
static PendingIntent pendingIntent; 


public static void sendToApp(Bundle extras, Context context) { 
    Intent newIntent = new Intent(); 
    newIntent.setClass(context, MapsActivity.class); 
    newIntent.putExtras(extras); 

    ShortcutBadger.applyCount(Content.getAppContext(), 0); 

    newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
    context.startActivity(newIntent); 
} 

public void onCreate() { 
    super.onCreate(); 
    final String preferences = getString(R.string.preferences); 
    savedValues = getSharedPreferences(preferences, Context.MODE_PRIVATE); 
    // In later versions multi_process is no longer the default 
    if (VERSION.SDK_INT > 9) { 
     savedValues = getSharedPreferences(preferences, Context.MODE_MULTI_PROCESS); 
    } 
    gcm = GoogleCloudMessaging.getInstance(getBaseContext()); 






    // Let AndroidMobilePushApp know we have just initialized and there may be stored messages 
    sendToApp(new Bundle(), this); 
} 

protected static void saveToLog(Bundle extras, Context context) { 
    SharedPreferences.Editor editor = savedValues.edit(); 
    String numOfMissedMessages = context.getString(R.string.num_of_missed_messages); 
    int linesOfMessageCount = 0; 

    for (String key : extras.keySet()) { 
     String line = String.format("%s=%s", key, extras.getString(key)); 
     editor.putString(key, line); 
     linesOfMessageCount++; 
    } 
    editor.putInt(context.getString(R.string.lines_of_message_count), linesOfMessageCount); 
    editor.putInt(context.getString(R.string.lines_of_message_count), linesOfMessageCount); 
    editor.putInt(numOfMissedMessages, savedValues.getInt(numOfMissedMessages, 0) + 1); 
    editor.commit(); 

    String type = extras.getString("model"); 
    String id = extras.getString("id"); 
    String userId = extras.getString("user_id"); 

    //postNotification(new Intent(context, MapsActivity.class), context); 
    if(type != null) { 
     if (type.equals("content")) { 
      Intent contentIntent = new Intent(context, ContentDetailActivity.class); 

      Log.v("userID", userId); 

      contentIntent.putExtra("contentId", id); 
      if (userId != null) { 
       contentIntent.putExtra("userId", userId); 
      } 

      postNotification(contentIntent, context); 
     } else if (type.equals("user")) { 
      Intent userIntent = new Intent(context, ProfileActivity.class); 
      userIntent.putExtra("userId", id); 

      postNotification(userIntent, context); 
     } 
    } else { 
     postNotification(new Intent(context, NotificationsActivity.class), context); 
    } 

    ShortcutBadger.applyCount(Content.getAppContext(), Integer.valueOf(savedValues.getInt(Content.getAppContext().getString(R.string.num_of_missed_messages), 0))); 
} 

protected static void postNotification(Intent intentAction, Context context) { 
    final NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 

    pendingIntent = PendingIntent.getActivity(context, 0, intentAction, PendingIntent.FLAG_UPDATE_CURRENT); 

    int numOfMissedMessages = 0; 
    String missedMessage = ""; 
    if(savedValues != null){ 
     missedMessage = savedValues.getString("message", "nothing there"); 
    } 



    Log.v("NUMOFMISSEDMESSAGES", String.valueOf(numOfMissedMessages)); 

    final Notification notification = new NotificationCompat.Builder(context).setSmallIcon(R.drawable.ic_launcher) 
      .setContentTitle(missedMessage.substring(missedMessage.indexOf("=") + 1, missedMessage.length())) 
      .setContentText("") 
      .setContentIntent(pendingIntent) 
      .setAutoCancel(true) 
      .build(); 
    mNotificationManager.notify(R.string.notification_number, notification); 
} 

private void register() { 
    new AsyncTask() { 
     protected Object doInBackground(final Object... params) { 

      try { 
       String instanceId = InstanceID.getInstance(getApplicationContext()).getId(); 
       //token = gcm.register(getString(R.string.project_number)); 
       token = InstanceID.getInstance(getApplicationContext()).getToken(getString(R.string.project_number), INSTANCE_ID_SCOPE); 
       Log.i("registrationId", token); 
      } catch (IOException e) { 
       Log.i("Registration Error", e.getMessage()); 
      } 
      return true; 
     } 

     @Override 
     protected void onPostExecute(Object o) { 
      super.onPostExecute(o); 
      new SendRegUserId().execute(); 
     } 
    }.execute(); 
} 

public IBinder onBind(Intent arg0) { 
    return null; 
} 
} 
+0

Verwenden Sie einen 'Broadcast Receiver'? – SQLiteNoob

+0

Sie verwenden viele statische Variablen in Ihrem 'Service'. Dies ist wahrscheinlich der Grund für Ihre Probleme. Wenn Sie 'NullPointerException' erhalten, poste bitte die Fehlermeldungen einschließlich stacktrace von logcat und erkläre, was zur Zeit passierte. Veröffentlichen Sie auch den Code aus Ihrem 'Service' 'onStartCommand()' –

Antwort

2

ein 01 Verwenden, um die Benachrichtigung zu erhalten, und senden Sie sie an Ihre Service. Dadurch können Sie eine notification an den Benutzer senden, ohne Ihre App zu starten.

=========
Edit 1:

So braucht Ihr Rundfunkempfänger den Dienst statt Aufruf seiner Methoden zu starten. So nach dem Check für Vorsatz ist null, etwas entlang der Linien von:

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

Auch Ihre Broadcast Receiver sollte WakefulBroadcastReceiver verlängern, wenn Sie weiterhin Benachrichtigungen erhalten möchten, wenn das Telefon ausgeschaltet worden ist.

Auch Ihr Service sollte ein IntentService sein. Ich denke, Android Studio kommt mit einigen vorgefertigten GCM-Klassen oder einer GCM-App, die sich um 90% dieser kleinen Probleme kümmern wird. Es ist ein besserer Ausgangspunkt.

Überprüfen Sie die GCM docs für weitere Hilfe.

+0

Ich habe mit gcm für eine sehr lange Zeit gekämpft und hatte Probleme damit. Ich würde gerne den gegebenen Code reparieren, denn abgesehen von dem Selbststartproblem funktionierte es gut. Ich bin ziemlich verzweifelt – rudi

+0

Ernsthaft, überprüfen Sie https://github.com/googlesamples/google-services/tree/master/android/gcm und erwägen Sie, Ihre Anwendungsfälle in dieses Beispiel zu integrieren - es ist sofort einsatzbereit zu gehen, und wird Ihnen eine Menge Kopfschmerzen ersparen. GCM ändert sich ständig (jetzt Firebase) und ich musste den Code in jeder Iteration manuell aktualisieren, und es ist nicht die Art, wie ich Dinge empfehlen würde – SQLiteNoob

0

Einige wenige mögliche Lösungen-

1) Verwendung BroadcastReceiver

2) Verwenden Sie onPause(), onResume() -Methoden

SharedPreferences prefs=PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); 

Intent messageReceivingIntent = new Intent(this,MessageReceivingService.class); 

    onCreate(){ 

    //YOUR OWN CODE 
    prefs.getBoolean("service_started",false); 
} 

onPause(){ 

//YOUR OWN CODE 
prefs.edit().putBoolean("service_started",true).apply(); 
startService(messageReceivingIntent); 
} 

onResume(){ 

//YOUR OWN CODE 
if(prefs.getBoolean("service_started",false)){ 
    stopService(new Intent(this, MessageReceivingService.class)); 
    prefs.edit().putBoolean("service_started",false).apply(); 
} 
} 

3) oder die Besten nach mir zu tun besteht darin, Firebase Cloud Messaging zur Benachrichtigung zu implementieren. diese

Check out https://firebase.google.com/docs/cloud-messaging/

Es reduziert Ihre Batterie und Server viel Aufwand. Es ist ein brandneuer Service von Google.

ODER Ich denke, es kann einen Fehler in Ihrem Servicecode geben