একটি সিস্টেম ওভারলে উইন্ডো তৈরি করা (সর্বদা উপরে)


285

আমি একটি সর্বদা-অপ-টপ বোতাম / ক্লিকযোগ্য-চিত্র তৈরি করার চেষ্টা করছি যা সমস্ত সময় সমস্ত উইন্ডোর উপরে থাকে।

ধারণার প্রমাণ হয়

আমি সফল এবং এখন একটি চলমান সেবা আছে। পরিষেবাটি সর্বদা স্ক্রিনের উপরের বাম কোণে কিছু পাঠ্য প্রদর্শন করে যখন ব্যবহারকারীরা স্বাভাবিকভাবে অন্যান্য অ্যাপ্লিকেশনগুলির সাথে অবাধে যোগাযোগ করতে পারে।

আমি যা করছি তা হচ্ছে সাবক্লাস ViewGroupএবং এটি পতাকা সহ মূল উইন্ডো ম্যানেজারে যুক্ত করুন TYPE_SYSTEM_OVERLAY। এখন আমি এই পাঠ্যের জায়গায় একটি বোতাম / ক্লিকযোগ্য-চিত্র যুক্ত করতে চাই যা নিজেই স্পর্শ ইভেন্টগুলি পেতে পারে। আমি পুরোটির জন্য "অন টাচএভেন্ট" ওভাররাইড করার চেষ্টা করেছি ViewGroupতবে এটি কোনও ইভেন্ট পায় না।

আমি কীভাবে কেবলমাত্র আমার সর্বদা শীর্ষে থাকা গোষ্ঠীর কয়েকটি অংশে ইভেন্টগুলি পেতে পারি? দয়া করে পরামর্শ দিন।

public class HUD extends Service {
    HUDView mView;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Toast.makeText(getBaseContext(),"onCreate", Toast.LENGTH_LONG).show();
        mView = new HUDView(this);
        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
                0,
//              WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
//                      | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
                PixelFormat.TRANSLUCENT);
        params.gravity = Gravity.RIGHT | Gravity.TOP;
        params.setTitle("Load Average");
        WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
        wm.addView(mView, params);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Toast.makeText(getBaseContext(),"onDestroy", Toast.LENGTH_LONG).show();
        if(mView != null)
        {
            ((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(mView);
            mView = null;
        }
    }
}

class HUDView extends ViewGroup {
    private Paint mLoadPaint;

    public HUDView(Context context) {
        super(context);
        Toast.makeText(getContext(),"HUDView", Toast.LENGTH_LONG).show();

        mLoadPaint = new Paint();
        mLoadPaint.setAntiAlias(true);
        mLoadPaint.setTextSize(10);
        mLoadPaint.setARGB(255, 255, 0, 0);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawText("Hello World", 5, 15, mLoadPaint);
    }

    @Override
    protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) {
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //return super.onTouchEvent(event);
        Toast.makeText(getContext(),"onTouchEvent", Toast.LENGTH_LONG).show();
        return true;
    }
}

2
@ কোরসোলো, আমি আশা করি আপনি উত্তর পেয়ে গেছেন, আমার অদ্ভুতভাবে অনুরূপ প্রশ্নগুলির কোনও প্রতিক্রিয়া পাইনি। :) +1
st0le

3
@ st0le আমি প্রতিশ্রুতি দিচ্ছি যে আমি সমাধান না পাওয়া এবং আপনার সাথে ভাগ করে নেওয়ার আগ পর্যন্ত আমার রাত ও দিন
কাটাবো

1
@ st0le ঠিক আছে আপনি এবং আমি এটি এক সাথে খনন করতে পারি, আমাকে আপনার প্রশ্নের একটি লিঙ্ক দিন এবং আমাকে আপনি কতটা অগ্রগতি করতে পেরেছিলেন তা আমাকে জানাতে ...
কোরসোলো

তার অনেক: - \ stackoverflow.com/questions/3732935/...
st0le

3
অবাক onDraw()করা হচ্ছে যে আপনাকে ডাকা হচ্ছে। dispatchDraw()পরিবর্তে ওভাররাইড করা উচিত নয় ? গ্রুপ. google.com/forum/?fromgroups#!topic/android-developers/…
ফাইজাল

উত্তর:


158

এটি একটি নির্বোধ সমাধান হতে পারে। কিন্তু এটি কাজ করে. আপনি যদি এটির উন্নতি করতে পারেন তবে দয়া করে আমাকে জানান।

আপনার পরিষেবাটির অনক্রিট: আমি WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCHপতাকা ব্যবহার করেছি । এটিই কেবলমাত্র পরিষেবাতে পরিবর্তন।

@Override
    public void onCreate() {
        super.onCreate();
        Toast.makeText(getBaseContext(),"onCreate", Toast.LENGTH_LONG).show();
        mView = new HUDView(this);
        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
                WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
                PixelFormat.TRANSLUCENT);
        params.gravity = Gravity.RIGHT | Gravity.TOP;
        params.setTitle("Load Average");
        WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
        wm.addView(mView, params);
    }

এখন, আপনি প্রতিটি ক্লিক ইভেন্ট পেতে শুরু করবে। সুতরাং, আপনাকে আপনার ইভেন্ট হ্যান্ডলারটি সংশোধন করতে হবে।

আপনার ভিউগ্রুপ টাচ ইভেন্টে

@Override
public boolean onTouchEvent(MotionEvent event) {

    // ATTENTION: GET THE X,Y OF EVENT FROM THE PARAMETER
    // THEN CHECK IF THAT IS INSIDE YOUR DESIRED AREA


    Toast.makeText(getContext(),"onTouchEvent", Toast.LENGTH_LONG).show();
    return true;
}

এছাড়াও আপনার নিজের প্রকাশ্যে এই অনুমতিটি যুক্ত করতে হতে পারে:

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

1
@ পেপওয়াং: আপনি কী ত্রুটি পাচ্ছেন? এই কোডটি স্বতন্ত্র নয়, আপনার যথাযথ প্রকল্পের অধীনে যথাযথ ফাইল নাম সহ এটি আপনার প্রকল্পে স্থাপন করা দরকার।
সরোয়ার এরফান

4
: @pengwang: সহজ বাস্তবায়ন এখানে খুঁজে পাও docs.google.com/...
সারওয়ার এরফান

6
পুরো কোডটি সঠিক, আমি আমার ভুলটি খুঁজে পেয়েছি, <লিঙ্কটি ভুলে
গেছি

1
এই উত্তরটি একটি বিষয় বাদে খুব সহায়ক। কোডটিতে যেমন ব্যবহার করা হয়েছে, উইন্ডো ম্যানেজ.লায়আউটপ্যারামস.এফ.এফ.এল.জি. / WATCH_OUTSIDE_TOUCH, ডকুমেন্টেশন অনুসারে, "ফুল আপ / মুভ / ডাউন ইশারাটি পাবেন না"। অন্য কথায়, একটি অ্যাকশন_ডাউন ছাড়া সোয়াইপগুলি বা অন্য কিছু সনাক্ত করা সম্ভব নয়। ওয়েল আমি জানি যে সোয়াইপগুলি সনাক্ত করা সম্ভব কারণ ওয়েভ লঞ্চার এই জাতীয় ধারণাটি ব্যবহার করে এবং তারা সোয়াইপগুলি সনাক্ত করতে সক্ষম হয়। কেউ কীভাবে আমাকে বোঝাতে পারে যে এটি কীভাবে কাজ করে?
ব্রায়ান

6
@ সরওয়ারআরফান - আমি এটির কর্কিংটি ২.৩-এ পুরোপুরিভাবে ব্যবহার করেছি তবে অন টচ ইভেন্টটি অ্যান্ড্রয়েড 4.0.০, ১ ম এবং ৪.১ এ জিত করছে না। দয়া করে সহায়তা করুন
সঞ্জয় সিংহ

66

সাম লু এর উত্তর অনুসরণ করে, প্রকৃতপক্ষে অ্যান্ড্রয়েড 4..x কিছু ধরণের বাইরের স্পর্শ ইভেন্টগুলি শুনতে বাধা দেয়, তবে কিছু ধরণের TYPE_SYSTEM_ALERTকাজ এখনও কাজ করে।

উদাহরণ

    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.MATCH_PARENT,
            WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                    | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
            PixelFormat.TRANSLUCENT);

    WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
    LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
    View myView = inflater.inflate(R.layout.my_view, null);
    myView.setOnTouchListener(new OnTouchListener() {
       @Override
       public boolean onTouch(View v, MotionEvent event) {
           Log.d(TAG, "touch me");
           return true;
       }
     });

    // Add layout to window manager
    wm.addView(myView, params);

অনুমতিসমূহ

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

5
এটি আমার স্ক্রিনটিকে
ফাঁসিয়ে

দুর্দান্ত পোস্ট। আশা করি এটি ভবিষ্যতে প্রকাশেও অক্ষম নয়।
কুকস্টার

