Giter Site home page Giter Site logo

magnet's Introduction

Build Status Maven Central Android Weekly Android Arsenal

Magnet

This library enables you to create a window icon similar to Facebooks chat icon, and also similar to the Link Bubble app. See the demo project for sample implementations.

Sample play store app:

Google play link

The library takes care of all the touching and dragging of the window icon, leaving you with callbacks so you can save your time to implement your app.

Usage (gradle)

Via maven central

<dependency>
  <groupId>com.premnirmal.magnet</groupId>
  <artifactId>library</artifactId>
  <version>1.2.7</version>
  <type>aar</type>
</dependency>

Add the following to your build.gradle

compile 'com.premnirmal.magnet:library:1.2.7'
compile 'com.facebook.rebound:rebound:0.3.8'
compile 'com.tumblr:backboard:0.1.2'

How to create a Magnet

Use the required permission

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

Android api level 23+

Request the permission at runtime in your activity, before calling Magnet#show():

  void checkDrawOverlayPermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
      if (!Settings.canDrawOverlays(this)) {
        final Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
            Uri.parse("package:" + getPackageName()));
        startActivityForResult(intent, REQUEST_CODE);
      } else {
        // continue here - permission was granted
      }
    } else {
      // continue here - permission was granted
    }
  }

  @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_CODE) {
      if (Settings.canDrawOverlays(this)) {
        // continue here - permission was granted
      }
    }
}

Use the magnet builder in your Activity or Service

final ImageView iconView = new ImageView(this);
iconView.setImageResource(R.drawable.ic_launcher);
final Magnet magnet = Magnet.newBuilder(this)
        // a view is required
        .setIconView(iconView)
        // all the parameters below are optional
        .setIconCallback(this)
        .setHideFactor(0.2f)
        .setShouldShowRemoveView(true)
        .setRemoveIconShouldBeResponsive(true)
        .setRemoveIconResId(R.drawable.ic_close)
        .setRemoveIconShadow(R.drawable.bottom_shadow)
        .setShouldStickToWall(true)
        .setRemoveIconShouldBeResponsive(true)
        .setInitialPosition(300, 400)
        .withSpringConfig(springConfig)
        .build();
magnet.show();

        ...

magnet.setPosition(200, 800); // to manually move the magnet

        ...

magnet.goToWall(); // to stick the magnet to the wall (only works if shouldStickToXWall or shouldStickToYWall is enabled)

        ...

magnet.destroy(); // to remove the magnet

Subclassing

Instantiate your subclass of Magnet using the Builder

final MyMagnet magnet = new Magnet.Builder<MyMagnet>(MyMagnet.class, context)
                        .setIconView(iconView)
                        .build();

Use the callbacks per your needs

  @Override public void onFlingAway() {
    Log.i(TAG, "onFlingAway");
  }

  @Override public void onMove(float x, float y) {
    Log.i(TAG, "onMove(" + x + "," + y + ")");
  }

  @Override public void onIconClick(View icon, float iconXPose, float iconYPose) {
    Log.i(TAG, "onIconClick(..)");
  }

  @Override public void onIconDestroyed() {
    Log.i(TAG, "onIconDestroyed()");
  }

API Requirements

  • The minimum supported Android version is Android 4.0 Ice cream sandwich (API Level 14)
  • Requires the permission android.permission.SYSTEM_ALERT_WINDOW

Dependencies

Contributing

Please fork this repository and contribute back using pull requests.

License

