Saturday, October 3, 2015

Android listen for Incoming and Outgoing calls and block calls automatically in android using java reflection


First of all create a new aidl directory, and add ITelephony.aidl.
ITelephony.aidl file should be like this. Its package name must be same as below.


package com.android.internal.telephony; 
interface ITelephony {

 
   boolean endCall();
    void answerRingingCall();
     void silenceRinger();
 }


Create a new class named PhoneCallReceiver add Add these lines in Manifest.xml

<receiver android:name=".PhoneCallReceiver">
<intent-filter><action android:name="android.intent.action.PHONE_STATE"/></intent-filter>
</receiver>
If you want to enable/disable this broadcast receiver. You can add following code inActivity from where you want to start/stop this call blocking functionality.
extends PhoneCallReceiver class from BroadCastReceiver and implement onReceive method,onReceive method will be called whenever Phone_STATE will be changed which we added as action in intent-filter in manifest file
public void onReceive(Context context, Intent intent) {
    Log.v(TAG, "Receving....");    telephony = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
If statement will be true if there is Incoming Call, if you want to block Outgoing calls
add this code in else body which is below. 
if(intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_RINGING)) {
You can get Caller number using below line of code.
      caller_number = intent.getStringExtra("incoming_number");
       
 try {
           Class c = Class.forName(telephony.getClass().getName()); 
           Method m = c.getDeclaredMethod("getITelephony");
           m.setAccessible(true);
           telephonyService = (ITelephony) m.invoke(telephony);
           telephonyService.endCall();
           Log.d("CallBlocked", "CallBlocked");
           
        }
 catch (Exception e) {
            e.printStackTrace();      
  }

    } else {

        If you want to block Outgoing calls add the above code here...
    }
}

Write in Air Using Mobile Phone, Windows phone 8.1 Application source code

Using below code you can make drawing by moving Mobile phone in the Air. This application was done for Windows Phone 8.1 during a project, however its not a complete code, you can add more methods and can apply different techniques to smooth accelerometer values.

MainPage.XAML

This is not complete code of xaml file, this code is just to give you an idea, xaml file which is layout
file contains Canvas like below, application will draw hand movements on canvas. You can also add a pencil in canvas and move it / change its position within canvas as accelerometer values changes.

        <!--TODO: Content should be placed within the following grid-->
        <Grid Grid.Row="1" x:Name="root_layout" Tapped="root_layout_Tapped"
           Margin="19,9.5,19,0">
        <StackPanel Orientation="Vertical" VerticalAlignment="Center">
        <Canvas Background="White" Name="MyCanvas" Height="500"  Width="500">
        </Canvas>
        </StackPanel>
        </Grid>

---------------------------------------------------------------------------------------------------------------

MainPage.XAML.CS

This file contains actual logic,
Below is accelerometer reading change event, this will be called when you want app to start detecting hand movments, you can initialize accelerometer object.

