Thursday, March 10, 2016

How to use RecyclerView in Android efficiently



In this tutorial I will not explain you how to use RecyclerView  and what is it. Infact I will share some important tips on when to use which overriden method of RecyclerView.

first of all let me add basic code for RecyclerView Adapter and then I will explain when to use which method of RecyclerView. I will explain it with the help of an example so you better understand what am trying to say :)

Because most of the time people use onBindViewHolder and ViewHolder for initializing and other implementation because in these methods we can easily get position of an item for getting data from model position wise. but we do not have position variable or getPosition() method in onCreateViewHolder so I have used global variable position  for this purpose :)

Hope it will help someone, you can also add your findings about RecycelerView in comments below :)

some thing more about recycelerView:

RecyclerView uses LayoutManager for positioning of an items in adapter.
LayoutManager has subclasses which are
Linear Layout Managaer (Similar to ListView, can be used for vertical scrolling or horizontal scrolling)
Grid Layout Manager (Similar to GridView)
StaggeredGridLayoutManager (shows items in a staggered grid)

RecyclerView and CardView are part of android support library so you need to add dependencies in your module build.gradle file. like below

    compile 'com.android.support:cardview-v7:21.0.+'
    compile 'com.android.support:recyclerview-v7:21.0.+'

Now come to point :)
public class UsageDetailsAdapter extends RecyclerView.Adapter<UsageDetailsAdapter.ViewHolder> {

Context mContext;
int position;
DecoView decoView;

public UsageDetailsAdapter(Context context) {
    this.mContext = context;
}

@Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_adapter_usage_details, parent, false);
    decoView = (DecoView) view.findViewById(R.id.dynamicArcView);
    decoView.configureAngles(357, 52);
    ArrayList<Integer> colorsList = new ArrayList<>();
    colorsList.add(mContext.getResources().getColor(R.color.DigitalService1));


 //   Toast.makeText(mContext,""+ position, Toast.LENGTH_SHORT).show();        
    SeriesItem seriesItem = new SeriesItem.Builder(Color.parseColor("#FFE2E2E2"))
            .setRange(0, 70, 50)
            .build();
    int backIndex = decoView.addSeries(seriesItem);
    /*        * seriesItem2, it's second value will be used for calculating percentage.        * */        int newPosition = (position % 7);

    SeriesItem seriesItem2 = null;
    seriesItem2 = new SeriesItem.Builder(colorsList.get(newPosition))
            .setRange(0, 70, 0).setCapRounded(true).setChartStyle(SeriesItem.ChartStyle.STYLE_DONUT)
            .setInterpolator(new AccelerateInterpolator()).setSpinClockwise(true)
            .build();
    SeriesItem seriesItemText = new SeriesItem.Builder(Color.argb(255, 64, 196, 0))
            .setSeriesLabel(new SeriesLabel.Builder("Percent %.0f%%")
                    .setColorBack(Color.argb(218, 0, 0, 0))
                    .setColorText(Color.argb(255, 255, 255, 255))
                    .build())
            .build();
    SeriesItem seriesItemTest = new SeriesItem.Builder(Color.argb(255, 64, 196, 0))
            .setRange(0, 25, 0)
            .addEdgeDetail(new EdgeDetail(EdgeDetail.EdgeType.EDGE_OUTER, Color.parseColor("#22000000"), 0.4f))
            .build();
    //int seriesIndexText =   decoView.addSeries(seriesItemText);        int series1Index = decoView.addSeries(seriesItem2);
    int series1Test = decoView.addSeries(seriesItemTest);
 decoView.addEvent(new    DecoEvent.Builder(25).setIndex(series1Index).setDelay(100).build());
   // decoView.addEvent(new DecoEvent.Builder(25).setIndex(seriesIndexText).setDelay(100).build());//        decoView.addEvent(new DecoEvent.Builder(25).setIndex(series1Test).setDelay(100).build());

    position++;
    return new ViewHolder(view);


}

@Override    public void onBindViewHolder(ViewHolder holder, int position) {

    /*        * onBindViewHolder will be called every time user scroll up or down        *        * */
}

@Override    public int getItemCount() {
    return 10;
}

public class ViewHolder extends RecyclerView.ViewHolder {

