master bae3c082f98b cached
151 files
364.0 KB
97.3k tokens
200 symbols
1 requests
Download .txt
Showing preview only (412K chars total). Download the full file or copy to clipboard to get everything.
Repository: hejunlin2013/MultiMediaSample
Branch: master
Commit: bae3c082f98b
Files: 151
Total size: 364.0 KB

Directory structure:
gitextract_hegirt9z/

├── .gitignore
├── .project
├── CameraSample/
│   ├── app/
│   │   ├── build.gradle
│   │   ├── proguard-rules.pro
│   │   └── src/
│   │       ├── androidTest/
│   │       │   └── java/
│   │       │       └── com/
│   │       │           └── hejunlin/
│   │       │               └── camerasample/
│   │       │                   └── ApplicationTest.java
│   │       ├── main/
│   │       │   ├── AndroidManifest.xml
│   │       │   ├── java/
│   │       │   │   └── com/
│   │       │   │       └── hejunlin/
│   │       │   │           └── camerasample/
│   │       │   │               ├── MainActivity.java
│   │       │   │               └── SurfacePreview.java
│   │       │   └── res/
│   │       │       ├── layout/
│   │       │       │   └── activity_main.xml
│   │       │       ├── values/
│   │       │       │   ├── colors.xml
│   │       │       │   ├── dimens.xml
│   │       │       │   ├── strings.xml
│   │       │       │   └── styles.xml
│   │       │       └── values-w820dp/
│   │       │           └── dimens.xml
│   │       └── test/
│   │           └── java/
│   │               └── com/
│   │                   └── hejunlin/
│   │                       └── camerasample/
│   │                           └── ExampleUnitTest.java
│   ├── build.gradle
│   ├── gradle/
│   │   └── wrapper/
│   │       ├── gradle-wrapper.jar
│   │       └── gradle-wrapper.properties
│   ├── gradle.properties
│   ├── gradlew
│   ├── gradlew.bat
│   └── settings.gradle
├── CameraSample2/
│   ├── app/
│   │   ├── build.gradle
│   │   ├── proguard-rules.pro
│   │   └── src/
│   │       ├── androidTest/
│   │       │   └── java/
│   │       │       └── com/
│   │       │           └── hejunlin/
│   │       │               └── camerasample2/
│   │       │                   └── ApplicationTest.java
│   │       ├── main/
│   │       │   ├── AndroidManifest.xml
│   │       │   ├── java/
│   │       │   │   └── com/
│   │       │   │       └── hejunlin/
│   │       │   │           └── camerasample2/
│   │       │   │               ├── Camera2Fragment.java
│   │       │   │               ├── MainActivity.java
│   │       │   │               └── SuperTextureView.java
│   │       │   └── res/
│   │       │       ├── layout/
│   │       │       │   ├── activity_main.xml
│   │       │       │   └── fragment_camera2.xml
│   │       │       ├── values/
│   │       │       │   ├── colors.xml
│   │       │       │   ├── dimens.xml
│   │       │       │   ├── strings.xml
│   │       │       │   └── styles.xml
│   │       │       └── values-w820dp/
│   │       │           └── dimens.xml
│   │       └── test/
│   │           └── java/
│   │               └── com/
│   │                   └── hejunlin/
│   │                       └── camerasample2/
│   │                           └── ExampleUnitTest.java
│   ├── build.gradle
│   ├── gradle/
│   │   └── wrapper/
│   │       ├── gradle-wrapper.jar
│   │       └── gradle-wrapper.properties
│   ├── gradle.properties
│   ├── gradlew
│   ├── gradlew.bat
│   └── settings.gradle
├── GuardProcessSample/
│   ├── app/
│   │   ├── build.gradle
│   │   ├── proguard-rules.pro
│   │   └── src/
│   │       ├── androidTest/
│   │       │   └── java/
│   │       │       └── com/
│   │       │           └── hejunlin/
│   │       │               └── guardprocesssample/
│   │       │                   └── ApplicationTest.java
│   │       ├── main/
│   │       │   ├── AndroidManifest.xml
│   │       │   ├── aidl/
│   │       │   │   └── com/
│   │       │   │       └── hejunlin/
│   │       │   │           └── guardprocesssample/
│   │       │   │               └── aidl/
│   │       │   │                   └── IBridgeInterface.aidl
│   │       │   ├── java/
│   │       │   │   └── com/
│   │       │   │       └── hejunlin/
│   │       │   │           └── guardprocesssample/
│   │       │   │               ├── MainActivity.java
│   │       │   │               ├── ServiceA.java
│   │       │   │               └── ServiceB.java
│   │       │   └── res/
│   │       │       ├── layout/
│   │       │       │   └── activity_main.xml
│   │       │       ├── values/
│   │       │       │   ├── colors.xml
│   │       │       │   ├── dimens.xml
│   │       │       │   ├── strings.xml
│   │       │       │   └── styles.xml
│   │       │       └── values-w820dp/
│   │       │           └── dimens.xml
│   │       └── test/
│   │           └── java/
│   │               └── com/
│   │                   └── hejunlin/
│   │                       └── guardprocesssample/
│   │                           └── ExampleUnitTest.java
│   ├── build.gradle
│   ├── gradle/
│   │   └── wrapper/
│   │       ├── gradle-wrapper.jar
│   │       └── gradle-wrapper.properties
│   ├── gradle.properties
│   ├── gradlew
│   ├── gradlew.bat
│   └── settings.gradle
├── LICENSE
├── MediaCodcSample/
│   ├── .gitignore
│   ├── app/
│   │   ├── .gitignore
│   │   ├── build.gradle
│   │   ├── proguard-rules.pro
│   │   └── src/
│   │       ├── androidTest/
│   │       │   └── java/
│   │       │       └── com/
│   │       │           └── hejunlin/
│   │       │               └── mediacodcsample/
│   │       │                   └── ApplicationTest.java
│   │       ├── main/
│   │       │   ├── AndroidManifest.xml
│   │       │   ├── java/
│   │       │   │   └── com/
│   │       │   │       └── hejunlin/
│   │       │   │           └── mediacodcsample/
│   │       │   │               └── MainActivity.java
│   │       │   └── res/
│   │       │       ├── layout/
│   │       │       │   └── activity_main.xml
│   │       │       ├── values/
│   │       │       │   ├── colors.xml
│   │       │       │   ├── dimens.xml
│   │       │       │   ├── strings.xml
│   │       │       │   └── styles.xml
│   │       │       └── values-w820dp/
│   │       │           └── dimens.xml
│   │       └── test/
│   │           └── java/
│   │               └── com/
│   │                   └── hejunlin/
│   │                       └── mediacodcsample/
│   │                           └── ExampleUnitTest.java
│   ├── build.gradle
│   ├── gradle/
│   │   └── wrapper/
│   │       ├── gradle-wrapper.jar
│   │       └── gradle-wrapper.properties
│   ├── gradle.properties
│   ├── gradlew
│   ├── gradlew.bat
│   └── settings.gradle
├── MediaPlayerSample/
│   ├── app/
│   │   ├── build.gradle
│   │   ├── proguard-rules.pro
│   │   └── src/
│   │       ├── androidTest/
│   │       │   └── java/
│   │       │       └── com/
│   │       │           └── hejunlin/
│   │       │               └── mediaplayersample/
│   │       │                   └── ApplicationTest.java
│   │       └── main/
│   │           ├── AndroidManifest.xml
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── hejunlin/
│   │           │           └── mediaplayersample/
│   │           │               └── MainActivity.java
│   │           └── res/
│   │               ├── layout/
│   │               │   └── activity_main.xml
│   │               ├── menu/
│   │               │   └── menu_main.xml
│   │               ├── values/
│   │               │   ├── dimens.xml
│   │               │   ├── strings.xml
│   │               │   └── styles.xml
│   │               ├── values-v21/
│   │               │   └── styles.xml
│   │               └── values-w820dp/
│   │                   └── dimens.xml
│   ├── build.gradle
│   ├── gradle/
│   │   └── wrapper/
│   │       ├── gradle-wrapper.jar
│   │       └── gradle-wrapper.properties
│   ├── gradle.properties
│   ├── gradlew
│   ├── gradlew.bat
│   └── settings.gradle
├── README.md
└── VideoWaterMarkSample/
    ├── .gitignore
    ├── .idea/
    │   ├── compiler.xml
    │   ├── copyright/
    │   │   └── profiles_settings.xml
    │   ├── encodings.xml
    │   ├── gradle.xml
    │   ├── libraries/
    │   │   ├── animated_vector_drawable_23_3_0.xml
    │   │   ├── appcompat_v7_23_3_0.xml
    │   │   ├── hamcrest_core_1_3.xml
    │   │   ├── junit_4_12.xml
    │   │   ├── support_annotations_23_3_0.xml
    │   │   ├── support_v4_23_3_0.xml
    │   │   └── support_vector_drawable_23_3_0.xml
    │   ├── misc.xml
    │   ├── modules.xml
    │   ├── runConfigurations.xml
    │   └── workspace.xml
    ├── app/
    │   ├── .gitignore
    │   ├── build.gradle
    │   ├── proguard-rules.pro
    │   └── src/
    │       └── main/
    │           ├── AndroidManifest.xml
    │           ├── java/
    │           │   └── com/
    │           │       └── hejunlin/
    │           │           └── videorecord/
    │           │               ├── ColorFormatUtil.java
    │           │               ├── MainActivity.java
    │           │               ├── TakeVideoActivity.java
    │           │               ├── VideoCodecModel.java
    │           │               └── VideoCodecTask.java
    │           └── res/
    │               ├── drawable/
    │               │   ├── diverde.xml
    │               │   ├── litte_red_point.xml
    │               │   ├── play.xml
    │               │   └── progressbar_drawable.xml
    │               ├── layout/
    │               │   ├── activity_main.xml
    │               │   └── activity_take_video.xml
    │               ├── values/
    │               │   ├── colors.xml
    │               │   ├── dimens.xml
    │               │   ├── strings.xml
    │               │   └── styles.xml
    │               └── values-w820dp/
    │                   └── dimens.xml
    ├── build.gradle
    ├── gradle/
    │   └── wrapper/
    │       ├── gradle-wrapper.jar
    │       └── gradle-wrapper.properties
    ├── gradle.properties
    ├── gradlew
    ├── gradlew.bat
    └── settings.gradle

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
# Built application files
*.apk
*.ap_

# Files for the ART/Dalvik VM
*.dex

# Java class files
*.class

# Generated files
bin/
gen/
out/

# Gradle files
.gradle/
build/

# Local configuration file (sdk path, etc)
local.properties

# Proguard folder generated by Eclipse
proguard/

# Log Files
*.log

# Android Studio Navigation editor temp files
.navigation/

# Android Studio captures folder
captures/

# Intellij
*.iml
.idea/workspace.xml

# Keystore files
*.jks


================================================
FILE: .project
================================================
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
	<name>MultiMediaSample</name>
	<comment></comment>
	<projects>
	</projects>
	<buildSpec>
	</buildSpec>
	<natures>
	</natures>
</projectDescription>


================================================
FILE: CameraSample/app/build.gradle
================================================
apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {
        applicationId "com.hejunlin.camerasample"
        minSdkVersion 17
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

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


================================================
FILE: CameraSample/app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in D:\Studio SDK/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}


================================================
FILE: CameraSample/app/src/androidTest/java/com/hejunlin/camerasample/ApplicationTest.java
================================================
package com.hejunlin.camerasample;

import android.app.Application;
import android.test.ApplicationTestCase;

/**
 * <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
 */
public class ApplicationTest extends ApplicationTestCase<Application> {
    public ApplicationTest() {
        super(Application.class);
    }
}

================================================
FILE: CameraSample/app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.hejunlin.camerasample">

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

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

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

</manifest>

================================================
FILE: CameraSample/app/src/main/java/com/hejunlin/camerasample/MainActivity.java
================================================
package com.hejunlin.camerasample;

import android.hardware.Camera;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.jar.Manifest;

public class MainActivity extends AppCompatActivity implements Camera.PictureCallback, View.OnClickListener {

    private static final String TAG = MainActivity.class.getSimpleName();
    private SurfacePreview mCameraSurPreview;
    private ImageView mCaptureButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Create our Preview view and set it as the content of our activity.
        FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
        mCameraSurPreview = new SurfacePreview(this);
        preview.addView(mCameraSurPreview);

        // Add a listener to the Capture button
        mCaptureButton = (ImageView) findViewById(R.id.capture);
        mCaptureButton.setOnClickListener(this);
    }

    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
        //save the picture to sdcard
        File pictureFile = getOutputMediaFile();
        if (pictureFile == null){
            Log.d(TAG, "Error creating media file, check storage permissions: ");
            return;
        }

        try {
            FileOutputStream fos = new FileOutputStream(pictureFile);
            fos.write(data);
            fos.close();
        } catch (FileNotFoundException e) {
            Log.d(TAG, "File not found: " + e.getMessage());
        } catch (IOException e) {
            Log.d(TAG, "Error accessing file: " + e.getMessage());
        }

        // Restart the preview and re-enable the shutter button so that we can take another picture
        camera.startPreview();

        //See if need to enable or not
        mCaptureButton.setEnabled(true);
        Toast.makeText(this, "拍照成功", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onClick(View v) {
        mCaptureButton.setEnabled(false);
        // get an image from the camera
        mCameraSurPreview.takePicture(this);
    }

    private File getOutputMediaFile(){
        //get the mobile Pictures directory
        File picDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
        //get the current time
        String timeStamp = new SimpleDateFormat("yyyy-MMdd-HHmmss").format(new Date());
        return new File(picDir.getPath() + File.separator + "hejunlin_"+ timeStamp + ".jpg");
    }
}


================================================
FILE: CameraSample/app/src/main/java/com/hejunlin/camerasample/SurfacePreview.java
================================================
package com.hejunlin.camerasample;

import android.content.Context;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.os.Build;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import java.io.IOException;
import java.lang.reflect.Method;

/**
 * Created by hejunlin on 2016/10/5.
 */
public class SurfacePreview extends SurfaceView implements SurfaceHolder.Callback {

    private static final String TAG = SurfacePreview.class.getSimpleName();
    private SurfaceHolder mHolder;
    private Camera mCamera;
    private Camera.Parameters mParameters;

    public SurfacePreview(Context context) {
        super(context);

        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        mHolder = getHolder();
        mHolder.setFormat(PixelFormat.TRANSPARENT);
        mHolder.addCallback(this);
        // deprecated setting, but required on Android versions prior to 3.0
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public void surfaceCreated(SurfaceHolder holder) {
        Log.d(TAG, "surfaceCreated() is called");
        try {
            // Open the Camera in preview mode
            mCamera = Camera.open(0);
            mCamera.setDisplayOrientation(90);
            mCamera.setPreviewDisplay(holder);
            mCamera.startPreview();
        } catch (IOException e) {
            Log.d(TAG, "Error setting camera preview: " + e.getMessage());
        }
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        Log.d(TAG, "surfaceChanged() is called");
        try {
//            mCamera.startPreview();
            mCamera.autoFocus(new Camera.AutoFocusCallback() {
                @Override
                public void onAutoFocus(boolean success, Camera camera) {
                    if(success){
                        initCamera();
                        camera.cancelAutoFocus();
                    }
                }
            });
        } catch (Exception e){
            Log.d(TAG, "Error starting camera preview: " + e.getMessage());
        }
    }

    private void initCamera() {
        mParameters = mCamera.getParameters();
        mParameters.setPictureFormat(PixelFormat.JPEG);
        mParameters.setPictureSize(1080,1920);
        mParameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
        mParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
        setDispaly(mParameters, mCamera);
        mCamera.setParameters(mParameters);
        mCamera.startPreview();
        mCamera.cancelAutoFocus();

    }
    private void setDispaly(Camera.Parameters parameters,Camera camera) {
        if (Integer.parseInt(Build.VERSION.SDK) >= 8){
            setDisplayOrientation(camera,90);
        } else {
            parameters.setRotation(90);
        }
    }

    private void setDisplayOrientation(Camera camera, int i) {
        Method downPolymorphic;
        try{
            downPolymorphic = camera.getClass().getMethod("setDisplayOrientation", new Class[]{int.class});
            if(downPolymorphic!=null) {
                downPolymorphic.invoke(camera, new Object[]{i});
            }
        }
        catch(Exception e){
            Log.e(TAG, "image error");
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        if (mCamera != null) {
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
        Log.d(TAG, "surfaceDestroyed() is called");
    }

    public void takePicture(Camera.PictureCallback imageCallback) {
        mCamera.takePicture(null, null, imageCallback);
    }
}


================================================
FILE: CameraSample/app/src/main/res/layout/activity_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:id="@+id/camera_preview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="100dp"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:layout_gravity="bottom|center"
        android:background="#000000">

        <ImageView
            android:id="@+id/capture"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:src="@mipmap/capture"
            android:layout_gravity="center" />

    </LinearLayout>
</FrameLayout>

================================================
FILE: CameraSample/app/src/main/res/values/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
</resources>


================================================
FILE: CameraSample/app/src/main/res/values/dimens.xml
================================================
<resources>
    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>
</resources>


================================================
FILE: CameraSample/app/src/main/res/values/strings.xml
================================================
<resources>
    <string name="app_name">CameraSample</string>
</resources>


================================================
FILE: CameraSample/app/src/main/res/values/styles.xml
================================================
<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

</resources>


================================================
FILE: CameraSample/app/src/main/res/values-w820dp/dimens.xml
================================================
<resources>
    <!-- Example customization of dimensions originally defined in res/values/dimens.xml
         (such as screen margins) for screens with more than 820dp of available width. This
         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
    <dimen name="activity_horizontal_margin">64dp</dimen>
</resources>


================================================
FILE: CameraSample/app/src/test/java/com/hejunlin/camerasample/ExampleUnitTest.java
================================================
package com.hejunlin.camerasample;

import org.junit.Test;

import static org.junit.Assert.*;

/**
 * To work on unit tests, switch the Test Artifact in the Build Variants view.
 */
public class ExampleUnitTest {
    @Test
    public void addition_isCorrect() throws Exception {
        assertEquals(4, 2 + 2);
    }
}

================================================
FILE: CameraSample/build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.1.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}


================================================
FILE: CameraSample/gradle/wrapper/gradle-wrapper.properties
================================================
#Mon Dec 28 10:00:20 PST 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip


================================================
FILE: CameraSample/gradle.properties
================================================
# Project-wide Gradle settings.

# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.

# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html

# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8

# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true

================================================
FILE: CameraSample/gradlew
================================================
#!/usr/bin/env bash

##############################################################################
##
##  Gradle start up script for UN*X
##
##############################################################################

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""

APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"

warn ( ) {
    echo "$*"
}

die ( ) {
    echo
    echo "$*"
    echo
    exit 1
}

# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
  CYGWIN* )
    cygwin=true
    ;;
  Darwin* )
    darwin=true
    ;;
  MINGW* )
    msys=true
    ;;
esac

# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '/.*' > /dev/null; then
        PRG="$link"
    else
        PRG=`dirname "$PRG"`"/$link"
    fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar

# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
        # IBM's JDK on AIX uses strange locations for the executables
        JAVACMD="$JAVA_HOME/jre/sh/java"
    else
        JAVACMD="$JAVA_HOME/bin/java"
    fi
    if [ ! -x "$JAVACMD" ] ; then
        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
    fi
else
    JAVACMD="java"
    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi

# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
    MAX_FD_LIMIT=`ulimit -H -n`
    if [ $? -eq 0 ] ; then
        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
            MAX_FD="$MAX_FD_LIMIT"
        fi
        ulimit -n $MAX_FD
        if [ $? -ne 0 ] ; then
            warn "Could not set maximum file descriptor limit: $MAX_FD"
        fi
    else
        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
    fi
fi

# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi

# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
    JAVACMD=`cygpath --unix "$JAVACMD"`

    # We build the pattern for arguments to be converted via cygpath
    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
    SEP=""
    for dir in $ROOTDIRSRAW ; do
        ROOTDIRS="$ROOTDIRS$SEP$dir"
        SEP="|"
    done
    OURCYGPATTERN="(^($ROOTDIRS))"
    # Add a user-defined pattern to the cygpath arguments
    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
    fi
    # Now convert the arguments - kludge to limit ourselves to /bin/sh
    i=0
    for arg in "$@" ; do
        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option

        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
        else
            eval `echo args$i`="\"$arg\""
        fi
        i=$((i+1))
    done
    case $i in
        (0) set -- ;;
        (1) set -- "$args0" ;;
        (2) set -- "$args0" "$args1" ;;
        (3) set -- "$args0" "$args1" "$args2" ;;
        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
    esac
fi

# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
    JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"

exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"


================================================
FILE: CameraSample/gradlew.bat
================================================
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem  Gradle startup script for Windows
@rem
@rem ##########################################################################

@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=

set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto init

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:init
@rem Get command-line arguments, handling Windowz variants

if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args

:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2

:win9xME_args_slurp
if "x%~1" == "x" goto execute

set CMD_LINE_ARGS=%*
goto execute

:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$

:execute
@rem Setup the command line

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd

:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1

:mainEnd
if "%OS%"=="Windows_NT" endlocal

:omega


================================================
FILE: CameraSample/settings.gradle
================================================
include ':app'


================================================
FILE: CameraSample2/app/build.gradle
================================================
apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {
        applicationId "com.hejunlin.camerasample2"
        minSdkVersion 17
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.4.0'
    compile "com.android.support:support-v13:23.4.0"
    compile "com.android.support:support-v4:23.4.0"
    compile "com.android.support:cardview-v7:23.4.0"
}


================================================
FILE: CameraSample2/app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in D:\Studio SDK/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}


================================================
FILE: CameraSample2/app/src/androidTest/java/com/hejunlin/camerasample2/ApplicationTest.java
================================================
package com.hejunlin.camerasample2;

import android.app.Application;
import android.test.ApplicationTestCase;

/**
 * <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
 */
public class ApplicationTest extends ApplicationTestCase<Application> {
    public ApplicationTest() {
        super(Application.class);
    }
}

================================================
FILE: CameraSample2/app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.hejunlin.camerasample2">

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

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

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

</manifest>

================================================
FILE: CameraSample2/app/src/main/java/com/hejunlin/camerasample2/Camera2Fragment.java
================================================
package com.hejunlin.camerasample2;

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.Fragment;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.RectF;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CameraMetadata;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.CaptureResult;
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.media.Image;
import android.media.ImageReader;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.support.annotation.NonNull;
import android.support.v13.app.FragmentCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.util.Size;
import android.util.SparseIntArray;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

public class Camera2Fragment extends Fragment
        implements View.OnClickListener, FragmentCompat.OnRequestPermissionsResultCallback {

    /**
     * Conversion from screen rotation to JPEG orientation.
     */
    private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
    private static final int REQUEST_CAMERA_PERMISSION = 1;
    private static final String FRAGMENT_DIALOG = "dialog";

    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);
    }

    /**
     * Tag for the {@link Log}.
     */
    private static final String TAG = "Camera2Fragment";

    /**
     * Camera state: Showing camera preview.
     */
    private static final int STATE_PREVIEW = 0;

    /**
     * Camera state: Waiting for the focus to be locked.
     */
    private static final int STATE_WAITING_LOCK = 1;

    /**
     * Camera state: Waiting for the exposure to be precapture state.
     */
    private static final int STATE_WAITING_PRECAPTURE = 2;

    /**
     * Camera state: Waiting for the exposure state to be something other than precapture.
     */
    private static final int STATE_WAITING_NON_PRECAPTURE = 3;

    /**
     * Camera state: Picture was taken.
     */
    private static final int STATE_PICTURE_TAKEN = 4;

    /**
     * Max preview width that is guaranteed by Camera2 API
     */
    private static final int MAX_PREVIEW_WIDTH = 1920;

    /**
     * Max preview height that is guaranteed by Camera2 API
     */
    private static final int MAX_PREVIEW_HEIGHT = 1080;

    /**
     * {@link TextureView.SurfaceTextureListener} handles several lifecycle events on a
     * {@link TextureView}.
     */
    private final TextureView.SurfaceTextureListener mSurfaceTextureListener
            = new TextureView.SurfaceTextureListener() {

        @Override
        public void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) {
            openCamera(width, height);
        }

        @Override
        public void onSurfaceTextureSizeChanged(SurfaceTexture texture, int width, int height) {
            configureTransform(width, height);
        }

        @Override
        public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) {
            return true;
        }

        @Override
        public void onSurfaceTextureUpdated(SurfaceTexture texture) {
        }

    };

    /**
     * ID of the current {@link CameraDevice}.
     */
    private String mCameraId;

    /**
     * An {@link SuperTextureView} for camera preview.
     */
    private SuperTextureView mTextureView;

    /**
     * A {@link CameraCaptureSession } for camera preview.
     */
    private CameraCaptureSession mCaptureSession;

    /**
     * A reference to the opened {@link CameraDevice}.
     */
    private CameraDevice mCameraDevice;

    /**
     * The {@link Size} of camera preview.
     */
    private Size mPreviewSize;

    /**
     * {@link CameraDevice.StateCallback} is called when {@link CameraDevice} changes its state.
     */
    private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {

        @Override
        public void onOpened(@NonNull CameraDevice cameraDevice) {
            // This method is called when the camera is opened.  We start camera preview here.
            mCameraOpenCloseLock.release();
            mCameraDevice = cameraDevice;
            createCameraPreviewSession();
        }

        @Override
        public void onDisconnected(@NonNull CameraDevice cameraDevice) {
            mCameraOpenCloseLock.release();
            cameraDevice.close();
            mCameraDevice = null;
        }

        @Override
        public void onError(@NonNull CameraDevice cameraDevice, int error) {
            mCameraOpenCloseLock.release();
            cameraDevice.close();
            mCameraDevice = null;
            Activity activity = getActivity();
            if (null != activity) {
                activity.finish();
            }
        }

    };

    /**
     * An additional thread for running tasks that shouldn't block the UI.
     */
    private HandlerThread mBackgroundThread;

    /**
     * A {@link Handler} for running tasks in the background.
     */
    private Handler mBackgroundHandler;

    /**
     * An {@link ImageReader} that handles still image capture.
     */
    private ImageReader mImageReader;

    /**
     * This is the output file for our picture.
     */
    private File mFile;

    /**
     * This a callback object for the {@link ImageReader}. "onImageAvailable" will be called when a
     * still image is ready to be saved.
     */
    private final ImageReader.OnImageAvailableListener mOnImageAvailableListener
            = new ImageReader.OnImageAvailableListener() {

        @Override
        public void onImageAvailable(ImageReader reader) {
            mBackgroundHandler.post(new ImageSaver(reader.acquireNextImage(), mFile));
        }

    };

    /**
     * {@link CaptureRequest.Builder} for the camera preview
     */
    private CaptureRequest.Builder mPreviewRequestBuilder;

    /**
     * {@link CaptureRequest} generated by {@link #mPreviewRequestBuilder}
     */
    private CaptureRequest mPreviewRequest;

    /**
     * The current state of camera state for taking pictures.
     *
     * @see #mCaptureCallback
     */
    private int mState = STATE_PREVIEW;

    /**
     * A {@link Semaphore} to prevent the app from exiting before closing the camera.
     */
    private Semaphore mCameraOpenCloseLock = new Semaphore(1);

    /**
     * Whether the current camera device supports Flash or not.
     */
    private boolean mFlashSupported;

    /**
     * Orientation of the camera sensor
     */
    private int mSensorOrientation;

    /**
     * A {@link CameraCaptureSession.CaptureCallback} that handles events related to JPEG capture.
     */
    private CameraCaptureSession.CaptureCallback mCaptureCallback
            = new CameraCaptureSession.CaptureCallback() {

        private void process(CaptureResult result) {
            switch (mState) {
                case STATE_PREVIEW: {
                    // We have nothing to do when the camera preview is working normally.
                    break;
                }
                case STATE_WAITING_LOCK: {
                    Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);
                    if (afState == null) {
                        captureStillPicture();
                    } else if (CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED == afState ||
                            CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED == afState) {
                        // CONTROL_AE_STATE can be null on some devices
                        Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
                        if (aeState == null ||
                                aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED) {
                            mState = STATE_PICTURE_TAKEN;
                            captureStillPicture();
                        } else {
                            runPrecaptureSequence();
                        }
                    }
                    break;
                }
                case STATE_WAITING_PRECAPTURE: {
                    // CONTROL_AE_STATE can be null on some devices
                    Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
                    if (aeState == null ||
                            aeState == CaptureResult.CONTROL_AE_STATE_PRECAPTURE ||
                            aeState == CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED) {
                        mState = STATE_WAITING_NON_PRECAPTURE;
                    }
                    break;
                }
                case STATE_WAITING_NON_PRECAPTURE: {
                    // CONTROL_AE_STATE can be null on some devices
                    Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
                    if (aeState == null || aeState != CaptureResult.CONTROL_AE_STATE_PRECAPTURE) {
                        mState = STATE_PICTURE_TAKEN;
                        captureStillPicture();
                    }
                    break;
                }
            }
        }

        @Override
        public void onCaptureProgressed(@NonNull CameraCaptureSession session,
                                        @NonNull CaptureRequest request,
                                        @NonNull CaptureResult partialResult) {
            process(partialResult);
        }

        @Override
        public void onCaptureCompleted(@NonNull CameraCaptureSession session,
                                       @NonNull CaptureRequest request,
                                       @NonNull TotalCaptureResult result) {
            process(result);
        }

    };

    /**
     * Shows a {@link Toast} on the UI thread.
     *
     * @param text The message to show
     */
    private void showToast(final String text) {
        final Activity activity = getActivity();
        if (activity != null) {
            activity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(activity, text, Toast.LENGTH_SHORT).show();
                }
            });
        }
    }

    /**
     * Given {@code choices} of {@code Size}s supported by a camera, choose the smallest one that
     * is at least as large as the respective texture view size, and that is at most as large as the
     * respective max size, and whose aspect ratio matches with the specified value. If such size
     * doesn't exist, choose the largest one that is at most as large as the respective max size,
     * and whose aspect ratio matches with the specified value.
     *
     * @param choices           The list of sizes that the camera supports for the intended output
     *                          class
     * @param textureViewWidth  The width of the texture view relative to sensor coordinate
     * @param textureViewHeight The height of the texture view relative to sensor coordinate
     * @param maxWidth          The maximum width that can be chosen
     * @param maxHeight         The maximum height that can be chosen
     * @param aspectRatio       The aspect ratio
     * @return The optimal {@code Size}, or an arbitrary one if none were big enough
     */
    private static Size chooseOptimalSize(Size[] choices, int textureViewWidth,
            int textureViewHeight, int maxWidth, int maxHeight, Size aspectRatio) {

        // Collect the supported resolutions that are at least as big as the preview Surface
        List<Size> bigEnough = new ArrayList<>();
        // Collect the supported resolutions that are smaller than the preview Surface
        List<Size> notBigEnough = new ArrayList<>();
        int w = aspectRatio.getWidth();
        int h = aspectRatio.getHeight();
        for (Size option : choices) {
            if (option.getWidth() <= maxWidth && option.getHeight() <= maxHeight &&
                    option.getHeight() == option.getWidth() * h / w) {
                if (option.getWidth() >= textureViewWidth &&
                    option.getHeight() >= textureViewHeight) {
                    bigEnough.add(option);
                } else {
                    notBigEnough.add(option);
                }
            }
        }

        // Pick the smallest of those big enough. If there is no one big enough, pick the
        // largest of those not big enough.
        if (bigEnough.size() > 0) {
            return Collections.min(bigEnough, new CompareSizesByArea());
        } else if (notBigEnough.size() > 0) {
            return Collections.max(notBigEnough, new CompareSizesByArea());
        } else {
            Log.e(TAG, "Couldn't find any suitable preview size");
            return choices[0];
        }
    }

    public static Camera2Fragment newInstance() {
        return new Camera2Fragment();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_camera2, container, false);
    }

    @Override
    public void onViewCreated(final View view, Bundle savedInstanceState) {
        view.findViewById(R.id.picture).setOnClickListener(this);
//        view.findViewById(R.id.info).setOnClickListener(this);
        mTextureView = (SuperTextureView) view.findViewById(R.id.texture);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mFile = getOutputMediaFile();
    }

    private File getOutputMediaFile(){
        //get the mobile Pictures directory
        File picDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
        //get the current time
        String timeStamp = new SimpleDateFormat("yyyy-MMdd-HHmmss").format(new Date());
        return new File(picDir.getPath() + File.separator + "hejunlin_camera2_"+ timeStamp + ".jpg");
    }

    @Override
    public void onResume() {
        super.onResume();
        startBackgroundThread();

        // When the screen is turned off and turned back on, the SurfaceTexture is already
        // available, and "onSurfaceTextureAvailable" will not be called. In that case, we can open
        // a camera and start preview from here (otherwise, we wait until the surface is ready in
        // the SurfaceTextureListener).
        if (mTextureView.isAvailable()) {
            openCamera(mTextureView.getWidth(), mTextureView.getHeight());
        } else {
            mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
        }
    }

    @Override
    public void onPause() {
        closeCamera();
        stopBackgroundThread();
        super.onPause();
    }

    private void requestCameraPermission() {
        if (FragmentCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
            new ConfirmationDialog().show(getChildFragmentManager(), FRAGMENT_DIALOG);
        } else {
            FragmentCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA},
                    REQUEST_CAMERA_PERMISSION);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        if (requestCode == REQUEST_CAMERA_PERMISSION) {
            if (grantResults.length != 1 || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                ErrorDialog.newInstance("需要申请摄像头权限")
                        .show(getChildFragmentManager(), FRAGMENT_DIALOG);
            }
        } else {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

    /**
     * Sets up member variables related to camera.
     *
     * @param width  The width of available size for camera preview
     * @param height The height of available size for camera preview
     */
    private void setUpCameraOutputs(int width, int height) {
        Activity activity = getActivity();
        CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
        try {
            for (String cameraId : manager.getCameraIdList()) {
                CameraCharacteristics characteristics
                        = manager.getCameraCharacteristics(cameraId);

                // We don't use a front facing camera in this sample.
                Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
                if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT) {
                    continue;
                }

                StreamConfigurationMap map = characteristics.get(
                        CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
                if (map == null) {
                    continue;
                }

                // For still image captures, we use the largest available size.
                Size largest = Collections.max(
                        Arrays.asList(map.getOutputSizes(ImageFormat.JPEG)),
                        new CompareSizesByArea());
                mImageReader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(),
                        ImageFormat.JPEG, /*maxImages*/2);
                mImageReader.setOnImageAvailableListener(
                        mOnImageAvailableListener, mBackgroundHandler);

                // Find out if we need to swap dimension to get the preview size relative to sensor
                // coordinate.
                int displayRotation = activity.getWindowManager().getDefaultDisplay().getRotation();
                //noinspection ConstantConditions
                mSensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
                boolean swappedDimensions = false;
                switch (displayRotation) {
                    case Surface.ROTATION_0:
                    case Surface.ROTATION_180:
                        if (mSensorOrientation == 90 || mSensorOrientation == 270) {
                            swappedDimensions = true;
                        }
                        break;
                    case Surface.ROTATION_90:
                    case Surface.ROTATION_270:
                        if (mSensorOrientation == 0 || mSensorOrientation == 180) {
                            swappedDimensions = true;
                        }
                        break;
                    default:
                        Log.e(TAG, "Display rotation is invalid: " + displayRotation);
                }

                Point displaySize = new Point();
                activity.getWindowManager().getDefaultDisplay().getSize(displaySize);
                int rotatedPreviewWidth = width;
                int rotatedPreviewHeight = height;
                int maxPreviewWidth = displaySize.x;
                int maxPreviewHeight = displaySize.y;

                if (swappedDimensions) {
                    rotatedPreviewWidth = height;
                    rotatedPreviewHeight = width;
                    maxPreviewWidth = displaySize.y;
                    maxPreviewHeight = displaySize.x;
                }

                if (maxPreviewWidth > MAX_PREVIEW_WIDTH) {
                    maxPreviewWidth = MAX_PREVIEW_WIDTH;
                }

                if (maxPreviewHeight > MAX_PREVIEW_HEIGHT) {
                    maxPreviewHeight = MAX_PREVIEW_HEIGHT;
                }

                // Danger, W.R.! Attempting to use too large a preview size could  exceed the camera
                // bus' bandwidth limitation, resulting in gorgeous previews but the storage of
                // garbage capture data.
                mPreviewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class),
                        rotatedPreviewWidth, rotatedPreviewHeight, maxPreviewWidth,
                        maxPreviewHeight, largest);

                // We fit the aspect ratio of TextureView to the size of preview we picked.
                int orientation = getResources().getConfiguration().orientation;
                if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
//                    mTextureView.setAspectRatio(
//                            mPreviewSize.getWidth(), mPreviewSize.getHeight());
                } else {
//                    mTextureView.setAspectRatio(
//                            mPreviewSize.getHeight(), mPreviewSize.getWidth());
                }

                // Check if the flash is supported.
                Boolean available = characteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE);
                mFlashSupported = available == null ? false : available;

                mCameraId = cameraId;
                return;
            }
        } catch (CameraAccessException e) {
            e.printStackTrace();
        } catch (NullPointerException e) {
            // Currently an NPE is thrown when the Camera2API is used but not supported on the
            // device this code runs.
            ErrorDialog.newInstance("该设备不支持Camera2API")
                    .show(getChildFragmentManager(), FRAGMENT_DIALOG);
        }
    }

    /**
     * Opens the camera specified by {@link Camera2Fragment#mCameraId}.
     */
    private void openCamera(int width, int height) {
        if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA)
                != PackageManager.PERMISSION_GRANTED) {
            requestCameraPermission();
            return;
        }
        setUpCameraOutputs(width, height);
        configureTransform(width, height);
        Activity activity = getActivity();
        CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
        try {
            if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {
                throw new RuntimeException("Time out waiting to lock camera opening.");
            }
            manager.openCamera(mCameraId, mStateCallback, mBackgroundHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            throw new RuntimeException("Interrupted while trying to lock camera opening.", e);
        }
    }

    /**
     * Closes the current {@link CameraDevice}.
     */
    private void closeCamera() {
        try {
            mCameraOpenCloseLock.acquire();
            if (null != mCaptureSession) {
                mCaptureSession.close();
                mCaptureSession = null;
            }
            if (null != mCameraDevice) {
                mCameraDevice.close();
                mCameraDevice = null;
            }
            if (null != mImageReader) {
                mImageReader.close();
                mImageReader = null;
            }
        } catch (InterruptedException e) {
            throw new RuntimeException("Interrupted while trying to lock camera closing.", e);
        } finally {
            mCameraOpenCloseLock.release();
        }
    }

    /**
     * Starts a background thread and its {@link Handler}.
     */
    private void startBackgroundThread() {
        mBackgroundThread = new HandlerThread("CameraBackground");
        mBackgroundThread.start();
        mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
    }

    /**
     * Stops the background thread and its {@link Handler}.
     */
    private void stopBackgroundThread() {
        mBackgroundThread.quitSafely();
        try {
            mBackgroundThread.join();
            mBackgroundThread = null;
            mBackgroundHandler = null;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * Creates a new {@link CameraCaptureSession} for camera preview.
     */
    private void createCameraPreviewSession() {
        try {
            SurfaceTexture texture = mTextureView.getSurfaceTexture();
            assert texture != null;

            // We configure the size of default buffer to be the size of camera preview we want.
            texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());

            // This is the output Surface we need to start preview.
            Surface surface = new Surface(texture);

            // We set up a CaptureRequest.Builder with the output Surface.
            mPreviewRequestBuilder
                    = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
            mPreviewRequestBuilder.addTarget(surface);

            // Here, we create a CameraCaptureSession for camera preview.
            mCameraDevice.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()),
                    new CameraCaptureSession.StateCallback() {

                        @Override
                        public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
                            // The camera is already closed
                            if (null == mCameraDevice) {
                                return;
                            }

                            // When the session is ready, we start displaying the preview.
                            mCaptureSession = cameraCaptureSession;
                            try {
                                // Auto focus should be continuous for camera preview.
                                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                                        CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
                                // Flash is automatically enabled when necessary.
                                setAutoFlash(mPreviewRequestBuilder);

                                // Finally, we start displaying the camera preview.
                                mPreviewRequest = mPreviewRequestBuilder.build();
                                mCaptureSession.setRepeatingRequest(mPreviewRequest,
                                        mCaptureCallback, mBackgroundHandler);
                            } catch (CameraAccessException e) {
                                e.printStackTrace();
                            }
                        }

                        @Override
                        public void onConfigureFailed(
                                @NonNull CameraCaptureSession cameraCaptureSession) {
                            showToast("Failed");
                        }
                    }, null
            );
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    /**
     * Configures the necessary {@link Matrix} transformation to `mTextureView`.
     * This method should be called after the camera preview size is determined in
     * setUpCameraOutputs and also the size of `mTextureView` is fixed.
     *
     * @param viewWidth  The width of `mTextureView`
     * @param viewHeight The height of `mTextureView`
     */
    private void configureTransform(int viewWidth, int viewHeight) {
        Activity activity = getActivity();
        if (null == mTextureView || null == mPreviewSize || null == activity) {
            return;
        }
        int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
        Matrix matrix = new Matrix();
        RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);
        RectF bufferRect = new RectF(0, 0, mPreviewSize.getHeight(), mPreviewSize.getWidth());
        float centerX = viewRect.centerX();
        float centerY = viewRect.centerY();
        if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {
            bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());
            matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);
            float scale = Math.max(
                    (float) viewHeight / mPreviewSize.getHeight(),
                    (float) viewWidth / mPreviewSize.getWidth());
            matrix.postScale(scale, scale, centerX, centerY);
            matrix.postRotate(90 * (rotation - 2), centerX, centerY);
        } else if (Surface.ROTATION_180 == rotation) {
            matrix.postRotate(180, centerX, centerY);
        }
        mTextureView.setTransform(matrix);
    }

    /**
     * Initiate a still image capture.
     */
    private void takePicture() {
        lockFocus();
    }

    /**
     * Lock the focus as the first step for a still image capture.
     */
    private void lockFocus() {
        try {
            // This is how to tell the camera to lock focus.
            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
                    CameraMetadata.CONTROL_AF_TRIGGER_START);
            // Tell #mCaptureCallback to wait for the lock.
            mState = STATE_WAITING_LOCK;
            mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
                    mBackgroundHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    /**
     * Run the precapture sequence for capturing a still image. This method should be called when
     * we get a response in {@link #mCaptureCallback} from {@link #lockFocus()}.
     */
    private void runPrecaptureSequence() {
        try {
            // This is how to tell the camera to trigger.
            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
                    CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
            // Tell #mCaptureCallback to wait for the precapture sequence to be set.
            mState = STATE_WAITING_PRECAPTURE;
            mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
                    mBackgroundHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    /**
     * Capture a still picture. This method should be called when we get a response in
     * {@link #mCaptureCallback} from both {@link #lockFocus()}.
     */
    private void captureStillPicture() {
        try {
            final Activity activity = getActivity();
            if (null == activity || null == mCameraDevice) {
                return;
            }
            // This is the CaptureRequest.Builder that we use to take a picture.
            final CaptureRequest.Builder captureBuilder =
                    mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
            captureBuilder.addTarget(mImageReader.getSurface());

            // Use the same AE and AF modes as the preview.
            captureBuilder.set(CaptureRequest.CONTROL_AF_MODE,
                    CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
            setAutoFlash(captureBuilder);

            // Orientation
            int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
            captureBuilder.set(CaptureRequest.JPEG_ORIENTATION, getOrientation(rotation));

            CameraCaptureSession.CaptureCallback CaptureCallback
                    = new CameraCaptureSession.CaptureCallback() {

                @Override
                public void onCaptureCompleted(@NonNull CameraCaptureSession session,
                                               @NonNull CaptureRequest request,
                                               @NonNull TotalCaptureResult result) {
                    showToast("拍照成功,图片保存为: " + mFile);
                    Log.d(TAG, mFile.toString());
                    unlockFocus();
                }
            };

            mCaptureSession.stopRepeating();
            mCaptureSession.capture(captureBuilder.build(), CaptureCallback, null);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    /**
     * Retrieves the JPEG orientation from the specified screen rotation.
     *
     * @param rotation The screen rotation.
     * @return The JPEG orientation (one of 0, 90, 270, and 360)
     */
    private int getOrientation(int rotation) {
        // Sensor orientation is 90 for most devices, or 270 for some devices (eg. Nexus 5X)
        // We have to take that into account and rotate JPEG properly.
        // For devices with orientation of 90, we simply return our mapping from ORIENTATIONS.
        // For devices with orientation of 270, we need to rotate the JPEG 180 degrees.
        return (ORIENTATIONS.get(rotation) + mSensorOrientation + 270) % 360;
    }

    /**
     * Unlock the focus. This method should be called when still image capture sequence is
     * finished.
     */
    private void unlockFocus() {
        try {
            // Reset the auto-focus trigger
            mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
                    CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
            setAutoFlash(mPreviewRequestBuilder);
            mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback,
                    mBackgroundHandler);
            // After this, the camera will go back to the normal state of preview.
            mState = STATE_PREVIEW;
            mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback,
                    mBackgroundHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.picture: {
                takePicture();
                break;
            }
        }
    }

    private void setAutoFlash(CaptureRequest.Builder requestBuilder) {
        if (mFlashSupported) {
            requestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
                    CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
        }
    }

    /**
     * Saves a JPEG {@link Image} into the specified {@link File}.
     */
    private static class ImageSaver implements Runnable {

        /**
         * The JPEG image
         */
        private final Image mImage;
        /**
         * The file we save the image into.
         */
        private final File mFile;

        public ImageSaver(Image image, File file) {
            mImage = image;
            mFile = file;
        }

        @Override
        public void run() {
            ByteBuffer buffer = mImage.getPlanes()[0].getBuffer();
            byte[] bytes = new byte[buffer.remaining()];
            buffer.get(bytes);
            FileOutputStream output = null;
            try {
                output = new FileOutputStream(mFile);
                output.write(bytes);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                mImage.close();
                if (null != output) {
                    try {
                        output.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

    }

    /**
     * Compares two {@code Size}s based on their areas.
     */
    static class CompareSizesByArea implements Comparator<Size> {

        @Override
        public int compare(Size lhs, Size rhs) {
            // We cast here to ensure the multiplications won't overflow
            return Long.signum((long) lhs.getWidth() * lhs.getHeight() -
                    (long) rhs.getWidth() * rhs.getHeight());
        }

    }

    /**
     * Shows an error message dialog.
     */
    public static class ErrorDialog extends DialogFragment {

        private static final String ARG_MESSAGE = "message";

        public static ErrorDialog newInstance(String message) {
            ErrorDialog dialog = new ErrorDialog();
            Bundle args = new Bundle();
            args.putString(ARG_MESSAGE, message);
            dialog.setArguments(args);
            return dialog;
        }

        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            final Activity activity = getActivity();
            return new AlertDialog.Builder(activity)
                    .setMessage(getArguments().getString(ARG_MESSAGE))
                    .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            activity.finish();
                        }
                    })
                    .create();
        }

    }

    /**
     * Shows OK/Cancel confirmation dialog about camera permission.
     */
    public static class ConfirmationDialog extends DialogFragment {

        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            final Fragment parent = getParentFragment();
            return new AlertDialog.Builder(getActivity())
                    .setMessage("需要申请摄像头权限")
                    .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            FragmentCompat.requestPermissions(parent,
                                    new String[]{Manifest.permission.CAMERA},
                                    REQUEST_CAMERA_PERMISSION);
                        }
                    })
                    .setNegativeButton(android.R.string.cancel,
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    Activity activity = parent.getActivity();
                                    if (activity != null) {
                                        activity.finish();
                                    }
                                }
                            })
                    .create();
        }
    }

}