WWWWWW||WWWWWW
 W W W||W W W
      ||
    ( OO )__________
     /  |           \
    /o o|    MIT     \
    \___/||_||__||_|| *
         || ||  || ||
        _||_|| _||_||
       (__|__|(__|__|

The MIT License (MIT)

Copyright (c) 2014 Prem Nirmal

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Author

Prem Nirmal

magnet's People

Contributors

patelnishantk avatar premnirmal avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

magnet's Issues

Stick to wall horizontal only

Hi,

Thanks for the quick fix on the other issue.
I have another request, I would like the 'Stick to wall' option to only work horizontally, so only stick to the left or right wall.

Magnet used in Service crashes after second removing of magnet isntance

Hello,

I found the following exception when I trying to destroy second magnet instance used as a preloader.

The exception is following:

10-24 09:18:47.395 12745-12906 A: java_vm_ext.cc:504] JNI DETECTED ERROR IN APPLICATION: JNI CallStaticVoidMethodV called with pending exception android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
10-24 09:18:47.395 12745-12906 A: java_vm_ext.cc:504] at void android.view.ViewRootImpl.checkThread() (ViewRootImpl.java:7286)
10-24 09:18:47.395 12745-12906 A: java_vm_ext.cc:504] at android.view.ViewParent android.view.ViewRootImpl.invalidateChildInParent(int[], android.graphics.Rect) (ViewRootImpl.java:1198)
10-24 09:18:47.395 12745-12906 A: java_vm_ext.cc:504] at void android.view.ViewRootImpl.invalidateChild(android.view.View, android.graphics.Rect) (ViewRootImpl.java:1193)
10-24 09:18:47.395 12745-12906 A: java_vm_ext.cc:504] at void android.view.View.invalidateInternal(int, int, int, int, boolean, boolean) (View.java:15470)
10-24 09:18:47.395 12745-12906 A: java_vm_ext.cc:504] at void android.view.View.invalidate(int, int, int, int) (View.java:15405)
10-24 09:18:47.395 12745-12906 A: java_vm_ext.cc:504] at void android.widget.ProgressBar.invalidateDrawable(android.graphics.drawable.Drawable) (ProgressBar.java:1709)
10-24 09:18:47.395 12745-12906 A: java_vm_ext.cc:504] at void android.graphics.drawable.DrawableContainer.invalidateDrawable(android.graphics.drawable.Drawable) (DrawableContainer.java:400)
10-24 09:18:47.395 12745-12906 A: java_vm_ext.cc:504] at void android.graphics.drawable.Drawable.invalidateSelf() (Drawable.java:450)
10-24 09:18:47.395 12745-12906 A: java_vm_ext.cc:504] at void android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorRT.invalidateOwningView() (AnimatedVectorDrawable.java:1589)
10-24 09:18:47.395 12745-12906 A: java_vm_ext.cc:504] at void android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorRT.onAnimationEnd(int) (AnimatedVectorDrawable.java:1764)
10-24 09:18:47.395 12745-12906 A: java_vm_ext.cc:504] at void android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorRT.callOnFinished(android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorRT, int) (AnimatedVectorDrawable.java:1772)

Exception Occurrences:
Each time when I trying to remove preloader which is displayed second time in magnet instance. Preloader is displayed after click on the bubble icon. In other words, the workflow is following:

  • Show bubble
  • Click (Event)
  • Show preloader bubble
  • Remove preloader bubble (Event)
  • Show bubble
  • Click (Event)
  • Show preloader bubble
  • Remove preloader bubble**(Crash)**

What I tried
I tried to resolve this problem using running removal code on the main thread. I tried to use the different instances, finalize instance variables. Could You please confirm this issue or is problem elsewhere?

Handler mainHandler = new Handler(mContext.getMainLooper());
                Runnable myRunnable = new Runnable() {
                    @Override
                    public void run() {
                        magnet.destroy();
                        stopService(intent);
                    } 
                };
                myRunnable.run();

**Class code to reproduce **

public class BubbleService extends Service {

    private Context mContext;
    private Handler mHandler;
    private Runnable mRunnable;
    private String textToTranslate;
    private Magnet magnet, magnetLoading;
    private Integer iconCoordsX, iconCoordsY;
    private ImageView iconViewBubble;
    private ProgressBar progressBar;
    private Intent intent;


    @Override
    public void onCreate() {
        super.onCreate();
        mContext = this;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Logger.d("onStartCommand");
        if(intent != null) {
            Bundle b = intent.getExtras();
            textToTranslate = b.getString(Constants.Global.TRANSLATION);
            this.showBubble();
        }
            return Service.START_STICKY;
    }

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

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    private void removeCallback() {
        if(mRunnable != null && mHandler != null)
            mHandler.removeCallbacks(mRunnable);
    }

