Amaç - etkinlik devam ediyorsa, öne getirin, aksi takdirde yeni bir tane başlatın (bildirimden)


129

Uygulamamda - tabii ki - herhangi bir bayrak olmadan, her seferinde yeni bir aktivite başlatan, böylece birden fazla aynı aktivitenin birbiri üzerinde çalışmasını sağlayan bildirimler var, bu tamamen yanlış.

Yapmasını istediğim, niyet bekleyen bildirimlerde belirtilen faaliyeti zaten çalışıyorsa öne getirmek, yoksa başlatmaktır.

Şimdiye kadar, sahip olduğum bu bildirimin amacı / bekleyen niyetim

private static PendingIntent prepareIntent(Context context) {
    Intent intent = new Intent(context, MainActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);

    return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}

ve tuhaf bir şekilde, bazen işe yarıyor, bazen işe yaramıyor ... Her bir bayrak kombinasyonunu zaten denediğimi hissediyorum.

Yanıtlar:


131

Bunu kullanabilirsiniz:

<activity 
   android:name=".YourActivity"
   android:launchMode="singleTask"/>

Bu, benzer şekilde çalışacak, "singleInstance"ancak o tuhaf animasyona sahip olmayacak.


15
+1, kabul edilen cevap siz olmalısınız. Farklılıklar burada: developer.android.com/guide/topics/manifest/…
user1032613

1
Açıklığa kavuşturmak için, uygulamada birden fazla etkinliğiniz varsa ve bu, yalnızca bir Etkinliğiniz varsa, üst, singleInstance ise singleTask kullanın.
donma harikası

4
Benim gibi biri bu siteye gelmeden önce birçok çözüm kombinasyonunu denediyse: Denediğiniz diğer değişikliklerden kurtulduğunuzdan ve bu değişikliği doğru etkinlikte yaptığınızdan emin olun. Başka çözümleri de onNewIntent
denemeseydim

Messenger, Activity çifti haritam var. Bir mesaj alırsam Activity örneğini görüntülemek istiyorum. Bunu yapmanın bir yolu var mı. örneğin: HashMap.get (Messenger) .bringActivityToFront (); Demek istediğim, aktivite hala devam ediyor. Son görevi açıp tıklarsam, şu görünecektirResume (); Programatik olarak onResume () yapamıyorum.

Tamamen farklı bir soru gibi görünen @JaveneCPPMcGowan, bunu kendi sorusu olarak göndermenizi öneririm, maalesef cevabını gerçekten bilmiyorum.
Franco

46

Bunu yapmanın en iyi yolu ve basit bir şekilde faaliyete normal şekilde başlamak, ancak bu etkinliği manifestte singleInstancemülk ile ayarlamaktır . Bununla, aktiviteyi her zaman öne çıkararak ve işletim sisteminin herhangi bir aktivite yoksa otomatik olarak yeni bir tane oluşturmasına izin vererek veya mevcut aktiviteyi öne çıkararak şu anda sahip olduğunuz her iki soruna da pratik olarak yaklaşırsınız (teşekkürler singleInstanceEmlak).

Bu, bir faaliyetin tek bir örnek olarak bildirilme şeklidir:

<activity 
   android:name=".YourActivity"
   android:launchMode="singleInstance"/>

Ayrıca singleInstance aracılığıyla başlatılırken dalgalı bir animasyondan kaçınmak için, bunun yerine "singleTask" kullanabilirsiniz, her ikisi de çok benzerdir ancak fark, Google'ın belgelerine göre burada açıklanmaktadır:

<activity 
   android:name=".YourActivity"
   android:launchMode="singleTask"/>

singleInstance, sistemin örneği tutan göreve başka herhangi bir etkinlik başlatmaması dışında "singleTask" ile aynıdır. Faaliyet her zaman görevinin tek ve tek üyesidir.

Bu yardımcı olur umarım.

Saygılarımızla!


4
işe yarıyor gibi görünüyor, ancak şimdi singleIntent MainActivity'den başlattığım diğer her yeni aktivite, normal fade & scale yerine bu garip ark animasyonunu oynat
urSus

Her seferinde yeni bir aktivite başlatsam da diğer tüm çalışan örneklerini temizlememe ne dersin, bu mümkün olabilir mi?
urSus

Şey, bahsettiğiniz animasyonun "singleInstance" özelliğiyle bir ilgisi olduğunu sanmıyorum, tek yaptığı mevcut örneği yeniden kullanmak, belki de bahsettiğiniz animasyon tamamen farklı bir konu ...
Martin Cazares

1
iyi şimdi test ediyorum ve öyle. Tüm niyet bayraklarını kaldırırsam ve manifest'te launchMode = "singleInstance" olarak ayarlarsam, tuhaf animasyon oradadır, eğer onu kaldırırsam normale döner
urSus

Evet, android belgelerine göre, "init" animasyonu artık her zamanki gibi yok gibi görünüyor çünkü etkinlik başlatılmıyor, sadece yeniden kullanılıyor ...
Martin Cazares

26

Sanırım ihtiyacın olan şey singleTop Activitya singleTaskveya yerine içinde singleInstance.

<activity android:name=".MyActivity"
          android:launchMode="singleTop"
          ...the rest... >

Ne belgelerine diyor mükemmel ihtiyaçlarına uygun vermez:

[...] singleTopyeni bir amacı işlemek için bir " " etkinliğin yeni bir örneği de oluşturulabilir. Bununla birlikte, hedef görev yığınının üstünde zaten mevcut bir etkinlik örneğine sahipse, bu örnek yeni amacı alır (bir onNewIntent()çağrıda); yeni bir örnek oluşturulmaz. Diğer durumlarda - örneğin, " singleTop" etkinliğin mevcut bir örneği hedef görevdeyse, ancak yığının en üstünde değilse veya bir yığının en üstündeyse, ancak hedef görevde değilse - yeni örnek oluşturulacak ve yığın üzerinde itilecek.

