Niyeti temizleme


111

Android uygulamam bilgi ileten bir amaç tarafından çağrılıyor (durum çubuğunda beklemede).

Ana sayfa düğmesine bastığımda ve ana sayfa düğmesini basılı tutarak uygulamamı yeniden açtığımda, amacı tekrar çağırıyor ve aynı ekstralar hala orada.

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
      super.onSaveInstanceState(savedInstanceState);
    }
    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState) {
      super.onRestoreInstanceState(savedInstanceState);
    }

bu, olması gerektiği gibi çalışmayan koddur

    String imgUrl;
    Bundle extras = this.getIntent().getExtras();


    if(extras != null){
        imgUrl = extras.getString("imgUrl");
        if( !imgUrl.equals(textView01.getText().toString()) ){

            imageView.setImageDrawable( getImageFromUrl( imgUrl ) );
            layout1.setVisibility(0);
            textView01.setText(imgUrl);//textview to hold the url

        }

    }

Ve niyetim:

public void showNotification(String ticker, String title, String message, 
    String imgUrl){
    String ns = Context.NOTIFICATION_SERVICE;
    NotificationManager mNotificationManager = 
        (NotificationManager) getSystemService(ns);
    int icon = R.drawable.icon;        // icon from resources
    long when = System.currentTimeMillis();         // notification time
    CharSequence tickerText = ticker;              // ticker-text

    //make intent
    Intent notificationIntent = new Intent(this, activity.class);
    notificationIntent.putExtra("imgUrl", imgUrl);
    notificationIntent.setFlags(
        PendingIntent.FLAG_UPDATE_CURRENT | 
        PendingIntent.FLAG_ONE_SHOT);
    PendingIntent contentIntent = 
        PendingIntent.getActivity(this, 0, 
        notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT | 
        PendingIntent.FLAG_ONE_SHOT);

    //make notification
    Notification notification = new Notification(icon, tickerText, when);
    notification.setLatestEventInfo(this, title, message, contentIntent);
    //flags
    notification.flags = Notification.FLAG_SHOW_LIGHTS | 
        Notification.FLAG_ONGOING_EVENT | 
        Notification.FLAG_ONLY_ALERT_ONCE | 
        Notification.FLAG_AUTO_CANCEL;
    //sounds
    notification.defaults |= Notification.DEFAULT_SOUND;
    //notify
    mNotificationManager.notify(1, notification);
}

Niyeti temizlemenin veya daha önce kullanılıp kullanılmadığını kontrol etmenin bir yolu var mı?


Kodlarınızı gönderebilir misiniz?
xandy

Kodu soruma ekledim
Mars

Amacı temizlemek yerine, başlatma türünü belirleyebilir ve uygulama akışını buna göre yönetebilirsiniz. Ekstraları, arka planda değil, yalnızca bildirim için başlatılmışsa alın. stackoverflow.com/questions/4116110/clearing-intent/…
BB

Yanıtlar:


168

GÜNCELLEME:

5 yıldan daha uzun bir süre önce ilk yazdığımda bu cevaba bu kadar çok atıfta bulunulacağını fark etmemiştim!

@ Tato-rodrigo cevabına göre, bunun bazı durumlarda halihazırda ele alınmış bir niyeti tespit etmenize yardımcı olmayacağını açıklığa kavuşturacağım.

Eğer edilir - Ayrıca ben bir sebebi tırnak içinde "açık" koymak işaret etmelidir değil gerçekten, sadece bu niyet zaten aktivitesiyle görülmüştür ki bayrak olarak ekstra kaldırılmasını kullandığınız bunu yaparak niyet takas .


Ben de tamamen aynı sorunu yaşadım.

Yukarıdaki cevap beni doğru yola soktu ve daha da basit bir çözüm buldum, şunu kullanın:

getIntent().removeExtra("key"); 

Amacı "temizlemek" için yöntem çağrısı.

Bir yıl önce sorulduğu için biraz geç cevap veriliyor, ancak umarım bu gelecekte başkalarına yardımcı olur.


