Zamknout android aplikace po určitou dobu nečinnosti

hlasů
6

Můj android aplikace vyžaduje heslo, které mají být uvedeny v první aktivitě. Chci, aby bylo možné automaticky odeslat žádost zpět na obrazovku pro zadání hesla poté, co byla žádost nepracoval po stanovenou dobu.

Aplikace má mnoho aktivit, ale rád bych časový limit být globální pro všechny činnosti. Tak, to by nemělo být postačující pro vytvoření časovače nit ve onPause()způsobu Activity.

Nejsem si jistý, co je nejlepší definice pro uplatnění nečinnosti je, ale žádná činnost pohody aktivní by mělo stačit.

Položena 23/02/2009 v 06:23
zdroj uživatelem
V jiných jazycích...                            


4 odpovědí

hlasů
5

Vím, že jiná odpověď byla přijata již, ale narazil jsem na tomto pracoval na podobném problému a myslím, že budu snažit střídavou mnohem jednodušší přístup, který mě napadlo, může stejně dokumentovat, jestli někdo chce pokusit se jít dolů stejný path.enter kód zde

Obecná myšlenka je jen sledovat čas systémových hodin v SharedPreference kdykoli pozastaví každou činnost - Zní to dost jednoduché, ale bohužel, je tu bezpečnostní díra v případě, že je vše, co použít, protože to hodiny vynuluje při restartu. Obejít, že:

  • Mají Applicationpodtřídy nebo sdílené statické třídě ojedinělým s globální odemčena, neboť-boot state (zpočátku false). Tato hodnota by měla žít tak dlouho, jak proces vaší aplikace.
  • Ušetřit systémový čas ( v reálném čase od zavedení systému) v každé příslušné Activitytých onPausedo SharedPreferencejestli je současný stav aplikace odemčena.
  • V případě, že appwide odemčené, protože-boot stát je falešný (čisté spuštění aplikace - buď aplikace nebo telefon restartován), zobrazí obrazovku uzamčení. V opačném případě zkontrolujte SharedPreference‚s value at onResume uzamykatelném činnost vznikla; jestli je to neexistující nebo větší než SharedPreferencehodnota + intervalu časového limitu, také ukazují na obrazovku uzamčení.
  • Je-li aplikace odemčena, nastavte appwide odemknout-Since spouštění stavu na hodnotu true.

Kromě časového limitu, tento přístup bude také automaticky zamknout aplikaci, pokud vaše aplikace je zabit a restartuje nebo je-li váš telefon restartuje, ale nemyslím si, že to je především špatný problém pro většinu aplikací. Je to něco málo přes bezpečné a mohou uzamknout unecessarily na uživatelích, kteří úkol přepínat hodně, ale myslím, že to stojí za kompromis pro snížení kód a složitosti prostřednictvím úplné odstranění případných pozadí procesu / zámek probuzení obavy (ne služby, alarmy nebo přijímačů potřebných ).

Obejít proces zabíjení zablokování aplikace bez ohledu na čas, místo sdílení appwide Singleton pro odemčené-od-boot, můžete použít SharedPreference a zaregistrovat posluchače k ​​zavádění systému vysílání úmyslem stanovit, že přednost false. Že re-přidává některé složitosti výchozího roztoku se dávka je trochu více pohodlí v případě, že proces této aplikace je zabit, když do pozadí v průběhu času timeoutu, ačkoliv pro většinu aplikací je to asi zbytečná.

Odpovězeno 28/06/2011 v 05:10
zdroj uživatelem

hlasů
3

jsem se zabýval tím, že pomocí AlarmManager naplánovat a zrušení časového limitu akci.

Poté v onPause () případě všech svých aktivit, naplánovat alarm. V onResume () případě všech svých aktivit, zkontrolujte, zda jsem se zjistit, zda se spustí alarm. V případě, že alarm odešel, jsem shutdown moje app. V případě, že alarm nebyl dosud zhasnul jsem ho zrušit.

Vytvořil jsem Timeout.java řídit své alarmy. Když se spustí alarm záměr je aktivována:

public class Timeout {
    private static final int REQUEST_ID = 0;
    private static final long DEFAULT_TIMEOUT = 5 * 60 * 1000;  // 5 minutes

    private static PendingIntent buildIntent(Context ctx) {
        Intent intent = new Intent(Intents.TIMEOUT);
        PendingIntent sender = PendingIntent.getBroadcast(ctx, REQUEST_ID, intent, PendingIntent.FLAG_CANCEL_CURRENT);

        return sender;
    }

    public static void start(Context ctx) {
        ctx.startService(new Intent(ctx, TimeoutService.class));

        long triggerTime = System.currentTimeMillis() + DEFAULT_TIMEOUT;

        AlarmManager am = (AlarmManager) ctx.getSystemService(Context.ALARM_SERVICE);

        am.set(AlarmManager.RTC, triggerTime, buildIntent(ctx));
    }

    public static void cancel(Context ctx) {
        AlarmManager am = (AlarmManager) ctx.getSystemService(Context.ALARM_SERVICE);

        am.cancel(buildIntent(ctx));

        ctx.startService(new Intent(ctx, TimeoutService.class));

    }

}

Pak jsem vytvořil službu zachytit záměr generovaný alarmem. Stanoví nějaké globální stát v mé instance třídy aplikačního což znamená, že aplikace by měla zamknout:

public class TimeoutService extends Service {
    private BroadcastReceiver mIntentReceiver;

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

        mIntentReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();

                if ( action.equals(Intents.TIMEOUT) ) {
                    timeout(context);
                }
            }
        };

        IntentFilter filter = new IntentFilter();
        filter.addAction(Intents.TIMEOUT);
        registerReceiver(mIntentReceiver, filter);

    }

    private void timeout(Context context) {
        App.setShutdown();

        NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        nm.cancelAll();
    }

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

        unregisterReceiver(mIntentReceiver);
    }

    public class TimeoutBinder extends Binder {
        public TimeoutService getService() {
            return TimeoutService.this;
        }
    }

    private final IBinder mBinder = new TimeoutBinder();

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

}

Nakonec jsem vytvořil podtřídy aktivity, aby veškeré činnosti mé aplikaci je podtřídy od řídit zamykání a odemykání:

public class LockingActivity extends Activity {

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

        Timeout.start(this);
    }

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

        Timeout.cancel(this);
        checkShutdown();
    }

    private void checkShutdown() {
        if ( App.isShutdown() ) {
            finish();
        }

    }

}

Používání onPause a onResume ke spuštění a zastavení timeout mi dává následující sémantiku. Tak dlouho, dokud je aktivní jedna z činností mé žádosti je časový limit hodiny neběží. Vzhledem k tomu jsem použil typ alarmu z AlarmManager.RTC, kdykoli telefon přejde do režimu spánku prodlevu hodiny běží. V případě, že timeout se stane, když je telefon v režimu spánku, pak můj servis zvedne časový limit, jakmile telefon probudí. Navíc, čas běží, když jakákoliv jiná aktivita je otevřená.

Pro podrobnější verzi z nich, můžete vidět, jak jsem ve skutečnosti realizována je v mé žádosti https://github.com/bpellin/keepassdroid

Odpovězeno 28/11/2009 v 02:22
zdroj uživatelem

hlasů
2

Podívejte se, jak OpenIntents Safe implementuje tuto funkci.

Odpovězeno 23/02/2009 v 06:37
zdroj uživatelem

hlasů
0

To bylo opravdu užitečné místo pro mě. Chcete-li zálohovat koncepci vydané @Yoni Samlan. Jsem implementoval to takhle

public void pause() {
        // Record timeout time in case timeout service is killed    
        long time = System.currentTimeMillis();     
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
        SharedPreferences.Editor edit = preferences.edit();
        edit.putLong("Timeout_key", time);// start recording the current time as soon as app is asleep
        edit.apply();
    }

    public void resume() {       
        // Check whether the timeout has expired
        long cur_time = System.currentTimeMillis();
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
        long timeout_start = preferences.getLong("Timeout_key", -1);
        // The timeout never started
        if (timeout_start == -1) {
            return;
        }   
        long timeout;
        try {
            //timeout = Long.parseLong(sTimeout);
            timeout=idle_delay;
        } catch (NumberFormatException e) {
            timeout = 60000;
        }
        // We are set to never timeout
        if (timeout == -1) {
            return;
        }
        if (idle){
        long diff = cur_time - timeout_start;
        if (diff >= timeout) {  
            //Toast.makeText(act, "We have timed out", Toast.LENGTH_LONG).show(); 
            showLockDialog();
        }
        }
    } 

Volejte metodu pauzy od onPause a obnovení metody z onResume.

Odpovězeno 06/11/2014 v 16:17
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more