記一次Android掃碼經歷

作爲一枚新手,進公司第一天產品就告訴我,華爲手機掃碼有問題,讓我看看代碼準備修復吧,我覺得這不是小問題嗎?掃碼這玩意我已經玩過了,沒什麼難度。可是我看了之後傻眼了,怎麼會這樣,用的是zbar來寫的,華爲手機,掃碼界面模糊,除華爲手機以外,別的手機清晰而且靈敏,查了半天沒頭緒,沒辦法,重做吧。。。。太多廢話了,不說了,反正後面兜兜轉轉,還是重做了,還是用的zbar,封裝的很好的一個庫,由於需要開啓閃光燈功能,所以把庫中封裝好的代碼做了一些修改
看下主代碼吧

package com.lg.scandemo.zbar;

import android.content.DialogInterface;
import android.content.res.AssetFileDescriptor;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Vibrator;
import android.support.annotation.NonNull;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
import android.widget.TextView;

import com.lg.scandemo.R;
import com.yanzhenjie.permission.AndPermission;
import com.yanzhenjie.permission.PermissionListener;
import com.yanzhenjie.zbar.camera.ScanCallback;

import java.io.IOException;
import java.util.List;

/**
 * Created by Administrator on 2017/7/31.
 */

public class ZBarScanActivity extends AppCompatActivity {

    private CameraPreview mPreviewView;

    private MediaPlayer mediaPlayer;
    private boolean playBeep;
    private static final float BEEP_VOLUME = 0.10f;
    private boolean vibrate;

    private ImageView ivLightControl;
    private TextView tvLightStatus;
    private boolean flag = false;
    private CameraManager cameraManager;
    private InactivityTimer inactivityTimer;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_qr_scan);
        initView();

        mPreviewView = (CameraPreview) findViewById(R.id.capture_preview);
        ImageView mScanLine = (ImageView) findViewById(R.id.capture_scan_line);

        inactivityTimer = new InactivityTimer(this);

        TranslateAnimation animation = new TranslateAnimation(
                Animation.RELATIVE_TO_PARENT, 0.0f,
                Animation.RELATIVE_TO_PARENT, 0.0f,
                Animation.RELATIVE_TO_PARENT, -1.0f,
                Animation.RELATIVE_TO_PARENT, 0.0f);
        animation.setDuration(4500);
        animation.setRepeatCount(-1);
        animation.setRepeatMode(Animation.RESTART);
        mScanLine.startAnimation(animation);

        mPreviewView.setScanCallback(resultCallback);
        cameraManager = mPreviewView.mCameraManager;