4
removeExtra () yöntemi bir String parametresi almıyor mu? bunun gibi getIntent (). removeExtra ("String");
tony9099

25
@Maks Yanılıyor olabilirim ama bunun aşağıdaki senaryoda işe yaramayacağını düşünüyorum: 1) Bildirim yoluyla etkinliği açın; 2) Geri düğmesine basarak etkinliği bitirin; 3) Geçmiş (Son Uygulamalar) aracılığıyla etkinliği yeniden açın. Diğer bir durum, sistemin kaynak yetersizliğinden dolayı uygulamayı sonlandırmasıdır (geliştirici seçenekleri altında "Faaliyetleri tutma" seçeneğini etkinleştirin ve bundan sonra sadece ana ekrana basın ve ardından etkinliği Geçmişten tekrar açın). Kullandığım çözümü aşağıda yayınladım. Bu konuda yorum yapabilirseniz iyi olur.
tato.rodrigo

2
Maalesef bizim için işe yaramıyor. Yeni bir faaliyete başlamanın ve ardından ilk etkinliği başlatmanın OnNewIntent'in aynı niyetle tekrar ateşlenmesine neden olduğunu görüyoruz.
Le-roy Staines

2
Amacı temizlemek yerine, başlatma türünü belirleyebilir ve uygulama akışını buna göre yönetebilirsiniz. Ekstraları, arka planda değil, yalnızca bildirim için başlatılmışsa alın. stackoverflow.com/questions/4116110/clearing-intent/…
BB

2
Benim için çalışmadı. @ Tato.rodrigo ile aynı sorunla karşı karşıyaydım, etkinlik bildirim yoluyla veya geçmişten veya bahsettiği diğer nedenlerden açılırsa niyetin netleşmemesi, bu yüzden niyet bilgisini tükettikten sonra yaptığım şey amacı sıfırlamaktı. bu setIntent(new Intent())ve şimdi iyi çalışıyor.
Shubhral

43

DÜZENLEME: Kullandığım tam çözümü göndermek için düzenleme yapıyorum.

Bu çözüm, sorun "Etkinlik Geçmişten (Son Uygulamalar) başladığında bazı kod çalıştırma" ise işe yarar .

Her şeyden önce, zaten tüketilip tüketilmediğini belirtmek için booleaniçinde bir beyan edin :ActivityIntent

    private boolean consumedIntent;

Ardından, yapılandırma değişikliklerini ve arka plana gittiğinde sistemin sizi öldürebileceği durumları işlemek için onSaveInstanceStateve onCreateyöntemlerini kullanarak bu değeri güvenli bir şekilde depolayın ve geri yükleyin Activity.

    private final String SAVED_INSTANCE_STATE_CONSUMED_INTENT = "SAVED_INSTANCE_STATE_CONSUMED_INTENT";

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean(SAVED_INSTANCE_STATE_CONSUMED_INTENT, consumedIntent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //set content view ...

        if( savedInstanceState != null ) {
            consumedIntent = savedInstanceState.getBoolean(SAVED_INSTANCE_STATE_CONSUMED_INTENT);
        }

        //other initializations
    }

Şimdi, kodunuzu onResumeyöntem altında çalıştırıp çalıştıramayacağınızı kontrol edin .

    @Override
    protected void onResume() {
        super.onResume();

        //check if this intent should run your code
        //for example, check the Intent action
        boolean shouldThisIntentTriggerMyCode = [...];
        Intent intent = getIntent();
        boolean launchedFromHistory = intent != null ? (intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0 : false;
        if( !launchedFromHistory && shouldThisIntentTriggerMyCode && !consumedIntent ) {
            consumedIntent = true;
            //execute the code that should be executed if the activity was not launched from history
        }
    }

Ek olarak, eğer Activityyapılandırıldıysa singleTop, yenisi Intentteslim edildiğinde bayrağınızı sıfırlamalısınız .

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        consumedIntent = false;
    }