এনিমেশনগুলি এতে কাজ করবে না ... :( এবং এটি কোনও দৃশ্যে 4.2.X এ ক্লিক করতে অক্ষম Any কোনও পরামর্শ?
কামরান আহমেদ

এটি কাজ করে তবে আমি যখন শর্টকাটটি (যেমন সিস্টেমের স্তর সতর্কতা) ব্যবহার করি তখন অন্যান্য সংলাপগুলি প্রদর্শিত হয় না। কেন?
চিমু

@ আরজু মানে কি? আপনি এটি অপসারণ করার চেষ্টা করছেন?
amirlazarovich

18

অ্যান্ড্রয়েড 4.x থেকে শুরু করে, অ্যান্ড্রয়েড টিম একটি নতুন ফাংশন যোগ করে একটি সম্ভাব্য নিরাপত্তাজনিত সমস্যা সংশোধন করা হয়েছে adjustWindowParamsLw()যেখানে এটি যোগ করা হবে FLAG_NOT_FOCUSABLE, FLAG_NOT_TOUCHABLEএবং অপসারণ FLAG_WATCH_OUTSIDE_TOUCHজন্য পতাকার TYPE_SYSTEM_OVERLAYজানালা।

এটি হ'ল, একটি TYPE_SYSTEM_OVERLAYউইন্ডো আইসিএস প্ল্যাটফর্মে কোনও স্পর্শ ইভেন্ট পাবে না এবং অবশ্যই, ব্যবহার TYPE_SYSTEM_OVERLAYকরা আইসিএস এবং ভবিষ্যতের ডিভাইসের জন্য কার্যকর সমাধান নয়।


4
তাহলে বিকল্পগুলি কি?
রাধু

1
: ছাত্রশিবির সম্বন্ধে প্রশ্নগুলির দেখুন stackoverflow.com/questions/9656185/type-system-overlay-in-ics
clemp6r

13

আমি টোলিপ এসডিকে অন্যতম বিকাশকারী । আমরা বিকাশকারীদের সর্বদা শীর্ষ উইন্ডো এবং বোতামগুলিতে প্রদর্শন করার জন্য একটি উপায়ও সরবরাহ করি এবং আমরা একই ধরণের পরিস্থিতি মোকাবিলা করেছি।

এখানে যে সমস্যার উত্তরগুলির সমাধান করা যায় নি তা হ'ল অ্যান্ড্রয়েড "সুরক্ষিত বোতাম"।

সুরক্ষিত বোতামগুলির filterTouchesWhenObscuredসম্পত্তি রয়েছে যার অর্থ উইন্ডোটির নীচে রাখলে এমনকি যদি সে উইন্ডোটি কোনও স্পর্শ না পেয়ে থাকে তবে তাদের সাথে ইন্টারঅ্যাক্ট করা যাবে না। অ্যান্ড্রয়েড ডকুমেন্টেশন উদ্ধৃত:

ভিউটির উইন্ডোটি অন্য কোনও দৃশ্যমান উইন্ডো দ্বারা অস্পষ্ট হয়ে গেলে স্পর্শগুলি ফিল্টার করতে হবে কিনা তা সুনির্দিষ্ট করে। সত্য হিসাবে সেট করা হলে, যখনই কোনও টোস্ট, ডায়ালগ বা অন্য উইন্ডো দর্শনের উইন্ডোর উপরে উপস্থিত হয় তখন ভিউটি স্পর্শ পাবে না। আরও তথ্যের জন্য l @ লিঙ্ক অ্যান্ড্রয়েড.ভিউ.ভিউ} সুরক্ষা ডকুমেন্টেশন দেখুন।

তৃতীয় পক্ষের অ্যাপস ইনস্টল করার চেষ্টা করার সময় এই জাতীয় বোতামের উদাহরণ হ'ল ইনস্টল বোতাম। নিম্নলিখিত লাইনটি ভিউ লেআউটে যোগ করা হলে কোনও অ্যাপ্লিকেশন এ জাতীয় বোতামটি প্রদর্শন করতে পারে:

android:filterTouchesWhenObscured="true"

যদি আপনি একটি "সুরক্ষিত বোতাম" -র উপরে সর্বদা শীর্ষে উইন্ডোটি প্রদর্শন করেন, সুতরাং ওভারলেটি আচ্ছাদিত সমস্ত সুরক্ষিত বোতামের অংশগুলি কোনও ছোঁয়া সামলাবে না, এমনকি যদি ওভারলে ক্লিকযোগ্য না হয়। সুতরাং আপনি যদি এই জাতীয় উইন্ডোটি প্রদর্শন করার পরিকল্পনা করে থাকেন তবে আপনার ব্যবহারকারীকে এটি সরানোর বা খারিজ করার জন্য একটি উপায় সরবরাহ করা উচিত। এবং যদি আপনার ওভারলেয়ের একটি অংশ স্বচ্ছ হয়, তবে অ্যাকাউন্টটি বিবেচনা করুন যে আপনার ব্যবহারকারী বিভ্রান্ত হতে পারেন কেন অন্তর্নিহিত অ্যাপ্লিকেশনটির একটি নির্দিষ্ট বোতাম হঠাৎ করে তার জন্য কাজ করছে না।