//        startScanUnKnowPermission();
    }

    /**
     * Accept scan result.
     */
    private ScanCallback resultCallback = new ScanCallback() {
        @Override
        public void onScanResult(String result) {
            stopScan();
            inactivityTimer.onActivity();
            // 播放掃描成功聲音
            playBeepSoundAndVibrate();
            dispatch(result);
        }
    };

    private void initView() {
        findViewById(R.id.title_left_btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ZBarScanActivity.this.finish();
            }
        });
        ivLightControl = (ImageView) findViewById(R.id.mo_scanner_light);
        tvLightStatus = (TextView) findViewById(R.id.light_status_tv);
        ivLightControl.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        // 閃光燈
                        if (!flag) { // 開啓
                            flag = true;
                            ivLightControl.setImageResource(R.drawable.scan_open);
                            tvLightStatus.setText("關燈");
                            cameraManager.openLight();
                        } else {  // 關閉
                            flag = false;
                            ivLightControl.setImageResource(R.drawable.scan_close);
                            tvLightStatus.setText("開燈");
                            cameraManager.offLight();
                        }
                    }
                });

    }

    private void dispatch(String result) {
        flag = false;
        cameraManager.offLight();
        ivLightControl.setImageResource(R.drawable.scan_close);
        tvLightStatus.setText("開燈");
        AlertDialog ad = new AlertDialog.Builder(this).create();
        ad.setTitle("掃描結果");
        ad.setIcon(R.mipmap.ic_launcher);
        ad.setMessage(result);
        ad.setButton(DialogInterface.BUTTON_POSITIVE, "確定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                // 這樣做是爲了演示如果onPause可以使用該方法重新進入掃描
                startScanUnKnowPermission();
            }
        });
        ad.show();
    }

    /**
     * 初始化聲音池
     */
    private void initBeepSound() {
        if (playBeep && mediaPlayer == null) {
            // The volume on STREAM_SYSTEM is not adjustable, and users found it
            // too loud,
            // so we now play on the music stream.
            setVolumeControlStream(AudioManager.STREAM_MUSIC);
            mediaPlayer = new MediaPlayer();
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            mediaPlayer.setOnCompletionListener(beepListener);

            AssetFileDescriptor file = getResources().openRawResourceFd(
                    R.raw.mo_scanner_beep);
            try {
                mediaPlayer.setDataSource(file.getFileDescriptor(),
                        file.getStartOffset(), file.getLength());
                file.close();
                mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME);
                mediaPlayer.prepare();
            } catch (IOException e) {
                mediaPlayer = null;
            }
        }
    }

    private static final long VIBRATE_DURATION = 200L;

    /**
     * 播放掃描結束聲音
     */
    private void playBeepSoundAndVibrate() {
        if (playBeep && mediaPlayer != null) {
            mediaPlayer.start();
        }
        if (vibrate) {
            Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
            vibrator.vibrate(VIBRATE_DURATION);
        }
    }

    /**
     * When the beep has finished playing, rewind to queue up another one.
     */
    private final MediaPlayer.OnCompletionListener beepListener = new MediaPlayer.OnCompletionListener() {

        public void onCompletion(MediaPlayer mediaPlayer) {
            mediaPlayer.seekTo(0);
        }
    };

    @Override
    protected void onResume() {
        super.onResume();
        inactivityTimer.onResume();
        startScanUnKnowPermission();

        playBeep = true;
        AudioManager audioService = (AudioManager) getSystemService(AUDIO_SERVICE);
        if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) {
            playBeep = false;
        }
        initBeepSound();
        vibrate = true;
    }

    @Override
    public void onPause() {
        // Must be called here, otherwise the camera should not be released properly.
        stopScan();
        inactivityTimer.onPause();
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        inactivityTimer.shutdown();
        super.onDestroy();
    }

    /**
     * Do not have permission to request for permission and start scanning.
     */
    private void startScanUnKnowPermission() {
        AndPermission.with(this)
                .permission(android.Manifest.permission.CAMERA)
                .callback(new PermissionListener() {
                    @Override
                    public void onSucceed(int requestCode, @NonNull List<String> grantPermissions) {
                        startScanWithPermission();
                    }

                    @Override
                    public void onFailed(int requestCode, @NonNull List<String> deniedPermissions) {
                        AndPermission.defaultSettingDialog(ZBarScanActivity.this).show();
                    }
                })
                .start();
    }

    /**
     * There is a camera when the direct scan.
     */
    private void startScanWithPermission() {
        if (!mPreviewView.start()) {
            new AlertDialog.Builder(this)
                    .setTitle(R.string.camera_failure)
                    .setMessage(R.string.camera_hint)
                    .setCancelable(false)
                    .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            finish();
                        }
                    })
                    .show();
        }
    }

    /**
     * Stop scan.
     */
    private void stopScan() {
        mPreviewView.stop();
    }
}

主要配置是build.gradle中dependencies中的這些

    // zbar的封裝
    compile 'com.yanzhenjie.zbar:zbar:1.0.0'
    // 相機的封裝
    compile 'com.yanzhenjie.zbar:camera:1.0.0'
    // 6.0權限的封裝,該項目中相機權限
    compile 'com.yanzhenjie:permission:1.0.7'

另外不要忘記AndroidMainfest中配置權限哦

    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.FLASHLIGHT" />
    <uses-permission android:name="android.permission.VIBRATE" />

其實主要是爲自己以後開發做準備,暫時先這樣寫吧
Demo下載地址:http://download.csdn.net/detail/alwaysgoalong/9917622

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章