I am trying to make a view in Android which cannot be closed. I mean that all UI system buttons (Home, back, status bar, etc.) are disabled. Destination way to close app or to open not blocked view is NFC card.
I have been trying to do this for last week and i have no more idea. Maybe someone of you will know how to do that. Thanks for any help.
I am able to hide navigation and status bar, but if I swipe from edge of the screen then it appears again.
Most of working things I have found on the developer.android.com and in (GitHub repo).
But still I am able to close app.
Playground code: https://github.com/BoguskiAdam/AndroidNoUiButtons
_________________________
EDIT:
I have seen few applications like that. I want to make it to be something like in the 'kiosk' mode. User shouldn't be allowed to minimalize application. He may only use it but he can't go to the first view. Only I can open first view using NFC card. NFC is configured to open first view (which is not available for user) which contains configuration etc and allows me to close app.
_________________________
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.adam.nohome">
<uses-permission android:name="android.permission.REORDER_TASKS"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning">
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="Test label"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name=".NoUiActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="Test tittle"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
View XML:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000"
tools:context=".NoUiActivity">
</android.support.constraint.ConstraintLayout>
View code:
package com.example.adam.nohome
import android.app.ActivityManager
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.os.PersistableBundle
import android.util.Log
import android.view.*
class NoUiActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?, persistentState: PersistableBundle?) {
supportActionBar?.setDisplayHomeAsUpEnabled(false)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_no_ui)
hideUi()
}
override fun onPause() {
val activityManager = applicationContext
.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
activityManager.moveTaskToFront(taskId, 0)
super.onPause()
}
private fun hideUi() {
window.statusBarColor = Color.TRANSPARENT
setGestureDetector()
hideSystemUI()
setUiListener()
}
private fun setGestureDetector() {
val contentView = window.decorView
contentView.isClickable = true
val clickDetector = GestureDetector(this,
object : GestureDetector.SimpleOnGestureListener() {
override fun onSingleTapUp(e: MotionEvent): Boolean {
hideSystemUI()
return true
}
}
)
contentView.setOnTouchListener { _, motionEvent -> clickDetector.onTouchEvent(motionEvent) }
}
private fun hideSystemUI() {
window.decorView.systemUiVisibility = (
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_FULLSCREEN
//or View.SYSTEM_UI_FLAG_LOW_PROFILE
or View.SYSTEM_UI_FLAG_IMMERSIVE
)
}
// private fun hideSystemUI() {
// window.decorView.systemUiVisibility = (
// View.SYSTEM_UI_FLAG_LAYOUT_STABLE
// or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
// or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
// or View.SYSTEM_UI_FLAG_IMMERSIVE
// )
// }
private fun setUiListener() {
window.decorView.setOnSystemUiVisibilityChangeListener { flags ->
run {
supportActionBar?.hide()
hideSystemUI()
}
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
//handle the click on the back arrow click
val result = when (item.itemId) {
android.R.id.home -> {
onBackPressed()
true
}
else -> super.onOptionsItemSelected(item)
}
return result
}
override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
hideSystemUI()
}
// It recognize here only 'Back' button
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_HOME || keyCode == KeyEvent.KEYCODE_MOVE_HOME) {
return true;
}
return super.onKeyDown(keyCode, event)
}
}
First view that opens view that cannot be closed:
Second view that shouldn't allow to easily go close app:
Second view after swipe from edge of the screen:
SOLVED: Used Spinned screen / kiosk / Cosu mode. I had additional problem with allowing NFC but found workaround. How can I send a string through NFC while Screen-Pinning?