আপনি কি দয়া করে আমার প্রশ্নের উত্তর দিতে পারেন: stackoverflow.com/questions/28964771/…
নওমান আফজাল

অ্যান্ড্রয়েড 10 এ কিছু ক্রিয়াকলাপ রয়েছে যা ওভারলে ভিউ তাদের উপরে দেখাতে পারে না আপনি দয়া করে কারণটি বলতে পারেন বা আমার প্রশ্নটি এখানে দেখতে পারেন এটি খুব সহায়ক হবে স্ট্যাকওভারফ্লো.com
Qestions/

12

সর্বদা শীর্ষ চিত্রের বোতামে কাজ করা

আমার ইংরাজির জন্য প্রথম দুঃখিত

আমি আপনার কোডগুলি সম্পাদনা করি এবং কাজের চিত্রের বোতামটি তৈরি করি যা তার স্পর্শ ইভেন্টটি শোনায় তার পটভূমির উপাদানগুলিকে স্পর্শ নিয়ন্ত্রণ দেয় না।

এছাড়াও এটি অন্যান্য উপাদানগুলির বাইরে স্পর্শ শ্রোতাদের দেয়

বোতাম alingments নীচে এবং বাম হয়

আপনি অ্যালিংমেন্টগুলি ছাঁটাই করতে পারেন তবে আপনাকে যদি এলিমেন্টে স্পর্শ ইভেন্টে কর্ডিনেটগুলি ছাটা করতে হবে

import android.annotation.SuppressLint;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Toast;

public class HepUstte extends Service {
    HUDView mView;

    @Override
    public void onCreate() {
        super.onCreate();   

        Toast.makeText(getBaseContext(),"onCreate", Toast.LENGTH_LONG).show();

        final Bitmap kangoo = BitmapFactory.decodeResource(getResources(),
                R.drawable.logo_l);


        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                kangoo.getWidth(), 
                kangoo.getHeight(),
                WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                |WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                |WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
                 PixelFormat.TRANSLUCENT);






        params.gravity = Gravity.LEFT | Gravity.BOTTOM;
        params.setTitle("Load Average");
        WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);



        mView = new HUDView(this,kangoo);

        mView.setOnTouchListener(new OnTouchListener() {


            @Override
            public boolean onTouch(View arg0, MotionEvent arg1) {
                // TODO Auto-generated method stub
                //Log.e("kordinatlar", arg1.getX()+":"+arg1.getY()+":"+display.getHeight()+":"+kangoo.getHeight());
                if(arg1.getX()<kangoo.getWidth() & arg1.getY()>0)
                {
                 Log.d("tıklandı", "touch me");
                }
                return false;
            }
             });


        wm.addView(mView, params);



        }



    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        return null;
    }

}



@SuppressLint("DrawAllocation")
class HUDView extends ViewGroup {


    Bitmap kangoo;

    public HUDView(Context context,Bitmap kangoo) {
        super(context);

        this.kangoo=kangoo;



    }


    protected void onDraw(Canvas canvas) {
        //super.onDraw(canvas);


        // delete below line if you want transparent back color, but to understand the sizes use back color
        canvas.drawColor(Color.BLACK);

        canvas.drawBitmap(kangoo,0 , 0, null); 


        //canvas.drawText("Hello World", 5, 15, mLoadPaint);

    }


    protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) {
    }

    public boolean onTouchEvent(MotionEvent event) {
        //return super.onTouchEvent(event);
       // Toast.makeText(getContext(),"onTouchEvent", Toast.LENGTH_LONG).show();

        return true;
    }
}

এটি কাজ করে, তবে আমি কীভাবে নিশ্চিত করব যে আমার চিত্রটি ক্লিক করা হয়েছিল এবং চিত্রের চারপাশে কিছু নয়?
লিয়াম ডাব্লু

@ লিয়ামডাব্লু, স্পর্শের স্থানাঙ্কগুলি এই উদাহরণে ক্যাঙ্গারু.জেটভিডথ () এর সাথে তুলনা করা হচ্ছে। আপনি নিজের ইমেজটি কোথায় আঁকছেন তার উপর ভিত্তি করে আপনার নিজের কোডে এর সাথে কী তুলনা করতে হবে তা নির্ধারণ করতে পারেন।
ইয়েভেগেনি সিমকিন