    private void removeExistingBubble() {
        try {
            Logger.d("removeExistingBubble");
            mHandler = new Handler();
            if(magnet != null) {
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        Logger.d("magnet destroy");
                        magnet.destroy();
                        magnet = null;
                    }
                });
            }
            if(magnetLoading != null) {
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        Logger.d("magnetLoading destroy");
                        magnetLoading.destroy();
                        magnetLoading = null;
                    }
                });

            }
        } catch (Exception e) {
            Logger.e(e.getMessage());
        }
    }

    private void showBubble() {
        try {
            Logger.d("Show bubble");
            //this.removeExistingBubble();
            iconViewBubble = new ImageView(this);
                iconViewBubble.setImageResource(R.drawable.ic_launcher);
            magnet = Magnet.newBuilder(this)
                    // a view is required
                    .setIconView(iconViewBubble)
                    // all the parameters below are optional
                    .setIconCallback(mIconCallback)
                    .setHideFactor(0.2f)
                    .setShouldShowRemoveView(true)
                    .setRemoveIconShouldBeResponsive(true)
                    .setRemoveIconResId(R.drawable.ic_close)
                    .setRemoveIconShadow(R.drawable.bottom_shadow)
                    //.setShouldStickToWall(true)
                    .setRemoveIconShouldBeResponsive(true)
                    .setInitialPosition(300, 400)
                    .build();
            magnet.show();
            //setTimerForInactiveBubble();
        } catch (Exception e) {
            Logger.e(e.getMessage());
        }
    }

    private void showLoadingBubble() {
        Logger.d("showLoadingBubble");
        magnet.destroy();
        //removeCallback();
        progressBar = new ProgressBar(mContext);
        magnet = Magnet.newBuilder(this)
                // a view is required
                .setIconView(progressBar)
                // all the parameters below are optional
                .setIconCallback(mLoadingIconCallback)
                .setHideFactor(0.2f)
                .setShouldShowRemoveView(true)
                .setRemoveIconShouldBeResponsive(true)
                .setRemoveIconResId(R.drawable.ic_close)
                .setRemoveIconShadow(R.drawable.bottom_shadow)
                .setShouldStickToWall(true)
                .setInitialPosition(iconCoordsX, iconCoordsY)
                .build();
        magnet.show();
    }

    private void setTimerForInactiveBubble() {
        try {
            Logger.d("setTimerForInactiveBubble");
            mHandler = new Handler();
            mRunnable = new Runnable() {
                @Override
                public void run() {
                    try {
                        Logger.d("Remove bubble from inactivity");
                        magnet.destroy();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };
            mHandler.postDelayed(mRunnable,
                    Constants.Global.BUBBLE_DISMISS_DURATION);
        } catch (Exception e) {
            Logger.e(e.getMessage());
        }
    }

    private void bubbleClickCallback() {
        try {
            Logger.d("Clicked on the bubble");
            if (CommonHelper.isDeviceOnline(mContext)) {
                showLoadingBubble();
                //callTranslationService();
            }
            else {
                ToastHelper.showToastMessage(mContext, //TODO: ADD THE OFFLINE TRANSACTION //TODO: MOVE TOAST TO HELPER?
                        mContext.getResources().getString(R.string.no_internet_connectivity),
                        Constants.Global.DEBUG_ENABLED);
            }
        } catch (Exception e) {
            Logger.d(e.getMessage());
        }
    }

    private IconCallback mIconCallback = new IconCallback() {
        @Override
        public void onFlingAway() {
            Logger.d("onFlingAway");
            mHandler = new Handler();
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    Logger.d("destroy");
                    magnet.destroy();
                }
            });

        }

        @Override
        public void onMove(float v, float v1) {
            //Logger.d("onMove");
            iconCoordsX = (int) v;
            iconCoordsY = (int) v1;
        }

        @Override
        public void onIconClick(View view, float v, float v1) {
            Logger.d("onIconClick");
            bubbleClickCallback();
        }

        @Override
        public void onIconDestroyed() {
            Logger.d("onIconDestroyed");
            removeCallback();
            //magnet = null;
        }
    };

    private IconCallback mLoadingIconCallback = new IconCallback() {
        @Override
        public void onFlingAway() {
            try {
                Logger.d("onFlingAway");
                Handler mainHandler = new Handler(mContext.getMainLooper());
                Runnable myRunnable = new Runnable() {
                    @Override
                    public void run() {
                        magnet.destroy();
                        stopService(intent);
                    } // This is your code
                };
                myRunnable.run();

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onMove(float v, float v1) {
            iconCoordsX = (int) v;
            iconCoordsY = (int) v1;
        }

        @Override
        public void onIconClick(View view, float v, float v1) {
            Logger.d("onIconClick");
        }

        @Override
        public void onIconDestroyed() {
            try {
                Logger.d("onIconDestroyed");
                //removeCallback();
                //stopService(intent);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };

    private void callTranslationService() throws Exception {
        Logger.d("callTranslationService");
        //Intent myIntent = new Intent(mContext, TranslateService.class);
        //Intent myIntent = new Intent(mContext, ResultService.class);
        Intent myIntent = new Intent(mContext, ResultServiceCard.class);
        myIntent.putExtra(Constants.Global.TRANSLATION, textToTranslate);
        mContext.startService(myIntent);
    }

}

uses-sdk element cannot have a "tools:node" attribute

When I try to add this library to my app I get this error.

Error:Execution failed for task ':hover:processDebugAndroidTestManifest'.
java.lang.RuntimeException: Manifest merger failed : uses-sdk element cannot have a "tools:node" attribute

Demo not working

I made a project just like the demo, and it didn't work and no bubble showed after giving the permission.!
so I cloned the library and run the demo module, and it worked the first time, if I open it again, no bubble showed just like my project..!?

Can you please double check the demo again, and see if you can add a button that shows the bubble.. and if pressed again it would delete the previous one and show a new one!?

NullPointerException

Occasional crash on some devices on Android 10

Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
at com.premnirmal.Magnet.Magnet.onGlobalLayout(Magnet.java:488)
at android.view.ViewTreeObserver.dispatchOnGlobalLayout(ViewTreeObserver.java:1056)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2818)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1852)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8084)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1057)
at android.view.Choreographer.doCallbacks(Choreographer.java:875)
at android.view.Choreographer.doFrame(Choreographer.java:776)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1042)
at android.os.Handler.handleCallback(Handler.java:888)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:213)
at android.app.ActivityThread.main(ActivityThread.java:8147)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)