12
Çok teşekkürler! Bu koda yardım (intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY)ettim, böylece artık faaliyetin ne zaman tarihe ait olduğunu anlayabiliyorum ve ekstralarımı görmezden gelebiliyorum.
Roman Nazarevych

1
@Lemberg Bende de aynı sorun var ve ben de sizin gibi çözdüm, Anlık bildirimlerden gelen bazı ekstraları kullanırsanız, faaliyetinize geçmişten başlama riski vardır ve dışarıda ekstralarınızı tüketir ve sizinki gibi aynı eyleme yönlendirilirsiniz. bildirim almak. Başlatılan
bayrakFromHistory

etkinlik yok edilse ve onu tarih yığınından tekrar açsak bile işe yarayacak mı?
kullanıcı25

harika! uygulama yok edilmiş olsa bile çalışıyor gibi görünüyor ... ama lütfen @ tato.rodrigo yanıttan kaldırın boolean shouldThisIntentTriggerMyCode = [...];(ne için kullanılır?)
kullanıcı25

Belirli bir kullanıcı için çoklu bildirimleri ile Benim durumumda bu daha iyi bir kullanıcı var consumedIntentolarak Stringbildirim UID içeren. Bu Uid, arka uçtaki bildirime geçerli zaman damgası olarak eklenebilir. Ayrıca, bu Uid'i onSaveInstanceStateyalnızca Intent form geliyorsa kaydetmelisiniz onCreate. Bu, Uid'i kurtarmamanız gerektiği anlamına gelir onNewIntent.
Konstantin Konopko

22

Maks cevabı fazladan bir şeyi temizlemek için çalışır:

    getIntent().removeExtra("key"); 

Başka bir yararlı komut şudur:

    getIntent().setAction("");

Ayrıca şunu arayarak da bir amacı etiketleyebilirsiniz:

    getIntent().putExtra("used", true);

ve sonra sadece değeri kontrol edin.


21

Android uygulamalarını Geçmişten (Son Uygulamalar) başlattığımızda, uygulama öncelikle üç farklı Amaç işaretiyle başlatılabilir.

  1. FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
    Bu, simge durumuna küçültülmüş bir uygulamanın geçmişinden faaliyetin başlatıldığı zamandır (ana sayfa tuşuna uzun basın).
    Sabit Değer: 1048576 (0x00100000)
  2. FLAG_ACTIVITY_NEW_TASK
    Bu, etkinlik "uygulama simgesine tıklayarak" veya " Amaç filtreleri " aracılığıyla başlatıldığında gerçekleşir . Burada etkinlik, bu geçmiş yığınında yeni bir görevin başlangıcı olacaktır.
    Sabit Değer: 268435456 (0x10000000)
  3. FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY | FLAG_ACTIVITY_NEW_TASK
    Bu, geri düğmesine basılarak uygulamadan çıkıldığında ve ardından Geçmiş'ten (son uygulamalar) devam ettirildiğinde gerçekleşir.
    Sabit Değer: 269484032 (0x10100000)

Sabit değer şu yolla alınabilir: getIntent().getFlags()

Üçüncü durumda, Android son Intent değerlerini hafızasından yeniden yükler. Dolayısıyla, uygulamanızın amacı ( getIntent), uygulamayı başlatan son amaçtan değerlere sahip olacaktır.

Aslında, uygulama, önceki lansmanın amaç değerleri yerine yeni bir lansman için amaç değerleriyle yeni bir lansmanmış gibi davranmalıdır. Bu davranış, uygulama simgesini tıklayarak uygulamayı başlatırsanız görülebilir, hiçbir zaman eski amaç değerlerine sahip olmaz. Bunun nedeni, Android'in bu senaryo için aşağıdaki amaç filtresini kullanmasıdır

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

Ancak üçüncü durumda (Kapatılan uygulama, Son uygulamaların Geçmişinden başlatılır), Android OS, uygulamayı çıkmadan önce başlatan son amacı kullanır (geri düğmesine basarak). Böylece eski amaç değerlerine sahip olursunuz ve uygulama akışı düzgün olmaz.