public async void _accelerometer_ReadingChanged(Accelerometer sender, AccelerometerReadingChangedEventArgs args)
        {

            await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {

_num variable is used for, how many previous values you want to consider for calculating hand movment.
                if (_index >= _num)
                {
                    _index = 0;
                }

 As line is 2-D object, so we need only 2 values for x and y, but accelerometer gives us three     values  for X,Y,Z axis. so you can transform three values into 2. but I am using X and Z axis just to give you an Idea,

 X and Z axis values of accelerometer will be saved in an array so that application can calculate      average of values for noise removal and smoothing values of accelerometer.
 As you may have an idea that accelerometer gives us almost 180 values in a second for all the three    axis and application cannot process all values, so it needs to remove noise and smooth values.

                _x[_index] = (_accelerometer.GetCurrentReading().AccelerationX);
                _y[_index] = (_accelerometer.GetCurrentReading().AccelerationZ);

                _index++;
                for (int i = 0; i < _num; i++)
                {
                    _sumx += _x[i];
                    _sumy += _y[i];

                }

      y and x variable below contains smoothed values after averaging, which we will use for drawing.
                double y = _sumx / _num;

                double x = _sumy / _num;


                _currentposition.X = (x * 200);
                _currentposition.Y = (y * 200);


                // boundry detect

If you need to make sure that line which you are drawing donot cross Canvas boundary, you can //add a check like below.

if (_currentposition.X > MyCanvas.ActualWidth - 30 || _currentposition.Y > MyCanvas.ActualHeight - 30)
                {
                }

Here we will make a line object like below by giving it current and previous values of acceleromter
and then we will add this line object in Canvas.
           
                _drawLine = new Line()
                {
                    X1 = _previousposition.X,
                    Y1 = _previousposition.Y,
                    X2 = _currentposition.X,
                    Y2 = _currentposition.Y,
                    StrokeThickness = _strokrthick,
                    Stroke = new SolidColorBrush(Colors.Blue)

                };

                _previousposition.X = _currentposition.X;
                _previousposition.Y = _currentposition.Y;


If you need to detect pause, in accelerometer values, or hand movement, you can use below code.
it will calculate distance between values, if distance is below a certain threshold, you can make sure that user is not moving mobile phone or not drawing. You can find distance function below.
                //if (gloabal_length > 0)
                //{
                //    gloabal_array[cc] = _previousposition.X;
                //    gloabal_array[++cc] = _previousposition.Y;

                //    cc++;
                //    gloabal_length = gloabal_length - 2;
                //}

                //else if (gloabal_length == 0)
                //{
                //    gloabal_length = 6;
                //    cc = 0;

                //    int i = 0;
                //    g1 = gloabal_array[i];
                //    g2 = gloabal_array[i + 1];
                //    g3 = gloabal_array[i + 2];
                //    g4 = gloabal_array[i + 3];
                //    g5 = gloabal_array[i + 4];
                //    g6 = gloabal_array[i + 5];

                //}

                MyCanvas.Children.Add(_drawLine);
                double dist = Distance(g1, g2, g3, g4, g5, g6);

         
                if (flag == 0)
                {
                    MyCanvas.Children.Remove(_drawLine);
                    flag = 1;
                }

            });
     
     
        }

function for calculating distance between accelerometer values.

   /*CALCULATING DISTANCE*/
        private double Distance(double x1, double y1, double x2, double y2, double x3, double y3)
        {
            double d = 0;
       
            double[] dist_values = new double[200];

            d = Math.Sqrt(Math.Pow((x2 - x1), 2) + Math.Pow((y2 - y1), 2) + Math.Pow((x3 - x2), 2) +    Math.Pow((y3 - y2), 2));

            return d;
        }/*DISTANCE FUNCTION ENDS HERE */


If you want to convert this drawing into an image and want to store it on your device or want to send it, you can convert canvas into an image using below code.


     RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
                await renderTargetBitmap.RenderAsync(MyCanvas, (int)MyCanvas.Width, (int)MyCanvas.Height);
                IBuffer pixelBuffer = await renderTargetBitmap.GetPixelsAsync();
                byte[] pixels = null;
                pixels = pixelBuffer.ToArray();

                // 2. Write the pixels to a InMemoryRandomAccessStream
                var stream = new InMemoryRandomAccessStream();
                var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.BmpEncoderId, stream);

                encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight, (uint)renderTargetBitmap.PixelWidth,
                    (uint)renderTargetBitmap.PixelHeight, 96, 96, pixels);

                await encoder.FlushAsync();
                WB = new WriteableBitmap(renderTargetBitmap.PixelWidth, renderTargetBitmap.PixelHeight);
                WB.SetSource(stream);
                if (WB == null)
                    return;

                string filename = "Image-" + DateTime.Now.ToFileTime() + ".jpeg";
                await SaveWriteableBitmapAsJpeg(WB, filename);

                StorageFile userPhoto = await KnownFolders.CameraRoll.GetFileAsync(filename);

                BitmapImage image = new BitmapImage();

                byte[] fileBytes = null;
                using (IRandomAccessStreamWithContentType _stream = await userPhoto.OpenReadAsync())
                {

                    fileBytes = new byte[_stream.Size];
                    using (DataReader reader = new DataReader(_stream))
                    {
                        await reader.LoadAsync((uint)_stream.Size);
                        reader.ReadBytes(fileBytes);
                    }
                }


// If you want to convert it into string for serializing/streaming. than use below code
string encodedImage = Convert.ToBase64String(fileBytes);







Kotlin Android MVP Dagger 2 Retrofit Tutorial

http://developine.com/building-android-mvp-app-in-kotlin-using-dagger-retrofit/