2012-10-15 24 views
9

Bir Launcher yazıyorum, sistemden son uygulama/görev listesini temizlemem gerekiyor, "uygulamalarımı son görev listesinde göstermedim", ancak şu an hakkında hiçbir fikrim yok. Yığın akışında arama yaptım ve yalnızca this issue eşleşti, ancak yanıtın hiçbir yardımı yok. Başka bir adam da aynı soruları sordu, Android 4.0'dan gelen RemoveTask'a katıldı. Evet, Android 2.3.7 ve Android 4.0 kaynak kodunu kontrol ettim, tahmin edilen bir turda, ActivityMangerService.Java:Android, çoğu telefondaki Ana ekran düğmesinden alabileceğiniz son görev listesini nasıl temizlerim? Yansıma olası bir yoldur?

final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 

Ve başka belki yararlı tanım:

public static <T> void clearRecentTaskList(Launcher launcher){ 
    ActivityManager am = (ActivityManager) launcher.getSystemService(Context.ACTIVITY_SERVICE); 
    Object systemRecentTask = new ArrayList<T>(); 

    Object receiver = null; 
    Field recentTaskList = null; 
    Class<?> service = null; 
    Field self = null;   


    try { 
     service = Class.forName("com.android.server.am.ActivityManagerService"); 
     Log.d(LOG_TAG, "clearRecentTaskList, service gotton"+service.getName()); 
    } catch (ClassNotFoundException e2) { 
     Log.d(LOG_TAG, "clearRecentTaskList, class service not found"); 
    } 

    try { 
     self = service.getDeclaredField("mSelf"); 
    } catch (SecurityException e2) { 
     Log.d(LOG_TAG, "clearRecentTaskList, SecurityException during get mSelf"); 

    } catch (NoSuchFieldException e2) { 
     Log.d(LOG_TAG, "clearRecentTaskList, NoSuchFieldException during get mSelf"); 
    } 
    Log.d(LOG_TAG, "clearRecentTaskList, self gotton " + self.toGenericString()); 

    try { 
     self.setAccessible(true); 
     receiver = self.get(null); 
    } catch (IllegalArgumentException e2) { 
     Log.d(LOG_TAG, "clearRecentTaskList, IllegalArgumentException during use self to get the receiver"); 
    } catch (IllegalAccessException e2) { 
     Log.d(LOG_TAG, "clearRecentTaskList, IllegalAccessException during use self to get the receiver"); 
    } 

    if (receiver != null){ 
     Log.d(LOG_TAG, "clearRecentTaskList, receiver is : "+receiver.toString()); 
    } else { 
     Log.d(LOG_TAG, "clearRecentTaskList, receiver is NULL"); 
    } 


    try { 
     recentTaskList = service.getDeclaredField("mRecentTasks"); 
     recentTaskList.setAccessible(true); 
     Log.d(LOG_TAG, "clearRecentTaskList, recentTaskList gotton"+recentTaskList.toGenericString()); 

     try { 
      systemRecentTask = recentTaskList.get(receiver); 
     } catch (IllegalArgumentException e1) { 
      Log.d(LOG_TAG, "IllegalArgumentException during try to clearRecentTask"); 
     } catch (IllegalAccessException e1) { 
      Log.d(LOG_TAG, "IllegalAccessException during try to clearRecentTask"); 
     } 

     Log.d(LOG_TAG, "Try to print the size of recent task: "+((ArrayList<T>) systemRecentTask).size()); 

    } catch (SecurityException e) { 
     Log.d(LOG_TAG, "SecurityException during try to clearRecentTask"); 
    } catch (NoSuchFieldException e) { 
     Log.d(LOG_TAG, "NoSuchFieldException during try to clearRecentTask"); 
    } 
} 
: Java & refelction aşina değilim çünkü ben bir şekilde açık bu liste hakkında yardıma ihtiyacım

static ActivityManagerService mSelf; 
public static ActivityManagerService self() { 
    return mSelf; 
} 

aşağıda Sesimin kodudur

Bu işlevle, her zaman "NullPointerException" ile tanıştım çünkü alıcı kendiliğinden alınıyor. (Bütün deneyin/catch kaldırırsanız) Ve böyle başka bir yol denedi:

self = service.getDeclaredMethod("mSelf", null); 
receiver = self.invoke(null, null); // mSelf is a static method which in ActivityMangerService class 

aynı sonucu ben ActivityManagerService örneğini alamayan ve sonra mRecentTasks alamıyorum. Herhangi bir yorum takdir edildi ve "bu listedeki tüm öğeleri nasıl kaldıracağımı" bilmiyorum, ancak başka sorular olabilir.

Teşekkürler.

+0

Ne tür başlatıcı yazdığınızı anlamıyorum ... neden son programları silmelisiniz? Bana sadece bir güvenlik istisnası gibi geliyor ya da en azından Android varsayılan davranışını çok hoş olmayan bir şekilde değiştiriyormuşsunuz gibi geliyor. Örneğin, bir kötü amaçlı yazılım programı kendini gizleyebilir ... – Radu

+0

Uygulamaya açık olmayan API, uygulamanızın _break_'ine gidecek olan her yayınlama/güncelleme ile değişebilir. Kendi iyi uygulama list_ bileşenine sahip ol. –

+0

İnşallah, bu, yalnızca cihaz yazılımı uygulamalarının tutabileceği bir izinle korunmaktadır; – CommonsWare

cevap

0

burada bu soru üzerinde bunun nasıl ilgili bazı iyi ipucu vardır:

Altering the result of getRecentTasks

bu ardından, tabletler ödünç edilir kendi amaçları için aşağıdaki yaklaşımı (benzer bir durum almış insanlara ve sonra birilerinin bir sonraki kişiye teslim etmeden önce “tarihi temizlemesi” gerekir. Yardımcısı tableti kullanmak sonraki kişi için "Karşılama Ekranı" start ne zaman başlıyorum bir AsyncTask içinde, İkinci

<activity 
    android:name=".nul.Null0" 
    android:enabled="false" 
    android:excludeFromRecents="false" 
    android:exported="false" 
    android:label="n0" 
    android:launchMode="singleInstance" 
    android:stateNotNeeded="true" 
    android:taskAffinity="" 
    android:theme="@android:style/Theme.Translucent.NoTitleBar" > 
    <intent-filter> 
    <action android:name="com.morphoss.blah.welcome.nul.Null0" /> 
    <category android:name="android.intent.category.DEFAULT" /> 
    </intent-filter> 
</activity> 

:

Öncelikle, benim manifest'te, böyle 18 görevleri yarattı Ben tarayıcı geçmişini ve çerezleri temizleyin sonra, aşağıdakileri yapın:

Ben "Thread.sleep (20)" her görevin başlatılması arasında kullanmış iken ben tam orada tam olarak ne tabi incelememiş olduğu
try { 
    PackageManager pm = getPackageManager(); 
    ComponentName cn; 
    Intent nullActivity; 
    for(int i=0; i<19; i++) { 
     cn = new ComponentName("com.morphoss.blah.welcome","com.morphoss.blah.welcome.nul.Null"+i); 
     pm.setComponentEnabledSetting(cn, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP); 
     nullActivity = new Intent(); 
     nullActivity.setComponent(cn); 
     nullActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
     startActivity(nullActivity); 
     Thread.sleep(20); 
    } 
    Thread.sleep(100); 
    for(int i=0; i<18; i++) { 
     cn = new ComponentName("com.morphoss.blah.welcome","com.morphoss.blah.welcome.nul.Null"+i); 
     pm.setComponentEnabledSetting(cn, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); 
    } 
} 
catch(Exception e) { 
    if (Constants.LOG_DEBUG) Log.d(TAG,Log.getStackTraceString(e)); 
} 

ve belki daha kısa bir süre işe yarayabilir. Benim amaçlarım için bunlar silinirken 1 saniyelik bir gecikme sorunlu değildir. Bu yardımcı olur

package com.morphoss.blah.welcome.nul; 

import android.app.Activity; 
import android.os.Bundle; 

public class Null0 extends Activity { 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     this.finish(); 
    } 
} 

Hope: Nihai maddeler

şuna benzer başlatan ediliyor onsekiz (çok basit) faaliyetlerdir.

+0

Teşekkürler, Karora, ekibimizin yeterince iyi olduğunu düşünmese de uygulanabilir bir çözüm olabilir. Umarız yansıma yolu çalışabilir –

1

Ben olabilir benim daha önceki cevabı düzenlenmiş olsa da, ben farklı bir projede kullanmış bu çözüm yeniden başlamak daha iyi olması için kapsamlı farklı (ve daha kolay) 'dir ... Bu durumda

Ben basitçe ActivityManager ait removeTask() yöntemini erişmek için yansıma kullanmış ve şöyle ben MyActivityManager bir kolaylık sınıfa bütün bunlar sarılmış ettik:

import java.lang.reflect.Method; 

public class MyActivityManager { 


    private ActivityManager mActivityManager = null; 
    private Method mRemoveTask; 

    public MyActivityManager(Context context) { 
     try { 
      Class<?> activityManagerClass = Class.forName("android.app.ActivityManager"); 
      mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); 

      mRemoveTask = activityManagerClass.getMethod("removeTask", new Class[] { int.class, int.class }); 
      mRemoveTask.setAccessible(true); 

     } 
     catch (ClassNotFoundException e) { 
      Log.i("MyActivityManager", "No Such Class Found Exception", e); 
     } 
     catch (Exception e) { 
      Log.i("MyActivityManager", "General Exception occurred", e); 
     } 
    } 

    /** 
    * If set, the process of the root activity of the task will be killed 
    * as part of removing the task. 
    */ 
    public static final int REMOVE_TASK_KILL_PROCESS = 0x0001; 

    /** 
    * Completely remove the given task. 
    * 
    * @param taskId Identifier of the task to be removed. 
    * @param flags Additional operational flags. May be 0 or 
    * {@link #REMOVE_TASK_KILL_PROCESS}. 
    * @return Returns true if the given task was found and removed. 
    */ 
    public boolean removeTask(int taskId, int flags) { 
     try { 
      return (Boolean) mRemoveTask.invoke(mActivityManager, Integer.valueOf(taskId), Integer.valueOf(flags)); 
     } catch (Exception ex) { 
      Log.i("MyActivityManager", "Task removal failed", ex); 
     } 
     return false; 
    } 

    public void clearRecentTasks() { 
     List<RecentTaskInfo> recents = mActivityManager.getRecentTasks(1000, ActivityManager.RECENT_IGNORE_UNAVAILABLE); 
     // Start from 1, since we don't want to kill ourselves! 
     for(int i=1; i < recents.size(); i++) { 
      removeTask(recents.get(i).persistentId, 0); 
     } 
    } 

} 

Sonra son görevlerini temizlemek istediğinizde, ben aşağıdakileri yapın:

new MyActivityManager(this).clearRecentTasks(); 

Bu çalışması için bir veya bunlardan her ikisi de gereklidir mümkündür: Benim durumumda

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

uygulama sistemi izinleri ile birlikte yüklenir.

+3

Bu bağlantıya göre: http://stackoverflow.com/questions/19349958/clear-all-recent-task-programmaticcally Cevabınız aslında görevleri kaldırmayacaktır.Hala ROM imzalı bir geliştirici değilseniz, işe yaramazsa, görevleri kaldırmak için izin eklemeniz gerekir. –

1

bulduğum en iyi yolu bu yapmaktır: Bu benim kendi kodu değil, ama bu sadece gösterilmesini son uygulamalar listesini gizler

public class BaseActivity extends Activity { 
    public void onWindowFocusChanged(boolean hasFocus) { 
     super.onWindowFocusChanged(hasFocus); 

      Log.d("Focus debug", "Focus changed !"); 

     if(!hasFocus) { 
      Log.d("Focus debug", "Lost focus !"); 

      Intent closeDialog = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 
      sendBroadcast(closeDialog); 
     } 
    } 
}// all credit goes here: http://www.juliencavandoli.com/how-to-disable-recent-apps-dialog-on-long-press-home-button/ 

.

+1

bunu diğer etkinliklerde nasıl arayabilirim? – androidBoomer

0

Sadece aynı sorunla karşılaştım. Tamam, son listeyi ne kadar açık bilmiyorum, ama biliyorum, uygulamanızı oraya nasıl koymuyorsunuz. ile başlayın: FLAG_ACTIVITY_NO_HISTORY bayrağı.

Bu benim için çalıştı, umarım sizin için yardımcı olabilirim. Şerefe, ayrıntılar: min SDK seviyesi 14