Unit Tests for improved test coverage

Hi there,

My name is Farid. I'm a developer with great interest in making open source contributions to popular projects.

My company - DevFactory - is sponsoring me to improve unit test coverage in open source projects.

I have analysed Magnet and observed that there is room for improvement of coverage. The results indicate that the project has no test coverage at the moment.

If you are interested in having us work towards improving the project’s coverage to 80%, please let me know and we will add it to our pipeline. Our first step will be to create a pull request with a sample. Once you approve it, we'll follow up with one or two more pull requests. Our target is to increase code coverage to above 80 percent.

For an example of our work, please see these Pull Requests accepted by the community:

I'm looking forward to your confirmation.

Thank you,
Mohd Farid
Open Source Code Coverage Team
DevFactory

Size of magnet

Is it possible to change the size of custom view, looks like my width and height are ignored.

Min SDK ?

There is no information about the minSDK for this library.

Crash on Android 6+

Caused by: android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@20c99f0 -- permission denied for this window type

App crashes on Android Oreo while showing a magnet

android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@4bd3454 – permission denied for window type 2006

Happens probably because flag WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY was deprecated since API level 26. Need to use WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY

https://developer.android.com/about/versions/oreo/android-8.0-changes.html

https://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#TYPE_SYSTEM_OVERLAY

Cannot set initial position on right side because of spring effect

The magnet initial position (or setInitialPosition(x,y) ) is not working right -- the x parameter (setting horizontal position) would never work, since the spring effect every update when moving -- including move to initial position.

I've tried resetting the SpringConfig , but that does not help.

java.lang.IllegalArgumentException: View=android.widget.FrameLayout{e3fb200 V.E...C.. ......I. 0,0-210,210} not attached to window manager

crash in VERSION 7 and WORKING IN 8 OREO

java.lang.IllegalArgumentException: View=android.widget.FrameLayout{e3fb200 V.E...C.. ......I. 0,0-210,210} not attached to window manager at android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:473) at android.view.WindowManagerGlobal.updateViewLayout(WindowManagerGlobal.java:368) at android.view.WindowManagerImpl.updateViewLayout(WindowManagerImpl.java:99) at com.premnirmal.Magnet.Magnet$WindowManagerPerformer.onSpringUpdate(Magnet.java:666) at com.facebook.rebound.Spring.advance(Spring.java:441) at com.facebook.rebound.BaseSpringSystem.advance(BaseSpringSystem.java:129) at com.facebook.rebound.BaseSpringSystem.loop(BaseSpringSystem.java:143) at com.facebook.rebound.AndroidSpringLooperFactory$ChoreographerAndroidSpringLooper$1.doFrame(AndroidSpringLooperFactory.java:118) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:869) at android.view.Choreographer.doCallbacks(Choreographer.java:683) at android.view.Choreographer.doFrame(Choreographer.java:616) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:857) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6123) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)