খুব সুন্দর! পুরোপুরি কাজ করে।
ইয়েগজেনি সিমকিন 21

এটি কাজ করে সর্বনিম্ন অ্যান্ড্রয়েড সংস্করণটি কী? আমি এটি লেখার বিষয়ে কাজ করছি তবে অ্যান্ড্রয়েডে আমি নতুন so
Noitidart

6

প্রকৃতপক্ষে, আপনি উইন্ডো ম্যানেজ.লাইআউটপ্যারামগুলি ব্যবহার করতে পারেন TYPE_SYSTEM_OVRLAY এর পরিবর্তে TYPE_SYSTEM_ERROR। এটি হ্যাকের মতো শোনাতে পারে তবে এটি আপনাকে সমস্ত কিছুর উপরে প্রদর্শন করতে দেয় এবং এখনও স্পর্শ ইভেন্ট পেতে পারে।


1
আমি এটিকে কাজ করার জন্য প্রতিটি জিনিস চেষ্টা করেছি, তবে কোনও সাফল্য নেই .... তবে TYPE_SYSTEM_ERROR যুক্ত করে কাজটি করা হয়েছে .... আসলে TYPE_SYSTEM_OVERLAY টা টা ব্লক করছিল ..... + 1।
রবি কুমার তোমার

6

TYPE_SYSTEM_OVERLAY এই ধ্রুবকটি এপিআই স্তরের ২ since সাল থেকে অবচয় করা হয়েছিল instead পরিবর্তে TYPE_APPLICATION_OVERLAY ব্যবহার করুন। বা ** নীচে এবং অ্যান্ড্রয়েড 8 এর উপরে ব্যবহারকারীদের জন্য

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
    LAYOUT_FLAG = WindowManager.LayoutParams.TYPE_PHONE;
}

5

এটা চেষ্টা কর. আইসিএসে সূক্ষ্মভাবে কাজ করে। আপনি যদি পরিষেবাটি বন্ধ করতে চান তবে স্ট্যাটাসবারে উত্পন্ন নোটিফিকেশনটি কেবল ক্লিক করুন।

 public class HUD extends Service
 {
    protected boolean foreground = false;
    protected boolean cancelNotification = false;
    private Notification notification;
    private View myView;
    protected int id = 0;
    private WindowManager wm;
    private WindowManager.LayoutParams params;
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    @Override
    public void onCreate() {
        super.onCreate();
       // System.exit(0);
        Toast.makeText(getBaseContext(),"onCreate", Toast.LENGTH_SHORT).show();
        params = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_PHONE, WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                        | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT);
        params.gravity=Gravity.TOP|Gravity.LEFT;
    wm = (WindowManager) getSystemService(WINDOW_SERVICE);
    inflateview();
    foregroundNotification(1);
    //moveToForeground(1,n,true);
    }     
   @Override
    public void onDestroy() {
        super.onDestroy();
        ((NotificationManager) getSystemService(NOTIFICATION_SERVICE)).cancel(0);
        Toast.makeText(getBaseContext(),"onDestroy", Toast.LENGTH_SHORT).show();
        if(myView != null)
        {
            ((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(myView);
            myView = null;
        }
    }
    protected Notification foregroundNotification(int notificationId) 
   {    
    notification = new Notification(R.drawable.ic_launcher, "my Notification", System.currentTimeMillis());    
        notification.flags = notification.flags | Notification.FLAG_ONGOING_EVENT | Notification.FLAG_ONLY_ALERT_ONCE;   
        notification.setLatestEventInfo(this, "my Notification", "my Notification", notificationIntent());          
        ((NotificationManager) getSystemService(NOTIFICATION_SERVICE)).notify(id, notification);            
        return notification;
    }
    private PendingIntent notificationIntent() {
        Intent intent = new Intent(this, stopservice.class);    
        PendingIntent pending = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);    
        return pending;
    }
    public void inflateview()
    {
         LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
            myView = inflater.inflate(R.layout.activity_button, null);
            myView.setOnTouchListener(new OnTouchListener() {
               @Override
               public boolean onTouch(View v, MotionEvent event) {
                   Toast.makeText(getBaseContext(),"onToasttt", Toast.LENGTH_SHORT).show();
                   return false;
               }
             });
            // Add layout to window manager
            wm.addView(myView, params); 
    }
}

হালনাগাদ

নমুনা এখানে

ওভারলে ভিউ তৈরি করতে, লেআউটপ্যারাম সেট আপ করার সময় টাইপটি TYPE_SYSTEM_OVERLAY এ সেট করবেন না।

