版權宣告:本文為博主原創文章,未經博主允許不得轉載
系列教程:Android開發之從零開始系列
原始碼:AnliaLee/PhotoFactory,歡迎star
大家要是看到有錯誤的地方或者有啥好的建議,歡迎留言評論
初看標題是不是覺得博主是標題黨,故意把你們騙了進來?告訴你
博主幫大家封裝好了PhotoFactory類,只需三行程式碼就可以完成選擇照片,獲取其bitmap或uri路徑(可自行配置是否壓縮)的功能。下面來看下如何使用PhotoFactory
PhotoFactory簡介
使用PhotoFactory分為三步,首先我們要例項化一個photoFactory
PhotoFactory photoFactory = new PhotoFactory(this, this);//(Activity activity,Context context)
複製程式碼
設定選擇照片的方式
//提供三種選擇照片的方式
photoFactory.FactoryStart().SetStartType(PhotoFactory.TYPE_PHOTO_UNTREATED).Start();//呼叫相機拍照,照相後返回高清原圖相片
/*photoFactory.FactoryStart().SetStartType(PhotoFactory.TYPE_PHOTO_AUTO_COMPRESS).Start();//呼叫相機拍照,照相後返回系統自動壓縮過的相片
photoFactory.FactoryStart().SetStartType(PhotoFactory.TYPE_PHOTO_FROM_GALLERY).Start();//從本地相簿中選取圖片*/
複製程式碼
獲取相片bitmap或uri
/**
* 在onActivityResult中呼叫此方法
*/
photoFactory.FactoryFinish(requestCode,resultCode,data).GetBitmap();
//photoFactory.FactoryFinish(requestCode,resultCode,data).GetUri();
複製程式碼
就這麼簡單,當然,你還可以對照片進行壓縮處理,這裡提供了三種壓縮的方式
addScaleCompress(int w, int h)//按目標寬高縮放
addScaleCompress(int scale)//等比例縮放,縮放比為 原圖:新圖 = scale:1
addQualityCompress(int targetSize)//質量壓縮,targetSize為目標大小
複製程式碼
你可以選擇其中一種或多種壓縮方式對相片進行壓縮,例如
//只選擇一種壓縮方式
photoFactory.FactoryFinish(requestCode,resultCode,data)
.addQualityCompress(128)
.GetBitmap();
//按順序逐步壓縮
photoFactory.FactoryFinish(requestCode,resultCode,data)
.addQualityCompress(128)
.addScaleCompress(5)
.addScaleCompress(300,300)
.GetBitmap();
複製程式碼
完整示例
PhotoFactory相容了Android 7.0 FileProvider獲取相片uri的問題,當然具體Provider的配置以及Android 6.0的動態許可權管理需要大家在專案中自行完成。這裡為了方便大家完成配置,我將完整的流程貼出來供大家參考
1.在Github下載photofactory library並匯入到你的專案中
2. 在res\xml目錄中建立provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
複製程式碼
3. 在AndroidManifest.xml中新增相應許可權及配置Provider
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:icon="@mipmap/ic_launcher"
...
>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
...
</application>
複製程式碼
4. 在AndroidManifest.xml中新增相應許可權及配置Provider
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:icon="@mipmap/ic_launcher"
...
>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
...
</application>
複製程式碼
5. 在Activity中進行動態許可權管理以及使用PhotoFactory
public class PhotoTestActivity extends AppCompatActivity {
private Button btnPhoto;
private ImageView imgPhoto;
private PhotoFactory photoFactory;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_photo_test);
photoFactory = new PhotoFactory(this,this);
imgPhoto = (ImageView) findViewById(R.id.img_photo);
btnPhoto = (Button) findViewById(R.id.btn_photo);
btnPhoto.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (ContextCompat.checkSelfPermission(PhotoTestActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
//申請寫入許可權
ActivityCompat.requestPermissions(PhotoTestActivity.this, new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE
}, 100);
} else {
photoFactory.FactoryStart()
.SetStartType(PhotoFactory.TYPE_PHOTO_UNTREATED)
.Start();
}
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch(requestCode) {
case 100:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
photoFactory.FactoryStart()
.SetStartType(PhotoFactory.TYPE_PHOTO_UNTREATED)
.Start();
}else{// 沒有獲取到許可權,做特殊處理
Toast.makeText(this, "請授予許可權!", Toast.LENGTH_SHORT).show();
}
break;
default:
break;
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == RESULT_CANCELED){
Toast.makeText(this, "取消拍照!", Toast.LENGTH_SHORT).show();
}else {
if(data == null){
Toast.makeText(this, "取消選擇!", Toast.LENGTH_SHORT).show();
return;
}
//使用你選取的照片
Uri uri = photoFactory.FactoryFinish(requestCode,resultCode,data).GetUri();
imgPhoto.setImageURI(uri);
}
super.onActivityResult(requestCode, resultCode, data);
}
}
複製程式碼
PhotoFactory至此介紹完畢,具體實現並不複雜,有興趣瞭解內部是如何實現的可以自行查閱原始碼,如果有不懂的地方或者檢查到程式碼有什麼問題歡迎給我留言~
更新
之前的程式碼雖然簡化了選取照片的過程,但沒有考慮到把取消選擇的處理也封裝進來,使用者還得在onActivityResult中寫一堆程式碼去處理取消選擇的情況,這說明PhotoFactory用起來還不夠方便,於是我動手增加了判斷取消選擇的介面,現在我們可以呼叫這些新的介面進行容錯了
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//依然可以這樣去獲取相片,但需要你自己去寫取消選擇的處理
Uri uri = photoFactory.FactoryFinish(requestCode,resultCode,data).GetUri();
imgPhoto.setImageURI(uri);
//現在只要這樣呼叫setOnResultListener就可以一步到位了
photoFactory.FactoryFinish(requestCode,resultCode,data)
.setOnResultListener(new PhotoFactory.OnResultListener() {
@Override
public void TakePhotoCancel() {
Toast.makeText(PhotoTestActivity.this, "取消拍照", Toast.LENGTH_SHORT).show();
}
@Override
public void GalleryPhotoCancel() {
Toast.makeText(PhotoTestActivity.this, "取消選擇", Toast.LENGTH_SHORT).show();
}
@Override
public void HasData(PhotoFactory.FinishBuilder resultData) {//正確選取了相片
Uri uri = resultData.GetUri();
imgPhoto.setImageURI(uri);
}
});
super.onActivityResult(requestCode, resultCode, data);
}
複製程式碼
但是...這樣好像就不止三行程式碼了啊...