below is the function to start a Magnet
`public void startMagnet() {
try {
View mFloatingView = LayoutInflater.from(this).inflate(R.layout.layout_floating_widget, null);

        if (magnet == null) {
            magnet = Magnet.newBuilder(this)
                    .setIconView(mFloatingView)
                    .setIconCallback(this)
                    .setHideFactor(0.2f)
                    .setShouldShowRemoveView(true)
                    .setRemoveIconResId(R.drawable.trash)
                    .setRemoveIconShadow(R.drawable.bottom_shadow)
                    .setShouldStickToWall(true)
                    .setRemoveIconShouldBeResponsive(true)
                    .setInitialPosition(100, 200)
                    .build();
            magnet.show();
            // magnet.setPosition(200, 800);
            mFloatingView.postDelayed(new Runnable() {
                @Override
                public void run() {
                    if (magnet != null) {
                        magnet.setPosition(500, 800);
                        mFloatingView.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                magnet.goToWall();
                            }
                        }, 500);
                    }
                }
            }, 1000);

            mFloatingView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    startActivity(new Intent(MyFirebaseMessagingService.this, HomeActivity.class));
                }
            });
        }

    } catch (Exception e) {
        Log.e("BUBBLE-catch", e.toString());
    }
}`

below is the function to check permission IN SERVICE
`@RequiresApi(api = Build.VERSION_CODES.M)
boolean checkAndLaunch() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (Settings.canDrawOverlays(this)) {
return true;

        }
    }
   /* final Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
            Uri.parse("package:" + getPackageName()));
    startActivityForResult(intent, REQUEST_CODE);*/
    return false;
}`

this function is in MainActivity so user will be showing permission window
` @RequiresApi(api = Build.VERSION_CODES.M)
void checkAndLaunch() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(this)) {
final Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, REQUEST_CODE);
}

}}`

Destroy current visible magnet

im adding a magnet from a service like this :

public class BubbleService extends Service implements IconCallback {

    private static final String TAG = "Magnet";
    private Magnet mMagnet;

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

    @Override
    public void onCreate() {
        super.onCreate();
        ImageView iconView = new ImageView(this);
        iconView.setImageResource(R.drawable.ic);
        iconView.setBackgroundResource(R.drawable.fab);
        mMagnet = new Magnet.Builder(this)
                .setIconView(iconView)
                .setIconCallback(this)
                .setRemoveIconResId(R.mipmap.bubblebackground)
                .setRemoveIconShadow(R.drawable.bottom_shadow)
                .setShouldFlingAway(true)
                .setShouldStickToWall(true)
                .setRemoveIconShouldBeResponsive(true)
                .build();
        mMagnet.show();
    }


    @Override
    public void onFlingAway() {
        Log.i(TAG, "onFlingAway");
        stopSelf();
    }

    @Override
    public void onMove(float x, float y) {
        Log.i(TAG, "onMove(" + x + "," + y + ")");
    }

    @Override
    public void onIconClick(View icon, float iconXPose, float iconYPose) {
        Log.i(TAG, "onIconClick(..)");
    }



    @Override
    public void onIconDestroyed() {
        Log.i(TAG, "onIconDestroyed()");
    }
}

Now if i want to remove this magnet im trying to stop the service but the magnet is still visible .

I cant call mMagnet.destroy() because it gives me null pointer exception.
any idea?

NullPointerException

Dear Premnirmal,
I've applied Magnet in my free app (SC Memo),
thanks for your kindness to share this excellent open source!
Recently, some app users (most of them are using Android 6.0 devices) have reported the NullPointerException below:

java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
at com.premnirmal.Magnet.Magnet.move(Magnet.java:318)
at com.premnirmal.Magnet.Magnet$MoveAnimator.run(Magnet.java:380)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:168)
at android.app.ActivityThread.main(ActivityThread.java:5885)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)

The onMove code in my project is:

//to remember the position
@OverRide
public void onMove(float x, float y) {
posX = (int) x;
posY = (int) y;
}

After days of works (googling and trying to modify my code...), I still cannot figure out the proper solution yet.
Could you please tell me that is there something I can do to fix this error in my code?
Thank you so much. = )

Best,
Summer

Attempting to destroy the window while drawing!

Hi,

When the onIconDestroyed is called, it will show this message and nothing happens.

E/ViewRootImpl[]: Attempting to destroy the window while drawing!
window=android.view.ViewRootImpl@aa5238c, title=

Thanks.

How to set position for Magnet without the animation?

Dear Premnirmal,

Thanks for share this great library : )

Since the method "setPosition(x, y, animate)" was deprecated,

is it possible to set position for Magnet without the animation (works like "setPosition(x, y, false)") in this version?

Thank you very much.

Best,

Summer

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.