Instead set it to TYPE_PHONE.

Use the following flags:

FLAG_NOT_TOUCH_MODAL

FLAG_WATCH_OUTSIDE_TOUCH

এটি আমার পক্ষে কাজ করে না, আমার স্ক্রিন ব্যাকগ্রাউন্ডের সাথে ইন্টারঅ্যাক্ট করে না। আপনার জানা অন্য কোনও পদ্ধতি ...
বিনুথান

@ বিনুথান আপনার আউটপুটটি কী, তা কী প্রতিক্রিয়া জানায়
বিশ্বনাথ লেকশমানান

না, এটি কোনও প্রতিক্রিয়া দেয় না। আমি আমার ক্রিয়াকলাপটি উপরের পর্দার অর্ধেক উপরে রেখেছি যাতে আমি ব্যাকগ্রাউন্ডের সাথে ইন্টারঅ্যাক্ট করতে পারি তবে আমি ব্যাকগ্রাউন্ডের সাথে ইন্টারঅ্যাক্ট করতে পারি না।
বিনুথান

FLAG_WATCH_OUTSIDE_TOUCH আপনাকে পটভূমির সাথে আলাপচারিতা থেকে বাধা দেয়
রিচার্ড লে ম্যাসুরিয়ার

1
TYPE_PHONE আমার জন্য কাজ করেছে - এখন ছোঁয়া বিতরণ করা হয় - কমপক্ষে আমি একটি বোতাম টিপতে সক্ষম হয়েছি;) ধন্যবাদ!
ভাইরাস আমাদের

3

এখানে কিছু সহজ সমাধান রয়েছে, আপনার কেবলমাত্র XML লেআউটটি স্ফীত করা যেমন আপনি তালিকা অ্যাডাপ্টারগুলিতে করেন কেবল এক্সএমএল লেআউটটিকে স্ফীত করতে। এখানে আপনার প্রয়োজনীয় সমস্ত কোড রয়েছে।

 public class HUD extends Service {
    View mView;

    LayoutInflater inflate;
    TextView t;
    Button b;

    @Override
    public void onCreate() {
        super.onCreate();   

        Toast.makeText(getBaseContext(),"onCreate", Toast.LENGTH_LONG).show();


        WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);

        Display display = wm.getDefaultDisplay();  get phone display size
        int width = display.getWidth();  // deprecated - get phone display width
        int height = display.getHeight(); // deprecated - get phone display height 


        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                width, 
                height,
                WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                |WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                |WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
                 PixelFormat.TRANSLUCENT);


        params.gravity = Gravity.LEFT | Gravity.CENTER;
        params.setTitle("Load Average");

        inflate = (LayoutInflater) getBaseContext()
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        mView = inflate.inflate(R.layout.canvas, null);

        b =  (Button) mView.findViewById(R.id.button1);
        t = (TextView) mView.findViewById(R.id.textView1);
        b.setOnClickListener(new OnClickListener() {

        public void onClick(View v) {
            // TODO Auto-generated method stub
            t.setText("yes you click me ");
        }
       });

        wm.addView(mView, params);

        }



    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        return null;
    }

}

3

ঠিক এমনটি করে এমন একটি লাইব্রেরি পেয়েছে: https://github.com/recruit-lLive/FloatingView

মূল ফোল্ডারে একটি নমুনা প্রকল্প রয়েছে। আমি এটি চালিয়েছি এবং এটি প্রয়োজনীয় হিসাবে কাজ করে। পটভূমিটি ক্লিকযোগ্য - এটি অন্য কোনও অ্যাপ্লিকেশন হলেও।

এখানে চিত্র বর্ণনা লিখুন


সুপারিশের জন্য ধন্যবাদ, আমি এই দুর্দান্ত প্রকল্পটি সন্ধানের চেষ্টা করছিলাম।
আপিং


1

ভাল আমার কোডটি চেষ্টা করে দেখুন, এটি অন্ততপক্ষে আপনাকে ওভারলে হিসাবে একটি স্ট্রিং দেয়, আপনি এটি খুব ভালভাবে একটি বোতাম বা কোনও চিত্র দিয়ে প্রতিস্থাপন করতে পারেন। আপনি বিশ্বাস করবেন না এটি আমার প্রথম অ্যান্ড্রয়েড অ্যাপ্লিকেশন এলএলএল। যাইহোক আপনি যদি আমার চেয়ে অ্যান্ড্রয়েড অ্যাপসের সাথে বেশি অভিজ্ঞ হন তবে দয়া করে চেষ্টা করুন

  • "নতুন উইন্ডো ম্যানেজ। লেআউটপ্যারামস" এ 2 এবং 3 পরামিতি পরিবর্তন করা হচ্ছে
  • কিছু ভিন্ন ইভেন্ট পদ্ধতির চেষ্টা করুন