Niyeti kaldırmak, onu çözmenin bir yoludur, ancak sorunu tamamen çözmez! Android OS, Intent'i son başlatılan uygulamalardan yeniden yüklerken, başlatma amacının son örneğini değil.

Bunun olmasını önlemenin temiz bir yolu , başlatma türünü belirlemek için Niyet türünü alarak bunun üstesinden gelmektir .

Yani LaunchActivity içinde (bildirim tanımlanan amaç filtresini vardır bir), sen aşağıdaki kodu kullanabilirsiniz onCreate(), onStart()ya da onResume()yöntemlerin.

if(getIntent().getFlags() == (Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY)) {
    //app is launched from recent apps after it was closed
        normalLaunch();
    } else {
        String intentAction = getIntent().getAction();
        String scheme = getIntent().getScheme();
        //app is launched via other means
        // URL intent scheme, Intent action etc
        if("https".equalsIgnoreCase(scheme)) {
            // URL intent for browser
        } else if("com.example.bb".equalsIgnoreCase(intentAction)) {
            // App launched via package name
        } else {
            // App was launched via Click on App Icon, or other means
            normalLaunch();
        }
    }

Niyetteki normalLaunch()parametreleri kullanmamalıyım; aksi takdirde Amaç parametrelerini kullanmamak için varsayılan başlatma yönteminizi ayırmanız ve optimize etmeniz gerekir.


1
Tüm kahramanlar şapka takmaz!
Sdghasemi

Bilmiyorum, ancak getIntent().getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORYetkinliği başka bir etkinlikten (startActivity yöntemi) başlatırsam veya Geçmiş yığınından (son uygulamalar) yeniden açarsam her zaman doğru döndürür .
kullanıcı25

onu başka bayraklarla birlikte kullanmanız gerekir, belki FLAG_ACTIVITY_NEW_TASK
BB

1
Bu, Geliştirici ayarları "Etkinlikleri tutma" nedeniyle arka planda etkinlik öldürüldüğünde çalışmaz. Bu durumda getIntent () getFlags (), etkinliğin 1. kez başlatıldığı zamanki ile aynıdır.
Malachiasz

açıklamayı takdir ediyorum ama amaçlandığı gibi değil
Azlan Jamal

18

Bir amaç nesnesini temizlemek :

intent.replaceExtras(new Bundle());
intent.setAction("");
intent.setData(null);
intent.setFlags(0);

2
Kabul edilen cevap bu olmalıdır. Gerçekten iyi çalışıyor!
Martin Erlic

2
Geliştirici seçeneklerinde "etkinlikleri tutma" seçeneği işaretlendiğinde
çalışmıyor

8

Kısa cevap Mümkün değil

Uzun cevap. "Tek seferlik" niyet diye bir şey yoktur. Deneyden, modern Android'lerde yakın zamandaki etkinlik geçmişinin "Niyet geçmişi" nden başka bir şey olmadığı görülmüştür. Aktiviteye aktarılan en son amaç, basitçe sisteme girilir ve anlaşma budur. Yukarıdaki insanlar kullanmanızı önerir

setAction("")

Ancak, onNewIntent () veya onStart () yöntemine girdiğiniz ana kadar niyet zaten günlüğe kaydedildiği için çalışmaz.

Amacı kullanmaktan kaçınarak sorunu çözdüm. Benim sorunum yazarın gönderdiği soruna benzerdi. Uygulamadan Global Exit'i bildirim alanında kontrol ile uygulamaya çalıştım. Temel hizmeti durdurmalı ve uygulamanın tüm etkinliklerini kapatmalıdır. Waze uygulamasında da aynı davranışı bulabilirsiniz.