Üstelik (kelime oyunu amaçlanmadı), seninle tamamen aynı ihtiyacım vardı. launchModePratikte nasıl davrandıklarını anlamak için tüm bayrakları test ettim ve sonuç singleTopolarak aslında bunun için en iyisi: tuhaf bir animasyon yok, uygulama son uygulamalar listesinde bir singleInstancekez görüntüleniyor (bunun aksine , öyle olmadığı için iki kez görüntüleniyor '' Başkalarının Activitygörevinin bir parçası olmasına izin vermeyin ) ve hedef Activityhalihazırda var olsun ya da olmasın uygun davranış .


2
Cuma akşamı 22: 00'ye kadar çalışın ve istediğim şey bu ... Üzücü geliştirici hayatı.
felixwcf

Zamanımın çoğunu kurtardım! Teşekkür ederim!
hetsgandhi

13

Bu eski bir konu, ama hala cevap arayanlar için, işte benim çözümüm. Bildirim ayarları olmadan tamamen kod içindedir:

private static PendingIntent prepareIntent(Context context) {
  Intent intent = new Intent(context, MainActivity.class);
  intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);      
  return PendingIntent.getActivity(context, NON_ZERO_REQUEST_CODE, intent, 
    PendingIntent.FLAG_UPDATE_CURRENT);
}

Burada FLAG_ACTIVITY_SINGLE_TOP, görev yığınının en üstündeyse mevcut etkinliği açar. Üstte değilse, ancak yığının içindeyse, FLAG_ACTIVITY_CLEAR_TOP hedef etkinliğin üstündeki tüm etkinlikleri kaldıracak ve gösterecektir. Etkinlik görev yığınında değilse, yeni bir tane oluşturulur. Bahsetmek için çok önemli bir nokta - PendingIntent.getActivity () 'nin ikinci parametresi, yani requestCode sıfır olmayan bir değere sahip olmalıdır (hatta benim snippet'imde NON_ZERO_REQUEST_CODE olarak adlandırdım), aksi takdirde bu amaç bayrakları çalışmayacaktır. Neden olduğu hakkında hiçbir fikrim yok. FLAG_ACTIVITY_SINGLE_TOP bayrağı, manifestteki etkinlik etiketinde android: launchMode = "singleTop" ile değiştirilebilir.


Saatlerce bu bayraklarla savaşıyorum ve niyet bayraklarımı değiştirmenin neden hiçbir şeyi değiştirmediğini merak ediyordum. Sıfır olmayan istek kodu ... belirtilmesi gereken çok önemli bir nokta !!! Şimdi çalışıyor! Teşekkür ederim!
Max Power

9

Eski olduğunu biliyorum, ancak yukarıdaki hiçbir şey başvuruma uymuyordu.

Manifestleri ve diğer yapılandırmaları değiştirmeden, uygulamanızı tekrar öne getirecek veya kapatıldığında açacak kodu burada bulabilirsiniz.

Intent notificationIntent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
notificationIntent.setPackage(null); // The golden row !!!
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);

Bu gerçek cevap!
azizbekian

2
hayır, çalışmıyor - mevcut olanın üzerine yeni bir aktivite ekler.
Tobliug

3

Bunu denedim ve IDE kod hakkında şikayet etmesine rağmen işe yaradı

Intent notificationIntent = new Intent(THIS_CONTEXT, MainActivity.class);
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
    PendingIntent intent = PendingIntent.getActivity(THIS_CONTEXT, 0, notificationIntent, Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);

    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(THIS_CONTEXT)
            .setSmallIcon(R.drawable.cast_ic_notification_0)
            .setContentTitle("Title")
            .setContentText("Content")
            .setContentIntent(intent)
            .setPriority(PRIORITY_HIGH) //private static final PRIORITY_HIGH = 5;
            .setAutoCancel(true)
            /*.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_LIGHTS)*/;
    NotificationManager mNotificationManager = (NotificationManager) THIS_CONTEXT.getSystemService(Context.NOTIFICATION_SERVICE);
    mNotificationManager.notify(0, mBuilder.build());

2
<activity android: name = ". MainActivity" android: launchMode = "singleTask">
nada

Intent.FLAG_ACTIVITY_REORDER_TO_FRONTgeçerli bir bayrak değilPendingINtent.getActivity
rds

@rds Kaynağı bağlayabilir misiniz?
Louis CAD

@LouisCAD Üzgünüm, artık kaynak koduna erişimim yok
nada

@rds Kaynak kodunu istemiyorum, ancak okuduğunuz yerin bağlantısını, Intent.FLAG_ACTIVITY_REORDER_TO_FRONTbir PendingIntent. Veya belki de getActivityyönteme geçmek için geçerli olmadığını, ancak Intentdaha sonra bir PendingIntent?
Louis

2

Zaten başlamamışsa faaliyete başlamak istediğini söylediğine göre, belki yeniden başlatmayı düşünmezsin. Niyet için bir ton öneri ve bayrak kombinasyonunu da test ettim, bu her zaman ihtiyacınız olan aktiviteyi öne çıkaracak, ancak daha önce onunla ilişkili herhangi bir durumu tutmayacak.

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);

Yalnızca API11 +.


0

Android eğitim sitesinde bulunan bildirimleri ekledikten sonra benzer bir sorunla karşılaştım . Buradaki diğer cevapların hiçbiri benim için işe yaramadı , ancak bu cevap benim için işe yaradı . Özet:

final Intent notificationIntent = new Intent(context, YourActivity.class);
notificationIntent.setAction(Intent.ACTION_MAIN);
notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.