================================================
FILE: CameraSample2/app/src/main/java/com/hejunlin/camerasample2/MainActivity.java
================================================
package com.hejunlin.camerasample2;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (null == savedInstanceState) {
            getFragmentManager().beginTransaction()
                    .replace(R.id.container, Camera2Fragment.newInstance())
                    .commit();
        }
    }
}


================================================
FILE: CameraSample2/app/src/main/java/com/hejunlin/camerasample2/SuperTextureView.java
================================================
package com.hejunlin.camerasample2;

import android.content.Context;
import android.util.AttributeSet;
import android.view.TextureView;

/**
 * A {@link TextureView} that can be adjusted to a specified aspect ratio.
 */
public class SuperTextureView extends TextureView {

    private int mRatioWidth = 0;
    private int mRatioHeight = 0;

    public SuperTextureView(Context context) {
        this(context, null);
    }

    public SuperTextureView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SuperTextureView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    /**
     * Sets the aspect ratio for this view. The size of the view will be measured based on the ratio
     * calculated from the parameters. Note that the actual sizes of parameters don't matter, that
     * is, calling setAspectRatio(2, 3) and setAspectRatio(4, 6) make the same result.
     *
     * @param width  Relative horizontal size
     * @param height Relative vertical size
     */
//    public void setAspectRatio(int width, int height) {
//        if (width < 0 || height < 0) {
//            throw new IllegalArgumentException("Size cannot be negative.");
//        }
//        mRatioWidth = width;
//        mRatioHeight = height;
//        requestLayout();
//    }
//
//    @Override
//    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//        int width = MeasureSpec.getSize(widthMeasureSpec);
//        int height = MeasureSpec.getSize(heightMeasureSpec);
//        if (0 == mRatioWidth || 0 == mRatioHeight) {
//            setMeasuredDimension(width, height);
//        } else {
//            if (width < height * mRatioWidth / mRatioHeight) {
//                setMeasuredDimension(width, width * mRatioHeight / mRatioWidth);
//            } else {
//                setMeasuredDimension(height * mRatioWidth / mRatioHeight, height);
//            }
//        }
//    }

}


================================================
FILE: CameraSample2/app/src/main/res/layout/activity_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#000" />


================================================
FILE: CameraSample2/app/src/main/res/layout/fragment_camera2.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.hejunlin.camerasample2.SuperTextureView
        android:id="@+id/texture"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <FrameLayout
        android:id="@+id/control"
        android:layout_width="match_parent"
        android:layout_height="112dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentStart="true"
        android:background="#000000">

        <ImageView
            android:id="@+id/picture"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:src="@mipmap/capture" />

    </FrameLayout>

</RelativeLayout>


================================================
FILE: CameraSample2/app/src/main/res/values/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
</resources>


================================================
FILE: CameraSample2/app/src/main/res/values/dimens.xml
================================================
<resources>
    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>
</resources>


================================================
FILE: CameraSample2/app/src/main/res/values/strings.xml
================================================
<resources>
    <string name="app_name">CameraSample2</string>
</resources>


================================================
FILE: CameraSample2/app/src/main/res/values/styles.xml
================================================
<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

</resources>


================================================
FILE: CameraSample2/app/src/main/res/values-w820dp/dimens.xml
================================================
<resources>
    <!-- Example customization of dimensions originally defined in res/values/dimens.xml
         (such as screen margins) for screens with more than 820dp of available width. This
         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
    <dimen name="activity_horizontal_margin">64dp</dimen>
</resources>


================================================
FILE: CameraSample2/app/src/test/java/com/hejunlin/camerasample2/ExampleUnitTest.java
================================================
package com.hejunlin.camerasample2;

import org.junit.Test;

import static org.junit.Assert.*;

/**
 * To work on unit tests, switch the Test Artifact in the Build Variants view.
 */
public class ExampleUnitTest {
    @Test
    public void addition_isCorrect() throws Exception {
        assertEquals(4, 2 + 2);
    }
}

================================================
FILE: CameraSample2/build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.1.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}


================================================
FILE: CameraSample2/gradle/wrapper/gradle-wrapper.properties
================================================
#Mon Dec 28 10:00:20 PST 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip


================================================
FILE: CameraSample2/gradle.properties
================================================
# Project-wide Gradle settings.

# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.

# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html

# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8

# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true

================================================
FILE: CameraSample2/gradlew
================================================
#!/usr/bin/env bash

##############################################################################
##
##  Gradle start up script for UN*X
##
##############################################################################

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""

APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"

warn ( ) {
    echo "$*"
}

die ( ) {
    echo
    echo "$*"
    echo
    exit 1
}

# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
  CYGWIN* )
    cygwin=true
    ;;
  Darwin* )
    darwin=true
    ;;
  MINGW* )
    msys=true
    ;;
esac

# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '/.*' > /dev/null; then
        PRG="$link"
    else
        PRG=`dirname "$PRG"`"/$link"
    fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar

# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
        # IBM's JDK on AIX uses strange locations for the executables
        JAVACMD="$JAVA_HOME/jre/sh/java"
    else
        JAVACMD="$JAVA_HOME/bin/java"
    fi
    if [ ! -x "$JAVACMD" ] ; then
        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
    fi
else
    JAVACMD="java"
    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi

# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
    MAX_FD_LIMIT=`ulimit -H -n`
    if [ $? -eq 0 ] ; then
        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
            MAX_FD="$MAX_FD_LIMIT"
        fi
        ulimit -n $MAX_FD
        if [ $? -ne 0 ] ; then
            warn "Could not set maximum file descriptor limit: $MAX_FD"
        fi
    else
        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
    fi
fi

# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi

# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
    JAVACMD=`cygpath --unix "$JAVACMD"`

    # We build the pattern for arguments to be converted via cygpath
    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
    SEP=""
    for dir in $ROOTDIRSRAW ; do
        ROOTDIRS="$ROOTDIRS$SEP$dir"
        SEP="|"
    done
    OURCYGPATTERN="(^($ROOTDIRS))"
    # Add a user-defined pattern to the cygpath arguments
    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
    fi
    # Now convert the arguments - kludge to limit ourselves to /bin/sh
    i=0
    for arg in "$@" ; do
        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option

        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
        else
            eval `echo args$i`="\"$arg\""
        fi
        i=$((i+1))
    done
    case $i in
        (0) set -- ;;
        (1) set -- "$args0" ;;
        (2) set -- "$args0" "$args1" ;;
        (3) set -- "$args0" "$args1" "$args2" ;;
        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
    esac
fi

# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
    JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"

exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"


================================================
FILE: CameraSample2/gradlew.bat
================================================
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem  Gradle startup script for Windows
@rem
@rem ##########################################################################

@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=

set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto init

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:init
@rem Get command-line arguments, handling Windowz variants

if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args

:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2

:win9xME_args_slurp
if "x%~1" == "x" goto execute

set CMD_LINE_ARGS=%*
goto execute

:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$

:execute
@rem Setup the command line

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd

:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1

:mainEnd
if "%OS%"=="Windows_NT" endlocal

:omega


================================================
FILE: CameraSample2/settings.gradle
================================================
include ':app'


================================================
FILE: GuardProcessSample/app/build.gradle
================================================
apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {
        applicationId "com.hejunlin.guardprocesssample"
        minSdkVersion 17
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

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


================================================
FILE: GuardProcessSample/app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in D:\Studio SDK/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}


================================================
FILE: GuardProcessSample/app/src/androidTest/java/com/hejunlin/guardprocesssample/ApplicationTest.java
================================================
package com.hejunlin.guardprocesssample;

import android.app.Application;
import android.test.ApplicationTestCase;

/**
 * <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
 */
public class ApplicationTest extends ApplicationTestCase<Application> {
    public ApplicationTest() {
        super(Application.class);
    }
}

================================================
FILE: GuardProcessSample/app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.hejunlin.guardprocesssample">

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

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

        <service android:name=".ServiceA"></service>
        <service
            android:name=".ServiceB"
            android:process="com.guardprocess.remote"></service>
    </application>

</manifest>

================================================
FILE: GuardProcessSample/app/src/main/aidl/com/hejunlin/guardprocesssample/aidl/IBridgeInterface.aidl
================================================
// IBridgeInterface.aidl
package com.hejunlin.guardprocesssample.aidl;

// Declare any non-default types here with import statements

interface IBridgeInterface {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
//    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
//            double aDouble, String aString);
      String getName();

}


================================================
FILE: GuardProcessSample/app/src/main/java/com/hejunlin/guardprocesssample/MainActivity.java
================================================
package com.hejunlin.guardprocesssample;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 启动两个守护服务
        startService(new Intent(this, ServiceA.class));
        startService(new Intent(this, ServiceB.class));
    }
}


================================================
FILE: GuardProcessSample/app/src/main/java/com/hejunlin/guardprocesssample/ServiceA.java
================================================
package com.hejunlin.guardprocesssample;

import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.widget.Toast;

import com.hejunlin.guardprocesssample.aidl.IBridgeInterface;

/**
 * Created by hejunlin on 2016/10/10.
 */
public class ServiceA extends Service {

    private static final String TAG = ServiceA.class.getSimpleName();
    private MyBinder mBinder;
    private PendingIntent mPendingIntent;
    private MyServiceConnection mServiceConnection;

    @Override
    public void onCreate() {
        super.onCreate();
        if (mBinder == null) {
            mBinder = new MyBinder();
        }
        mServiceConnection = new MyServiceConnection();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        this.bindService(new Intent(this, ServiceB.class), mServiceConnection, Context.BIND_IMPORTANT);
        mPendingIntent = PendingIntent.getService(this, 0, intent, 0);
        Notification.Builder builder = new Notification.Builder(this);
        builder.setTicker("守护服务A启动中")
               .setContentText("我是来守护B不被杀的!")
               .setContentTitle("守护服务A")
               .setSmallIcon(R.mipmap.ic_launcher)
               .setContentIntent(mPendingIntent)
               .setWhen(System.currentTimeMillis());
        Notification notification = builder.build();
        // 设置service为前台进程,避免手机休眠时系统自动杀掉该服务
        startForeground(startId, notification);
        return START_STICKY;
    }

    class MyServiceConnection implements ServiceConnection {

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder binder) {
            Log.i(TAG, "ServiceA连接成功");
            Toast.makeText(ServiceA.this, "ServiceA连接成功", Toast.LENGTH_LONG).show();
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            // 连接出现了异常断开了,RemoteService被杀掉了
            Toast.makeText(ServiceA.this, "ServiceA被干掉", Toast.LENGTH_LONG).show();
            // 启动ServiceB
            ServiceA.this.startService(new Intent(ServiceA.this, ServiceB.class));
            ServiceA.this.bindService(new Intent(ServiceA.this, ServiceB.class),
                    mServiceConnection, Context.BIND_IMPORTANT);
        }

    }

    class MyBinder extends IBridgeInterface.Stub {

        @Override
        public String getName() throws RemoteException {
            return "ServiceA";
        }

    }

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

}


================================================
FILE: GuardProcessSample/app/src/main/java/com/hejunlin/guardprocesssample/ServiceB.java
================================================
package com.hejunlin.guardprocesssample;

import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.widget.Toast;

import com.hejunlin.guardprocesssample.aidl.IBridgeInterface;

/**
 * Created by hejunlin on 2016/10/10.
 */
public class ServiceB extends Service {

    private static final String TAG = ServiceB.class.getSimpleName();
    private MyBinder mBinder;
    private PendingIntent mPendingIntent;
    private MyServiceConnection mServiceConnection;

    @Override
    public void onCreate() {
        super.onCreate();
        if (mBinder == null) {
            mBinder = new MyBinder();
        }
        mServiceConnection = new MyServiceConnection();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        this.bindService(new Intent(this,ServiceA.class), mServiceConnection, Context.BIND_IMPORTANT);
        mPendingIntent =PendingIntent.getService(this, 0, intent, 0);
        Notification.Builder builder = new Notification.Builder(this);
        builder.setTicker("守护服务B启动中")
                .setContentText("我是来守护A不被杀的!")
                .setContentTitle("守护服务B")
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentIntent(mPendingIntent)
                .setWhen(System.currentTimeMillis());
        Notification notification = builder.build();
        //设置service为前台进程,避免手机休眠时系统自动杀掉该服务
        startForeground(startId, notification);
        return START_STICKY;
    }