অবশেষে আমি এটি অনুসরণ করার জন্য সময় পাইনি, অতএব আমি এখনও তার বিবরণে খুব
কমই

1

যদি এখনও কেউ এই থ্রেডটি পড়েন এবং এই কাজটি করতে সক্ষম না হন তবে মোশির ইভেন্টটিকে বাধা দেওয়ার এই উপায়টি আপনাকে বাগ হিসাবে বিবেচনা করা হয় এবং অ্যান্ড্রয়েড> = ৪.২ এ ফিক্স করাতে আমি দুঃখিত sorry

মোশন ইভেন্টটি আপনাকে বাধা দিয়েছিল, যদিও ACTION_OUTSIDE হিসাবে অ্যাকশন রয়েছে, getX এবং getY এ 0 ফিরে আসুন। এর অর্থ আপনি পর্দার সমস্ত গতি অবস্থান দেখতে পারবেন না, আপনি কিছু করতে পারবেন না। আমি জানি ডক বলেছিল এটি এক্স এবং ওয়াই পাবে, তবে সত্য এটি হবে না। দেখে মনে হচ্ছে এটি কী লগারটি ব্লক করার জন্য।

কারও যদি কাজটি করতে না পারে তবে আপনার মতামত জানান।

রেফ: কেন ACTION_OUTSIDE কিটকাট ৪.৪.২ এ প্রতিবার 0 দেয়?

https://code.google.com/p/android/issues/detail?id=72746


1

পরিষেবা ব্যবহার করে আপনি এটি অর্জন করতে পারেন:

public class PopupService extends Service{

    private static final String TAG = PopupService.class.getSimpleName();
    WindowManager mWindowManager;
    View mView;
    String type ;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
//        registerOverlayReceiver();
        type = intent.getStringExtra("type");
        Utils.printLog("type = "+type);
        showDialog(intent.getStringExtra("msg"));
        return super.onStartCommand(intent, flags, startId);
    }

    private void showDialog(String aTitle)
    {
        if(type.equals("when screen is off") | type.equals("always"))
        {
            Utils.printLog("type = "+type);
            PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
            WakeLock mWakeLock = pm.newWakeLock((PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "YourServie");
            mWakeLock.acquire();
            mWakeLock.release();
        }

        mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        mView = View.inflate(getApplicationContext(), R.layout.dialog_popup_notification_received, null);
        mView.setTag(TAG);

        int top = getApplicationContext().getResources().getDisplayMetrics().heightPixels / 2;

        LinearLayout dialog = (LinearLayout) mView.findViewById(R.id.pop_exit);
//        android.widget.LinearLayout.LayoutParams lp = (android.widget.LinearLayout.LayoutParams) dialog.getLayoutParams();
//        lp.topMargin = top;
//        lp.bottomMargin = top;
//        mView.setLayoutParams(lp);

        final EditText etMassage = (EditText) mView.findViewById(R.id.editTextInPopupMessageReceived);

        ImageButton imageButtonSend = (ImageButton) mView.findViewById(R.id.imageButtonSendInPopupMessageReceived);
//        lp = (LayoutParams) imageButton.getLayoutParams();
//        lp.topMargin = top - 58;
//        imageButton.setLayoutParams(lp);
        imageButtonSend.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Utils.printLog("clicked");
//                mView.setVisibility(View.INVISIBLE);
                if(!etMassage.getText().toString().equals(""))
                {
                    Utils.printLog("sent");
                    etMassage.setText("");
                }
            }
        });

        TextView close = (TextView) mView.findViewById(R.id.TextViewCloseInPopupMessageReceived);
        close.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                hideDialog();   
            }
        });

        TextView view = (TextView) mView.findViewById(R.id.textviewViewInPopupMessageReceived);
        view.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                hideDialog();   
            }
        });

        TextView message = (TextView) mView.findViewById(R.id.TextViewMessageInPopupMessageReceived);
        message.setText(aTitle);

        final WindowManager.LayoutParams mLayoutParams = new WindowManager.LayoutParams(
        ViewGroup.LayoutParams.MATCH_PARENT,
        ViewGroup.LayoutParams.MATCH_PARENT, 0, 0,
        WindowManager.LayoutParams.TYPE_SYSTEM_ERROR,
        WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
//                | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
                | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON ,
        PixelFormat.RGBA_8888);

        mView.setVisibility(View.VISIBLE);
        mWindowManager.addView(mView, mLayoutParams);
        mWindowManager.updateViewLayout(mView, mLayoutParams);

    }

    private void hideDialog(){
        if(mView != null && mWindowManager != null){
            mWindowManager.removeView(mView);
            mView = null;
        }
    }
}