    public ViewHolder(View itemView) {
        super(itemView);
        decoView = (DecoView) itemView.findViewById(R.id.dynamicArcView);
        decoView.setBackgroundColor(mContext.getResources().getColor(R.color.textColorPrimary));
        /*            * View holder will be called once, but if user scroll before completing arc view            * animation will not be completed.            *            * */        }
}
}
ViewHolder
ViewHolder provides a reference to the views.

I am using DecoView library for making arc veiw animation in my app. the problem which I faced here is I added all my code for making animation in ViewHolder (constructor) of ViewHolder class.

but if you scroll down your RecyclerView (items in RecycelerView) before the completion of animation , animation will not be completed and it will be stoped where it was for those items which has been scrolled up.


onBindViewHolder
replace the content of a view

then I added my code for making animation in onBindViewHolder method of RecycelerView adapter.

problem which I faced here is every time user scroll items in RecyclerView onBindViewHolder is called and animation again starts from zero.


onCreateViewHolder
create a new view, you can set margins, and other parameters here.

then I moved code inside onCreateViewHolder method and it worked for me as I wanted. means onCreateViewHolder is called only once. and arc view animates only once and it animates completely as you want.



Monday, February 15, 2016

Android Information security Guidelines with code examples


Following are requirements which should be met before submitting any APK file to Information security or before publishing app at play store.  

Always Use Proguard

Proguard will obfuscate your code. If someone decompiles your code, Your code will be useless. Because proguard will change classes, methods, variables names.


1. Add these lines in build.gradle file to enable proguard.

 minifEnabled must be true.

buildTypes {
    release {
        minifyEnabled true

        proguardFiles getDefaultProguardFile('proguard-android.txt'),
                'proguard-rules.pro'    }
    debug {
        minifyEnabled false    
}
}


2. Configure proguard-rules.pro file in your project

If you are using libraries in your project. Proguard will replace classes or remove classes. And you will get ClassDefNotFoundException.

To avoid this. Add proguard rules in Pro-guard rules.pro file. Check all dependencies in project build.gradle file and add rules for each of them.

I am using volley, mix panel, ACRA, sliding menu, jackson libraries in my project for which I am using below rules.

Example:

-keep class android.support.v4.app.** { *; }
 -keep interface android.support.v4.app.** { *; }
-keep class android.support.v7.app.** { *; }
-keep interface android.support.v7.app.** { *; }
 -keep class android.support.v13.app.** { *; }
 -keep interface android.support.v13.app.** { *; }
-dontwarn android.support.design.**
-keep class android.support.design.** { *; }
-keep interface android.support.design.** { *; }
-keep public class android.support.design.R$* { *; }
#-dontwarn android.support.design.internal.NavigationMenu.**
android.support.design.widget.NavigationView -dontwarn org.apache.http.**
 -dontwarn com.mixpanel.**
-dontwarn org.codehaus.jackson.**
-dontwarn org.acra.ErrorReporter.**
-dontwarn com.jeremyfeinstein.slidingmenu.**
-keepnames class com.fasterxml.jackson.** { *; }
 -keepclassmembers public final enum org.codehaus.jackson.annotate.JsonAutoDetect$Visibility {

 public static final org.codehaus.jackson.annotate.JsonAutoDetect$Visibility *; } -keep class  com.tozny.crypto.android.AesCbcWithIntegrity$PrngFixes$* { *; }  


4. I used allatori  for String encryption and for hiding static code blocks in my application. as proguard do not obfuscate Strings so I had to use allotri for that purpose.

5. To avoid Intent Injection
    I will explain how to do this later.

6. Remove logs from application before publishing it to play store.

7. Do not allow application to be installed on rooted devices. so that your application sensitive  information is not exposed to other apps.

To do this below is code to check if device is rooted or not. finish splash activity or application is below code returns true.

public boolean isRooted() {

    // get from build info    String buildTags = android.os.Build.TAGS;
    if (buildTags != null && buildTags.contains("test-keys")) {
        return true;
    }

    // check if /system/app/Superuser.apk is present    try {
        File file = new File("/system/app/Superuser.apk");
        if (file.exists()) {
            return true;
        }
    } catch (Exception e1) {
        // ignore    }

    // try executing commands    return canExecuteCommand("/system/xbin/which su")
            || canExecuteCommand("/system/bin/which su") || canExecuteCommand("which su");
}

