簡體   English   中英

用戶關閉屏幕后是否開始活動?

[英]Start activity when user turns screen off?

我有一個想要提高安全性的應用程序。 當用戶解鎖設備時,我希望應用程序返回登錄屏幕,以使入侵者無法僅通過解鎖設備並使應用程序恢復其原始狀態就可以使用該應用程序。

我正在使用BroadcastReceiver來檢測何時按下電源按鈕,但這當前導致登錄屏幕被加載,而不管用戶在按下電源按鈕之前是否正在使用該應用程序。

在下面,我包括了我的BroadcastReceiver代碼,如果可能的話,也許有人可以闡明這個問題?

public class ScreenReceiver extends BroadcastReceiver {

    public static boolean wasScreenOn = true;

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
            Intent n = new Intent(context, MainActivity.class);
            context.startActivity(n);
            wasScreenOn = false;
        } else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
            wasScreenOn = true;
        }
    }
}

當用戶單擊主頁按鈕時 ,將調用onPause()和onStop()。 當他們單擊后退按鈕 (退出應用程序)時,將調用onPause(),onStop()和onDestory()。 最后,當他們按下電源按鈕時 ,將調用onPause()和onStop()。

它們都有onPause()首先被調用。 覆蓋onPause()並使用intent返回主活動。 您還可以清除活動堆棧,以使它們無法單擊“后退”按鈕返回到一項。

主要活動

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button goPrivate = (Button) findViewById(R.id.goPrivate);

        goPrivate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startActivity(new Intent(MainActivity.this, Private.class));
            }
        });
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.vzw.www.myapplication.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="MAIN"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="GO TO PRIVATE"
        android:id="@+id/goPrivate"/>

</RelativeLayout>

創建一個新的活動。 我命名為Private.java

私有.java

public class Private extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_private);
    }

    @Override
    protected void onPause() {
        super.onPause();
        startActivity(new Intent(Private.this, MainActivity.class));
    }
}

activity_private.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.vzw.www.myapplication.Private"
    android:layout_gravity="center">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="PRIVATE!"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true" />

</RelativeLayout>

只需在Android Studio中創建一個空白項目,然后嘗試即可。 有用! :)

如果我們單擊另一個活動並深入應用程序,會發生什么?

在Private類內部創建一個布爾值。

boolean goSuperClicked = false;

更新后的私有類如下:

public class Private extends AppCompatActivity {

    Button goSuper;
    boolean goSuperClicked = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_private);

        goSuper = (Button) findViewById(R.id.goSuper);

        goSuper.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                goSuperClicked = true;
                startActivity(new Intent(Private.this, SuperPrivate.class));
            }
        });
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d("onPause()", "onPause called");
        if (!goSuperClicked) {
            startActivity(new Intent(Private.this, MainActivity.class));
        }

    }
}

我認為這實際上不是您想要的。 如果他們有鎖定屏幕,則必須在屏幕上輸入密碼。 您可以確定它是合適的人。 如果您想要這種行為,則由於不活動而希望使會話超時。

無論哪種方式,解決方案都是相同的。 在onResume中,您應該檢查它們是否超時/進入鎖定屏幕。 如果是這樣,將登錄屏幕作為一個新任務啟動(這將阻止后退按鈕將您帶回到該屏幕),並完成()當前活動。 向登錄屏幕傳遞一些信息,以便它可以重新創建當前活動。 驗證用戶后,檢查該信息並從中創建正確的活動。 如果該信息不存在,請啟動標准主屏幕。

傳遞足夠信息以創建新Activity的最簡單方法是,將包含活動名稱或URL以及調用onSaveInstanceState的結果的Bundle傳遞給它。

一些建議:

1)設置檢測屏幕開/關意圖的廣播接收器。

Intent.ACTION_SCREEN_OFF and ACTION_SCREEN_ON

2)實現廣播接收器,當它與“ 屏幕關閉”匹配時啟動“活動”

3)通過PowerManager檢測屏幕的開與關

PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
boolean isScreenOn = pm.isScreenOn();

4)由於屏幕關閉發生在onStop()回調上,因此,您必須將以上代碼放入Activity生命周期的onStop()回調中。 像下面這樣。

PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
    boolean isScreenOn = pm.isScreenOff();
if(isScreenOn) {
 sendBroadcast(<your_screenOff_intent);
}

這樣,但是由於安全鎖(打開設備),我認為它無法實現。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM