Friday, 5 February 2016

Creating a System Overlay (Always on Top over all Apps) in Android

In this post, we have learn about creating a system overlay (Always on Top over all Apps).

1)Add the following permission to Android Manifest.XML.

 <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
 
2)Add WindowManager.

The Android WindowManager is a system service, which is responsible for managing the z-ordered list of windows, which windows are visible, and how they are laid out on screen. Among other things, it automatically performs window transitions and animations when opening or closing an app or rotating the screen.

Every activity has a Window that is used to display its content on the screen. When you call setContentView on an activity, it attaches that view to the activity's default window. The default window fills the screen, so that your activity's window hides any other activities -- the WindowManager will display whichever window is on top. So normally you don't need to worry about windows - you just create an activity and Android will do the rest for you.

But you need to interact with the WindowManager if you want to do something unusual like create floating windows that don't fill the screen. If you want to create a floating window that is visible in front of other applications, you can't use an activity because your activity will stop when another app comes to the foreground, and its window will be hidden or destroyed. Instead you need to display a window from a background service.

 For example:

 private WindowManager windowManager;
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
 LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
        WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_PHONE,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
                PixelFormat.TRANSLUCENT);
       params.gravity = Gravity.TOP | Gravity.LEFT;
        params.x = 0;
        params.y = 100;
        chatheadView = (RelativeLayout) inflater.inflate(R.layout.activity_alert_dialog, null);
windowManager.addView(chatheadView, params);

For  Lollipop and Marshmallow  devices, you need to add following code for Notification Overlay:

 public static void requestSystemAlertPermission(Activity context, int requestCode) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
            return;
        final String packageName = context == null ? context.getPackageName() : context.getPackageName();
      final Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + packageName));
        if (context != null)
            context.startActivityForResult(intent, requestCode);
        else
            context.startActivityForResult(intent, requestCode);
    }
    @TargetApi(23)
    public static boolean isSystemAlertPermissionGranted(Context context) {
        final boolean result = Build.VERSION.SDK_INT < Build.VERSION_CODES.M || Settings.canDrawOverlays(context);
        return result;
    }

To get full code:  Click Here

Result:


Enable Location Services and GPS programmatically (without navigating to the location settings)

In this post, we have learn about enabling  Location Services and GPS programmatically (without navigating to the location settings).

First,
1) Add add google play services into android studio.

2) Create new project in android studio.

3)Implement GoogleApiClinet for enabling  Location Services.

Once play services are available on the device, build the GoogleApiClient by calling buildGoogleApiClient() method.

 Connect to google api client by calling googleApiClient.connect() method. By calling this, onConnectionFailed(), onConnected() and onConnectionSuspended() will be triggered depending upon the connection status.

Add the below code to your main activity and run the project.

      private void enableLoc() {
        if (googleApiClient == null) {
            googleApiClient = new GoogleApiClient.Builder(this)
                    .addApi(LocationServices.API)
                    .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
                        @Override
                        public void onConnected(Bundle bundle) {

                        }

                        @Override
                        public void onConnectionSuspended(int i) {
                            googleApiClient.connect();
                        }
                    })
                    .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
                        @Override
                        public void onConnectionFailed(ConnectionResult connectionResult) {

                            Log.d("Location error","Location error " + connectionResult.getErrorCode());
                        }
                    }).build();
            googleApiClient.connect();

            LocationRequest locationRequest = LocationRequest.create();
            locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            locationRequest.setInterval(30 * 1000);
            locationRequest.setFastestInterval(5 * 1000);
            LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                    .addLocationRequest(locationRequest);

            builder.setAlwaysShow(true);

            PendingResult<LocationSettingsResult> result =
                    LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
            result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
                @Override
                public void onResult(LocationSettingsResult result) {
                    final Status status = result.getStatus();
                    switch (status.getStatusCode()) {
                        case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                            try {
                                // Show the dialog by calling startResolutionForResult(),
                                // and check the result in onActivityResult().
                                status.startResolutionForResult(MainActivity.this, REQUEST_LOCATION);
                            } catch (IntentSender.SendIntentException e) {
                                // Ignore the error.
                            }
                            break;
                    }
                }
            });
        }

    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        switch (requestCode) {
            case REQUEST_LOCATION:
                switch (resultCode) {
                    case Activity.RESULT_CANCELED: {
                        // The user was asked to change settings, but chose not to
                        finish();
                        break;
                    }
                    default: {
                        break;
                    }
                }
                break;
        }

    }

Output: