Wednesday, 12 July 2017

Using an expandable Listview in android

Using an expandable Listview in android is much easier than we think. It is having an adapter and two custom views to inflate into it. Android hive has given a perfect example of it . You can check it by Clicking here or go to this URL: http://www.androidhive.info/2013/07/android-expandable-list-view-tutorial/

Wednesday, 21 June 2017

How to make a screen Recording app in Android - 100% Working Source code

Below is the source code for developing a screen Recording app.
NOTE: This code will work only for 21 and above api devices.

You can also watch video Click here

MainActivity.java
public class MainActivity extends AppCompatActivity
{
    private static final String TAG = "MainActivity";
    private static final int REQUEST_CODE = 1000;
    private int mScreenDensity;
    private MediaProjectionManager mProjectionManager;
    private static final int DISPLAY_WIDTH = 720;
    private static final int DISPLAY_HEIGHT = 1280;
    private MediaProjection mMediaProjection;
    private VirtualDisplay mVirtualDisplay;
    private MediaProjectionCallback mMediaProjectionCallback;
    private ToggleButton mToggleButton;
    private MediaRecorder mMediaRecorder;
    private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
    private static final int REQUEST_PERMISSIONS = 10;

    static    {
        ORIENTATIONS.append(Surface.ROTATION_0, 90);
        ORIENTATIONS.append(Surface.ROTATION_90, 0);
        ORIENTATIONS.append(Surface.ROTATION_180, 270);
        ORIENTATIONS.append(Surface.ROTATION_270, 180);
    }

    @Override    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        DisplayMetrics metrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metrics);
        mScreenDensity = metrics.densityDpi;

        mMediaRecorder = new MediaRecorder();

        mProjectionManager = (MediaProjectionManager) getSystemService
                (Context.MEDIA_PROJECTION_SERVICE);

        mToggleButton = (ToggleButton) findViewById(R.id.toggle);
        mToggleButton.setOnClickListener(new View.OnClickListener()
        {
            @Override            public void onClick(View v)
            {
                if (ContextCompat.checkSelfPermission(MainActivity.this,
                        Manifest.permission.WRITE_EXTERNAL_STORAGE) + ContextCompat
                        .checkSelfPermission(MainActivity.this,
                                Manifest.permission.RECORD_AUDIO)
                        != PackageManager.PERMISSION_GRANTED)
                {
                    if (ActivityCompat.shouldShowRequestPermissionRationale                            (MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) ||
                            ActivityCompat.shouldShowRequestPermissionRationale                                    (MainActivity.this, Manifest.permission.RECORD_AUDIO))
                    {
                        mToggleButton.setChecked(false);
                        Snackbar.make(findViewById(android.R.id.content), R.string.label_permissions,
                                Snackbar.LENGTH_INDEFINITE).setAction("ENABLE",
                                new View.OnClickListener()
                                {
                                    @Override                                    public void onClick(View v)
                                    {
                                        ActivityCompat.requestPermissions(MainActivity.this,
                                                new String[]{Manifest.permission
                                                        .WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO},
                                                REQUEST_PERMISSIONS);
                                    }
                                }).show();
                    } else                    {
                        ActivityCompat.requestPermissions(MainActivity.this,
                                new String[]{Manifest.permission
                                        .WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO},
                                REQUEST_PERMISSIONS);
                    }
                } else                {
                    onToggleScreenShare(v);
                }
            }
        });
    }

    @Override    public void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        if (requestCode != REQUEST_CODE)
        {
            Log.e(TAG, "Unknown request code: " + requestCode);
            return;
        }
        if (resultCode != RESULT_OK)
        {
            Toast.makeText(this,
                    "Screen Cast Permission Denied", Toast.LENGTH_SHORT).show();
            mToggleButton.setChecked(false);
            return;
        }
        mMediaProjectionCallback = new MediaProjectionCallback();
        mMediaProjection = mProjectionManager.getMediaProjection(resultCode, data);
        mMediaProjection.registerCallback(mMediaProjectionCallback, null);
        mVirtualDisplay = createVirtualDisplay();
        mMediaRecorder.start();
    }

    public void onToggleScreenShare(View view)
    {
        if (((ToggleButton) view).isChecked())
        {
            initRecorder();
            shareScreen();
        } else        {
            mMediaRecorder.stop();
            mMediaRecorder.reset();
            Log.v(TAG, "Stopping Recording");
            stopScreenSharing();
        }
    }

    private void shareScreen()
    {
        if (mMediaProjection == null)
        {
            startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_CODE);
            return;
        }
        mVirtualDisplay = createVirtualDisplay();
        mMediaRecorder.start();
    }

    private VirtualDisplay createVirtualDisplay()
    {
        return mMediaProjection.createVirtualDisplay("MainActivity",
                DISPLAY_WIDTH, DISPLAY_HEIGHT, mScreenDensity,
                DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
                mMediaRecorder.getSurface(), null, null);
    }

    private void initRecorder()
    {
        try        {
            mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
            mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
            mMediaRecorder.setOutputFile(Environment
                    .getExternalStoragePublicDirectory(Environment
                            .DIRECTORY_DOWNLOADS) + "/video.mp4");
            mMediaRecorder.setVideoSize(DISPLAY_WIDTH, DISPLAY_HEIGHT);
            mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
            mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
            mMediaRecorder.setVideoEncodingBitRate(512 * 1000);
            mMediaRecorder.setVideoFrameRate(30);
            int rotation = getWindowManager().getDefaultDisplay().getRotation();
            int orientation = ORIENTATIONS.get(rotation + 90);
            mMediaRecorder.setOrientationHint(orientation);
            mMediaRecorder.prepare();
        } catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    private class MediaProjectionCallback extends MediaProjection.Callback
    {
        @Override        public void onStop()
        {
            if (mToggleButton.isChecked())
            {
                mToggleButton.setChecked(false);
                mMediaRecorder.stop();
                mMediaRecorder.reset();
                Log.v(TAG, "Recording Stopped");
            }
            mMediaProjection = null;
            stopScreenSharing();
        }
    }

    private void stopScreenSharing()
    {
        if (mVirtualDisplay == null)
        {
            return;
        }
        mVirtualDisplay.release();
        destroyMediaProjection();
    }

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

    private void destroyMediaProjection()
    {
        if (mMediaProjection != null)
        {
            mMediaProjection.unregisterCallback(mMediaProjectionCallback);
            mMediaProjection.stop();
            mMediaProjection = null;
        }
        Log.i(TAG, "MediaProjection Stopped");
    }

    @Override    public void onRequestPermissionsResult(int requestCode,
                                           @NonNull String permissions[],
                                           @NonNull int[] grantResults)
    {
        switch (requestCode)
        {
            case REQUEST_PERMISSIONS:
            {
                if ((grantResults.length > 0) && (grantResults[0] +
                        grantResults[1]) == PackageManager.PERMISSION_GRANTED)
                {
                    onToggleScreenShare(mToggleButton);
                } else                {
                    mToggleButton.setChecked(false);
                    Snackbar.make(findViewById(android.R.id.content), R.string.label_permissions,
                            Snackbar.LENGTH_INDEFINITE).setAction("ENABLE",
                            new View.OnClickListener()
                            {
                                @Override                                public void onClick(View v)
                                {
                                    Intent intent = new Intent();
                                    intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                    intent.addCategory(Intent.CATEGORY_DEFAULT);
                                    intent.setData(Uri.parse("package:" + getPackageName()));
                                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                    intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
                                    intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
                                    startActivity(intent);
                                }
                            }).show();
                }
                return;
            }
        }
    }
}

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"                
xmlns:tools="http://schemas.android.com/tools"                
android:layout_width="match_parent"                
android:layout_height="match_parent"                
android:background="#FFFFFF"                
android:paddingBottom="@dimen/activity_vertical_margin"                
android:paddingLeft="@dimen/activity_horizontal_margin"                
android:paddingRight="@dimen/activity_horizontal_margin"                
android:paddingTop="@dimen/activity_vertical_margin"                
tools:context=".MainActivity">


    <TextView        