// executes a command on the systemprivate boolean canExecuteCommand(String command) {
    boolean executedSuccesfully;
    try {
        Runtime.getRuntime().exec(command);
        executedSuccesfully = true;
    } catch (Exception e) {
        executedSuccesfully = false;
    }

    return executedSuccesfully;
} 


Always Sign APK before giving it to Information Security team. Do not give APK in debug mode. It should be in release mode.

8. Sensitive information stored in Database and SharedPreferences should be encrypted. Because any one can read this on rooted devices or using different tools they can break APK file and can get all files.

9. compile 'com.scottyab:secure-preferences-lib:0.1.4'
I used above mentioned library for encrypting data stored in sharedPreferences. You can read its documentation for further information. There are many other libraries for SqliteDB and sharedPreferences encryption.

This is proguard rule which I am using for above library. To make sure that it do not obfuscate classes in this library. So my app do not crash.

-keep class com.tozny.crypto.android.AesCbcWithIntegrity$PrngFixes$* { *; }

You can check/search proguard rules against other libraries which you are using in your project.

10. Error messages in case of incorrect username/password should be general. We should never tell explicitly if username is not valid or password is not valid.

Further information can be found at below links.

References:
http://developer.android.com/training/articles/security-tips.html 
http://developer.android.com/training/best-security.html

Wednesday, February 10, 2016

How to read precise state of an outgoing call in Android programatically


In this example I will show you how to get precise call state in Android programatically using java reflection API. 


Add this in Android Manifest file. Declare Broadcast receiver.




<receiver
        android:name=".OutCallLogger"
        android:enabled="true"
        android:exported="true" >
            <intent-filter>
                <action android:name="android.intent.action.PRECISE_CALL_STATE" />
                <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
            </intent-filter>
    </receiver>
Add below permissions in android manifest file.
<uses-permission android:name="android.permission.READ_PHONE_STATE" />  
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.READ_PRECISE_PHONE_STATE" />
Also add this line in manifest file.
 <uses-feature android:name="android.hardware.telephony"></uses-feature>
