کلیدستان

نسخه‌ی کامل: نحوه ی کار با کانتکست (context) در برنامه نویسی اندروید ؟ (و notifications Floating)
شما در حال مشاهده نسخه آرشیو هستید. برای مشاهده نسخه کامل کلیک کنید.
سلام
یکی اینجا نحوه کار با کانتکست رو اموزش میده؟  دقیقا چطوریه  ؟
ممنون[عکس: sad.gif]
سلام.
کلیدهای زیر را بخوانید :

http://www.kelidestan.com/keys/keys.php?key=341

http://www.kelidestan.com/keys/keys.php?key=342

اگر سوالی بود، بفرمایید.

سلام داداش من اینا رو قبلا خوندم میشه بیشتر توضیح بدید ... اصن کلا چی هست ؟
یه مثال هم بزنید خیلی عالی میشه
دمتون هم گرم
ممنون
کلید زیر را برایتان نوشتم و مختصری در مورد آن توضیح دادم :

http://www.kelidestan.com/keys/keys.php?key=2803

به عنوان مثال، فرض کنید یک کلاس (class) ساخته ایم که می خواهیم در یک Activity ، یک پیام را با روش Toast نمایش بدهد. کدهای کلاس باید به صورت زیر باشد :

کد:
package com.kelidestan.com;

import junit.framework.TestCase;
import android.content.Context;
import android.widget.Toast;

public class MyClass extends TestCase {
        
    private Context context;
        
    public MyClass (Context context) {
        this.context = context;
        Toast.makeText(this.context, "www.kelidestan.com", Toast.LENGTH_SHORT).show();
    }

}

همان طور که مشاهده می کنید، context مربوط به Activity را به کلاس ارسال می کنیم (به عنوان ورودی کلاس)، زیرا شاید برنامه اندروید ما 100 تا Activity داشته باشه و کلاس باید بداند که با کدامیک سر و کار دارد و پیام را برای کدامیک باید نمایش بدهد.

داداش من احتیاج به یدونه  notifications Floating دارم که سورسشو فقط تونستم یه جا پیدا کنم 
http://www.jawsware.mobi/code_OverlayView/
حالا من این کدو دارم  میخوام وقتی روش میزنیم یه برنامه یا اکتیویتی باز کنه کدش تقریبا مث لمس بک گرانده فقط این داخل یه کلاس اکتیویتی نیس ک بتونم به راحتتی انجامش بدم ... از یکی پرسیدم گفت با کانتکست شاید بتونی انجامش بدی
این کدمه به نظرتون چطوری این کار رو انجام بدم من


کد:
import android.content.Context;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.RelativeLayout;

import com.jikopok.book.HomeActivity;

public abstract class OverlayView extends RelativeLayout {

    protected WindowManager.LayoutParams layoutParams;

    private int layoutResId;
    private int notificationId = 0;

    public OverlayView(OverlayService service, int layoutResId, int notificationId) {
        super(service);

        this.layoutResId = layoutResId;
        this.notificationId = notificationId;

        this.setLongClickable(true);
        
        this.setOnLongClickListener(new OnLongClickListener() {
            
            @Override
            public boolean onLongClick(View v) {
                return onTouchEvent_LongPress();
            }
        });

        load();
    }


    public OverlayService getService() {
        return (OverlayService) getContext();
    }

    public int getLayoutGravity() {
        // Override this to set a custom Gravity for the view.

        return Gravity.LEFT;
    }

    private void setupLayoutParams() {
        layoutParams = 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);

        layoutParams.gravity = getLayoutGravity();