    class MyServiceConnection implements ServiceConnection {

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder binder) {
            Log.i(TAG, "ServiceB连接成功");
            Toast.makeText(ServiceB.this, "ServiceB连接成功", Toast.LENGTH_LONG).show();
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            // 连接出现了异常断开了,LocalCastielService被杀死了
            Toast.makeText(ServiceB.this, "ServiceB被干掉", Toast.LENGTH_LONG).show();
            // 启动ServiceA
            ServiceB.this.startService(new Intent(ServiceB.this, ServiceA.class));
            ServiceB.this.bindService(new Intent(ServiceB.this, ServiceA.class), mServiceConnection, Context.BIND_IMPORTANT);
        }

    }

    class MyBinder extends IBridgeInterface.Stub {

        @Override
        public String getName() throws RemoteException {
            return "ServiceB";
        }

    }

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


================================================
FILE: GuardProcessSample/app/src/main/res/layout/activity_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<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: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="com.hejunlin.guardprocesssample.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />
</RelativeLayout>


================================================
FILE: GuardProcessSample/app/src/main/res/values/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
</resources>


================================================
FILE: GuardProcessSample/app/src/main/res/values/dimens.xml
================================================
<resources>
    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>
</resources>


================================================
FILE: GuardProcessSample/app/src/main/res/values/strings.xml
================================================
<resources>
    <string name="app_name">GuardProcessSample</string>
</resources>


================================================
FILE: GuardProcessSample/app/src/main/res/values/styles.xml
================================================
<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

</resources>


================================================
FILE: GuardProcessSample/app/src/main/res/values-w820dp/dimens.xml
================================================
<resources>
    <!-- Example customization of dimensions originally defined in res/values/dimens.xml
         (such as screen margins) for screens with more than 820dp of available width. This
         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
    <dimen name="activity_horizontal_margin">64dp</dimen>
</resources>


================================================
FILE: GuardProcessSample/app/src/test/java/com/hejunlin/guardprocesssample/ExampleUnitTest.java
================================================
package com.hejunlin.guardprocesssample;

import org.junit.Test;

import static org.junit.Assert.*;

/**
 * To work on unit tests, switch the Test Artifact in the Build Variants view.
 */
public class ExampleUnitTest {
    @Test
    public void addition_isCorrect() throws Exception {
        assertEquals(4, 2 + 2);
    }
}

================================================
FILE: GuardProcessSample/build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.1.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}


================================================
FILE: GuardProcessSample/gradle/wrapper/gradle-wrapper.properties
================================================
#Mon Dec 28 10:00:20 PST 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip


================================================
FILE: GuardProcessSample/gradle.properties
================================================
# Project-wide Gradle settings.

# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.

# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html

# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8

# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true

================================================
FILE: GuardProcessSample/gradlew
================================================
#!/usr/bin/env bash

##############################################################################
##
##  Gradle start up script for UN*X
##
##############################################################################

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""

APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"

warn ( ) {
    echo "$*"
}

die ( ) {
    echo
    echo "$*"
    echo
    exit 1
}

# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
  CYGWIN* )
    cygwin=true
    ;;
  Darwin* )
    darwin=true
    ;;
  MINGW* )
    msys=true
    ;;
esac

# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '/.*' > /dev/null; then
        PRG="$link"
    else
        PRG=`dirname "$PRG"`"/$link"
    fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar

# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
        # IBM's JDK on AIX uses strange locations for the executables
        JAVACMD="$JAVA_HOME/jre/sh/java"
    else
        JAVACMD="$JAVA_HOME/bin/java"
    fi
    if [ ! -x "$JAVACMD" ] ; then
        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
    fi
else
    JAVACMD="java"
    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi

# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
    MAX_FD_LIMIT=`ulimit -H -n`
    if [ $? -eq 0 ] ; then
        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
            MAX_FD="$MAX_FD_LIMIT"
        fi
        ulimit -n $MAX_FD
        if [ $? -ne 0 ] ; then
            warn "Could not set maximum file descriptor limit: $MAX_FD"
        fi
    else
        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
    fi
fi

# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi

# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
    JAVACMD=`cygpath --unix "$JAVACMD"`

    # We build the pattern for arguments to be converted via cygpath
    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
    SEP=""
    for dir in $ROOTDIRSRAW ; do
        ROOTDIRS="$ROOTDIRS$SEP$dir"
        SEP="|"
    done
    OURCYGPATTERN="(^($ROOTDIRS))"
    # Add a user-defined pattern to the cygpath arguments
    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
    fi
    # Now convert the arguments - kludge to limit ourselves to /bin/sh
    i=0
    for arg in "$@" ; do
        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option

        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
        else
            eval `echo args$i`="\"$arg\""
        fi
        i=$((i+1))
    done
    case $i in
        (0) set -- ;;
        (1) set -- "$args0" ;;
        (2) set -- "$args0" "$args1" ;;
        (3) set -- "$args0" "$args1" "$args2" ;;
        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
    esac
fi

# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
    JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"

exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"


================================================
FILE: GuardProcessSample/gradlew.bat
================================================
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem  Gradle startup script for Windows
@rem
@rem ##########################################################################

@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=

set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto init

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:init
@rem Get command-line arguments, handling Windowz variants

if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args

:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2

:win9xME_args_slurp
if "x%~1" == "x" goto execute

set CMD_LINE_ARGS=%*
goto execute

:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$

:execute
@rem Setup the command line

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd

:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1

:mainEnd
if "%OS%"=="Windows_NT" endlocal

:omega


================================================
FILE: GuardProcessSample/settings.gradle
================================================
include ':app'


================================================
FILE: LICENSE
================================================
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "{}"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright {yyyy} {name of copyright owner}

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: MediaCodcSample/.gitignore
================================================
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures


================================================
FILE: MediaCodcSample/app/.gitignore
================================================
/build


================================================
FILE: MediaCodcSample/app/build.gradle
================================================
apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.3"

    defaultConfig {
        applicationId "com.hejunlin.mediacodcsample"
        minSdkVersion 17
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

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


================================================
FILE: MediaCodcSample/app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in D:\Studio SDK/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}


================================================
FILE: MediaCodcSample/app/src/androidTest/java/com/hejunlin/mediacodcsample/ApplicationTest.java
================================================
package com.hejunlin.mediacodcsample;

import android.app.Application;
import android.test.ApplicationTestCase;

/**
 * <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
 */
public class ApplicationTest extends ApplicationTestCase<Application> {
    public ApplicationTest() {
        super(Application.class);
    }
}

================================================
FILE: MediaCodcSample/app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.hejunlin.mediacodcsample">

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

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

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

</manifest>

================================================
FILE: MediaCodcSample/app/src/main/java/com/hejunlin/mediacodcsample/MainActivity.java
================================================
package com.hejunlin.mediacodcsample;

import android.media.MediaCodec;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import java.io.IOException;
import java.nio.ByteBuffer;

public class MainActivity extends AppCompatActivity implements SurfaceHolder.Callback {

    private static final String SAMPLE = Environment.getExternalStorageDirectory() + "/device-2016-11-15.mp4";
    private static final String TAG = MainActivity.class.getSimpleName();
    private WorkThread mWorkThread = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SurfaceView surfaceView = new SurfaceView(this);
        /*下面设置Surface不维护自己的缓冲区,而是等待屏幕的渲染引擎将内容推送到用户面前*/
        surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        surfaceView.getHolder().addCallback(this);
        setContentView(surfaceView);
    }

    protected void onDestroy() {
        super.onDestroy();
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        if (mWorkThread == null) {
            mWorkThread = new WorkThread(holder.getSurface());
            mWorkThread.start();
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        if (mWorkThread != null) {
            mWorkThread.interrupt();
        }
    }

    private class WorkThread extends Thread {
        private MediaExtractor mMediaExtractor;
        private MediaCodec mMediaCodec;
        private Surface mSurface;

        public WorkThread(Surface surface) {
            this.mSurface = surface;
        }

        @Override
        public void run() {
            mMediaExtractor = new MediaExtractor();//数据解析器
            try {
                mMediaExtractor.setDataSource(SAMPLE);
            } catch (IOException e) {
                e.printStackTrace();
            }

            for (int i = 0; i < mMediaExtractor.getTrackCount(); i++) {//遍历数据源音视频轨迹
                MediaFormat format = mMediaExtractor.getTrackFormat(i);
                Log.d(TAG, ">> format i " + i + ": " +  format);
                String mime = format.getString(MediaFormat.KEY_MIME);
                Log.d(TAG, ">> mime i " + i + ": " +  mime);
                if (mime.startsWith("video/")) {
                    mMediaExtractor.selectTrack(i);
                    try {
                        mMediaCodec = MediaCodec.createDecoderByType(mime);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    mMediaCodec.configure(format, mSurface, null, 0);
                    break;
                }
            }
            if (mMediaCodec == null) {
                return;
            }
            mMediaCodec.start();//调用start后,如果没有异常信息,就表示成功构建组件
            ByteBuffer[] inputBuffers = mMediaCodec.getInputBuffers();
            ByteBuffer[] outputBuffers = mMediaCodec.getOutputBuffers();
            // 每个buffer的元数据包括具体范围偏移及大小 ,及有效数据中相关解码的buffer
            MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
            boolean isEOS = false;
            long startMs = System.currentTimeMillis();

            while (!Thread.interrupted()) {//只要线程不中断
                if (!isEOS) {
                    //返回用有效输出的buffer的索引,如果没有相关buffer可用,就返回-1
                    //如果传入的timeoutUs为0,将立马返回,如果输入buffer可用,将无限期等待
                    //timeoutUs的单位是微秒
                    int inIndex = mMediaCodec.dequeueInputBuffer(10000);//0.01s
                    if (inIndex >= 0) {
                        ByteBuffer buffer = inputBuffers[inIndex];
                        Log.d(TAG, ">> buffer " + buffer);
                        int sampleSize = mMediaExtractor.readSampleData(buffer, 0);
                        Log.d(TAG, ">> sampleSize " + sampleSize);
                        if (sampleSize < 0) {
                            // We shouldn't stop the playback at this point, just pass the EOS
                            // flag to mMediaCodec, we will get it again from the
                            // dequeueOutputBuffer
                            Log.d(TAG, "InputBuffer BUFFER_FLAG_END_OF_STREAM");
                            mMediaCodec.queueInputBuffer(inIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
                            isEOS = true;
                        } else {
                            mMediaCodec.queueInputBuffer(inIndex, 0, sampleSize, mMediaExtractor.getSampleTime(), 0);
                            mMediaExtractor.advance();
                        }
                    }
                }

                int outIndex = mMediaCodec.dequeueOutputBuffer(info, 10000);
                switch (outIndex) {
                    case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED://当buffer变化时,client必须重新指向新的buffer
                        Log.d(TAG, ">> output buffer changed ");
                        outputBuffers = mMediaCodec.getOutputBuffers();
                        break;
                    case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED://当buffer的封装格式变化,须指向新的buffer格式
                        Log.d(TAG, ">> output buffer changed ");
                        break;
                    case MediaCodec.INFO_TRY_AGAIN_LATER://当dequeueOutputBuffer超时,会到达此case
                        Log.d(TAG, ">> dequeueOutputBuffer timeout ");
                        break;
                    default:
                        ByteBuffer buffer = outputBuffers[outIndex];
                        // We use a very simple clock to keep the video FPS, or the video
                        // playback will be too fast
                        while (info.presentationTimeUs / 1000 > System.currentTimeMillis() - startMs) {
                            try {
                                sleep(10);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                                break;
                            }
                        }
                        mMediaCodec.releaseOutputBuffer(outIndex, true);
                        break;
                }
                // All decoded frames have been rendered, we can stop playing now
                if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                    Log.d(TAG, "OutputBuffer BUFFER_FLAG_END_OF_STREAM");
                    break;
                }
            }
            mMediaCodec.stop();
            mMediaCodec.release();//释放组件
            mMediaExtractor.release();
        }
    }

}


================================================
FILE: MediaCodcSample/app/src/main/res/layout/activity_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<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: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="com.hejunlin.mediacodcsample.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />
</RelativeLayout>


================================================
FILE: MediaCodcSample/app/src/main/res/values/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
</resources>


================================================
FILE: MediaCodcSample/app/src/main/res/values/dimens.xml
================================================
<resources>
    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>
</resources>


================================================
FILE: MediaCodcSample/app/src/main/res/values/strings.xml
================================================
<resources>
    <string name="app_name">MediaCodcSample</string>
</resources>


================================================
FILE: MediaCodcSample/app/src/main/res/values/styles.xml
================================================
<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

</resources>


================================================
FILE: MediaCodcSample/app/src/main/res/values-w820dp/dimens.xml
================================================
<resources>
    <!-- Example customization of dimensions originally defined in res/values/dimens.xml
         (such as screen margins) for screens with more than 820dp of available width. This
         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
    <dimen name="activity_horizontal_margin">64dp</dimen>
</resources>


================================================
FILE: MediaCodcSample/app/src/test/java/com/hejunlin/mediacodcsample/ExampleUnitTest.java
================================================
package com.hejunlin.mediacodcsample;

import org.junit.Test;

import static org.junit.Assert.*;

/**
 * To work on unit tests, switch the Test Artifact in the Build Variants view.
 */
public class ExampleUnitTest {
    @Test
    public void addition_isCorrect() throws Exception {
        assertEquals(4, 2 + 2);
    }
}

================================================
FILE: MediaCodcSample/build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.1.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}


================================================
FILE: MediaCodcSample/gradle/wrapper/gradle-wrapper.properties
================================================
#Mon Dec 28 10:00:20 PST 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip


================================================
FILE: MediaCodcSample/gradle.properties
================================================
# Project-wide Gradle settings.

# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.

# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html

# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8

# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true

================================================
FILE: MediaCodcSample/gradlew
================================================
#!/usr/bin/env bash

##############################################################################
##
##  Gradle start up script for UN*X
##
##############################################################################

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""

APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"

warn ( ) {
    echo "$*"
}

die ( ) {
    echo
    echo "$*"
    echo
    exit 1
}

# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
  CYGWIN* )
    cygwin=true
    ;;
  Darwin* )
    darwin=true
    ;;
  MINGW* )
    msys=true
    ;;
esac

# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '/.*' > /dev/null; then
        PRG="$link"
    else
        PRG=`dirname "$PRG"`"/$link"
    fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar

# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
        # IBM's JDK on AIX uses strange locations for the executables
        JAVACMD="$JAVA_HOME/jre/sh/java"
    else
        JAVACMD="$JAVA_HOME/bin/java"
    fi
    if [ ! -x "$JAVACMD" ] ; then
        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
    fi
else
    JAVACMD="java"
    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi

# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
    MAX_FD_LIMIT=`ulimit -H -n`
    if [ $? -eq 0 ] ; then
        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
            MAX_FD="$MAX_FD_LIMIT"
        fi
        ulimit -n $MAX_FD
        if [ $? -ne 0 ] ; then
            warn "Could not set maximum file descriptor limit: $MAX_FD"
        fi
    else
        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
    fi
fi

# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi

# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
    JAVACMD=`cygpath --unix "$JAVACMD"`

    # We build the pattern for arguments to be converted via cygpath
    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
    SEP=""
    for dir in $ROOTDIRSRAW ; do
        ROOTDIRS="$ROOTDIRS$SEP$dir"
        SEP="|"
    done
    OURCYGPATTERN="(^($ROOTDIRS))"
    # Add a user-defined pattern to the cygpath arguments
    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
    fi
    # Now convert the arguments - kludge to limit ourselves to /bin/sh
    i=0
    for arg in "$@" ; do
        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option

        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
        else
            eval `echo args$i`="\"$arg\""
        fi
        i=$((i+1))
    done
    case $i in
        (0) set -- ;;
        (1) set -- "$args0" ;;
        (2) set -- "$args0" "$args1" ;;
        (3) set -- "$args0" "$args1" "$args2" ;;
        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
    esac
fi

# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
    JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"

exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"


================================================
FILE: MediaCodcSample/gradlew.bat
================================================
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem  Gradle startup script for Windows
@rem
@rem ##########################################################################

@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=

set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto init

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:init
@rem Get command-line arguments, handling Windowz variants

if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args

:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2

:win9xME_args_slurp
if "x%~1" == "x" goto execute

set CMD_LINE_ARGS=%*
goto execute

:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$

:execute
@rem Setup the command line

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd

:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1

:mainEnd
if "%OS%"=="Windows_NT" endlocal

:omega


================================================
FILE: MediaCodcSample/settings.gradle
================================================
include ':app'


================================================
FILE: MediaPlayerSample/app/build.gradle
================================================
apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.1"

    defaultConfig {
        applicationId "com.hejunlin.mediaplayersample"
        minSdkVersion 21
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    sourceSets { main { assets.srcDirs = ['src/main/assets', 'src/main/assets/'] } }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
}


================================================
FILE: MediaPlayerSample/app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/hejunlin/Library/Android/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}


================================================
FILE: MediaPlayerSample/app/src/androidTest/java/com/hejunlin/mediaplayersample/ApplicationTest.java
================================================
package com.hejunlin.mediaplayersample;

import android.app.Application;
import android.test.ApplicationTestCase;

/**
 * <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>
 */
public class ApplicationTest extends ApplicationTestCase<Application> {
    public ApplicationTest() {
        super(Application.class);
    }
}

================================================
FILE: MediaPlayerSample/app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.hejunlin.mediaplayersample" >

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".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>


================================================
FILE: MediaPlayerSample/app/src/main/java/com/hejunlin/mediaplayersample/MainActivity.java
================================================
package com.hejunlin.mediaplayersample;


import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.EditText;
import android.widget.SeekBar;
import android.widget.Toast;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.app.Activity;


public class MainActivity extends Activity implements OnSeekBarChangeListener, OnCompletionListener {

    private boolean isStopUpdatingProgress=false;
    private EditText etPath;
    private MediaPlayer mMediapPlayer;
    private SeekBar mSeekbar;
    private TextView tvCurrentTime;
    private TextView tvTotalTime;

    private final int NORMAL=0;//闲置
    private final int PLAYING=1;//播放中
    private final int PAUSING=2;//暂停
    private final int STOPING=3;//停止中

    private  int currentstate=NORMAL;//播放器当前的状态,默认是空闲状态

    //用行动打消忧虑
    private SurfaceHolder holder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        etPath=(EditText)findViewById(R.id.et_path);
        mSeekbar=(SeekBar) findViewById(R.id.sb_progress);
        tvCurrentTime=(TextView)findViewById(R.id.tv_current_time);
        tvTotalTime=(TextView)findViewById(R.id.tv_total_time);

        mSeekbar.setOnSeekBarChangeListener(this);

        SurfaceView mSurfaceView=(SurfaceView) findViewById(R.id.surfaceview);
        holder=mSurfaceView.getHolder();//SurfaceView帮助类对象

