美文网首页
android异或加密

android异或加密

作者: 星_025f | 来源:发表于2020-07-04 11:08 被阅读0次
    异或加密 参考文档:https://www.cnblogs.com/whoislcj/p/5944917.html
    音频播放 参考文档:https://www.jianshu.com/p/74fa2b1ac61f
    什么是异或加密?

    异或运算中,如果某个字符(或数值)x 与 一个数值m 进行异或运算得到y,则再用y 与 m 进行异或运算就可以还原为 x ,因此应用这个原理可以实现数据的加密解密功能。

    异或运算使用场景?

    两个变量的互换(不借助第三个变量)

    数据的简单加密解密

    异或加密解密实现?

    1.固定key的方式

    这种方式加密解密 算法一样

    public byte[] encrypt(byte[] bytes) {
    
            if (bytes == null) {
    
                return null;
    
            }
    
            int len = bytes.length;
    
            int key = 0x12;
    
            for (int i = 0; i < len; i++) {
    
                bytes[i] ^= key;
    
            }
    
            return bytes;
    
        }
    

    测试加密解密

    //加密
    
    byte[] bytes = encrypt("whoislcj".getBytes());
    
    //加密
    
    String str1 =newString(encrypt(bytes));//解密
    

    2.不固定key的方式

    加密实现

    publicbyte[] encrypt(byte[] bytes) {
    
            if(bytes ==null) {
    
                returnnull;
    
            }
    
            intlen = bytes.length;
    
            intkey = 0x12;
    
            for(inti = 0; i < len; i++) {
    
                bytes[i] = (byte) (bytes[i] ^ key);
    
                key = bytes[i];
    
            }
    
            return bytes;
    
        }
    

    解密实现

    publicbyte[] decrypt(byte[] bytes) {
    
            if(bytes ==null) {
    
                returnnull;
    
            }
    
            intlen = bytes.length;
    
            intkey = 0x12;
    
            for(inti = len - 1; i > 0; i--) {
    
                bytes[i] = (byte) (bytes[i] ^ bytes[i - 1]);
    
            }
    
            bytes[0] = (byte) (bytes[0] ^ key);
    
            return bytes;
    
        }
    

    测试

    byte[] bytes = encrypt("whoislcj".getBytes());//加密
    
    String str1 =newString(decrypt(bytes));//解密
    
    运用

    1.文本加密

    //写入文件
    public static void setFileContent(String path,String value,boolean append){
    
    boolean isFirst =false;
    
        File file =new File(path);
    
        if(!file.exists()){
    
    try {
    
    file.createNewFile();
    
            }catch (IOException e) {
    
    e.printStackTrace();
    
            }
    
    isFirst =true;
    
        }
    
    try {
    
    FileOutputStream outputStream =new FileOutputStream(path,append);
    
            //文件第一次创建 写入加密头部信息
    
            if(isFirst){
             //读取头部信息判断文件被加密
              byte[] titleByte = {'a','b','c','d','e','f'};
    
                outputStream.write(titleByte);
    
            }
    
    byte[] valueArray = value.getBytes();
    
            byte[] result =encrypt(valueArray);
    
            outputStream.write(result);
    
            outputStream.close();
    
        }catch (FileNotFoundException e) {
    
    e.printStackTrace();
    
        }catch (IOException e) {
    
    e.printStackTrace();
    
        }
    
    }
    //读取文件
    public static String  getFileMag(String filePath){
            StringBuffer stringBuffer = new StringBuffer();
            byte[] bytes = new byte[1024];
            byte[] bytes2;
            try {
                FileInputStream inputStream = new FileInputStream(filePath);
                int index;
                while ((index = inputStream.read(bytes)) != -1) {
                   //如果数据比较大,第一次读取去除前面加密的字节
                    bytes2 = new byte[index - 6];
                    System.arraycopy(bytes, 6, bytes2, 0,index - 6);
                    stringBuffer.append(new String(encrypt(bytes2)));
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return stringBuffer.toString();
        }
    
     public static byte[] encrypt(byte[] bytes) {
            if (bytes == null) {
                return null;
            }
           byte[] titleByte = {'a','b','c','d','e','f'};
            int len = bytes.length;
            Log.e(TAG, "encrypt: len == " + len);
            for (int i = 0; i < len; i++) {
               /*
              //使用位置进行判断加密,如果多次往同一个文件中写数据会导致数据错乱。123  456分两次写。4写进去下标为1,读出来下标为2 
              if(i % 2 == 0){
                    bytes[i] ^= titleByte[1];
                }else{
                    bytes[i] ^= titleByte[0];
                }*/
                int ii =  bytes[i];
                bytes[i] ^= titleByte[0];
            }
            return bytes;
        }
    

    2.图片加密

    1.SurfaceView + camera进行拍照。
    2.onPictureTaken回调中对data数据进行加密保存
    3.读取文件存在byte数组,解密后转化成bitmap。显示在imageview

    
    
    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.Surface;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;
    import android.view.View;
    import android.widget.Button;
    
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class CameraActivity extends AppCompatActivity implements SurfaceHolder.Callback, Camera.PictureCallback {
    
        private SurfaceView surface_view;
        private SurfaceHolder surfaceHolder;
        private Camera camera;
    
        private static String TAG = "CameraActivity";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_camera);
    
    
            surface_view = findViewById(R.id.surface_view);
    
    
            surfaceHolder = surface_view.getHolder();
    
            surfaceHolder.addCallback(this);
    
        }
    
    
        public void take_photo(View view){
    
            if (camera != null) {
                camera.takePicture(null, null,this);
            }
    
        }
    
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
    
            camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
            Camera.Parameters parameters = camera.getParameters();
            parameters.setPictureSize(1920,1080);
    
    
           // camera.setDisplayOrientation(90);
            try {
                camera.setPreviewDisplay(surfaceHolder);
                camera.setPreviewCallback(new Camera.PreviewCallback() {
                    @Override
                    public void onPreviewFrame(byte[] data, Camera camera) {
    
                    }
                });
    
                camera.startPreview();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    
        }
    
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
    
            if(camera != null){
                camera.release();
                camera = null;
            }
        }
    
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
    
            Log.e(TAG, "onPictureTaken: " + data.length);
    
            String photoPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/11.png";
    
            File photoFile = new File(photoPath);
            if(photoFile.exists()){
                photoFile.delete();
            }
            try {
                photoFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
    
            try {
                FileOutputStream outputStream = new FileOutputStream(photoFile);
                outputStream.write(encrypt2(data));
                //outputStream.write(data);
    
                outputStream.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
    
    
        public static byte[] encrypt2(byte[] bytes) {
            if (bytes == null) {
                return null;
            }
            byte[] titleByte = {'a','b','c','d','e','f'};
            int len = bytes.length;
            Log.e(TAG, "encrypt: len == " + len);
            for (int i = 0; i < len; i++) {
                bytes[i] ^= titleByte[0];
            }
            return bytes;
        }
    }
    
    
    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".CameraActivity">
    
        <SurfaceView
            android:id="@+id/surface_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    
        <Button
            android:onClick="take_photo"
            android:text="拍照"
            android:layout_marginBottom="20dp"
            android:layout_centerHorizontal="true"
            android:layout_alignParentBottom="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    
    
    </RelativeLayout>
    
    public void look_camera(View view){
            String photoPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/11.png";
            final byte[] aaa = imageToByteArray(photoPath);
    
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Bitmap bitmap = BitmapFactory.decodeByteArray(aaa,0,aaa.length);
                    iv_image.setImageBitmap(bitmap);
                }
            });
    
    
        }
    
     public static byte[] imageToByteArray(String path) {
            // 将图片文件转化为字节数组字符串,并对其进行Base64编码处理
            byte[] data = null;
            // 读取图片字节数组
            try {
    
                InputStream in = new FileInputStream(path);
    
                data = new byte[in.available()];
    
                in.read(data);
    
    
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            return encrypt2(data);
        }
    

    3.音频加密

    1.采用AudioRecord录制文件的pcm裸数据
    2.增加头部信息,加密编译成MP4文件。(头部信息也要加密转换,不能还是能够播放,有杂音但是能听清)
    3.使用audioTrack读取文件byte数据,直接write播放

    1.录制
    public class RecordService extends Service {
    
    
        MainActivity mainActivity;
        // 音频获取源
        private int audioSource = MediaRecorder.AudioSource.MIC;
        // 设置音频采样率,44100是目前的标准,但是某些设备仍然支持22050,16000,11025
        private static int sampleRateInHz = 44100;
        // 设置音频的录制的声道CHANNEL_IN_STEREO为双声道,CHANNEL_CONFIGURATION_MONO为单声道
        private static int channelConfig = AudioFormat.CHANNEL_IN_STEREO;
        // 音频数据格式:PCM 16位每个样本。保证设备支持。PCM 8位每个样本。不一定能得到设备支持。
        private static int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
        // 缓冲区字节大小
        private int bufferSizeInBytes = 0;
        private AudioRecord audioRecord;
        public static boolean isRecord = false;// 设置正在录制的状态
        public static boolean isAVRecord = false;// 判断视频是否正在录制
    
        private String TAG = "RecordService";
    
    
        private File file;
        private String audioFile;
        private String newAudioFile;
        private File[] files;//获取路劲文件下的所有文件数组
        private List<String> fileDatas;//存储所有文件的路劲名
        private List<String> fileNames;//存储所有文件的文件名
    
        private String rawFile;
        private String rawName;
        private String rawNameRes;
        private Timer timer, setTvTime;
        private String audioName;
        private String audioFile1;
        //private ToneGenerator toneGenerator;
    
        @Override
        @Deprecated
        public void onStart(Intent intent, int startId) {
            // TODO Auto-generated method stub
            super.onStart(intent, startId);
    
    
        }
    
    
        @Override
        public IBinder onBind(Intent intent) {
            // TODO: Return the communication channel to the service.
    
            Log.d(TAG, "onBind: ");
            return new MyBinder();
        }
    
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
    
            startRecorder();
            return super.onStartCommand(intent, flags, startId);
        }
    
        @Override
        public void onDestroy() {
            Log.d(TAG, "onDestroy: ");
            super.onDestroy();
            close();
            //把没有转换的裸文件转换
            getDatas();
            rawToWav();
            isAVRecord = false;
        }
    
        public void setActivity(MainActivity mainActivity) {
    
            this.mainActivity = mainActivity;
    
        }
    
    
        public class MyBinder extends Binder {
    
            public RecordService getService() {
    
                return RecordService.this;
    
            }
    
        }
    
    
        /**
         * 开始录制操作
         */
        public void startRecorder() {
            Log.e(TAG, "wfx ---->> startRecorder");
            createNewFile();
            creatAudioRecord();
            audioRecord.startRecording();
            // 让录制状态为true
            isRecord = true;
            // 开启音频文件写入线程
            new Thread(new AudioRecordThread()).start();
            //创建一个timer类来实现录制时间实现
            setTvTime = new Timer();
            setTvTime.schedule(new TimerTask() {
                long duration = 0;
                @Override
                public void run() {
                    duration += 1000;
                    if(MainActivity.isVisible){
                        Message message = new Message();
                        message.obj = duration;
                        message.what = 333;
                        MainActivity.handler.sendMessage(message);
                    }
    
                }
            }, 1000, 1000);
        }
    
        /**
         * 停止录音操作
         */
        public void stopRecorder() {
            close();
        }
    
        public void close() {
            if (audioRecord != null) {         
                if (setTvTime != null) {
                    setTvTime.cancel();
                    setTvTime = null;
                }
                if (timer != null) {
                    timer.cancel();
                    timer = null;
                }
                if (audioRecord != null) {
                    isRecord = false;//停止文件写入
                    audioRecord.stop();
                    audioRecord.release();//释放资源
                    audioRecord = null;
                    //把没有转换的裸文件转换
                    getDatas();
                    rawToWav();
                }
            }
        }
    
    
        public void creatAudioRecord() {
            if (audioRecord != null) {
                stopRecorder();
            }
            // 获得缓冲区字节大小
            bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz,
                    channelConfig, audioFormat);
            // 创建AudioRecord对象
            audioRecord = new AudioRecord(audioSource, sampleRateInHz,
                    channelConfig, audioFormat, bufferSizeInBytes);
        }
    
    
        class AudioRecordThread implements Runnable {
            @Override
            public void run() {
                writeDateTOFile();//往文件中写入裸数据
            }
        }
    
        FileOutputStream fos = null;
        /**
         * 这里将数据写入文件,但是并不能播放,因为AudioRecord获得的音频是原始的裸音频,
         * 如果需要播放就必须加入一些格式或者编码的头信息。但是这样的好处就是你可以对音频的 裸数据进行处理,
         * 比如你要做一个爱说话的TOM
         * 在这里就进行音频的处理,然后重新封装 所以说这样得到的音频比较容易做一些音频的处理。
         */
        private void writeDateTOFile() {
            MyApplication.recordingTime = MyApplication.recordingTimeSharedPreferences.getLong("recordingTime", 5 * 60 * 1000);
            audioFile = getAudioFile();//先创建一个存储裸数据的文件
            fos = null;
            try {
                file = new File(audioFile);
                fos = new FileOutputStream(file);// 建立一个可存取字节的文件
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (timer != null) {
                timer.cancel();
                timer = null;
            }
            timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    try {
                        fos.close();// 关闭写入流
                        audioFile = getAudioFile();//新建一个文件保存裸数据
                        file = new File(audioFile);
                        //Log.d("print", "run: 创建文件");
                        fos = new FileOutputStream(file);// 建立一个可存取字节的文件
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }, MyApplication.recordingTime, MyApplication.recordingTime);
           // }, 60 * 1000, 60 * 1000);
            while (isRecord) {
                // new一个byte数组用来存一些字节数据,大小为缓冲区大小
                byte[] audiodata = new byte[bufferSizeInBytes];
                int readsize = 0;
                //往文件中写入数据
                readsize = audioRecord.read(audiodata, 0, bufferSizeInBytes);
                if (AudioRecord.ERROR_INVALID_OPERATION != readsize) {
                    try {
                        fos.write(encrypt2(audiodata));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
    
            }
        }
        // 这里得到可播放的音频文件
        private void copyWaveFile(String inFilename, String outFilename) {
            FileInputStream in = null;
            FileOutputStream out = null;
            long totalAudioLen = 0;
            long totalDataLen = totalAudioLen + 36;
            long longSampleRate = sampleRateInHz;
            int channels = 2;
            long byteRate = 16 * sampleRateInHz * channels / 8;
            byte[] data = new byte[bufferSizeInBytes];
            try {
                in = new FileInputStream(inFilename);
                out = new FileOutputStream(outFilename);
                totalAudioLen = in.getChannel().size();
                totalDataLen = totalAudioLen + 36;
                WriteWaveFileHeader(out, totalAudioLen, totalDataLen,
                        longSampleRate, channels, byteRate);
                while (in.read(data) != -1) {
                  //  out.write(encrypt2(data));
                    out.write(data);
                }
                in.close();
                out.close();
                //删除裸数据文件
                File file = new File(inFilename);
                file.delete();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 这里提供一个头信息。插入这些信息就可以得到可以播放的文件。每种格式的文件都有
         * 自己特有的头文件。
         */
        private void WriteWaveFileHeader(FileOutputStream out, long totalAudioLen,
                                         long totalDataLen, long longSampleRate, int channels, long byteRate)
                throws IOException {
            Log.e(TAG, "WriteWaveFileHeader: totalAudioLen == " + totalAudioLen + "  totalDataLen == " + totalDataLen + "  longSampleRate" + longSampleRate
             +  "  channels== " + channels +  "  byteRate == " + byteRate);
            byte[] header = new byte[44];
            header[0] = 'R'; // RIFF/WAVE header
            header[1] = 'I';
            header[2] = 'F';
            header[3] = 'F';
            header[4] = (byte) (totalDataLen & 0xff);
            header[5] = (byte) ((totalDataLen >> 8) & 0xff);
            header[6] = (byte) ((totalDataLen >> 16) & 0xff);
            header[7] = (byte) ((totalDataLen >> 24) & 0xff);
            header[8] = 'W';
            header[9] = 'A';
            header[10] = 'V';
            header[11] = 'E';
            header[12] = 'f'; // 'fmt ' chunk
            header[13] = 'm';
            header[14] = 't';
            header[15] = ' ';
            header[16] = 16; // 4 bytes: size of 'fmt ' chunk
            header[17] = 0;
            header[18] = 0;
            header[19] = 0;
            header[20] = 1; // format = 1
            header[21] = 0;
            header[22] = (byte) channels;
            header[23] = 0;
            header[24] = (byte) (longSampleRate & 0xff);
            header[25] = (byte) ((longSampleRate >> 8) & 0xff);
            header[26] = (byte) ((longSampleRate >> 16) & 0xff);
            header[27] = (byte) ((longSampleRate >> 24) & 0xff);
            header[28] = (byte) (byteRate & 0xff);
            header[29] = (byte) ((byteRate >> 8) & 0xff);
            header[30] = (byte) ((byteRate >> 16) & 0xff);
            header[31] = (byte) ((byteRate >> 24) & 0xff);
            header[32] = (byte) (2 * 16 / 8); // block align
            header[33] = 0;
            header[34] = 16; // bits per sample
            header[35] = 0;
            header[36] = 'd';
            header[37] = 'a';
            header[38] = 't';
            header[39] = 'a';
            header[40] = (byte) (totalAudioLen & 0xff);
            header[41] = (byte) ((totalAudioLen >> 8) & 0xff);
            header[42] = (byte) ((totalAudioLen >> 16) & 0xff);
            header[43] = (byte) ((totalAudioLen >> 24) & 0xff);
            out.write(encrypt2(header), 0, 44);
          // out.write(header, 0, 44);
        }
        /**
         * @return:得到裸数据文件
         */
        private String getAudioFile() {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd_hh-mm-ss");//定义时间格式
            String time = format.format(new Date());//把当前时间转化为指定格式
            audioName = MyApplication.getnowTimeFileName() + "/"  + getPoliceNum() + "_" +time ;
            audioFile1 = audioName + CameraSettings.RECROD_DEFAULT.FILE_RAW;
            
    
            return audioFile1;
        }
    
    
        /**
         * @return:得到新文件
         */
        private String getNewAudioFile(String name) {
            String newAudioFile = MyApplication.getnowTimeFileName() +  "/" + name + ".wav";
            return newAudioFile;
        }
    
        /**
         * 得到目录下所有文件
         */
        private List<File> getAllFile(String name) {
            List<File> fileList = new ArrayList<>();
            File parentFile = new File(name);
            File[] tempList = parentFile.listFiles();
            for (int i = 0; i < tempList.length; i++) {
                if(tempList[i].isDirectory()){
                    fileList.add(tempList[i]);
                }
            }
            return fileList;
    
        }
    
        /**
         * 获取路径下的所有.raw文件
         */
        public void getDatas() {
           // String fileName = MyApplication.getnowTimeFileName();
           // File file = new File(fileName);
            List<File> fileResultList = getAllFile(CameraSettings.RECROD_DEFAULT.DEFAULT_CARD+File.separator+CameraSettings.RECROD_DEFAULT.AUDIO_DIR);
            fileDatas = new ArrayList<>();
            fileNames = new ArrayList<>();
            for (int j = 0; j < fileResultList.size();j++) {
                File file = fileResultList.get(j);
    
                files = getFiles(file);
                if(files == null ){
                    return ;
                }
                for (int i = 0; i < files.length; i++) {
                    String fileS = files[i].getName().substring(
                            files[i].getName().indexOf("."));
                    if (fileS.toLowerCase().equals(".raw")) {
                        //获取路径
                        fileDatas.add(files[i].getPath());
                        //获取文件名
                        fileNames.add(files[i].getName());
                    }
                }
    
            }
    
        }
    
    
        /**
         * 把raw文件转换成wav文件
         */
        public void rawToWav() {
            for (int i = 0; i < fileDatas.size(); i++) {
                //获取路径
                rawFile = fileDatas.get(i);
                //获取文件名
                rawName = fileNames.get(i);
                rawNameRes = rawName.substring(0, rawName.length() - 4);
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                       // copyWaveFile(rawFile, getNewAudioFile(rawNameRes));
                        Log.d(TAG, "run: " + rawFile.substring(0, rawFile.length() - 4)  + ".wav");
                        copyWaveFile(rawFile, rawFile.substring(0, rawFile.length() - 4)  + ".wav");
                    }
                }).start();
                SystemClock.sleep(20);
            }
        }
    
        /**
         * 得到文件下的所有文件数组
         *
         * @param file
         * @return
         */
        public File[] getFiles(File file) {
            File[] files = file.listFiles();
            return files;
        }
    
        /**
         * 创建存储录音文件的文件夹
         */
        public void createNewFile() {
            if (FileUtils.isExtrapositionSdState()) {
                File file = new File(MyApplication.getnowTimeFileName());
                if (!file.exists()) {// 如果不存在就创建
                    file.mkdirs();
                }
            } else {
                Toast.makeText(this, R.string.please_check_sd_card, Toast.LENGTH_LONG).show();
            }
        }
    
    
        public static byte[] encrypt2(byte[] bytes) {
            if (bytes == null) {
                return null;
            }
            byte[] titleByte = {'a','b','c','d','e','f'};
            int len = bytes.length;
            for (int i = 0; i < len; i++) {
                bytes[i] ^= titleByte[0];
            }
            return bytes;
        }
    
    }
    

    2.播放

    public class MUsicActivity extends AppCompatActivity implements View.OnClickListener {
    
        private Chronometer chronometer;
        int miss = 0;
        private Button btn_start,btn_stop,btn_play;
        private AudioTracker mAudioTracker;
        String audioFilePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/55.wav";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_m_usic);
    
            chronometer = findViewById(R.id.chronometer);
            btn_start = findViewById(R.id.btn_start);
            btn_stop = findViewById(R.id.btn_stop);
            btn_play = findViewById(R.id.btn_play);
    
    
            btn_start.setOnClickListener(this);
            btn_stop.setOnClickListener(this);
            btn_play.setOnClickListener(this);
    
            chronometer.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
                @Override
                public void onChronometerTick(Chronometer chronometer) {
                    miss++;
                    chronometer.setText(FormatMiss(miss));
                }
            });
    
    
        }
    
    
    
        public static String FormatMiss(int miss){
            String hh=miss/3600>9?miss/3600+"":"0"+miss/3600;
            String  mm=(miss % 3600)/60>9?(miss % 3600)/60+"":"0"+(miss % 3600)/60;
            String ss=(miss % 3600) % 60>9?(miss % 3600) % 60+"":"0"+(miss % 3600) % 60;
            return hh+":"+mm+":"+ss;
        }
    
        @Override
        public void onClick(View v) {
    
            switch (v.getId()){
    
                case R.id.btn_start:
    
                    mAudioTracker = new AudioTracker(this);
                    File pcmFile = new File(audioFilePath);
                    mAudioTracker.createAudioTrack(pcmFile.getAbsolutePath());
                    mAudioTracker.start();
    
                    break;
                case R.id.btn_stop:
    
                    try {
                        mAudioTracker.stop();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
    
                    break;
                case R.id.btn_play:
                    break;
    
            }
    
    
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            mAudioTracker.release();
        }
    }
    
    public class AudioTracker {
        private static final String TAG = "AudioTracker";
        // 采样率 44100Hz,所有设备都支持
        private final static int SAMPLE_RATE = 44100;
        // 单声道,所有设备都支持
        private final static int CHANNEL = AudioFormat.CHANNEL_IN_STEREO;
        // 位深 16 位,所有设备都支持
        private final static int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
        // 缓冲区字节大小
        private int mBufferSizeInBytes = 0;
        // 播放对象
        private AudioTrack mAudioTrack;
        // 文件名
        private String mFilePath;
        // 状态
        private volatile Status mStatus = Status.STATUS_NO_READY;
        // 单任务线程池
        private ExecutorService mExecutorService = Executors.newSingleThreadExecutor();
    
        private Handler mMainHandler = new Handler(Looper.getMainLooper());
    
        private Context mContext;
    
        public AudioTracker(Context context) {
            mContext = context;
        }
    
        public void createAudioTrack(String filePath) throws IllegalStateException {
            mFilePath = filePath;
            mBufferSizeInBytes = AudioTrack.getMinBufferSize(SAMPLE_RATE, CHANNEL, AUDIO_FORMAT);
            if (mBufferSizeInBytes <= 0) {
                throw new IllegalStateException("AudioTrack is not available " + mBufferSizeInBytes);
            }
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                mAudioTrack = new AudioTrack.Builder()
                        .setAudioAttributes(new AudioAttributes.Builder()
                                .setUsage(AudioAttributes.USAGE_MEDIA)
                                .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                                .setLegacyStreamType(AudioManager.STREAM_MUSIC)
                                .build())
                        .setAudioFormat(new AudioFormat.Builder()
                                .setEncoding(AUDIO_FORMAT)
                                .setSampleRate(SAMPLE_RATE)
                                .setChannelMask(CHANNEL)
                                .build())
                        .setTransferMode(AudioTrack.MODE_STREAM)
                        .setBufferSizeInBytes(mBufferSizeInBytes)
                        .build();
            } else {
                mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLE_RATE, CHANNEL, AUDIO_FORMAT,
                        mBufferSizeInBytes, AudioTrack.MODE_STREAM);
            }
            mStatus = Status.STATUS_READY;
        }
    
        /**
         * 开始播放
         */
        public void start() throws IllegalStateException {
            if (mStatus == Status.STATUS_NO_READY || mAudioTrack == null) {
                throw new IllegalStateException("播放器尚未初始化");
            }
            if (mStatus == Status.STATUS_START) {
                throw new IllegalStateException("正在播放...");
            }
            Log.d(TAG, "===start===");
            mExecutorService.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        playAudioData();
                    } catch (IOException e) {
                        Log.e(TAG, e.getMessage());
                        mMainHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(mContext, "播放出错", Toast.LENGTH_SHORT).show();
                            }
                        });
                    }
                }
            });
            mStatus = Status.STATUS_START;
        }
    
        private void playAudioData() throws IOException {
            InputStream dis = null;
            try {
                mMainHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(mContext, "播放开始", Toast.LENGTH_SHORT).show();
                    }
                });
                dis = new DataInputStream(new BufferedInputStream(new FileInputStream(mFilePath)));
                byte[] bytes = new byte[mBufferSizeInBytes];
                int length;
                mAudioTrack.play();
                // write 是阻塞的方法
                while ((length = dis.read(bytes)) != -1 && mStatus == Status.STATUS_START) {
                    mAudioTrack.write(encrypt2(bytes), 0, length);
                }
                mMainHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(mContext, "播放结束", Toast.LENGTH_SHORT).show();
                    }
                });
            } finally {
                if (dis != null) {
                    dis.close();
                }
            }
        }
    
        public void stop() throws IllegalStateException {
            Log.d(TAG, "===stop===");
            if (mStatus == Status.STATUS_NO_READY || mStatus == Status.STATUS_READY) {
                throw new IllegalStateException("播放尚未开始");
            } else {
                mStatus = Status.STATUS_STOP;
                mAudioTrack.stop();
                release();
            }
        }
    
        public void release() {
            Log.d(TAG, "==release===");
            mStatus = Status.STATUS_NO_READY;
            if (mAudioTrack != null) {
                mAudioTrack.release();
                mAudioTrack = null;
            }
        }
    
        /**
         * 播放对象的状态
         */
        public enum Status {
            //未开始
            STATUS_NO_READY,
            //预备
            STATUS_READY,
            //播放
            STATUS_START,
            //停止
            STATUS_STOP
        }
    
        public static byte[] encrypt2(byte[] bytes) {
            if (bytes == null) {
                return null;
            }
            byte[] titleByte = {'a','b','c','d','e','f'};
            int len = bytes.length;
            for (int i = 0; i < len; i++) {
                bytes[i] ^= titleByte[0];
            }
            return bytes;
        }
    }
    

    4.视频加密

    相关文章

      网友评论

          本文标题:android异或加密

          本文链接:https://www.haomeiwen.com/subject/grxuqktx.html