        onSetupLayoutParams();

    }

    protected void onSetupLayoutParams() {
        // Override this to modify the initial LayoutParams. Be sure to call
        // super.setupLayoutParams() first.
    }

    private void inflateView() {
        // Inflates the layout resource, sets up the LayoutParams and adds the
        // View to the WindowManager service.

        LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        inflater.inflate(layoutResId, this);

        onInflateView();

    }

    protected void onInflateView() {
        // Override this to make calls to findViewById() to setup references to
        // the views that were inflated.
        // This is called automatically when the object is created right after
        // the resource is inflated.
    }

    public boolean isVisible() {
        // Override this method to control when the Overlay is visible without
        // destroying it.
        return true;
    }

    public void refreshLayout() {
        // Call this to force the updating of the view's layout.

        if (isVisible()) {
            removeAllViews();
            inflateView();

            onSetupLayoutParams();

            ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).updateViewLayout(this, layoutParams);

            refresh();
        }

    }

    protected void addView() {
        setupLayoutParams();

        ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).addView(this, layoutParams);

        super.setVisibility(View.GONE);
    }

    protected void load() {
        inflateView();
        addView();
        refresh();
    }

    protected void unload() {
        ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).removeView(this);

        removeAllViews();
    }

    protected void reload() {
        unload();

        load();
    }

    public void destory() {
        ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).removeView(this);
    }

    public void refresh() {
        // Call this to update the contents of the Overlay.

        if (!isVisible()) {
            setVisibility(View.GONE);
        } else {
            setVisibility(View.VISIBLE);

            refreshViews();
        }
    }

    protected void refreshViews() {
        // Override this method to refresh the views inside of the Overlay. Only
        // called when Overlay is visible.
    }

    protected boolean showNotificationHidden() {
        // Override this to configure the notification to remain even when the
        // overlay is invisible.
        return true;
    }

    protected boolean onVisibilityToChange(int visibility) {
        // Catch changes to the Overlay's visibility in order to animate

        return true;
    }

    protected View animationView() {
        return this;
    }

    protected void hide() {
        // Set visibility, but bypass onVisibilityToChange()
        super.setVisibility(View.GONE);
    }

    protected void show() {
        // Set visibility, but bypass onVisibilityToChange()

        super.setVisibility(View.VISIBLE);
    }

    @Override
    public void setVisibility(int visibility) {
        if (visibility == View.VISIBLE) {
            getService().moveToForeground(notificationId, !showNotificationHidden());
        } else {
            getService().moveToBackground(notificationId, !showNotificationHidden());
        }

        if (getVisibility() != visibility) {
            if (onVisibilityToChange(visibility)) {
                super.setVisibility(visibility);
            }
        }
    }

    protected int getLeftOnScreen() {
        int[] location = new int[2];

        getLocationOnScreen(location);

        return location[0];
    }

    protected int getTopOnScreen() {
        int[] location = new int[2];

        getLocationOnScreen(location);

        return location[1];
    }

    protected boolean isInside(View view, int x, int y) {
        // Use this to test if the X, Y coordinates of the MotionEvent are
        // inside of the View specified.

        int[] location = new int[2];

        view.getLocationOnScreen(location);

        if (x >= location[0]) {
            if (x <= location[0] + view.getWidth()) {
                if (y >= location[1]) {
                    if (y <= location[1] + view.getHeight()) {
                        return true;
                    }
                }
            }
        }

        return false;
    }

    protected void onTouchEvent_Up(MotionEvent event) {

    }

    protected int onTouchEvent_Move(MotionEvent event) {

        return 0;
    }


    protected void onTouchEvent_Press(MotionEvent event) {

    }
    
    public boolean onTouchEvent_LongPress()
    {
        return false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {

            onTouchEvent_Press(event);


        } else if (event.getActionMasked() == MotionEvent.ACTION_UP) {

            onTouchEvent_Up(event);

        } else if (event.getActionMasked() == MotionEvent.ACTION_MOVE) {

            onTouchEvent_Move(event);

        }

        return super.onTouchEvent(event);

    }

    public abstract void onCreate();
}

قسمت onTouchEvent_Press   فک میکنم بشه این کارو کرد
ممنون  
من از لینکی که داده بودید، کل فایل ها را دانلود کردم و بر اساس آن، یک پروژه اندروید جدید ساختم. کل پروژه اندروید به صورت سرویس (service) می باشد و با اجرای برنامه اندروید، برنامه بسته می شود و یک notifications Floating نمایش داده می شود. یعنی به شکل زیر :


همچنین در قسمت ongoing، با اشاره بر روی گزینه مربوط به آن، بسته خواهد شد :


من فایل های اصلی (که آنها را دانلود کرده و استفاده کردم) و همچنین پروژه اندروید ساخته شده (با نام Kelidestan.com) و همچنین فایل apk ساخته شده از آن را پیوست این ارسال کرده ام.
در پروژه اندروید، از موارد زیر (بر اساس فایل های دانلودی) استفاده شد (برخی با کپی کردن کل فایل و برخی هم با استفاده از بخشی از کدهای آنها) :


 دقت شود که در فایل AndroidManifest.xml ، باید یک اجازه (permission) و یک سرویس (service) اعلام می شد که من هر دو را از فایل AndroidManifest.xml در میان فایل های دانلودی، خواندم و در پروژه اندروید خود قرار دادم (در غیر این صورت، برنامه اندروید عمل نمی کرد).