        //是采用自己内部的双缓冲区,而是等待别人推送数据

        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    }

    /**
     * 开始
     * @param v
     */
    public void start(View v){
        if(mMediapPlayer!=null){
            if(currentstate!=PAUSING){
                mMediapPlayer.start();
                currentstate=PLAYING;
                isStopUpdatingProgress=false;//每次在调用刷新线程时,都要设为false
                return ;
                //下面这个判断完美的解决了停止后重新播放的,释放两个资源的问题
            }else if(currentstate==STOPING){
                mMediapPlayer.reset();
                mMediapPlayer.release();
            }
        }
        play();

    }
    /**
     * 停止
     * @param v
     */
    public void stop(View v){
        if(mMediapPlayer!=null){
            mMediapPlayer.stop();
        }
    }

    /**
     * 播放输入框的文件
     */
    private void play(){
        String path=etPath.getText().toString().trim();
        mMediapPlayer=new MediaPlayer();
        try {
            //设置数据类型
            mMediapPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            //设置以下播放器显示的位置
            mMediapPlayer.setDisplay(holder);

            mMediapPlayer.setDataSource(path);
            mMediapPlayer.prepare();
            mMediapPlayer.start();

            mMediapPlayer .setOnCompletionListener(this);
            //把当前播放器的状诚置为:播放中
            currentstate=PLAYING;

            //把音乐文件的总长度取出来,设置给seekbar作为最大值
            int duration=mMediapPlayer.getDuration();//总时长
            mSeekbar.setMax(duration);
            //把总时间显示textView上
            int m=duration/1000/60;
            int s=duration/1000%60;
            tvTotalTime.setText("/"+m+":"+s);
            tvCurrentTime.setText("00:00");

            isStopUpdatingProgress=false;
            new Thread(new UpdateProgressRunnable()).start();


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

    /**
     * 暂停
     * @param v
     */
    public void pause(View v){
        if(mMediapPlayer!=null&&currentstate==PLAYING){

            mMediapPlayer.pause();
            currentstate=PAUSING;
            isStopUpdatingProgress=true;//停止刷新主线程
        }
    }

    /**
     * 重播
     * @param v
     */
    public void restart(View v){
        if(mMediapPlayer!=null){
            mMediapPlayer.reset();
            mMediapPlayer.release();
            play();
        }
    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress,
                                  boolean fromUser) {

    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
        isStopUpdatingProgress=true;//当开始拖动时,那么就开始停止刷新线程
    }


    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        int progress=seekBar.getProgress();
        //播放器切换到指定的进度位置上
        mMediapPlayer.seekTo(progress);
        isStopUpdatingProgress=false;
        new Thread(new UpdateProgressRunnable()).start();
    }

    /**
     * 当播放完成时回调此方法
     */
    @Override
    public void onCompletion(MediaPlayer mp) {
        Toast.makeText(this, "播放完了,重新再播放", 0).show();
        mp.start();

    }

    /**
     * 刷新进度和时间的任务
     * @author hjl
     *
     */
    class  UpdateProgressRunnable implements Runnable{

        @Override
        public void run() {
            //每隔1秒钟取一下当前正在播放的进度,设置给seekbar
            while(!isStopUpdatingProgress){
                //得到当前进度
                int currentPosition=mMediapPlayer.getCurrentPosition();
                mSeekbar.setProgress(currentPosition);
                final int m=currentPosition/1000/60;
                final int s=currentPosition/1000%60;

                //此方法给定的runable对象,会执行主线程(UI线程中)
                runOnUiThread(new Runnable(){

                    @Override
                    public void run() {
                        tvCurrentTime.setText(m+":"+s);

                    }

                });
                SystemClock.sleep(1000);
            }

        }

    }

}


================================================
FILE: MediaPlayerSample/app/src/main/res/layout/activity_main.xml
================================================
<LinearLayout 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:orientation="vertical"
    tools:context=".MainActivity" >

    <EditText
        android:id="@+id/et_path"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint="请输入视频文件的路径"
        android:text="http://192.168.0.100/sanpan.mp4" />

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="start"
            android:text="播放" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="pause"
            android:text="暂停" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="stop"
            android:text="停止" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="restart"
            android:text="重播" />
    </LinearLayout>

    <SeekBar
        android:id="@+id/sb_progress"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <TextView
            android:id="@+id/tv_current_time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="00:03"
            android:textColor="#FF0000" />

        <TextView
            android:id="@+id/tv_total_time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="/03:33"
            android:textColor="#FF0000" />
    </LinearLayout>

    <SurfaceView
        android:id="@+id/surfaceview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

</LinearLayout>

================================================
FILE: MediaPlayerSample/app/src/main/res/menu/menu_main.xml
================================================
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity">
    <item android:id="@+id/action_settings" android:title="@string/action_settings"
        android:orderInCategory="100" android:showAsAction="never" />
</menu>


================================================
FILE: MediaPlayerSample/app/src/main/res/values/dimens.xml
================================================
<resources>
    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>
</resources>


================================================
FILE: MediaPlayerSample/app/src/main/res/values/strings.xml
================================================
<resources>
    <string name="app_name">MediaPlayerSample</string>

    <string name="hello_world">Hello world!</string>
    <string name="action_settings">Settings</string>
</resources>


================================================
FILE: MediaPlayerSample/app/src/main/res/values/styles.xml
================================================
<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
        <!-- Customize your theme here. -->
    </style>

</resources>


================================================
FILE: MediaPlayerSample/app/src/main/res/values-v21/styles.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="AppTheme" parent="android:Theme.Material.Light">
    </style>
</resources>


================================================
FILE: MediaPlayerSample/app/src/main/res/values-w820dp/dimens.xml
================================================
<resources>
    <!-- Example customization of dimensions originally defined in res/values/dimens.xml
         (such as screen margins) for screens with more than 820dp of available width. This
         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
    <dimen name="activity_horizontal_margin">64dp</dimen>
</resources>


================================================
FILE: MediaPlayerSample/build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.3.0'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}


================================================
FILE: MediaPlayerSample/gradle/wrapper/gradle-wrapper.properties
================================================
#Tue Aug 30 23:43:56 CST 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip


================================================
FILE: MediaPlayerSample/gradle.properties
================================================
# Project-wide Gradle settings.

# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.

# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html

# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8

# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true

================================================
FILE: MediaPlayerSample/gradlew
================================================
#!/usr/bin/env bash

##############################################################################
##
##  Gradle start up script for UN*X
##
##############################################################################

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""

APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"

warn ( ) {
    echo "$*"
}

die ( ) {
    echo
    echo "$*"
    echo
    exit 1
}

# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
  CYGWIN* )
    cygwin=true
    ;;
  Darwin* )
    darwin=true
    ;;
  MINGW* )
    msys=true
    ;;
esac

# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi

# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '/.*' > /dev/null; then
        PRG="$link"
    else
        PRG=`dirname "$PRG"`"/$link"
    fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar

# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
        # IBM's JDK on AIX uses strange locations for the executables
        JAVACMD="$JAVA_HOME/jre/sh/java"
    else
        JAVACMD="$JAVA_HOME/bin/java"
    fi
    if [ ! -x "$JAVACMD" ] ; then
        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
    fi
else
    JAVACMD="java"
    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi

# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
    MAX_FD_LIMIT=`ulimit -H -n`
    if [ $? -eq 0 ] ; then
        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
            MAX_FD="$MAX_FD_LIMIT"
        fi
        ulimit -n $MAX_FD
        if [ $? -ne 0 ] ; then
            warn "Could not set maximum file descriptor limit: $MAX_FD"
        fi
    else
        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
    fi
fi

# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi

# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`

    # We build the pattern for arguments to be converted via cygpath
    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
    SEP=""
    for dir in $ROOTDIRSRAW ; do
        ROOTDIRS="$ROOTDIRS$SEP$dir"
        SEP="|"
    done
    OURCYGPATTERN="(^($ROOTDIRS))"
    # Add a user-defined pattern to the cygpath arguments
    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
    fi
    # Now convert the arguments - kludge to limit ourselves to /bin/sh
    i=0
    for arg in "$@" ; do
        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option

        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
        else
            eval `echo args$i`="\"$arg\""
        fi
        i=$((i+1))
    done
    case $i in
        (0) set -- ;;
        (1) set -- "$args0" ;;
        (2) set -- "$args0" "$args1" ;;
        (3) set -- "$args0" "$args1" "$args2" ;;
        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
    esac
fi

# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
    JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"

exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"


================================================
FILE: MediaPlayerSample/gradlew.bat
================================================
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem  Gradle startup script for Windows
@rem
@rem ##########################################################################

@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=

set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto init

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:init
@rem Get command-line arguments, handling Windowz variants

if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args

:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2

:win9xME_args_slurp
if "x%~1" == "x" goto execute

set CMD_LINE_ARGS=%*
goto execute

:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$

:execute
@rem Setup the command line

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd

:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1

:mainEnd
if "%OS%"=="Windows_NT" endlocal

:omega


================================================
FILE: MediaPlayerSample/settings.gradle
================================================
include ':app'


================================================
FILE: README.md
================================================
# MultiMediaSample

###Android Multimediaܽ᰸MediaPlayer,Camera

1.CameraԶ
------------
![MultiMediaSample](/images/camera3.gif)

2.API android.hardware.camera2Զ
------------
![MultiMediaSample](/images/camera3.gif)

3.һػ̰ں̨פ֣Ϣ͵ȳ
------------
![MultiMediaSample](/images/guard3.gif)

4.MediaPlayerƵ
------------
![MultiMediaSample](/images/mediaplayer.png)

4.MediaCodeccodecƵ
------------
![MultiMediaSample](/images/mediacodec.gif)

