版權聲明:本文爲博主原創文章,未經博主容許不得轉載java
系列教程:Android開發之從零開始系列android
源碼:AnliaLee/PhotoFactory,歡迎stargit
你們要是看到有錯誤的地方或者有啥好的建議,歡迎留言評論github
初看標題是否是以爲博主是標題黨,故意把大家騙了進來?告訴你bash
博主幫你們封裝好了PhotoFactory類,只需三行代碼就能夠完成選擇照片,獲取其bitmap或uri路徑(可自行配置是否壓縮)的功能。下面來看下如何使用PhotoFactoryapp
使用PhotoFactory分爲三步,首先咱們要實例化一個photoFactoryide
PhotoFactory photoFactory = new PhotoFactory(this, this);//(Activity activity,Context context)
複製代碼
設置選擇照片的方式post
//提供三種選擇照片的方式
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或uriui
/** * 在onActivityResult中調用此方法 */
photoFactory.FactoryFinish(requestCode,resultCode,data).GetBitmap();
//photoFactory.FactoryFinish(requestCode,resultCode,data).GetUri();
複製代碼
就這麼簡單,固然,你還能夠對照片進行壓縮處理,這裏提供了三種壓縮的方式this
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);
}
複製代碼
可是...這樣好像就不止三行代碼了啊...