Im trying to overlay a TextView on top of the LockScreen (Similar to how Android Overlays the time).
Note: I dont want to by-pass the lockscreen, but just draw
Starting with Android Lollipop (5.0), support for lockscreen widgets has been removed (see the very bottom). Instead, you should be using Notifications, which can now appear on the lockscreen.
Since you want to display things out of your app activity, you can use a Service and WindowManager for that, the same way how Facebook Messenger and other floating windows apps works ;)
LockScreenTextService.class
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.support.v4.content.ContextCompat;
import android.view.Gravity;
import android.view.WindowManager;
import android.widget.TextView;
/**
* Created on 2/20/2016.
*/
public class LockScreenTextService extends Service {
private BroadcastReceiver mReceiver;
private boolean isShowing = false;
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
private WindowManager windowManager;
private TextView textview;
WindowManager.LayoutParams params;
@Override
public void onCreate() {
super.onCreate();
windowManager = (WindowManager)getSystemService(WINDOW_SERVICE);
//add textview and its properties
textview = new TextView(this);
textview.setText("Hello There!");
textview.setTextColor(ContextCompat.getColor(this, android.R.color.white));
textview.setTextSize(32f);
//set parameters for the textview
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
params.gravity = Gravity.BOTTOM;
//Register receiver for determining screen off and if user is present
mReceiver = new LockScreenStateReceiver();
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_USER_PRESENT);
registerReceiver(mReceiver, filter);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
public class LockScreenStateReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
//if screen is turn off show the textview
if (!isShowing) {
windowManager.addView(textview, params);
isShowing = true;
}
}
else if(intent.getAction().equals(Intent.ACTION_USER_PRESENT)) {
//Handle resuming events if user is present/screen is unlocked remove the textview immediately
if (isShowing) {
windowManager.removeViewImmediate(textview);
isShowing = false;
}
}
}
}
@Override
public void onDestroy() {
//unregister receiver when the service is destroy
if (mReceiver != null) {
unregisterReceiver(mReceiver);
}
//remove view if it is showing and the service is destroy
if (isShowing) {
windowManager.removeViewImmediate(textview);
isShowing = false;
}
super.onDestroy();
}
}
and add the necessary permission on AndroidManifest.xml and add the service
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.textonlockscreenusingservice">
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> //this
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".LockScreenTextService" /> //this
</application>
</manifest>
Don't forget to start the service on onCreate() of your activity
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = new Intent(this, LockScreenTextService.class);
startService(intent);
}
TextView showing on lockscreen
TextView removed when unlocked