I am working on a research project for my university. The app will never be put on the market and only used for research.
I have made a homescreen app by using the Google Homescreen sample code.
In there, I have made an activity that is a lockscreen.
While in there, the user should not be able to get out of the lock by pressing Home, Back, etc.
The Back-Button seems to be disabled, but the Home-Button is not.
I have tried several solutions from the internet and stackoverflow, which are all not working.
Here is the important code:
(Notice: Logcat shows "Button pressed: 4" for the Back-Button but nothing for the home button!)
In my Lock-Screen Activity:
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
Log.v(TAG, "BUTTON PRESSED: " + new Integer(keyCode).toString());
if ((keyCode == KeyEvent.KEYCODE_BACK)) {
return true;
} else if ((keyCode == KeyEvent.KEYCODE_CALL)) {
return true;
}
else if ((keyCode == KeyEvent.KEYCODE_HOME)){
return true;
}
return super.onKeyDown(keyCode, event);
}
#Override
public void onAttachedToWindow() {
this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
super.onAttachedToWindow();
}
It seems like the onAttachedToWindow() Method is not working since Android Version 4.
How can I disable the homebutton?
EDIT: Manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.home" >
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.SET_WALLPAPER" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<permission android:name="android.permission.WRITE_SECURE_SETTINGS" >
</permission>
<application
android:icon="#drawable/ic_launcher_home"
android:label="#string/home_title" >
<service android:name=".MyService" >
</service>
<activity
android:name="Home"
android:launchMode="singleInstance"
android:stateNotNeeded="true"
android:theme="#style/Theme" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<receiver android:name=".ScreenReceiver" >
<intent-filter>
<action android:name="android.intent.action.SCREEN_ON" />
<action android:name="android.intent.action.SCREEN_OFF" />
<action android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
</receiver>
</activity>
<activity
android:name="Wallpaper"
android:icon="#drawable/bg_android_icon"
android:label="Wallpaper" >
<intent-filter>
<action android:name="android.intent.action.SET_WALLPAPER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:name=".LockPage" >
<intent-filter>
<action android:name="android.intent.action.SCREEN_ON" />
<action android:name="android.intent.action.SCREEN_OFF" />
<action android:name="android.intent.action.USER_PRESENT" />
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.MONKEY" />
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.MAIN" />
<data android:mimeType="text/plain" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" />
</intent-filter>
</activity>
</application>
</manifest>
This may come a bit late, I have been on a somewhat similar situation. My problem was that I didn't want users to leave the call screen during phone calls but I couldn't prevent it, so instead I simply brought it back front every time they left it.
In your case you could simply bring your app back to front on pause:
#Override
protected void onPause() {
super.onPause();
// Close and reopen app or bringToFront()
}
So leaving would automatically open the app again. You should try either reopening your activity or bringing it to front and see what works best. Reopening may be unnoticeable if you remove all animations and add FLAG_ACTIVITY_NO_ANIMATION.
It seems like the Home Button press is not forwarded to the app in a homescreen application.
Therefore I made a normal app, put my broadcastReceiver and my service in and now I can disable the homebutton and the backbutton.
Still the recent Apps button can be used to jump out of my lockscreen. You can flood it with dummy entries which might work.
Hope that helps someone!
#Override
public void onAttachedToWindow()
{
super.onAttachedToWindow();
this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
}
And now handle the key event like this,
#Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if(keyCode == KeyEvent.KEYCODE_HOME)
{
Log.i("Home Button","Clicked");
}
if(keyCode==KeyEvent.KEYCODE_BACK)
{
finish();
}
return false;
}
This is not possible without changing the Android source: [Mentioned here][1].
Also this would break the Android Activity Cycle, which is not recommended.
this code works in my application
#Override
public void onAttachedToWindow() {
this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD);
super.onAttachedToWindow();
}
Related
I'm using flutter and I'm a bad understand native android development very well.
I'm using 2 Activities in my project:
SplashActivity - visible 1 time at the time of launching the app.
MainActivity - the main part of the application.
The problem is that when receiving push-notification from Firebase and when clicking on the notification, the program is completely restarted starting from SlashActivity. I added isTaskRoot to my SplashActivity, but it turned out not to be true, because my notification, when clicked, stopped calling a callback(), only expands the app or opens it starting with SplashActivity.
How it should work:
If MainActivity already exists (either in the background or foreground), open that same instance.
If MainActivity was destroyed (the user previously pressed Back), then open the SplashActivity. The splash activity will redirect you itself to MainActivity.
Notification should be targeted at the MainActivity and changed flow (callback), in depend on the previous points.
#SuppressLint("CustomSplashScreen")
public class SplashActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
// bad decision
if (!isTaskRoot()) {
finish();
return;
}
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.launch_screen);
new Handler().postDelayed(() -> {
Intent intent = new Intent(SplashActivity.this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
startActivity(intent);
overridePendingTransition(0, 0);
finish();
}, 2000);
}
}
import io.flutter.embedding.android.FlutterFragmentActivity
class MainActivity: FlutterFragmentActivity() {
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app">
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:label="example"
android:name="${applicationName}"
android:icon="#mipmap/ic_launcher">
<activity
android:name=".SplashActivity"
android:parentActivityName=".MainActivity"
android:exported="true"
android:allowBackup="true"
android:launchMode="singleTask"
android:theme="#style/AppTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="#drawable/launch_background"
/>
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="#style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"
android:theme="#style/LaunchTheme">
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="#style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<meta-data
android:name="flutterEmbedding"
android:value="2" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="high_importance_channel" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="#drawable/ic_notification" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="#color/colorNotification" />
</application>
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
</intent>
<intent>
<action android:name="android.intent.action.SENDTO" />
<data android:scheme="mailto" />
</intent>
</queries>
</manifest>
I/flutter (16767): onMessage event: Notification text - Test a body message
E/libc (16767): Access denied finding property "ro.vendor.df.effect.conflict"
E/libc (16767): Access denied finding property "ro.vendor.knock.type"
W/example.app(16767): Accessing hidden method Landroid/os/WorkSource;->add(I)Z (greylist,test-api, reflection, allowed)
W/example.app(16767): Accessing hidden method Landroid/os/WorkSource;->add(ILjava/lang/String;)Z (greylist,test-api, reflection, allowed)
W/example.app(16767): Accessing hidden method Landroid/os/WorkSource;->get(I)I (greylist, reflection, allowed)
W/example.app(16767): Accessing hidden method Landroid/os/WorkSource;->getName(I)Ljava/lang/String; (greylist, reflection, allowed)
W/FirebaseMessaging(16767): Unable to log event: analytics library is missing
W/FirebaseMessaging(16767): Unable to log event: analytics library is missing
D/DecorView[](16767): getWindowModeFromSystem windowmode is 1
D/DecorView(16767): createDecorCaptionView windowingMode:1 mWindowMode 1 isFullscreen: true
I am working on an app In this, I have to send the current status of the android devices in 30-30 seconds through my app which I have done. But the problem I am facing is the app is not starting after boot complete this problem is related to some of android devices.
MY Code is:
public class BootCompletedReceiver extends BroadcastReceiver {
private static final String TAG = "BootCompletedReceiver";
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG,"action : "+intent.getAction());
if (Objects.requireNonNull(intent.getAction()).equals(Intent.ACTION_BOOT_COMPLETED)){
Log.d(TAG,"receive boot completes : "+intent.getAction());
#SuppressLint("StaticFieldLeak")
AsyncTask task = new AsyncTask() {
#Override
protected Object doInBackground(Object[] objects) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
context.startForegroundService(new Intent(context, StatUpdateService.class));
}
};
task.execute();
}
}
}
Manifests file:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<......./>
<receiver
android:name=".receiver.BootCompletedReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
List item
On Some of the android devices, This Code is working and My app is starting after boot complete, but on the Some of the android devices, it's not working.
Android does not auto-start any application until you manually launch it at least once. After that, the applications will automatically start on each Android boot.
Add android.permission.RECEIVE_BOOT_COMPLETED permission in your manifest.
When Android finishes booting and is ready to start the home activity, the home event is sent and qualifying applications identify themselves as bootable candidates. The system sends out the android.intent.category.HOME and android.intent.category.DEFAULT intents when it's done initializing.
<?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.test.app">
<!-- add this -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:theme="#style/app_theme_red">
<!-- main -->
<activity
android:name=".ui.activity.MainActivity"
android:exported="true">
<!-- main filter -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<!-- add this -->
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<!-- boot receiver -->
<receiver android:name=".BootReceiver"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
I'm creating a pinned shortcut of my app launcher icon for Android O device (either emulator or physical device) and found strange behaviour. My code looks like this:
#TargetApi(Build.VERSION_CODES.O)
private void createPinnedShortcut(Context context) {
ShortcutManager shortcutManager = context.getSystemService(ShortcutManager.class);
if (shortcutManager != null) {
if (shortcutManager.isRequestPinShortcutSupported()) {
Intent intent= MainActivity.getLaunchIntent(this);
intent.setAction(Intent.ACTION_VIEW);
ShortcutInfo shortcut = new ShortcutInfo.Builder(context, "my_shortcut_id")
.setShortLabel(context.getString(R.string.my_app_description))
.setLongLabel(context.getString(R.string.my_app_long_description))
.setIcon(Icon.createWithResource(context, R.mipmap.my_app_icon))
.setIntent(intent)
.build();
shortcutManager.requestPinShortcut(shortcut, null);
} else
Toast.makeText(context, "Pinned shortcuts are not supported!", Toast.LENGTH_SHORT).show();
}
}
Everything works, but the launcher icon on the home screen is duplicated:
There is a normal icon, but on right lower corner it placed yet another copy of the icon (about 30-40% smaller).
My icon resources are in res/mipmap-*dpi* folders
Any hints, clues?
Update
Answering to comments:
1) AndroidManifest under ./build/manifests/debug looks like:
<activity
android:name="ru.ivanovpv.cellboxkeeper.android.MainActivity"
android:exported="true"
android:label="#string/cellboxkeeper"
android:theme="#style/DefaultActivityTheme.Light"
android:windowSoftInputMode="adjustResize" >
<layout
android:defaultHeight="800dp"
android:defaultWidth="480dp"
android:gravity="top|end"
android:minHeight="320dp"
android:minWidth="240dp" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter> <!-- handle cbx files -->
<intent-filter
android:icon="#mipmap/cellboxkeeper"
android:label="#string/cellboxkeeper"
android:logo="#mipmap/cellboxkeeper" >
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="*"
android:mimeType="*/*"
android:pathPattern=".*\\.cbx"
android:scheme="content" />
</intent-filter>
<!-- receive files from android share intent -->
<intent-filter
android:icon="#mipmap/cellboxkeeper"
android:label="#string/addToCellboxKeeper" >
<action android:name="android.intent.action.SEND" />
<action android:name="android.intent.action.SEND_MULTIPLE" />
<data android:mimeType="*/*" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
2) There's not any folder like: mipmap-*-v26. Here's screenshot of folders in real apk. All icons in folders are normal (w/o duplication).
Any other versions?
I found solution, key is attribute android:logo:
<intent-filter
android:icon="#mipmap/cellboxkeeper"
android:label="#string/cellboxkeeper"
android:logo="#mipmap/cellboxkeeper" >
<action android:name="android.intent.action.VIEW" />
Deleting line with android:logo fixes duplication issue.
Hope, someone and sometimes will use and understands what's goin on
I can not disable home button and Which is next to it in android I tried this code but does not work
#Override
public void onAttachedToWindow() {
this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
super.onAttachedToWindow();
}
Do you have any idea for solve this problem?
Or Can I hide navigation bar permanently forever؟
Can I hide navigation bar permanently forever?
No, system would not allow you to do so. But you can prevent the app from exiting.
Do the following in your onPause() method.
#Override
protected void onPause() {
super.onPause();
ActivityManager activityManager = (ActivityManager) getApplicationContext()
.getSystemService(Context.ACTIVITY_SERVICE);
activityManager.moveTaskToFront(getTaskId(), 0);
}
You need the following permissions
<uses-permission android:name="android.permission.GET_TASKS"/>
<uses-permission android:name="android.permission.REORDER_TASKS" />
I found it.
I took a part from here
how to disable home button in android?
and added one row Which originally existed
LAUNCHER row as follow:
<activity android:name=".MainActivity"
android:clearTaskOnLaunch="true"
android:excludeFromRecents="true"
android:launchMode="singleTask"
android:screenOrientation="portrait"
android:stateNotNeeded="true" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
I have an android project for first time installation.
It is related with my firm agreement pages. It comes after google agreement pages.
I tried some technics for doing it. For example,I set it as a system application. However, it is cleaned when backup and reset operation.
Does anybody know how to run it?
on AndroidManifest.xml
<application
android:theme="#android:style/Theme.NoTitleBar"
android:allowBackup="true"
android:icon="#drawable/launcher"
android:label="#string/appname" >
<activity
android:name="xxxagreement.MainActivity"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen"
android:label="#string/app_name"
android:screenOrientation="portrait" >
<intent-filter android:priority="3">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
on MainActivity.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onResume() {
Intent i = new Intent();
i.setAction(AGREEGATE_STARTED);
sendBroadcast(i);
TextView t = (TextView)findViewById(R.id.textView1);
t.setSelected(true);
...
super.onResume();
}
Event Log prints:
Session 'app': Error Launching activity
Your application doesn't have any launcher activity. Replace these lines
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
with
<category android:name="android.intent.category.LAUNCHER" />