android:id="@+id/textView"        
android:layout_width="wrap_content"        
android:layout_height="wrap_content"       
android:layout_alignParentTop="true"        
android:layout_centerHorizontal="true"        
android:layout_marginTop="10dp"        
android:text="Recording Status: "        
android:textAppearance="?android:attr/textAppearanceLarge"/>

    <ToggleButton        
android:id="@+id/toggle"        
android:layout_width="wrap_content"        
android:layout_height="wrap_content"        
android:layout_below="@+id/textView"        
android:layout_centerHorizontal="true"        
android:layout_marginTop="5dp"        
android:text="Start"/>

    <ImageView        
android:id="@+id/imageView"        
android:layout_width="150dp"        
android:layout_height="150dp"        
android:layout_below="@+id/toggle"        
android:layout_centerHorizontal="true"        
android:layout_marginTop="85dp"        
android:src="@mipmap/icon"/>
</RelativeLayout>


string.xml
<resources>
    <string name="app_name">ScreenCapture</string>

    <string name="hello_world">Hello world!</string>
    <string name="action_settings">Settings</string>
    <string name="label_permissions">Please enable Microphone and Storage permissions.</string>
</resources>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?><manifest package="com.parambir.screencapture"          xmlns:android="http://schemas.android.com/apk/res/android">

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

    <application        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme">
        <activity            android:name="com.parambir.screencapture.MainActivity"            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

</manifest>

build.gradle

apply plugin: 'com.android.application'
android {
    compileSdkVersion 24    buildToolsVersion "24.0.0"
    defaultConfig {
        applicationId "com.parambir.screencapture"        minSdkVersion 21        targetSdkVersion 24        versionCode 1        versionName "1.0"    }
    buildTypes {
        release {
            minifyEnabled false            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:24.0.0'    compile 'com.android.support:design:24.0.0'}

Note: Code refrence taken from https://github.com/Truiton/ScreenCapture


Saturday, 3 June 2017

How to Resize ImageView by percentage in android - USING JAVA CODE

With every view, android provide an override method(onMeasure) in which there are 2 parameters(int widthMeasureSpec, int heightMeasureSpec), You can return height width according to your requirement. 
Example: If you want height = width means a square size view you can return height and width like this: 

@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
    super.onMeasure(heightMeasureSpec, heightMeasureSpec);
}

You can create your custom view for this :

Example: 
Make a class names CustomImageView extends with ImageView
public class CustomImageView extends ImageView
{
    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        super.onMeasure(heightMeasureSpec, heightMeasureSpec);

        // you can set this as per percentage also. For example: "heightMeasureSpec * 50 /100"  ---- the height will be 50% of the view's width. 
    }
}

Use this in your layout like this :
<CustomImageView    
    android:id="@+id/imageView"    
    android:layout_width="match_parent"    
    android:layout_height="wrap_content"
    android:src="@drawable/ic_launcher"    />