Algoritma:

  1. "Çıkış" eylemini etkinliğe geçiren bildirim kontrolü için PendingIntent oluşturun. Ama basit bir vekil olan özel aktiviteye.
  2. Proxy etkinliği onStart () kodu amacı ayrıştırır, eylemi kontrol eder ve bazı modellerin durumunu "Çıkıldı" olarak ayarlar.
  3. Proxy etkinliği onStart () kodu setIntent ("") kullanarak orijinal amacı temizler ve ardından startActivity (niyet) 'i çağırarak hedef "Kök" etkinliğine iletir.
  4. Proxy etkinliği onStart () kodu finish () 'yi çağırır.
  5. Hedef etkinliğinin onStart () ve onNewIntent () içinde model durumunu kontrol edin ve "Çıktı" ise finish () çağrısı yapın (ve benim durumumda stopService () 'i çağırın).

Umarım bu birisine yardımcı olur çünkü cevabı internette bulamadım.


Bunu en doğru cevap buluyorum, çünkü "amacı temizlemek" mutlaka "belirli fazlalıkları kaldırmak" anlamına gelmiyor. Ayrıca bunu yapmanın kolay bir yolu olduğunu da düşünmüyorum.
mdelolmo

5

PendingIntent için PendingIntent.FLAG_UPDATE_CURRENT işaretini kullandığınızdan emin olun. .

PendingIntent pendingIntent = PendingIntent.getActivity(this, 100, mPutIntent, PendingIntent.FLAG_UPDATE_CURRENT);

Nerede mPutIntentsenin Intent.

Umarım bu sana yardımcı olur.


1
hayatımı kurtardı!!
eren130

1
Bunun nasıl kabul edilen cevap olmadığını anlamıyorum. Tek pişmanlığım sadece bir: tek bir olumlu oy almak. Şerefe.
Andy

2

Son zamanlarda bu problemi yaşadım ve amaca ekstra parametre olarak bir zaman damgası ekleyerek çözdüm:

private void launchActivity(Context context) {
    Intent intent = new Intent(context, MainActivity.class);
    intent.putExtra("KEY_EXTRA_TIMESTAMP", System.currentTimeMillis());
    context.startActivity(intent);
}

Bundan sonra, zaman damgasını paylaşılan tercihlere kaydedin:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    long time = getIntent().getLongExtra("KEY_EXTRA_TIMESTAMP", -1);
    long previousTime = getPreferences(MODE_PRIVATE).getLong("timestamp", -1);

    //ignore if the timestamp is the same as the previous one  
    if (time != previousTime) {
        handleIntent(getIntent());
        if (time != -1) {
            //save the timestamp
            getPreferences(MODE_PRIVATE).edit().putLong("timestamp", time).apply();
        }
    }
}

1

Bende de tam olarak aynı sorun var. Benim çözümüm, 'kullanıldığında' booleanayarlanan değişkeni Intentve kullanmanız gerekip gerekmediğini kontrol etmek ifiçin buna dayalı bir ifade eklemekti .booleanIntent


3
Bu işe yaramayabilir, çünkü etkinlik durdurulduğunda ve yeniden başlatıldığında boole değerleri yeniden oluşturulacaktır (etkinlikte genel olarak belirtilmişse). (örneğin ana sayfa düğmesini tıklayarak)
tony9099

1

Niyeti işlemeyi bitirdiğinizde, şunu yapın:

setIntent(null);

Bu işlenmiş Niyeti bir daha görmeyeceksiniz ve işlenmiş Niyetin içeriğini düzenleyerek sorunu maskelemeyeceksiniz.


1

Intent Extra'yı kaldırmanın bir yolunu bulamadım . Geliştirici Seçeneklerinden " Etkinlikleri Tutmayın " seçeneğini etkinleştirirseniz, fazlalıkları amaçtan kaldırmayla ilgili yanıtların hiçbiri işe yaramaz (Bu şekilde Etkinliği kaldırabilir ve Ekstraların hala orada olup olmadığını test etmek için geri dönebilirsiniz).

Soruna bir çözüm olarak, Amaç Ekstraları işlendikten sonra Boole değerini SharedPreferences'da depoladım . Aktiviteye aynı Niyet tekrar teslim edildiğinde, SharedPreference değerini kontrol ediyorum ve Intent Extra'yı işlemeye karar veriyorum. Aynı Aktiviteye yeni bir Niyet Ekstra göndermeniz durumunda, SharedPreference değerini yanlış yaparsınız ve Activity bunu işler. Örnek :