1

@ সরোয়ার এরফানের উত্তর আর কাজ করে না, কারণ অ্যান্ড্রয়েড উইন্ডোম্যানেজ.লায়আউটপ্যারামস সহ ভিউ যুক্ত করার অনুমতি দেয় না। উইন্ডো ম্যানেজ.আর লেআউটপ্যারাম দিয়েও উইন্ডোতে আর স্পর্শযোগ্য হতে উইন্ডোটিকে আর স্পর্শ করা যায় না F

আমি এই সমস্যার সমাধান খুঁজে পেয়েছি। আপনি নিম্নলিখিত প্রশ্নে এটি পরীক্ষা করে দেখতে পারেন

উইন্ডোম্যানেজ.লায়আউটপ্যারামস.টিওয়াইপিএসএসটাইম_উভারলে দিয়ে উইন্ডোতে ভিউ যুক্ত করার সময়, এটি স্পর্শ ইভেন্ট পাচ্ছে না


আপনার উল্লেখিত সমাধান মার্শমেলোতেও কাজ করে না
আহমদ শাহওয়াইজ

@ আহমদশাহওয়াইজ দয়া করে আবার লিঙ্কটি পরীক্ষা করে দেখুন আপনার এখানে উল্লিখিত সমস্যার জন্য আমি মন্তব্য যুক্ত করেছি
পাতিলমন্দর ২০০7

হ্যাঁ, এখন এটি কাজ করছে। কিন্তু স্টার্টঅ্যাক্টিভিটি ফর রিসাল্ট (অভিপ্রায়, OVERLAY_REQ_CODE) কল করার পরে কলব্যাকের প্রতিক্রিয়া পাচ্ছেন না; অ্যাক্টিভিটিআরসাল্ট (ইন রিকোয়েস্টকোড, ইন রেজাল্টকোড, ইনটেন্ট ডেটা) পদ্ধতিতে সুরক্ষিত শূন্য।
আহমদ শাহওয়াইজ

@ আহমাদশাহওয়াইজ লিঙ্কে উল্লিখিত পরিবর্তনগুলি অ্যাক্টিভিটিস রেজাল্ট পদ্ধতিতে কলব্যাক পেলে ক্রিয়াকলাপ ব্যবহার করে কল করতে হয় called আপনি যদি পরিষেবায় উপরের অনুমতিটি যাচাই করে দেখছেন তবে আপনাকে পরিষেবা থেকে শুরু করার জন্য একটি ডামি স্বচ্ছ ক্রিয়াকলাপ যুক্ত করতে হতে পারে, যা ব্যবহারকারীকে অনুমতি চাইতে পারে এবং তারপরেঅ্যাক্টিভিটিস রেজাল্ট ডামি ক্রিয়াকলাপে আপনি ব্যবহারকারীর কাছ থেকে ফলাফল পাবেন। আপনার উইন্ডোতে ভিউ যুক্ত করতে বা ব্যবহারকারীর প্রতিক্রিয়ার উপর নির্ভর করে আপনার পরিষেবাটি অবহিত করতে হবে
পাতিলমন্দর ২০০7

1

এটি একটি পুরানো প্রশ্ন তবে সম্প্রতি বুদবুদগুলির জন্য অ্যান্ড্রয়েডের একটি সমর্থন রয়েছে। বুদবুদ শীঘ্রই চালু হতে চলেছে তবে বর্তমানে বিকাশকারীরা সেগুলি ব্যবহার শুরু করতে পারেন y তারা ব্যবহারের বিকল্প হিসাবে নকশাকৃত SYSTEM_ALERT_WINDOW। অ্যাপস (ফেসবুক ম্যাসেঞ্জার এবং মুসিক্স ম্যাচ একই ধারণা ব্যবহার করে)।

বুদবুদগুলি

বুদবুদগুলি বিজ্ঞপ্তি এপিআইয়ের মাধ্যমে তৈরি করা হয়, আপনি আপনার বিজ্ঞপ্তিটি সাধারণ হিসাবে প্রেরণ করেন। আপনি যদি এটি বুদ্বুদ করতে চান তবে আপনাকে এটিতে কিছু অতিরিক্ত ডেটা সংযুক্ত করতে হবে। বুদবুদ সম্পর্কে আরও তথ্যের জন্য আপনি বুদবুদগুলির আনুষ্ঠানিক অ্যান্ড্রয়েড বিকাশকারী গাইডে যেতে পারেন ।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.