And this is your class which will be used for getting precised call state for outgoing calls.
 public class OutCallLogger extends BroadcastReceiver {
public OutCallLogger() {
}
TelephonyManager Tm;
ITelephony telephonyService;
Class c = null;
Method methodGetInstance = null;
Method methodGetActiveFgCallState=null;
String TAG="Tag";
Object objectCallManager=null;
Context context1;
Class<?> classCallManager;

Class telephonyClass;
Class telephonyStubClass;
Class serviceManagerClass;
Class serviceManagerStubClass;
Class serviceManagerNativeClass;
Class serviceManagerNativeStubClass;

Method telephonyCall;
Method telephonyEndCall;
Method telephonyAnswerCall;
Method getDefault;

Method[] temps;
Constructor[] serviceManagerConstructor;

// Method getService;
Object telephonyObject;
Object serviceManagerObject;
private Timer timer= null;

@Override
public void onReceive(Context context, Intent intent) {
    // TODO: This method is called when the BroadcastReceiver is receiving
    // an Intent broadcast.



    this.context1= context;
 Tm=(TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
final ClassLoader classLoader = this.getClass().getClassLoader();
try {
     classCallManager = classLoader.loadClass("com.android.internal.telephony.CallManager");
    Log.e(TAG, "CallManager: Class loaded " + classCallManager.toString());
    methodGetInstance = classCallManager.getDeclaredMethod("getInstance");
    methodGetInstance.setAccessible(true);
    Log.e(TAG, "CallManager: Method loaded " + methodGetInstance.getName());
    objectCallManager = methodGetInstance.invoke(null);
    Log.e(TAG, "CallManager: Object loaded " + objectCallManager.getClass().getName());
    Method[] aClassMethods = classCallManager.getDeclaredMethods();
    for(Method m : aClassMethods)
    {
        Log.e("MEthods", m.getName());
    }
    methodGetActiveFgCallState = classCallManager.getDeclaredMethod("getActiveFgCallState");
    Log.e(TAG, "CallManager: Method loaded " + methodGetActiveFgCallState.getName());

    Log.e(TAG, "CallManager: What is the Call state = " + methodGetActiveFgCallState.invoke(objectCallManager));
}
catch (ClassNotFoundException e) {
    Log.e(TAG, e.getClass().getName() + e.toString());
}
catch (NoSuchMethodException e) {
    Log.e(TAG, e.getClass().getName() + e.toString());
}
catch (InvocationTargetException e) {
    Log.e(TAG, e.getClass().getName() + e.toString());
}
catch (IllegalAccessException e) {
    Log.e(TAG, e.getClass().getName() + e.toString());
}
Tm.listen(new PhoneStateListener(){
    public void  onCallStateChanged(int state,String number) {
        super.onCallStateChanged(state, number);

        try {
            if (methodGetActiveFgCallState.invoke(objectCallManager).toString().toLowerCase() .equals("idle"))
            {
                //Toast.makeText(context1, "I am in idle state", Toast.LENGTH_LONG).show();            }
            if (methodGetActiveFgCallState.invoke(objectCallManager).toString().toLowerCase() .equals("active"))
            {
                //Toast.makeText(context1, "I am in active state", Toast.LENGTH_LONG).show();            }

            Toast.makeText(context1, " "+methodGetActiveFgCallState.invoke(objectCallManager).toString(), Toast.LENGTH_LONG).show();


        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block            e.printStackTrace();
        }

    }

}, PhoneStateListener.LISTEN_CALL_STATE);
}

A Toast will appear which will tell you about call state. Find a line which shows Toast.

Wednesday, December 23, 2015

Android Volley Out of memory exception fixed using clear app cache dynamically


Hi, I used Volley in one of my project and at a time our API data changed from smaller to larger one.
and our Application started crashing and giving out of memory error. And when we clear App data and start Application again it worked fine.

After looking at certain links like
volley out of memory error
volley out of memory error 2

these links did'nt helped me but after noticing that when I clear App data app works fine. So here is solution which is working perfect for me and my App do not crash.

JSONObject mainObject = null;
INetworkOperationListner getJSONListener;

INetworkOperationListner will send data to Activity which called below doInBackGround method.
please note this is not AsyncTask doInBackground, this is my custom doInBackground. Volley donot need AsyncTask.

When request is completed and onResponse method is called I am callling deleteCache(context) method. which will clear cache after every call and no Out of memory error will occur.

public JSONObject doInBackground(HashMap<String,String> params, final String url) {
        RequestQueue mRequestQueue;
           JsonObjectRequest req = new JsonObjectRequest(url, new JSONObject(params),
                new com.android.volley.Response.Listener<JSONObject>() {
                    @Override                    public void onResponse(JSONObject response) {
                        mainObject = response;
                        try {
                            deleteCache(context);
                            getJSONListener.onRemoteCallComplete(response.toString());

                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                }, new com.android.volley.Response.ErrorListener() {
            @Override            public void onErrorResponse(VolleyError error) {
            }
        }
        )
        {
       @Override            public Map<String, String> getHeaders() throws AuthFailureError {
                HashMap<String, String> headers = new HashMap<String, String>();
                headers.put("Username", Constants.Username);
                headers.put("Password", Constants.Password);
                return headers;
            }
        };
        int socketTimeout = 15000;
        RetryPolicy policy = new DefaultRetryPolicy(socketTimeout, DefaultRetryPolicy.DEFAULT_TIMEOUT_MS, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
        req.setRetryPolicy(policy);
        //mRequestQueue.add(req);        Volley.newRequestQueue(context).add(req);

        return mainObject;
    }


How to delete Android Application cache programatically deleteCache(Context) will be called from onResponse.

public static void deleteCache(Context context) {
    try {
        File dir = context.getCacheDir();
        deleteDir(dir);
    } catch (Exception e) {}
}

public static boolean deleteDir(File dir) {
    if (dir != null && dir.isDirectory()) {
        String[] children = dir.list();
        for (int i = 0; i < children.length; i++) {
            boolean success = deleteDir(new File(dir, children[i]));
            if (!success) {
                return false;
            }
        }
        return dir.delete();
    }
    else if(dir!= null && dir.isFile())
        return dir.delete();
    else {
        return false;
    }
}

Acknowledgment: I got above delete app cache from stack overflow.
Use above code and enjoy your app will never crash due to volley out of memory error. :)




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/