// Start Activity with Intent Extras
Intent intent = new Intent(context, MyActivity.class);
intent.putExtra("someData", "my Data");
// Set data as not processed
context.getSharedPreferences(BuildConfig.APPLICATION_ID, Context.MODE_PRIVATE).edit().putBoolean("myActivityExtraProccessed", false).commit();
context.startActivity(intent);

...

public class MyActivity{

    ...
    public void someMethod(){
        boolean isExtrasProcessed = context.getSharedPreferences(BuildConfig.APPLICATION_ID, Context.MODE_PRIVATE).getBoolean("myActivityExtraProccessed", false);  
         if (!isExtrasProcessed) {
              // Use Extras

              //Set data as processed
              context.getSharedPreferences(BuildConfig.APPLICATION_ID, Context.MODE_PRIVATE).edit().putBoolean("myActivityExtraProccessed", true).commit();
         }
    }

}

startActivity kullanarak etkinliğe mi başladıysanız yoksa History Stack'den mi yeniden açtığınızı bilmediğiniz için tercih mantıklı değil
kullanıcı25

@ user25 Son uygulamalardan başlatılıp başlatılmadığını tespit etmenin bir yolu olduğunu düşünüyorum. Ama önemli mi, fazladan niyet ya tüketilir ya da tüketilmez, eğer tüketilirse bunu paylaşılan tercihlerden bilirsiniz. Bunu fazladan push bildirimini tüketmek için kullandım ve davam için nasıl aktivite açıldığı önemli değil.
Jemshit Iskenderov

0

Niyet ve Niyet ekstraları ayrıştırıldıktan sonra elle temizlendikten sonra bile Activity.getIntent () her zaman Aktiviteyi başlatan orijinal Niyeti döndürecek gibi görünüyor.

Bunu aşmak için şuna benzer bir şey tavsiye ederim:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // The Intent provided by getIntent() (and its extras) will persist through a restore
    // via savedInstance.  Because of this, restoring this activity from a
    // an instance that was originally started with extras (deep-link or 
    // pre-defined destination) may cause un-desired behavior
    // (ie...infinite loop of sending the user directly to somewhere else because of a
    // pre-defined alternate destination in the Intent's extras).
    //
    // To get around this, if restoring from savedInstanceState, we explicitly
    // set a new Intent *** to override the original Intent that started the activity.***
    // Note...it is still possible to re-use the original Intent values...simply
    // set them in the savedInstanceState Bundle in onSavedInstanceState.
    if (savedInstanceState != null) {
        // Place savedInstanceState Bundle as the Intent "extras"
        setIntent(new Intent().putExtras(savedInstanceState));
    }

    processIntent(getIntent())
}

private void processIntent(Intent intent) {
    if (getIntent().getExtras() == null) {
        // Protection condition
        return;
    }

    doSomething(intent.getExtras.getString("SOMETHING_I_REALLY_NEED_TO_PERSIST"));

    final String somethingIDontWantToPersist = 
        intent.getExtras.getString("SOMETHING_I_DONT_WANT_TO_PERSIST");

    if(somethingIDontWantToPersist != null) {
        doSomething(somethingIDontWantToPersist);
    }
}

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    // Save selective extras from original Intent...
    savedInstanceState.putString("SOMETHING_I_REALLY_NEED_TO_PERSIST", "persistedValued");
    super.onSaveInstanceState(savedInstanceState);
}

Bu şekilde, orijinal Niyet / Niyet ekstralarının belirli bölümlerini açık bir şekilde muhafaza etme yeteneğini korurken, orijinal Niyetten vazgeçmek için bir mekanizma vardır.

Tüm Aktivite başlatma modlarını test etmediğimi unutmayın.


0

Basit yol, onCreate () dışındaki yöntemlerden getIntent () yöntemini çağırmaktan kaçınmaktır. Ancak bu, kullanıcı Ana Sayfa düğmesine dokunarak Aktivitemizden çıkarsa sonraki başlatma sırasında soruna neden olur. Bu sorunun tam anlamıyla işlevsel bir çözümü olmadığını düşünüyorum.


