前言
上一篇完成了初步實現,當時說了要儘快加上相機拍照功能,於是乎,今天我又來啦。
上一篇的鏈接,已經不記得的小夥伴可以查看出處。
首先我還是對上篇進行一下部分的總結,可能誤導了一部分人,我引入的ocr-ui包沒有使用,確實,大家可以去掉,我本來沒看包裏什麼內容就先引用過來了,後來才發現根本沒用到0_0,其次類很簡單也只有兩個 Mainactivity和SimpleTextActivity,多餘的東西可以去掉。
話不多說看代碼
此次代碼就只貼SimpleTextActivity部分內容了,因爲這次的代碼裏面有很多註釋內容,就是我嘗試了種處理方法,但是沒有必要,所以都註釋了,但是這些代碼在別的地方可能需要,我並沒有刪除,方便自己下次記憶。對於大家來說沒有必要看這些亂七八糟的灰色註釋,於是我節選有用的代碼給大家分享一哈。
//從相冊選取圖片
findViewById(R.id.enhanced_photo).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (hasPermission()) {
Intent intent = new Intent(Intent.ACTION_PICK, null);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
startActivityForResult(intent, REQUEST_ENHANCED_CODE_ALBUM);
}
}
});
//拍照選取圖片
findViewById(R.id.enhanced_take_photo).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
takePhoto();
}
});
首先是兩個點擊事件,觸發一切的開始。點擊之後進行權限判斷,沒有權限的話打回!,拍照的權限放在takePhoto裏了。
/**
* 執行拍照
*/
private void takePhoto() {
if (!hasPermission()) {
return;
}
Intent intent = new Intent();
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
if (new File(path).exists()) {
try {
new File(path).createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
mTmpPath = path + "/temp.jpg";
mTmpFile = new File(mTmpPath);
mTmpFile.getParentFile().mkdirs();
Uri imageUri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
String authority = getPackageName() + ".provider";
imageUri = FileProvider.getUriForFile(SimpleTextActivity.this, authority, mTmpFile);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
List<ResolveInfo> resInfoList = this.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resInfoList) {
String packageName = resolveInfo.activityInfo.packageName;
this.grantUriPermission(packageName, imageUri, FLAG_GRANT_WRITE_URI_PERMISSION | FLAG_GRANT_READ_URI_PERMISSION);
}
} else {
imageUri = Uri.fromFile(mTmpFile);
}
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, REQUEST_ENHANCED_CODE_CAMERA);
}
其中mTmpFile和mTmpPath是成員變量,因爲下面傳遞需要。
順便把權限判斷的請求和回調都展示一下
/**
* 判斷是否有權限
* @return
*/
private boolean hasPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(this,Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.CAMERA}, REQUEST_PERIMISSION_CODE);
return false;
}else {
return true;
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_PERIMISSION_CODE) {
if (grantResults.length > 0) {
for (int grantResult: grantResults) {
if (grantResult == PackageManager.PERMISSION_DENIED) {
Toast.makeText(SimpleTextActivity.this, "拒絕權限將不能正常使用!", Toast.LENGTH_SHORT).show();
return;
}
}
}
}
}
然後在相機返回照片後的處理上,也是我當初不懂踩坑的地方。
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_ALBUM) {
// 從相冊返回的數據
if (data != null) {
// 得到圖片的全路徑
Uri uri = data.getData();
recSimpleText(getRealPathFromURI(uri));
}
} else if (requestCode == REQUEST_ENHANCED_CODE_ALBUM) {
// 從相冊返回的數據
if (data != null) {
// 得到圖片的全路徑
Uri uri = data.getData();
recEnhancedText(getRealPathFromURI(uri));
}
} else if (requestCode == REQUEST_ENHANCED_CODE_CAMERA) {
//相機返回
recEnhancedText(mTmpPath);
}
}
一開始我和上面一樣判斷data是否爲空然後從裏面取uri,但是一直都是空!後來很納悶爲什麼,但是我到現在也不知道爲什麼data返回就是空,然後看了一下別人的做法,並沒有從data裏面獲取uri!而是直接從上面的mTmpPath那直接獲取路徑,確實不用多此一舉!回頭想想也是,人傻了!
然後把provider的相關也貼一下,需要留意的是現在很多使用androidx,不用v4包了,照着網上的導肯定是要飈紅的。
這段貼在AndroidManifest.xml的<application>
中
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.kxqin.ocrtest.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
filepaths.xml
<resources>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path
name="camera_photos"
path="." />
</paths>
</resources>
不過我寫完了provider之後,有前輩說並不需要,我也不懂這個不需要是指哪部分代碼不需要還是說provider不需要?反正現在運行良好不報錯就行哈哈哈。
對了 ,還有一個需要注意的是,都加上豎屏鎖定吧,因爲在將識別後的文字展示之後,切換橫屏,文字就消失了。
//設置豎屏
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
放在onCreate裏。
關於佈局頁面,着實沒啥看的。
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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=".SimpleTextActivity" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/take_a_photo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="普通文字識別-拍照"
android:visibility="gone"/>
<Button
android:id="@+id/select_a_photo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="普通文字識別-相冊"/>
<Button
android:id="@+id/enhanced_photo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="高精度文字識別-相冊"/>
<Button
android:id="@+id/enhanced_take_photo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="高精度文字識別-拍照"/>
<TextView
android:id="@+id/info_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</ScrollView>
心滿意足了不?那我去瞅瞅百度人臉識別了,雖無遠大造輪志向,但是大佬們造好的輪子也得會用吧!