####ӭעҵĸ˹ںţandroid ɻܽᣬFrameWorkԴо¿ԴĿƼ
![дͼƬ](https://github.com/hejunlin2013/RedPackage/blob/master/image/qrcode.jpg)

License
--------
```
Copyright (C) 2016 hejunlin

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
```



================================================
FILE: VideoWaterMarkSample/.gitignore
================================================
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures


================================================
FILE: VideoWaterMarkSample/.idea/compiler.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="CompilerConfiguration">
    <resourceExtensions />
    <wildcardResourcePatterns>
      <entry name="!?*.java" />
      <entry name="!?*.form" />
      <entry name="!?*.class" />
      <entry name="!?*.groovy" />
      <entry name="!?*.scala" />
      <entry name="!?*.flex" />
      <entry name="!?*.kt" />
      <entry name="!?*.clj" />
      <entry name="!?*.aj" />
    </wildcardResourcePatterns>
    <annotationProcessing>
      <profile default="true" name="Default" enabled="false">
        <processorPath useClasspath="true" />
      </profile>
    </annotationProcessing>
    <bytecodeTargetLevel target="1.8" />
  </component>
</project>

================================================
FILE: VideoWaterMarkSample/.idea/copyright/profiles_settings.xml
================================================
<component name="CopyrightManager">
  <settings default="" />
</component>

================================================
FILE: VideoWaterMarkSample/.idea/encodings.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="Encoding">
    <file url="PROJECT" charset="UTF-8" />
  </component>
</project>

================================================
FILE: VideoWaterMarkSample/.idea/gradle.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="GradleSettings">
    <option name="linkedExternalProjectsSettings">
      <GradleProjectSettings>
        <option name="distributionType" value="DEFAULT_WRAPPED" />
        <option name="externalProjectPath" value="$PROJECT_DIR$" />
        <option name="modules">
          <set>
            <option value="$PROJECT_DIR$" />
            <option value="$PROJECT_DIR$/app" />
          </set>
        </option>
        <option name="resolveModulePerSourceSet" value="false" />
      </GradleProjectSettings>
    </option>
  </component>
</project>

================================================
FILE: VideoWaterMarkSample/.idea/libraries/animated_vector_drawable_23_3_0.xml
================================================
<component name="libraryTable">
  <library name="animated-vector-drawable-23.3.0">
    <CLASSES>
      <root url="file://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/animated-vector-drawable/23.3.0/res" />
      <root url="jar://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/animated-vector-drawable/23.3.0/jars/classes.jar!/" />
    </CLASSES>
    <JAVADOC />
    <SOURCES>
      <root url="jar://G:/E/Android/sdk/extras/android/m2repository/com/android/support/animated-vector-drawable/23.3.0/animated-vector-drawable-23.3.0-sources.jar!/" />
    </SOURCES>
  </library>
</component>

================================================
FILE: VideoWaterMarkSample/.idea/libraries/appcompat_v7_23_3_0.xml
================================================
<component name="libraryTable">
  <library name="appcompat-v7-23.3.0">
    <CLASSES>
      <root url="jar://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/appcompat-v7/23.3.0/jars/classes.jar!/" />
      <root url="file://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/appcompat-v7/23.3.0/res" />
    </CLASSES>
    <JAVADOC />
    <SOURCES>
      <root url="jar://G:/E/Android/sdk/extras/android/m2repository/com/android/support/appcompat-v7/23.3.0/appcompat-v7-23.3.0-sources.jar!/" />
    </SOURCES>
  </library>
</component>

================================================
FILE: VideoWaterMarkSample/.idea/libraries/hamcrest_core_1_3.xml
================================================
<component name="libraryTable">
  <library name="hamcrest-core-1.3">
    <CLASSES>
      <root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-core/1.3/42a25dc3219429f0e5d060061f71acb49bf010a0/hamcrest-core-1.3.jar!/" />
    </CLASSES>
    <JAVADOC />
    <SOURCES>
      <root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-core/1.3/1dc37250fbc78e23a65a67fbbaf71d2e9cbc3c0b/hamcrest-core-1.3-sources.jar!/" />
    </SOURCES>
  </library>
</component>

================================================
FILE: VideoWaterMarkSample/.idea/libraries/junit_4_12.xml
================================================
<component name="libraryTable">
  <library name="junit-4.12">
    <CLASSES>
      <root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/junit/junit/4.12/2973d150c0dc1fefe998f834810d68f278ea58ec/junit-4.12.jar!/" />
    </CLASSES>
    <JAVADOC />
    <SOURCES>
      <root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/junit/junit/4.12/a6c32b40bf3d76eca54e3c601e5d1470c86fcdfa/junit-4.12-sources.jar!/" />
    </SOURCES>
  </library>
</component>

================================================
FILE: VideoWaterMarkSample/.idea/libraries/support_annotations_23_3_0.xml
================================================
<component name="libraryTable">
  <library name="support-annotations-23.3.0">
    <CLASSES>
      <root url="jar://G:/E/Android/sdk/extras/android/m2repository/com/android/support/support-annotations/23.3.0/support-annotations-23.3.0.jar!/" />
    </CLASSES>
    <JAVADOC />
    <SOURCES>
      <root url="jar://G:/E/Android/sdk/extras/android/m2repository/com/android/support/support-annotations/23.3.0/support-annotations-23.3.0-sources.jar!/" />
    </SOURCES>
  </library>
</component>

================================================
FILE: VideoWaterMarkSample/.idea/libraries/support_v4_23_3_0.xml
================================================
<component name="libraryTable">
  <library name="support-v4-23.3.0">
    <CLASSES>
      <root url="jar://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/support-v4/23.3.0/jars/libs/internal_impl-23.3.0.jar!/" />
      <root url="file://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/support-v4/23.3.0/res" />
      <root url="jar://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/support-v4/23.3.0/jars/classes.jar!/" />
    </CLASSES>
    <JAVADOC />
    <SOURCES>
      <root url="jar://G:/E/Android/sdk/extras/android/m2repository/com/android/support/support-v4/23.3.0/support-v4-23.3.0-sources.jar!/" />
    </SOURCES>
  </library>
</component>

================================================
FILE: VideoWaterMarkSample/.idea/libraries/support_vector_drawable_23_3_0.xml
================================================
<component name="libraryTable">
  <library name="support-vector-drawable-23.3.0">
    <CLASSES>
      <root url="jar://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/support-vector-drawable/23.3.0/jars/classes.jar!/" />
      <root url="file://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/support-vector-drawable/23.3.0/res" />
    </CLASSES>
    <JAVADOC />
    <SOURCES>
      <root url="jar://G:/E/Android/sdk/extras/android/m2repository/com/android/support/support-vector-drawable/23.3.0/support-vector-drawable-23.3.0-sources.jar!/" />
    </SOURCES>
  </library>
</component>

================================================
FILE: VideoWaterMarkSample/.idea/misc.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="ProjectInspectionProfilesVisibleTreeState">
    <entry key="Project Default">
      <profile-state>
        <expanded-state>
          <State>
            <id />
          </State>
          <State>
            <id>Class structureJava</id>
          </State>
          <State>
            <id>Code maturity issuesJava</id>
          </State>
          <State>
            <id>Java</id>
          </State>
          <State>
            <id>Java language level migration aidsJava</id>
          </State>
          <State>
            <id>Javadoc issuesJava</id>
          </State>
          <State>
            <id>Performance issuesJava</id>
          </State>
          <State>
            <id>TestNGJava</id>
          </State>
          <State>
            <id>Threading issuesJava</id>
          </State>
        </expanded-state>
        <selected-state>
          <State>
            <id>Android</id>
          </State>
        </selected-state>
      </profile-state>
    </entry>
  </component>
  <component name="ProjectLevelVcsManager" settingsEditedManually="false">
    <OptionsSetting value="true" id="Add" />
    <OptionsSetting value="true" id="Remove" />
    <OptionsSetting value="true" id="Checkout" />
    <OptionsSetting value="true" id="Update" />
    <OptionsSetting value="true" id="Status" />
    <OptionsSetting value="true" id="Edit" />
    <ConfirmationsSetting value="0" id="Add" />
    <ConfirmationsSetting value="0" id="Remove" />
  </component>
  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
    <output url="file://$PROJECT_DIR$/build/classes" />
  </component>
  <component name="ProjectType">
    <option name="id" value="Android" />
  </component>
</project>

================================================
FILE: VideoWaterMarkSample/.idea/modules.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="ProjectModuleManager">
    <modules>
      <module fileurl="file://$PROJECT_DIR$/VideoWaterMarkSample.iml" filepath="$PROJECT_DIR$/VideoWaterMarkSample.iml" />
      <module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
    </modules>
  </component>
</project>

================================================
FILE: VideoWaterMarkSample/.idea/runConfigurations.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="RunConfigurationProducerService">
    <option name="ignoredProducers">
      <set>
        <option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
        <option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
      </set>
    </option>
  </component>
</project>

================================================
FILE: VideoWaterMarkSample/.idea/workspace.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="AndroidLogFilters">
    <option name="TOOL_WINDOW_CONFIGURED_FILTER" value="Show only selected application" />
  </component>
  <component name="ChangeListManager">
    <list default="true" id="c5caa382-76ce-41e4-883a-0006433b63a7" name="Default" comment="" />
    <ignored path="VideoWaterMarkSample.iws" />
    <ignored path=".idea/workspace.xml" />
    <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
    <option name="TRACKING_ENABLED" value="true" />
    <option name="SHOW_DIALOG" value="false" />
    <option name="HIGHLIGHT_CONFLICTS" value="true" />
    <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
    <option name="LAST_RESOLUTION" value="IGNORE" />
  </component>
  <component name="ChangesViewManager" flattened_view="true" show_ignored="false" />
  <component name="CreatePatchCommitExecutor">
    <option name="PATCH_PATH" value="" />
  </component>
  <component name="ExecutionTargetManager" SELECTED_TARGET="default_target" />
  <component name="ExternalProjectsData">
    <projectState path="$PROJECT_DIR$">
      <ProjectState />
    </projectState>
  </component>
  <component name="FavoritesManager">
    <favorites_list name="VideoWaterMarkSample" />
  </component>
  <component name="GradleLocalSettings">
    <option name="availableProjects">
      <map>
        <entry>
          <key>
            <ExternalProjectPojo>
              <option name="name" value="VideoWaterMarkSample" />
              <option name="path" value="$PROJECT_DIR$" />
            </ExternalProjectPojo>
          </key>
          <value>
            <list>
              <ExternalProjectPojo>
                <option name="name" value=":app" />
                <option name="path" value="$PROJECT_DIR$/app" />
              </ExternalProjectPojo>
              <ExternalProjectPojo>
                <option name="name" value="VideoWaterMarkSample" />
                <option name="path" value="$PROJECT_DIR$" />
              </ExternalProjectPojo>
            </list>
          </value>
        </entry>
      </map>
    </option>
    <option name="availableTasks">
      <map>
        <entry key="$PROJECT_DIR$">
          <value>
            <list>
              <ExternalTaskPojo>
                <option name="description" value="Displays the sub-projects of root project 'VideoWaterMarkSample'." />
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="projects" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="description" value="Prepare com.android.support:animated-vector-drawable:23.3.0" />
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="prepareComAndroidSupportAnimatedVectorDrawable2330Library" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="assembleReleaseUnitTest" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="prepareDebugDependencies" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="processReleaseJavaRes" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="generateReleaseAssets" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="description" value="Runs lint on the Debug build." />
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="lintDebug" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="assembleDebugUnitTest" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="prePackageMarkerForDebug" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="description" value="Displays the configuration model of root project 'VideoWaterMarkSample'. [incubating]" />
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="model" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="description" value="Creates a version of android.jar that's suitable for unit tests." />
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="mockableAndroidJar" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="description" value="Displays the tasks runnable from root project 'VideoWaterMarkSample' (some of the displayed tasks may belong to subprojects)." />
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="tasks" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="compileDebugSources" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="description" value="Initializes a new Gradle build. [incubating]" />
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="init" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="description" value="Runs all device checks using Device Providers and Test Servers." />
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="deviceCheck" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="description" value="Displays all dependencies declared in root project 'VideoWaterMarkSample'." />
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="dependencies" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="processDebugResources" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="description" value="Runs lint on all variants." />
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="lint" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="packageDebug" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="prePackageMarkerForRelease" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="compileReleaseNdk" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="generateDebugResources" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="compileDebugJavaWithJavac" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="description" value="Assembles and tests this project and all projects it depends on." />
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="buildNeeded" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="generateDebugAndroidTestBuildConfig" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="processDebugUnitTestJavaRes" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="description" value="Run unit tests for the release build." />
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="testReleaseUnitTest" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="transformNative_libsWithMergeJniLibsForDebugAndroidTest" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="compileDebugAndroidTestJavaWithJavac" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="description" value="Displays the components produced by root project 'VideoWaterMarkSample'. [incubating]" />
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="components" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="compileReleaseRenderscript" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="description" value="Assembles all Debug builds." />
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="assembleDebug" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="processDebugAndroidTestManifest" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="compileDebugUnitTestJavaWithJavac" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="transformResourcesWithMergeJavaResForReleaseUnitTest" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="prePackageMarkerForDebugAndroidTest" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="transformClassesWithDexForDebug" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="preDebugAndroidTestBuild" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="processDebugAndroidTestJavaRes" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="processReleaseUnitTestJavaRes" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="description" value="Uninstalls the Release build." />
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="uninstallRelease" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="mergeReleaseResources" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="generateDebugAndroidTestSources" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="prepareDebugAndroidTestDependencies" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="checkReleaseManifest" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="description" value="Prepare com.android.support:support-vector-drawable:23.3.0" />
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="prepareComAndroidSupportSupportVectorDrawable2330Library" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="compileDebugAndroidTestSources" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="mergeReleaseJniLibFolders" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="prepareReleaseDependencies" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="processReleaseResources" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="description" value="Installs and runs instrumentation tests using all Device Providers." />
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="deviceAndroidTest" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="mergeDebugAndroidTestAssets" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="processReleaseManifest" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="description" value="Uninstalls the android (on device) tests for the Debug build." />
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="uninstallDebugAndroidTest" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="description" value="Displays the insight into a specific dependency in root project 'VideoWaterMarkSample'." />
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="dependencyInsight" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="generateReleaseSources" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="preReleaseBuild" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="description" value="Assembles all variants of all applications and secondary packages." />
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="assemble" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="description" value="Displays a help message." />
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="help" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="compileReleaseUnitTestSources" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="description" value="Installs the android (on device) tests for the Debug build." />
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="installDebugAndroidTest" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="mergeDebugAssets" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="description" value="Runs all device checks on currently connected devices." />
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="connectedCheck" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="description" value="Installs and runs the tests for debug on connected devices." />
                <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
                <option name="name" value="connectedDebugAndroidTest" />
              </ExternalTaskPojo>
              <ExternalTaskPojo>
                <option name="description" value="Uninstall all applications." />
                <option name="linkedExter
Download .txt
gitextract_hegirt9z/

├── .gitignore
├── .project
├── CameraSample/
│   ├── app/
│   │   ├── build.gradle
│   │   ├── proguard-rules.pro
│   │   └── src/
│   │       ├── androidTest/
│   │       │   └── java/
│   │       │       └── com/
│   │       │           └── hejunlin/
│   │       │               └── camerasample/
│   │       │                   └── ApplicationTest.java
│   │       ├── main/
│   │       │   ├── AndroidManifest.xml
│   │       │   ├── java/
│   │       │   │   └── com/
│   │       │   │       └── hejunlin/
│   │       │   │           └── camerasample/
│   │       │   │               ├── MainActivity.java
│   │       │   │               └── SurfacePreview.java
│   │       │   └── res/
│   │       │       ├── layout/
│   │       │       │   └── activity_main.xml
│   │       │       ├── values/
│   │       │       │   ├── colors.xml
│   │       │       │   ├── dimens.xml
│   │       │       │   ├── strings.xml
│   │       │       │   └── styles.xml
│   │       │       └── values-w820dp/
│   │       │           └── dimens.xml
│   │       └── test/
│   │           └── java/
│   │               └── com/
│   │                   └── hejunlin/
│   │                       └── camerasample/
│   │                           └── ExampleUnitTest.java
│   ├── build.gradle
│   ├── gradle/
│   │   └── wrapper/
│   │       ├── gradle-wrapper.jar
│   │       └── gradle-wrapper.properties
│   ├── gradle.properties
│   ├── gradlew
│   ├── gradlew.bat
│   └── settings.gradle
├── CameraSample2/
│   ├── app/
│   │   ├── build.gradle
│   │   ├── proguard-rules.pro
│   │   └── src/
│   │       ├── androidTest/
│   │       │   └── java/
│   │       │       └── com/
│   │       │           └── hejunlin/
│   │       │               └── camerasample2/
│   │       │                   └── ApplicationTest.java
│   │       ├── main/
│   │       │   ├── AndroidManifest.xml
│   │       │   ├── java/
│   │       │   │   └── com/
│   │       │   │       └── hejunlin/
│   │       │   │           └── camerasample2/
│   │       │   │               ├── Camera2Fragment.java
│   │       │   │               ├── MainActivity.java
│   │       │   │               └── SuperTextureView.java
│   │       │   └── res/
│   │       │       ├── layout/
│   │       │       │   ├── activity_main.xml
│   │       │       │   └── fragment_camera2.xml
│   │       │       ├── values/
│   │       │       │   ├── colors.xml
│   │       │       │   ├── dimens.xml
│   │       │       │   ├── strings.xml
│   │       │       │   └── styles.xml
│   │       │       └── values-w820dp/
│   │       │           └── dimens.xml
│   │       └── test/
│   │           └── java/
│   │               └── com/
│   │                   └── hejunlin/
│   │                       └── camerasample2/
│   │                           └── ExampleUnitTest.java
│   ├── build.gradle
│   ├── gradle/
│   │   └── wrapper/
│   │       ├── gradle-wrapper.jar
│   │       └── gradle-wrapper.properties
│   ├── gradle.properties
│   ├── gradlew
│   ├── gradlew.bat
│   └── settings.gradle
├── GuardProcessSample/
│   ├── app/
│   │   ├── build.gradle
│   │   ├── proguard-rules.pro
│   │   └── src/
│   │       ├── androidTest/
│   │       │   └── java/
│   │       │       └── com/
│   │       │           └── hejunlin/
│   │       │               └── guardprocesssample/
│   │       │                   └── ApplicationTest.java
│   │       ├── main/
│   │       │   ├── AndroidManifest.xml
│   │       │   ├── aidl/
│   │       │   │   └── com/
│   │       │   │       └── hejunlin/
│   │       │   │           └── guardprocesssample/
│   │       │   │               └── aidl/
│   │       │   │                   └── IBridgeInterface.aidl
│   │       │   ├── java/
│   │       │   │   └── com/
│   │       │   │       └── hejunlin/
│   │       │   │           └── guardprocesssample/
│   │       │   │               ├── MainActivity.java
│   │       │   │               ├── ServiceA.java
│   │       │   │               └── ServiceB.java
│   │       │   └── res/
│   │       │       ├── layout/
│   │       │       │   └── activity_main.xml
│   │       │       ├── values/
│   │       │       │   ├── colors.xml
│   │       │       │   ├── dimens.xml
│   │       │       │   ├── strings.xml
│   │       │       │   └── styles.xml
│   │       │       └── values-w820dp/
│   │       │           └── dimens.xml
│   │       └── test/
│   │           └── java/
│   │               └── com/
│   │                   └── hejunlin/
│   │                       └── guardprocesssample/
│   │                           └── ExampleUnitTest.java
│   ├── build.gradle
│   ├── gradle/
│   │   └── wrapper/
│   │       ├── gradle-wrapper.jar
│   │       └── gradle-wrapper.properties
│   ├── gradle.properties
│   ├── gradlew
│   ├── gradlew.bat
│   └── settings.gradle
├── LICENSE
├── MediaCodcSample/
│   ├── .gitignore
│   ├── app/
│   │   ├── .gitignore
│   │   ├── build.gradle
│   │   ├── proguard-rules.pro
│   │   └── src/
│   │       ├── androidTest/
│   │       │   └── java/
│   │       │       └── com/
│   │       │           └── hejunlin/
│   │       │               └── mediacodcsample/
│   │       │                   └── ApplicationTest.java
│   │       ├── main/
│   │       │   ├── AndroidManifest.xml
│   │       │   ├── java/
│   │       │   │   └── com/
│   │       │   │       └── hejunlin/
│   │       │   │           └── mediacodcsample/
│   │       │   │               └── MainActivity.java
│   │       │   └── res/
│   │       │       ├── layout/
│   │       │       │   └── activity_main.xml
│   │       │       ├── values/
│   │       │       │   ├── colors.xml
│   │       │       │   ├── dimens.xml
│   │       │       │   ├── strings.xml
│   │       │       │   └── styles.xml
│   │       │       └── values-w820dp/
│   │       │           └── dimens.xml
│   │       └── test/
│   │           └── java/
│   │               └── com/
│   │                   └── hejunlin/
│   │                       └── mediacodcsample/
│   │                           └── ExampleUnitTest.java
│   ├── build.gradle
│   ├── gradle/
│   │   └── wrapper/
│   │       ├── gradle-wrapper.jar
│   │       └── gradle-wrapper.properties
│   ├── gradle.properties
│   ├── gradlew
│   ├── gradlew.bat
│   └── settings.gradle
├── MediaPlayerSample/
│   ├── app/
│   │   ├── build.gradle
│   │   ├── proguard-rules.pro
│   │   └── src/
│   │       ├── androidTest/
│   │       │   └── java/
│   │       │       └── com/
│   │       │           └── hejunlin/
│   │       │               └── mediaplayersample/
│   │       │                   └── ApplicationTest.java
│   │       └── main/
│   │           ├── AndroidManifest.xml
│   │           ├── java/
│   │           │   └── com/
│   │           │       └── hejunlin/
│   │           │           └── mediaplayersample/
│   │           │               └── MainActivity.java
│   │           └── res/
│   │               ├── layout/
│   │               │   └── activity_main.xml
│   │               ├── menu/
│   │               │   └── menu_main.xml
│   │               ├── values/
│   │               │   ├── dimens.xml
│   │               │   ├── strings.xml
│   │               │   └── styles.xml
│   │               ├── values-v21/
│   │               │   └── styles.xml
│   │               └── values-w820dp/
│   │                   └── dimens.xml
│   ├── build.gradle
│   ├── gradle/
│   │   └── wrapper/
│   │       ├── gradle-wrapper.jar
│   │       └── gradle-wrapper.properties
│   ├── gradle.properties
│   ├── gradlew
│   ├── gradlew.bat
│   └── settings.gradle
├── README.md
└── VideoWaterMarkSample/
    ├── .gitignore
    ├── .idea/
    │   ├── compiler.xml
    │   ├── copyright/
    │   │   └── profiles_settings.xml
    │   ├── encodings.xml
    │   ├── gradle.xml
    │   ├── libraries/
    │   │   ├── animated_vector_drawable_23_3_0.xml
    │   │   ├── appcompat_v7_23_3_0.xml
    │   │   ├── hamcrest_core_1_3.xml
    │   │   ├── junit_4_12.xml
    │   │   ├── support_annotations_23_3_0.xml
    │   │   ├── support_v4_23_3_0.xml
    │   │   └── support_vector_drawable_23_3_0.xml
    │   ├── misc.xml
    │   ├── modules.xml
    │   ├── runConfigurations.xml
    │   └── workspace.xml
    ├── app/
    │   ├── .gitignore
    │   ├── build.gradle
    │   ├── proguard-rules.pro
    │   └── src/
    │       └── main/
    │           ├── AndroidManifest.xml
    │           ├── java/
    │           │   └── com/
    │           │       └── hejunlin/
    │           │           └── videorecord/
    │           │               ├── ColorFormatUtil.java
    │           │               ├── MainActivity.java
    │           │               ├── TakeVideoActivity.java
    │           │               ├── VideoCodecModel.java
    │           │               └── VideoCodecTask.java
    │           └── res/
    │               ├── drawable/
    │               │   ├── diverde.xml
    │               │   ├── litte_red_point.xml
    │               │   ├── play.xml
    │               │   └── progressbar_drawable.xml
    │               ├── layout/
    │               │   ├── activity_main.xml
    │               │   └── activity_take_video.xml
    │               ├── values/
    │               │   ├── colors.xml
    │               │   ├── dimens.xml
    │               │   ├── strings.xml
    │               │   └── styles.xml
    │               └── values-w820dp/
    │                   └── dimens.xml
    ├── build.gradle
    ├── gradle/
    │   └── wrapper/
    │       ├── gradle-wrapper.jar
    │       └── gradle-wrapper.properties
    ├── gradle.properties
    ├── gradlew
    ├── gradlew.bat
    └── settings.gradle
Download .txt
SYMBOL INDEX (200 symbols across 24 files)

FILE: CameraSample/app/src/androidTest/java/com/hejunlin/camerasample/ApplicationTest.java
  class ApplicationTest (line 9) | public class ApplicationTest extends ApplicationTestCase<Application> {
    method ApplicationTest (line 10) | public ApplicationTest() {

FILE: CameraSample/app/src/main/java/com/hejunlin/camerasample/MainActivity.java
  class MainActivity (line 21) | public class MainActivity extends AppCompatActivity implements Camera.Pi...
    method onCreate (line 27) | @Override
    method onPictureTaken (line 42) | @Override
    method onClick (line 69) | @Override
    method getOutputMediaFile (line 76) | private File getOutputMediaFile(){

FILE: CameraSample/app/src/main/java/com/hejunlin/camerasample/SurfacePreview.java
  class SurfacePreview (line 17) | public class SurfacePreview extends SurfaceView implements SurfaceHolder...
    method SurfacePreview (line 24) | public SurfacePreview(Context context) {
    method surfaceCreated (line 36) | public void surfaceCreated(SurfaceHolder holder) {
    method surfaceChanged (line 49) | public void surfaceChanged(SurfaceHolder holder, int format, int w, in...
    method initCamera (line 67) | private void initCamera() {
    method setDispaly (line 79) | private void setDispaly(Camera.Parameters parameters,Camera camera) {
    method setDisplayOrientation (line 87) | private void setDisplayOrientation(Camera camera, int i) {
    method surfaceDestroyed (line 100) | public void surfaceDestroyed(SurfaceHolder holder) {
    method takePicture (line 109) | public void takePicture(Camera.PictureCallback imageCallback) {

FILE: CameraSample/app/src/test/java/com/hejunlin/camerasample/ExampleUnitTest.java
  class ExampleUnitTest (line 10) | public class ExampleUnitTest {
    method addition_isCorrect (line 11) | @Test

FILE: CameraSample2/app/src/androidTest/java/com/hejunlin/camerasample2/ApplicationTest.java
  class ApplicationTest (line 9) | public class ApplicationTest extends ApplicationTestCase<Application> {
    method ApplicationTest (line 10) | public ApplicationTest() {

FILE: CameraSample2/app/src/main/java/com/hejunlin/camerasample2/Camera2Fragment.java
  class Camera2Fragment (line 62) | public class Camera2Fragment extends Fragment
    method onSurfaceTextureAvailable (line 126) | @Override
    method onSurfaceTextureSizeChanged (line 131) | @Override
    method onSurfaceTextureDestroyed (line 136) | @Override
    method onSurfaceTextureUpdated (line 141) | @Override
    method onOpened (line 177) | @Override
    method onDisconnected (line 185) | @Override
    method onError (line 192) | @Override
    method onImageAvailable (line 232) | @Override
    method process (line 277) | private void process(CaptureResult result) {
    method onCaptureProgressed (line 323) | @Override
    method onCaptureCompleted (line 330) | @Override
    method showToast (line 344) | private void showToast(final String text) {
    method chooseOptimalSize (line 372) | private static Size chooseOptimalSize(Size[] choices, int textureViewW...
    method newInstance (line 405) | public static Camera2Fragment newInstance() {
    method onCreateView (line 409) | @Override
    method onViewCreated (line 415) | @Override
    method onActivityCreated (line 422) | @Override
    method getOutputMediaFile (line 428) | private File getOutputMediaFile(){
    method onResume (line 436) | @Override
    method onPause (line 452) | @Override
    method requestCameraPermission (line 459) | private void requestCameraPermission() {
    method onRequestPermissionsResult (line 468) | @Override
    method setUpCameraOutputs (line 487) | private void setUpCameraOutputs(int width, int height) {
    method openCamera (line 598) | private void openCamera(int width, int height) {
    method closeCamera (line 623) | private void closeCamera() {
    method startBackgroundThread (line 648) | private void startBackgroundThread() {
    method stopBackgroundThread (line 657) | private void stopBackgroundThread() {
    method createCameraPreviewSession (line 671) | private void createCameraPreviewSession() {
    method configureTransform (line 736) | private void configureTransform(int viewWidth, int viewHeight) {
    method takePicture (line 764) | private void takePicture() {
    method lockFocus (line 771) | private void lockFocus() {
    method runPrecaptureSequence (line 789) | private void runPrecaptureSequence() {
    method captureStillPicture (line 807) | private void captureStillPicture() {
    method getOrientation (line 853) | private int getOrientation(int rotation) {
    method unlockFocus (line 865) | private void unlockFocus() {
    method onClick (line 882) | @Override
    method setAutoFlash (line 892) | private void setAutoFlash(CaptureRequest.Builder requestBuilder) {
    class ImageSaver (line 902) | private static class ImageSaver implements Runnable {
      method ImageSaver (line 913) | public ImageSaver(Image image, File file) {
      method run (line 918) | @Override
    class CompareSizesByArea (line 946) | static class CompareSizesByArea implements Comparator<Size> {
      method compare (line 948) | @Override
    class ErrorDialog (line 960) | public static class ErrorDialog extends DialogFragment {
      method newInstance (line 964) | public static ErrorDialog newInstance(String message) {
      method onCreateDialog (line 972) | @Override
    class ConfirmationDialog (line 991) | public static class ConfirmationDialog extends DialogFragment {
      method onCreateDialog (line 993) | @Override

FILE: CameraSample2/app/src/main/java/com/hejunlin/camerasample2/MainActivity.java
  class MainActivity (line 6) | public class MainActivity extends AppCompatActivity {
    method onCreate (line 8) | @Override

FILE: CameraSample2/app/src/main/java/com/hejunlin/camerasample2/SuperTextureView.java
  class SuperTextureView (line 10) | public class SuperTextureView extends TextureView {
    method SuperTextureView (line 15) | public SuperTextureView(Context context) {
    method SuperTextureView (line 19) | public SuperTextureView(Context context, AttributeSet attrs) {
    method SuperTextureView (line 23) | public SuperTextureView(Context context, AttributeSet attrs, int defSt...

FILE: CameraSample2/app/src/test/java/com/hejunlin/camerasample2/ExampleUnitTest.java
  class ExampleUnitTest (line 10) | public class ExampleUnitTest {
    method addition_isCorrect (line 11) | @Test

FILE: GuardProcessSample/app/src/androidTest/java/com/hejunlin/guardprocesssample/ApplicationTest.java
  class ApplicationTest (line 9) | public class ApplicationTest extends ApplicationTestCase<Application> {
    method ApplicationTest (line 10) | public ApplicationTest() {

FILE: GuardProcessSample/app/src/main/java/com/hejunlin/guardprocesssample/MainActivity.java
  class MainActivity (line 7) | public class MainActivity extends AppCompatActivity {
    method onCreate (line 9) | @Override

FILE: GuardProcessSample/app/src/main/java/com/hejunlin/guardprocesssample/ServiceA.java
  class ServiceA (line 20) | public class ServiceA extends Service {
    method onCreate (line 27) | @Override
    method onStartCommand (line 36) | @Override
    class MyServiceConnection (line 53) | class MyServiceConnection implements ServiceConnection {
      method onServiceConnected (line 55) | @Override
      method onServiceDisconnected (line 61) | @Override
    class MyBinder (line 73) | class MyBinder extends IBridgeInterface.Stub {
      method getName (line 75) | @Override
    method onBind (line 82) | @Override

FILE: GuardProcessSample/app/src/main/java/com/hejunlin/guardprocesssample/ServiceB.java
  class ServiceB (line 20) | public class ServiceB extends Service {
    method onCreate (line 27) | @Override
    method onStartCommand (line 36) | @Override
    class MyServiceConnection (line 53) | class MyServiceConnection implements ServiceConnection {
      method onServiceConnected (line 55) | @Override
      method onServiceDisconnected (line 61) | @Override
    class MyBinder (line 72) | class MyBinder extends IBridgeInterface.Stub {
      method getName (line 74) | @Override
    method onBind (line 81) | @Override

FILE: GuardProcessSample/app/src/test/java/com/hejunlin/guardprocesssample/ExampleUnitTest.java
  class ExampleUnitTest (line 10) | public class ExampleUnitTest {
    method addition_isCorrect (line 11) | @Test

FILE: MediaCodcSample/app/src/androidTest/java/com/hejunlin/mediacodcsample/ApplicationTest.java
  class ApplicationTest (line 9) | public class ApplicationTest extends ApplicationTestCase<Application> {
    method ApplicationTest (line 10) | public ApplicationTest() {

FILE: MediaCodcSample/app/src/main/java/com/hejunlin/mediacodcsample/MainActivity.java
  class MainActivity (line 17) | public class MainActivity extends AppCompatActivity implements SurfaceHo...
    method onCreate (line 23) | @Override
    method onDestroy (line 33) | protected void onDestroy() {
    method surfaceCreated (line 37) | @Override
    method surfaceChanged (line 41) | @Override
    method surfaceDestroyed (line 49) | @Override
    class WorkThread (line 56) | private class WorkThread extends Thread {
      method WorkThread (line 61) | public WorkThread(Surface surface) {
      method run (line 65) | @Override

FILE: MediaCodcSample/app/src/test/java/com/hejunlin/mediacodcsample/ExampleUnitTest.java
  class ExampleUnitTest (line 10) | public class ExampleUnitTest {
    method addition_isCorrect (line 11) | @Test

FILE: MediaPlayerSample/app/src/androidTest/java/com/hejunlin/mediaplayersample/ApplicationTest.java
  class ApplicationTest (line 9) | public class ApplicationTest extends ApplicationTestCase<Application> {
    method ApplicationTest (line 10) | public ApplicationTest() {

FILE: MediaPlayerSample/app/src/main/java/com/hejunlin/mediaplayersample/MainActivity.java
  class MainActivity (line 21) | public class MainActivity extends Activity implements OnSeekBarChangeLis...
    method onCreate (line 40) | @Override
    method start (line 65) | public void start(View v){
    method stop (line 85) | public void stop(View v){
    method play (line 94) | private void play(){
    method pause (line 133) | public void pause(View v){
    method restart (line 146) | public void restart(View v){
    method onProgressChanged (line 154) | @Override
    method onStartTrackingTouch (line 160) | @Override
    method onStopTrackingTouch (line 166) | @Override
    method onCompletion (line 178) | @Override
    class UpdateProgressRunnable (line 190) | class  UpdateProgressRunnable implements Runnable{
      method run (line 192) | @Override

FILE: VideoWaterMarkSample/app/src/main/java/com/hejunlin/videorecord/ColorFormatUtil.java
  class ColorFormatUtil (line 12) | public class ColorFormatUtil {
    method convertRGB2YUV420sp (line 15) | public static byte[] convertRGB2YUV420sp(int[] argb, int width, int he...
    method convertRGB2YUV420p (line 53) | public static byte[] convertRGB2YUV420p(int[] argb, int width, int hei...
    method convertYUV420p2RGB (line 88) | public static int[] convertYUV420p2RGB(byte[] yuv, int width, int heig...
    method convertYUV420sp2RGB (line 133) | public static Bitmap convertYUV420sp2RGB(byte[] yuv, int width, int he...

FILE: VideoWaterMarkSample/app/src/main/java/com/hejunlin/videorecord/MainActivity.java
  class MainActivity (line 18) | public class MainActivity extends AppCompatActivity {
    method handleMessage (line 28) | @Override
    method onCreate (line 56) | @Override
    method initView (line 64) | private void initView() {
    method initData (line 70) | private void initData() {
    method onTakeVideo (line 75) | public void onTakeVideo(View v) {
    method onClick (line 89) | public void onClick(View v) {
    method onActivityResult (line 99) | @Override

FILE: VideoWaterMarkSample/app/src/main/java/com/hejunlin/videorecord/TakeVideoActivity.java
  class TakeVideoActivity (line 43) | public class TakeVideoActivity extends Activity implements SurfaceHolder...
    type State (line 62) | private enum State {
    method onCreate (line 66) | @Override
    method surfaceCreated (line 105) | @Override
    method surfaceChanged (line 119) | @Override
    method initCamera (line 148) | private void initCamera() {
    method setDispaly (line 160) | private void setDispaly(Camera.Parameters parameters,Camera camera) {
    method setDisplayOrientation (line 168) | private void setDisplayOrientation(Camera camera, int i) {
    method surfaceDestroyed (line 181) | @Override
    method onDestroy (line 195) | @Override
    method onClick (line 212) | @Override
    method startRecorder (line 240) | private void startRecorder() {
    method stopRecorder (line 286) | private void stopRecorder() {
    method previewVideo (line 304) | private void previewVideo() {
    method skipToCodec (line 313) | private void skipToCodec() {
    method onActivityResult (line 334) | @Override
    method run (line 357) | @Override
    method handleMessage (line 366) | @Override
    method secondToText (line 392) | String secondToText(int second) {
    method onBackPressed (line 402) | @Override
    method startTime (line 410) | void startTime() {
    method showSupportVideoSize (line 416) | private void showSupportVideoSize(Camera camera) {
    method initSupportProfile (line 435) | private void initSupportProfile() {
    method getVideoThumbnail (line 454) | public static Bitmap getVideoThumbnail(String filePath) {
    method saveBitmapWithName (line 458) | public static void saveBitmapWithName(Bitmap bitmap, String path) {

FILE: VideoWaterMarkSample/app/src/main/java/com/hejunlin/videorecord/VideoCodecModel.java
  class VideoCodecModel (line 5) | public class VideoCodecModel implements Serializable {
    method VideoCodecModel (line 14) | public VideoCodecModel() {
    method getSrcPath (line 17) | public String getSrcPath() {
    method setSrcPath (line 21) | public void setSrcPath(String srcPath) {
    method getDstPath (line 25) | public String getDstPath() {
    method setDstPath (line 29) | public void setDstPath(String dstPath) {
    method getVideoCreateTime (line 33) | public long getVideoCreateTime() {
    method setVideoCreateTime (line 37) | public void setVideoCreateTime(long videoCreateTime) {
    method equals (line 41) | @Override

FILE: VideoWaterMarkSample/app/src/main/java/com/hejunlin/videorecord/VideoCodecTask.java
  class VideoCodecTask (line 28) | @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
    method VideoCodecTask (line 70) | public VideoCodecTask(VideoCodecModel video) {
    method start (line 80) | public void start() {
    method init (line 98) | private void init(String srcPath, String dstPath) {
    method initMediaDecode (line 161) | private void initMediaDecode(String mime) {
    method initMediaEncode (line 184) | private void initMediaEncode() {
    method getEncodeColor (line 210) | private void getEncodeColor() {
    method extract (line 221) | private void extract() {
    method handleFrameData (line 251) | private void handleFrameData(byte[] data, MediaCodec.BufferInfo info) {
    method changeYUV2Bitmap (line 272) | public Bitmap changeYUV2Bitmap(byte[] data) {
    method getFrameData (line 290) | private Frame getFrameData() {
    method encodeYUV (line 304) | public byte[] encodeYUV(int width, int height, Bitmap scaled) {
    method rotaingImage (line 326) | public Bitmap rotaingImage(int angle, Bitmap bitmap) {
    method decode (line 334) | private void decode(MediaCodec.BufferInfo videoInfo, int inputIndex) {
    method encode (line 383) | private void encode() {
    method onEnd (line 434) | public void onEnd() {
    method release (line 447) | private void release() {
    method cancel (line 463) | public void cancel(boolean delete) {
    method setProgressHandler (line 476) | public void setProgressHandler(Handler handler) {
    class Frame (line 480) | class Frame {
      method Frame (line 485) | public Frame(MediaCodec.BufferInfo videoInfo, Bitmap bitmap) {
    class DecodeRunnable (line 494) | private class DecodeRunnable extends Thread {
      method run (line 496) | @Override
    class EncodeRunnable (line 518) | private class EncodeRunnable extends Thread {
      method run (line 519) | @Override
Condensed preview — 151 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (406K chars).
[
  {
    "path": ".gitignore",
    "chars": 465,
    "preview": "# Built application files\n*.apk\n*.ap_\n\n# Files for the ART/Dalvik VM\n*.dex\n\n# Java class files\n*.class\n\n# Generated file"
  },
  {
    "path": ".project",
    "chars": 220,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<projectDescription>\r\n\t<name>MultiMediaSample</name>\r\n\t<comment></comment>\r\n\t<pr"
  },
  {
    "path": "CameraSample/app/build.gradle",
    "chars": 652,
    "preview": "apply plugin: 'com.android.application'\r\n\r\nandroid {\r\n    compileSdkVersion 23\r\n    buildToolsVersion \"23.0.3\"\r\n\r\n    de"
  },
  {
    "path": "CameraSample/app/proguard-rules.pro",
    "chars": 661,
    "preview": "# Add project specific ProGuard rules here.\r\n# By default, the flags in this file are appended to flags specified\r\n# in "
  },
  {
    "path": "CameraSample/app/src/androidTest/java/com/hejunlin/camerasample/ApplicationTest.java",
    "chars": 368,
    "preview": "package com.hejunlin.camerasample;\r\n\r\nimport android.app.Application;\r\nimport android.test.ApplicationTestCase;\r\n\r\n/**\r\n"
  },
  {
    "path": "CameraSample/app/src/main/AndroidManifest.xml",
    "chars": 979,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    packag"
  },
  {
    "path": "CameraSample/app/src/main/java/com/hejunlin/camerasample/MainActivity.java",
    "chars": 3008,
    "preview": "package com.hejunlin.camerasample;\r\n\r\nimport android.hardware.Camera;\r\nimport android.os.Environment;\r\nimport android.su"
  },
  {
    "path": "CameraSample/app/src/main/java/com/hejunlin/camerasample/SurfacePreview.java",
    "chars": 3872,
    "preview": "package com.hejunlin.camerasample;\r\n\r\nimport android.content.Context;\r\nimport android.graphics.PixelFormat;\r\nimport andr"
  },
  {
    "path": "CameraSample/app/src/main/res/layout/activity_main.xml",
    "chars": 877,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    and"
  },
  {
    "path": "CameraSample/app/src/main/res/values/colors.xml",
    "chars": 214,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<resources>\r\n    <color name=\"colorPrimary\">#3F51B5</color>\r\n    <color name=\"co"
  },
  {
    "path": "CameraSample/app/src/main/res/values/dimens.xml",
    "chars": 216,
    "preview": "<resources>\r\n    <!-- Default screen margins, per the Android Design guidelines. -->\r\n    <dimen name=\"activity_horizont"
  },
  {
    "path": "CameraSample/app/src/main/res/values/strings.xml",
    "chars": 78,
    "preview": "<resources>\r\n    <string name=\"app_name\">CameraSample</string>\r\n</resources>\r\n"
  },
  {
    "path": "CameraSample/app/src/main/res/values/styles.xml",
    "chars": 394,
    "preview": "<resources>\r\n\r\n    <!-- Base application theme. -->\r\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkAction"
  },
  {
    "path": "CameraSample/app/src/main/res/values-w820dp/dimens.xml",
    "chars": 364,
    "preview": "<resources>\r\n    <!-- Example customization of dimensions originally defined in res/values/dimens.xml\r\n         (such as"
  },
  {
    "path": "CameraSample/app/src/test/java/com/hejunlin/camerasample/ExampleUnitTest.java",
    "chars": 332,
    "preview": "package com.hejunlin.camerasample;\r\n\r\nimport org.junit.Test;\r\n\r\nimport static org.junit.Assert.*;\r\n\r\n/**\r\n * To work on "
  },
  {
    "path": "CameraSample/build.gradle",
    "chars": 521,
    "preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\r\n\r\nbuildscript {\r\n  "
  },
  {
    "path": "CameraSample/gradle/wrapper/gradle-wrapper.properties",
    "chars": 231,
    "preview": "#Mon Dec 28 10:00:20 PST 2015\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
  },
  {
    "path": "CameraSample/gradle.properties",
    "chars": 872,
    "preview": "# Project-wide Gradle settings.\r\n\r\n# IDE (e.g. Android Studio) users:\r\n# Gradle settings configured through the IDE *wil"
  },
  {
    "path": "CameraSample/gradlew",
    "chars": 4971,
    "preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start "
  },
  {
    "path": "CameraSample/gradlew.bat",
    "chars": 2404,
    "preview": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@r"
  },
  {
    "path": "CameraSample/settings.gradle",
    "chars": 16,
    "preview": "include ':app'\r\n"
  },
  {
    "path": "CameraSample2/app/build.gradle",
    "chars": 814,
    "preview": "apply plugin: 'com.android.application'\r\n\r\nandroid {\r\n    compileSdkVersion 23\r\n    buildToolsVersion \"23.0.3\"\r\n\r\n    de"
  },
  {
    "path": "CameraSample2/app/proguard-rules.pro",
    "chars": 661,
    "preview": "# Add project specific ProGuard rules here.\r\n# By default, the flags in this file are appended to flags specified\r\n# in "
  },
  {
    "path": "CameraSample2/app/src/androidTest/java/com/hejunlin/camerasample2/ApplicationTest.java",
    "chars": 369,
    "preview": "package com.hejunlin.camerasample2;\r\n\r\nimport android.app.Application;\r\nimport android.test.ApplicationTestCase;\r\n\r\n/**\r"
  },
  {
    "path": "CameraSample2/app/src/main/AndroidManifest.xml",
    "chars": 967,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    packag"
  },
  {
    "path": "CameraSample2/app/src/main/java/com/hejunlin/camerasample2/Camera2Fragment.java",
    "chars": 39480,
    "preview": "package com.hejunlin.camerasample2;\n\nimport android.Manifest;\nimport android.app.Activity;\nimport android.app.AlertDialo"
  },
  {
    "path": "CameraSample2/app/src/main/java/com/hejunlin/camerasample2/MainActivity.java",
    "chars": 568,
    "preview": "package com.hejunlin.camerasample2;\r\n\r\nimport android.support.v7.app.AppCompatActivity;\r\nimport android.os.Bundle;\r\n\r\npu"
  },
  {
    "path": "CameraSample2/app/src/main/java/com/hejunlin/camerasample2/SuperTextureView.java",
    "chars": 2053,
    "preview": "package com.hejunlin.camerasample2;\n\nimport android.content.Context;\nimport android.util.AttributeSet;\nimport android.vi"
  },
  {
    "path": "CameraSample2/app/src/main/res/layout/activity_main.xml",
    "chars": 263,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    and"
  },
  {
    "path": "CameraSample2/app/src/main/res/layout/fragment_camera2.xml",
    "chars": 922,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    an"
  },
  {
    "path": "CameraSample2/app/src/main/res/values/colors.xml",
    "chars": 214,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<resources>\r\n    <color name=\"colorPrimary\">#3F51B5</color>\r\n    <color name=\"co"
  },
  {
    "path": "CameraSample2/app/src/main/res/values/dimens.xml",
    "chars": 216,
    "preview": "<resources>\r\n    <!-- Default screen margins, per the Android Design guidelines. -->\r\n    <dimen name=\"activity_horizont"
  },
  {
    "path": "CameraSample2/app/src/main/res/values/strings.xml",
    "chars": 79,
    "preview": "<resources>\r\n    <string name=\"app_name\">CameraSample2</string>\r\n</resources>\r\n"
  },
  {
    "path": "CameraSample2/app/src/main/res/values/styles.xml",
    "chars": 394,
    "preview": "<resources>\r\n\r\n    <!-- Base application theme. -->\r\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkAction"
  },
  {
    "path": "CameraSample2/app/src/main/res/values-w820dp/dimens.xml",
    "chars": 364,
    "preview": "<resources>\r\n    <!-- Example customization of dimensions originally defined in res/values/dimens.xml\r\n         (such as"
  },
  {
    "path": "CameraSample2/app/src/test/java/com/hejunlin/camerasample2/ExampleUnitTest.java",
    "chars": 333,
    "preview": "package com.hejunlin.camerasample2;\r\n\r\nimport org.junit.Test;\r\n\r\nimport static org.junit.Assert.*;\r\n\r\n/**\r\n * To work on"
  },
  {
    "path": "CameraSample2/build.gradle",
    "chars": 521,
    "preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\r\n\r\nbuildscript {\r\n  "
  },
  {
    "path": "CameraSample2/gradle/wrapper/gradle-wrapper.properties",
    "chars": 231,
    "preview": "#Mon Dec 28 10:00:20 PST 2015\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
  },
  {
    "path": "CameraSample2/gradle.properties",
    "chars": 872,
    "preview": "# Project-wide Gradle settings.\r\n\r\n# IDE (e.g. Android Studio) users:\r\n# Gradle settings configured through the IDE *wil"
  },
  {
    "path": "CameraSample2/gradlew",
    "chars": 4971,
    "preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start "
  },
  {
    "path": "CameraSample2/gradlew.bat",
    "chars": 2404,
    "preview": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@r"
  },
  {
    "path": "CameraSample2/settings.gradle",
    "chars": 16,
    "preview": "include ':app'\r\n"
  },
  {
    "path": "GuardProcessSample/app/build.gradle",
    "chars": 658,
    "preview": "apply plugin: 'com.android.application'\r\n\r\nandroid {\r\n    compileSdkVersion 23\r\n    buildToolsVersion \"23.0.3\"\r\n\r\n    de"
  },
  {
    "path": "GuardProcessSample/app/proguard-rules.pro",
    "chars": 661,
    "preview": "# Add project specific ProGuard rules here.\r\n# By default, the flags in this file are appended to flags specified\r\n# in "
  },
  {
    "path": "GuardProcessSample/app/src/androidTest/java/com/hejunlin/guardprocesssample/ApplicationTest.java",
    "chars": 374,
    "preview": "package com.hejunlin.guardprocesssample;\r\n\r\nimport android.app.Application;\r\nimport android.test.ApplicationTestCase;\r\n\r"
  },
  {
    "path": "GuardProcessSample/app/src/main/AndroidManifest.xml",
    "chars": 868,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    packag"
  },
  {
    "path": "GuardProcessSample/app/src/main/aidl/com/hejunlin/guardprocesssample/aidl/IBridgeInterface.aidl",
    "chars": 447,
    "preview": "// IBridgeInterface.aidl\r\npackage com.hejunlin.guardprocesssample.aidl;\r\n\r\n// Declare any non-default types here with im"
  },
  {
    "path": "GuardProcessSample/app/src/main/java/com/hejunlin/guardprocesssample/MainActivity.java",
    "chars": 524,
    "preview": "package com.hejunlin.guardprocesssample;\r\n\r\nimport android.content.Intent;\r\nimport android.support.v7.app.AppCompatActiv"
  },
  {
    "path": "GuardProcessSample/app/src/main/java/com/hejunlin/guardprocesssample/ServiceA.java",
    "chars": 2889,
    "preview": "package com.hejunlin.guardprocesssample;\r\n\r\nimport android.app.Notification;\r\nimport android.app.PendingIntent;\r\nimport "
  },
  {
    "path": "GuardProcessSample/app/src/main/java/com/hejunlin/guardprocesssample/ServiceB.java",
    "chars": 2874,
    "preview": "package com.hejunlin.guardprocesssample;\r\n\r\nimport android.app.Notification;\r\nimport android.app.PendingIntent;\r\nimport "
  },
  {
    "path": "GuardProcessSample/app/src/main/res/layout/activity_main.xml",
    "chars": 727,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    "
  },
  {
    "path": "GuardProcessSample/app/src/main/res/values/colors.xml",
    "chars": 214,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<resources>\r\n    <color name=\"colorPrimary\">#3F51B5</color>\r\n    <color name=\"co"
  },
  {
    "path": "GuardProcessSample/app/src/main/res/values/dimens.xml",
    "chars": 216,
    "preview": "<resources>\r\n    <!-- Default screen margins, per the Android Design guidelines. -->\r\n    <dimen name=\"activity_horizont"
  },
  {
    "path": "GuardProcessSample/app/src/main/res/values/strings.xml",
    "chars": 84,
    "preview": "<resources>\r\n    <string name=\"app_name\">GuardProcessSample</string>\r\n</resources>\r\n"
  },
  {
    "path": "GuardProcessSample/app/src/main/res/values/styles.xml",
    "chars": 394,
    "preview": "<resources>\r\n\r\n    <!-- Base application theme. -->\r\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkAction"
  },
  {
    "path": "GuardProcessSample/app/src/main/res/values-w820dp/dimens.xml",
    "chars": 364,
    "preview": "<resources>\r\n    <!-- Example customization of dimensions originally defined in res/values/dimens.xml\r\n         (such as"
  },
  {
    "path": "GuardProcessSample/app/src/test/java/com/hejunlin/guardprocesssample/ExampleUnitTest.java",
    "chars": 338,
    "preview": "package com.hejunlin.guardprocesssample;\r\n\r\nimport org.junit.Test;\r\n\r\nimport static org.junit.Assert.*;\r\n\r\n/**\r\n * To wo"
  },
  {
    "path": "GuardProcessSample/build.gradle",
    "chars": 521,
    "preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\r\n\r\nbuildscript {\r\n  "
  },
  {
    "path": "GuardProcessSample/gradle/wrapper/gradle-wrapper.properties",
    "chars": 231,
    "preview": "#Mon Dec 28 10:00:20 PST 2015\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
  },
  {
    "path": "GuardProcessSample/gradle.properties",
    "chars": 872,
    "preview": "# Project-wide Gradle settings.\r\n\r\n# IDE (e.g. Android Studio) users:\r\n# Gradle settings configured through the IDE *wil"
  },
  {
    "path": "GuardProcessSample/gradlew",
    "chars": 4971,
    "preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start "
  },
  {
    "path": "GuardProcessSample/gradlew.bat",
    "chars": 2404,
    "preview": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@r"
  },
  {
    "path": "GuardProcessSample/settings.gradle",
    "chars": 16,
    "preview": "include ':app'\r\n"
  },
  {
    "path": "LICENSE",
    "chars": 11357,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "MediaCodcSample/.gitignore",
    "chars": 105,
    "preview": "*.iml\r\n.gradle\r\n/local.properties\r\n/.idea/workspace.xml\r\n/.idea/libraries\r\n.DS_Store\r\n/build\r\n/captures\r\n"
  },
  {
    "path": "MediaCodcSample/app/.gitignore",
    "chars": 8,
    "preview": "/build\r\n"
  },
  {
    "path": "MediaCodcSample/app/build.gradle",
    "chars": 655,
    "preview": "apply plugin: 'com.android.application'\r\n\r\nandroid {\r\n    compileSdkVersion 23\r\n    buildToolsVersion \"23.0.3\"\r\n\r\n    de"
  },
  {
    "path": "MediaCodcSample/app/proguard-rules.pro",
    "chars": 661,
    "preview": "# Add project specific ProGuard rules here.\r\n# By default, the flags in this file are appended to flags specified\r\n# in "
  },
  {
    "path": "MediaCodcSample/app/src/androidTest/java/com/hejunlin/mediacodcsample/ApplicationTest.java",
    "chars": 371,
    "preview": "package com.hejunlin.mediacodcsample;\r\n\r\nimport android.app.Application;\r\nimport android.test.ApplicationTestCase;\r\n\r\n/*"
  },
  {
    "path": "MediaCodcSample/app/src/main/AndroidManifest.xml",
    "chars": 836,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    packag"
  },
  {
    "path": "MediaCodcSample/app/src/main/java/com/hejunlin/mediacodcsample/MainActivity.java",
    "chars": 7071,
    "preview": "package com.hejunlin.mediacodcsample;\r\n\r\nimport android.media.MediaCodec;\r\nimport android.media.MediaExtractor;\r\nimport "
  },
  {
    "path": "MediaCodcSample/app/src/main/res/layout/activity_main.xml",
    "chars": 724,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    "
  },
  {
    "path": "MediaCodcSample/app/src/main/res/values/colors.xml",
    "chars": 214,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<resources>\r\n    <color name=\"colorPrimary\">#3F51B5</color>\r\n    <color name=\"co"
  },
  {
    "path": "MediaCodcSample/app/src/main/res/values/dimens.xml",
    "chars": 216,
    "preview": "<resources>\r\n    <!-- Default screen margins, per the Android Design guidelines. -->\r\n    <dimen name=\"activity_horizont"
  },
  {
    "path": "MediaCodcSample/app/src/main/res/values/strings.xml",
    "chars": 81,
    "preview": "<resources>\r\n    <string name=\"app_name\">MediaCodcSample</string>\r\n</resources>\r\n"
  },
  {
    "path": "MediaCodcSample/app/src/main/res/values/styles.xml",
    "chars": 394,
    "preview": "<resources>\r\n\r\n    <!-- Base application theme. -->\r\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkAction"
  },
  {
    "path": "MediaCodcSample/app/src/main/res/values-w820dp/dimens.xml",
    "chars": 364,
    "preview": "<resources>\r\n    <!-- Example customization of dimensions originally defined in res/values/dimens.xml\r\n         (such as"
  },
  {
    "path": "MediaCodcSample/app/src/test/java/com/hejunlin/mediacodcsample/ExampleUnitTest.java",
    "chars": 335,
    "preview": "package com.hejunlin.mediacodcsample;\r\n\r\nimport org.junit.Test;\r\n\r\nimport static org.junit.Assert.*;\r\n\r\n/**\r\n * To work "
  },
  {
    "path": "MediaCodcSample/build.gradle",
    "chars": 521,
    "preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\r\n\r\nbuildscript {\r\n  "
  },
  {
    "path": "MediaCodcSample/gradle/wrapper/gradle-wrapper.properties",
    "chars": 231,
    "preview": "#Mon Dec 28 10:00:20 PST 2015\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
  },
  {
    "path": "MediaCodcSample/gradle.properties",
    "chars": 872,
    "preview": "# Project-wide Gradle settings.\r\n\r\n# IDE (e.g. Android Studio) users:\r\n# Gradle settings configured through the IDE *wil"
  },
  {
    "path": "MediaCodcSample/gradlew",
    "chars": 4971,
    "preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start "
  },
  {
    "path": "MediaCodcSample/gradlew.bat",
    "chars": 2404,
    "preview": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@r"
  },
  {
    "path": "MediaCodcSample/settings.gradle",
    "chars": 16,
    "preview": "include ':app'\r\n"
  },
  {
    "path": "MediaPlayerSample/app/build.gradle",
    "chars": 627,
    "preview": "apply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion 23\n    buildToolsVersion \"23.0.1\"\n\n    defaultC"
  },
  {
    "path": "MediaPlayerSample/app/proguard-rules.pro",
    "chars": 666,
    "preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /U"
  },
  {
    "path": "MediaPlayerSample/app/src/androidTest/java/com/hejunlin/mediaplayersample/ApplicationTest.java",
    "chars": 361,
    "preview": "package com.hejunlin.mediaplayersample;\n\nimport android.app.Application;\nimport android.test.ApplicationTestCase;\n\n/**\n "
  },
  {
    "path": "MediaPlayerSample/app/src/main/AndroidManifest.xml",
    "chars": 763,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package="
  },
  {
    "path": "MediaPlayerSample/app/src/main/java/com/hejunlin/mediaplayersample/MainActivity.java",
    "chars": 5700,
    "preview": "package com.hejunlin.mediaplayersample;\n\n\nimport android.media.AudioManager;\nimport android.media.MediaPlayer;\nimport an"
  },
  {
    "path": "MediaPlayerSample/app/src/main/res/layout/activity_main.xml",
    "chars": 2432,
    "preview": "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\r\n    xmlns:tools=\"http://schemas.android.com/to"
  },
  {
    "path": "MediaPlayerSample/app/src/main/res/menu/menu_main.xml",
    "chars": 309,
    "preview": "<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\" tool"
  },
  {
    "path": "MediaPlayerSample/app/src/main/res/values/dimens.xml",
    "chars": 211,
    "preview": "<resources>\n    <!-- Default screen margins, per the Android Design guidelines. -->\n    <dimen name=\"activity_horizontal"
  },
  {
    "path": "MediaPlayerSample/app/src/main/res/values/strings.xml",
    "chars": 187,
    "preview": "<resources>\n    <string name=\"app_name\">MediaPlayerSample</string>\n\n    <string name=\"hello_world\">Hello world!</string>"
  },
  {
    "path": "MediaPlayerSample/app/src/main/res/values/styles.xml",
    "chars": 197,
    "preview": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"android:Theme.Holo.Light.DarkAction"
  },
  {
    "path": "MediaPlayerSample/app/src/main/res/values-v21/styles.xml",
    "chars": 143,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <style name=\"AppTheme\" parent=\"android:Theme.Material.Light\">\n   "
  },
  {
    "path": "MediaPlayerSample/app/src/main/res/values-w820dp/dimens.xml",
    "chars": 358,
    "preview": "<resources>\n    <!-- Example customization of dimensions originally defined in res/values/dimens.xml\n         (such as s"
  },
  {
    "path": "MediaPlayerSample/build.gradle",
    "chars": 436,
    "preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n    r"
  },
  {
    "path": "MediaPlayerSample/gradle/wrapper/gradle-wrapper.properties",
    "chars": 230,
    "preview": "#Tue Aug 30 23:43:56 CST 2016\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
  },
  {
    "path": "MediaPlayerSample/gradle.properties",
    "chars": 855,
    "preview": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will o"
  },
  {
    "path": "MediaPlayerSample/gradlew",
    "chars": 5080,
    "preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start "
  },
  {
    "path": "MediaPlayerSample/gradlew.bat",
    "chars": 2404,
    "preview": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@r"
  },
  {
    "path": "MediaPlayerSample/settings.gradle",
    "chars": 15,
    "preview": "include ':app'\n"
  },
  {
    "path": "README.md",
    "chars": 1127,
    "preview": "# MultiMediaSample\n\n###Android Multimediaܽ᰸MediaPlayer,Camera\n\n1.CameraԶ\n------------\n![MultiMediaSample](/images/camera"
  },
  {
    "path": "VideoWaterMarkSample/.gitignore",
    "chars": 97,
    "preview": "*.iml\n.gradle\n/local.properties\n/.idea/workspace.xml\n/.idea/libraries\n.DS_Store\n/build\n/captures\n"
  },
  {
    "path": "VideoWaterMarkSample/.idea/compiler.xml",
    "chars": 727,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"CompilerConfiguration\">\n    <resourceExt"
  },
  {
    "path": "VideoWaterMarkSample/.idea/copyright/profiles_settings.xml",
    "chars": 76,
    "preview": "<component name=\"CopyrightManager\">\r\n  <settings default=\"\" />\r\n</component>"
  },
  {
    "path": "VideoWaterMarkSample/.idea/encodings.xml",
    "chars": 159,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"Encoding\">\n    <file url=\"PROJECT\" chars"
  },
  {
    "path": "VideoWaterMarkSample/.idea/gradle.xml",
    "chars": 626,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"GradleSettings\">\n    <option name=\"linke"
  },
  {
    "path": "VideoWaterMarkSample/.idea/libraries/animated_vector_drawable_23_3_0.xml",
    "chars": 647,
    "preview": "<component name=\"libraryTable\">\r\n  <library name=\"animated-vector-drawable-23.3.0\">\r\n    <CLASSES>\r\n      <root url=\"fil"
  },
  {
    "path": "VideoWaterMarkSample/.idea/libraries/appcompat_v7_23_3_0.xml",
    "chars": 587,
    "preview": "<component name=\"libraryTable\">\r\n  <library name=\"appcompat-v7-23.3.0\">\r\n    <CLASSES>\r\n      <root url=\"jar://$PROJECT_"
  },
  {
    "path": "VideoWaterMarkSample/.idea/libraries/hamcrest_core_1_3.xml",
    "chars": 526,
    "preview": "<component name=\"libraryTable\">\r\n  <library name=\"hamcrest-core-1.3\">\r\n    <CLASSES>\r\n      <root url=\"jar://$USER_HOME$"
  },
  {
    "path": "VideoWaterMarkSample/.idea/libraries/junit_4_12.xml",
    "chars": 477,
    "preview": "<component name=\"libraryTable\">\r\n  <library name=\"junit-4.12\">\r\n    <CLASSES>\r\n      <root url=\"jar://$USER_HOME$/.gradl"
  },
  {
    "path": "VideoWaterMarkSample/.idea/libraries/support_annotations_23_3_0.xml",
    "chars": 499,
    "preview": "<component name=\"libraryTable\">\r\n  <library name=\"support-annotations-23.3.0\">\r\n    <CLASSES>\r\n      <root url=\"jar://G:"
  },
  {
    "path": "VideoWaterMarkSample/.idea/libraries/support_v4_23_3_0.xml",
    "chars": 731,
    "preview": "<component name=\"libraryTable\">\r\n  <library name=\"support-v4-23.3.0\">\r\n    <CLASSES>\r\n      <root url=\"jar://$PROJECT_DI"
  },
  {
    "path": "VideoWaterMarkSample/.idea/libraries/support_vector_drawable_23_3_0.xml",
    "chars": 642,
    "preview": "<component name=\"libraryTable\">\r\n  <library name=\"support-vector-drawable-23.3.0\">\r\n    <CLASSES>\r\n      <root url=\"jar:"
  },
  {
    "path": "VideoWaterMarkSample/.idea/misc.xml",
    "chars": 1903,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectInspectionProfilesVisibleTreeStat"
  },
  {
    "path": "VideoWaterMarkSample/.idea/modules.xml",
    "chars": 377,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectModuleManager\">\n    <modules>\n   "
  },
  {
    "path": "VideoWaterMarkSample/.idea/runConfigurations.xml",
    "chars": 564,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"RunConfigurationProducerService\">\n    <o"
  },
  {
    "path": "VideoWaterMarkSample/.idea/workspace.xml",
    "chars": 146063,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"AndroidLogFilters\">\n    <option name=\"TO"
  },
  {
    "path": "VideoWaterMarkSample/app/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "VideoWaterMarkSample/app/build.gradle",
    "chars": 626,
    "preview": "apply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion 23\n    buildToolsVersion \"23.0.3\"\n\n    defaultC"
  },
  {
    "path": "VideoWaterMarkSample/app/proguard-rules.pro",
    "chars": 645,
    "preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in D:"
  },
  {
    "path": "VideoWaterMarkSample/app/src/main/AndroidManifest.xml",
    "chars": 1059,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package="
  },
  {
    "path": "VideoWaterMarkSample/app/src/main/java/com/hejunlin/videorecord/ColorFormatUtil.java",
    "chars": 5169,
    "preview": "package com.hejunlin.videorecord;\n\nimport android.graphics.Bitmap;\nimport android.graphics.BitmapFactory;\nimport android"
  },
  {
    "path": "VideoWaterMarkSample/app/src/main/java/com/hejunlin/videorecord/MainActivity.java",
    "chars": 3974,
    "preview": "package com.hejunlin.videorecord;\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.os.Environmen"
  },
  {
    "path": "VideoWaterMarkSample/app/src/main/java/com/hejunlin/videorecord/TakeVideoActivity.java",
    "chars": 16309,
    "preview": "package com.hejunlin.videorecord;\n\nimport android.app.Activity;\nimport android.content.Intent;\nimport android.graphics.B"
  },
  {
    "path": "VideoWaterMarkSample/app/src/main/java/com/hejunlin/videorecord/VideoCodecModel.java",
    "chars": 1206,
    "preview": "package com.hejunlin.videorecord;\n\nimport java.io.Serializable;\n\npublic class VideoCodecModel implements Serializable {\n"
  },
  {
    "path": "VideoWaterMarkSample/app/src/main/java/com/hejunlin/videorecord/VideoCodecTask.java",
    "chars": 19407,
    "preview": "package com.hejunlin.videorecord;\n\nimport android.annotation.TargetApi;\nimport android.graphics.Bitmap;\nimport android.g"
  },
  {
    "path": "VideoWaterMarkSample/app/src/main/res/drawable/diverde.xml",
    "chars": 225,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <size\n    "
  },
  {
    "path": "VideoWaterMarkSample/app/src/main/res/drawable/litte_red_point.xml",
    "chars": 251,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<shape xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:sha"
  },
  {
    "path": "VideoWaterMarkSample/app/src/main/res/drawable/play.xml",
    "chars": 245,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<selector xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item a"
  },
  {
    "path": "VideoWaterMarkSample/app/src/main/res/drawable/progressbar_drawable.xml",
    "chars": 753,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<layer-list xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n    <ite"
  },
  {
    "path": "VideoWaterMarkSample/app/src/main/res/layout/activity_main.xml",
    "chars": 1415,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmln"
  },
  {
    "path": "VideoWaterMarkSample/app/src/main/res/layout/activity_take_video.xml",
    "chars": 3057,
    "preview": "<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/t"
  },
  {
    "path": "VideoWaterMarkSample/app/src/main/res/values/colors.xml",
    "chars": 208,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"color"
  },
  {
    "path": "VideoWaterMarkSample/app/src/main/res/values/dimens.xml",
    "chars": 211,
    "preview": "<resources>\n    <!-- Default screen margins, per the Android Design guidelines. -->\n    <dimen name=\"activity_horizontal"
  },
  {
    "path": "VideoWaterMarkSample/app/src/main/res/values/strings.xml",
    "chars": 83,
    "preview": "<resources>\n    <string name=\"app_name\">VideoWaterMarkSample</string>\n</resources>\n"
  },
  {
    "path": "VideoWaterMarkSample/app/src/main/res/values/styles.xml",
    "chars": 382,
    "preview": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar"
  },
  {
    "path": "VideoWaterMarkSample/app/src/main/res/values-w820dp/dimens.xml",
    "chars": 358,
    "preview": "<resources>\n    <!-- Example customization of dimensions originally defined in res/values/dimens.xml\n         (such as s"
  },
  {
    "path": "VideoWaterMarkSample/build.gradle",
    "chars": 498,
    "preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n    r"
  },
  {
    "path": "VideoWaterMarkSample/gradle/wrapper/gradle-wrapper.properties",
    "chars": 231,
    "preview": "#Mon Dec 28 10:00:20 PST 2015\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
  },
  {
    "path": "VideoWaterMarkSample/gradle.properties",
    "chars": 832,
    "preview": "## Project-wide Gradle settings.\n#\n# For more details on how to configure your build environment visit\n# http://www.grad"
  },
  {
    "path": "VideoWaterMarkSample/gradlew",
    "chars": 4971,
    "preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start "
  },
  {
    "path": "VideoWaterMarkSample/gradlew.bat",
    "chars": 2314,
    "preview": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem "
  },
  {
    "path": "VideoWaterMarkSample/settings.gradle",
    "chars": 15,
    "preview": "include ':app'\n"
  }
]

// ... and 6 more files (download for full content)

About this extraction

This page contains the full source code of the hejunlin2013/MultiMediaSample GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 151 files (364.0 KB), approximately 97.3k tokens, and a symbol index with 200 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!