داداش من با این سورس یه پروژه قبلا ساخته بودم الان میخوام با کلیک روی اون یه اکتیویتی باز کنم یا خود برنامه ای که ساختم
بازم ممنون برا اموزشتون

 
(۱۳۹۳/۰۸/۱۳, ۱۰:۴۲ ب.ظ)'aliasghar' نوشته: [ -> ]داداش من با این سورس یه پروژه قبلا ساخته بودم الان میخوام با کلیک روی اون یه اکتیویتی باز کنم یا خود برنامه ای که ساختم
بازم ممنون برا اموزشتون


 


من فکر می کردم که با اصل کدها مشکل داشتید، دیگه هم ارسال شما رو نخوندم (که یادآوری بشه).
حالا پروژه اندروید رو که به طور آماده داریم. این مورد رو هم ان شاء الله درست می کنیم.
بررسی می کنم و نتیجه رو همینجا می نویسم (البته سرفرصت).

بازم ممنون داداش دمت گرم
موارد مورد نظرتون رو به پروژه اندروید اضافه کردم. در واقع مربوط به همان context بودند. تعیین کرده ام که با اشاره شما، هم یک پیام کوتاه نمایش داده شود (با روش Toast) و هم به یک Activity جدید با نام NextActivity وارد شویم (هر دو نیاز به Context داشتند).
قبلا برنامه اندروید به این شکل بود که با اجرا شدن، سرویس (service) را شروع می کرد و بعد برنامه اندروید بسته می شد. من ترجیح دادم که یک Activity دیگر را به عنوان Activity اصلی برنامه اندروید قرار بدهم که در آن یک دکمه (Button) وجود دارد که با کلیک بر روی آن، به همان Activity می رویم که بعد از شروع سرویس، بسته می شود (در صورت دلخواه، می توانید همان Activity را به عنوان Activity اصلی برنامه اندروید قرار بدهید).
فایل های پروژه اندروید و همچنین فایل apk ساخته شده از آن، پیوست این ارسال می باشد.
اگر می خواهید بدانید که چه بخش هایی از کدها را تغییر داده ام، دو فایل SampleOverlayService.java و  SampleOverlayView.java را باز کنید، در ادامه خط هایی از کدها که یا تازه نوشته ام یا تغییرشان داده ام، عبارت زیر نوشته شده است :

کد:
//----------> change

دو Activity هم به پروژه اندروید افزوده شده است.

ممنون داداش دمت گرم همون چیزی شد که میخواستم ممنون
سلام

من خواستم از این استفاده کنم منتها به 2تا مشکل خوردم اگه میشه راهنمایی کنید.

1- وقتی با استفاده از پنجره ظاهر شده وسط صفحه میخوام به اکتیویتی مورد نظر خودم در برنامم برم ، اکتیویتی رو از اول میسازه ( متود onCreate ) رو اجرا میکنه و اطلاعاتی که روی اکتیویتی مورد نظرم هست همش حذف میشه مثلا الان اگه شما چیزی روی nextActivtiy اعمال کرده باشید وقتی میخواید به این اکتیویتی برگردید کامل یه اکتیویتی دیگه ساخته میشه و اطلاعاتتون روی اون اکتیویتی رو نمیبینید مگر اینکه با دکمه بک اکتیویتی سCloseاخته شده جدید رو ببندید تا به قبلیه وارد بشید.

2- متود notification.setLatestEventInfo در فایل SampleOverlayService منسوخ شده و در اندرودی استودیو اصلا قبول نمی کنه تا برنامه رو کامپایل کنه بنابرین برای اجرای برنامه مجبور شدم همه بدنه متود foregroundNotification از فایل SampleOverlayService رو حذف کنم ( برای تست برنامه ) ، ضمنا ترجیحا میخوام از ناتیفیکیشن برای حذف پنجره استفاده نشه و در متود onDestroy در اکتیویتی اصلی برنامه حذفش رو بگنجونم ، میتونید راهنمایی کنید ؟ یا اگه نمیشه مشکل منسوخ بودن این متود ناتیفیکیشن رو چطور حل کنم ، در این مورد سرچ کردم اینو پیدا کردم که مثل اینکه طریقه حل این مشکل رو توضیح داده منتها چون تاحالا با ناتیفیکیشن کار نکردم زیاد سر در نیاوردم. Undecided 
Huh

ممنون
کسی پیشنهادی نداره ؟ پروژم همینطور مونده book