0

Aynı problemle yüzleşiyorum ve yukarıdaki yöntemleri kullanmaya çalışıyorum ama işe yaramıyor.

Bunun singleTop modunu kullandığım acitvity'nin başlatma modu olabileceğini düşünüyorum.

Uygulamayı arka planladığımda ve sorunu simüle etmek için RamEater'ı kullandığımda, bu niyetin her zaman fazladan vardır, hatta null ayarlasam veya anahtarı kaldırsam bile.

Sorun, geçip geçmediğini kontrol etmek için Android'de tercih depolaması kullanılarak giderildi.


0

Ekstraların tüketilip tüketilmediğini bilmek için fazladan bir tane daha eklemek iyi bir uygulama değil, neden bunu yapmayasınız ?:

if (intent.hasExtra(EXTRA_NAME) && intent.getBooleanExtra(EXTRA_NAME, false)) {
    // consume extra here after that set it to false
    putExtra(EXTRA_NAME, false)
}   

-1

Buna ne dersin? NewIntent'i amaç olarak ayarlar.

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    setIntent(intent);
}

1
Bunun işe yaradığını sanmıyorum. Etkinlik tarihten yeniden oluşturulduğunda, niyet etkilenmeden kalır.
mdelolmo

-1

Niyeti ne zaman temizlemek istediğinize ne dersiniz - onu boş bir tane ile değiştirin?

Örneğin.

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    setIntent(intent);
}

@Override 
public void onResume() {
    super.onResume();

    Intent theIntent = getIntent();
    if ("myaction".equals(theIntent.getAction()) {
         handleIntent();
         onNewIntent(new Intent());  // <--- "clear" the intent by setting empty one
    }
}

-1

Bu umarım herkese yardımcı olur. Bu yüzden önce amacı anlıyoruz

//globally
Intent myIntent;

Bunu üzerinde bir yere yerleştirin

myIntent = getIntent();
String data = myIntent.getStringExtra("yourdata");
//Your process here

Şimdi bunu, uygulamamız her yıkıldığında veya çıkıldığında verileri kaldıracak şekilde ayarlayalım

@Override
protected void onDestroy() {
    //TODO: Clear intents
    super.onDestroy();
    myIntent.removeExtra("data");
}
@Override
protected void onBackPressed() {
    //TODO: Clear intents
    super.onBackPressed();
    myIntent.removeExtra("data");
}

Fikri anladınız, eğer bu yeterli değilse, sadece 'geri aramalarda' daha fazlasını bulun


Amaç, yalnızca uygulamadan çıktığınızda temizlenir, ör. Son aramaları kaydırarak.
Pixeldroid Modding

-2

Intent.removeExtra("key")Ekstralardan belirli bir anahtarı kaldıracak olsa da, bir parametre olarak iletilirse , tüm ekstraları Intent'ten silmek için kullanılabilen Intent.replaceExtras (Bundle) yöntemi de vardır null.

Dokümanlardan:

Amaçtaki ekstraları, verilen Ekstra Paketi ile tamamen değiştirin.

Parametreler
ekstraları Amaçtaki yeni ekstralar kümesi veya tüm ekstraları silmek için boş.

PutXXX () yöntemleri ekstraları boşsa yeni bir Bundle ile başlattığından, bu sorun değildir.


-3
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
intent.addCategory(Intent.CATEGORY_HOME);  
startActivity(intent);

2
Yaptığınız şey ve OP'nin sorusunu nasıl yanıtladığı hakkında bazı ayrıntılar vererek cevabınızı detaylandırmayı düşünmelisiniz.
forsvarir

1
@Ramkumar bu kullanıcıyı eve götürür. Açıkça görüldüğü gibi onPause, onStop veya onDestroy çağrılmasına neden olabilecek 10000 vakadan sadece tek bir vakadır.
tony9099

Bu, soruyla uzaktan bile alakalı değil
Hossein Shahdoost
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.