2016-02-10 7 views
10

ConceptAndroid: Overlay TextView на LockScreen

Im пытается наложить TextView поверх LockScreen (подобно тому, как Android наложений времени).

Примечание: Я не хочу обходить блокирующий экран, но просто нарисую его (не вмешиваясь в какие-либо события касания).

Я попытался использовать следующие флаги (в OnCreate):

getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE); 
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); 
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED); 
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 
    getWindow().addFlags(WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY); 
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH); 
    getWindow().addFlags(PixelFormat.TRANSLUCENT); 

И применяя следующую тему (к конкретной деятельности):

<style name="Transparent"> 
    <item name="android:windowNoTitle">true</item> 
    <item name="android:windowContentOverlay">@null</item> 
    <item name="android:windowIsTranslucent">true</item> 
    <item name="android:windowBackground">@android:color/transparent</item> 
    <item name="android:windowActionBar">false</item> 
    <item name="android:backgroundDimEnabled">false</item> 
<item name="android:windowIsFloating">true</item> 
</style> 

Но это привлекает на вершине lockscreen скрывает блокировку экрана и отключает все события касания.

Edit: activity_overlay.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:paddingBottom="@dimen/activity_vertical_margin" 
android:paddingLeft="@dimen/activity_horizontal_margin" 
android:paddingRight="@dimen/activity_horizontal_margin" 
android:paddingTop="@dimen/activity_vertical_margin" 
tools:context="com.example.coco.MainActivity" > 

<TextView 
    android:id="@+id/textView1" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:textColor="@android:color/white" 
    android:layout_alignParentBottom="true" 
    android:text="TextView" /> 

</RelativeLayout> 

Manifest декларация деятельности (которая раздувает overlay_activity.xml)

 <activity 
     android:name=".DisplayActivity" 
     android:label="@string/app_name" 
     android:theme="@style/Transparent" /> 
+0

Можете ли вы показать свой фактический файл макета? – marktani

+0

@mcwise Добавлен файл макета. activity_overlay.xml. Также добавлено объявление манифеста – Zen

+0

Ive пробовал все комбинации Theme & Flags, но ни один не дал желаемого оверлея. Также попробовали использовать флаги из onCreate и onWindowFocusChanged – Zen

ответ

13

Так как вы хотите, чтобы отобразить вещи из вашего приложения активности, вы можете использовать службу и WindowManager для этого, точно так же, как Facebook Messenger и другие плавающие окна и приложения работает;)

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(); 
    } 

} 

и добавить необходимое разрешение на AndroidManifest.xml и добавить службу

<?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> 

Не забудьте запустить службу на OnCreate() вашей деятельности

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    Intent intent = new Intent(this, LockScreenTextService.class); 
    startService(intent); 

} 

TextView показывая на LockScreen TextView showing on lockscreen

TextView удалены, когда разблокирован TextView removed when unlocked

+0

Я не был активным в течение нескольких дней. Вы получили щедрость? Ответ правильный: – Zen

+0

смог получить половину щедрости ха-ха;) не волнуйся –

+1

У меня есть это предупреждение »** Невозможно добавить окно android.view.ViewRootImpl - разрешено разрешение для этого типа окна **" при выполнении 'windowManager.addView (textview, params);', и поэтому ничего не было прикреплено к экрану блокировки. Помощь Pls .. –

Смежные вопросы