Androidプロジェクトの実践——3行のコードは写真の選択と圧縮を解決します

12402 ワード

本文はブロガーのオリジナルの文章で、ブロガーの許可を得ないで転載してはいけません
シリーズチュートリアル:Android開発のゼロからシリーズ
ソース:AnliaLee/PhotoFactory、starへようこそ
もし皆さんが間違ったところや何か良いアドバイスを見たら、コメントを歓迎します.
初めてタイトルを見て、ブロガーがタイトル党だと思って、わざとあなたたちをだましたのではないでしょうか.教えてあげる
ブロガーはPhotoFactoryクラスをカプセル化し、3行のコードだけで写真の選択を完了し、bitmapまたはuriパス(圧縮するかどうかを自分で構成できる)の機能を取得することができます.PhotoFactoryの使い方を見てみましょう
PhotoFactoryの概要
PhotoFactoryを使用するには3つのステップに分かれています.まず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();

このように簡単です.もちろん、写真を圧縮することもできます.ここでは3つの圧縮方法を提供しています.
addScaleCompress(int w, int h)//       
addScaleCompress(int scale)//     ,       :   = scale:1
addQualityCompress(int targetSize)//    ,targetSize     

写真を圧縮する方法の1つまたは複数を選択できます.たとえば、
//         
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をダウンロードしてプロジェクトにインポート
アドレス:AnliaLee/PhotoFactory
2.resxmlディレクトリにprovider_を作成するpaths.xml

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="."/>
paths>

3.AndroidManifest.xmlに適切な権限を追加し、Providerを構成します.
"android.permission.WRITE_EXTERNAL_STORAGE" />
"@mipmap/ic_launcher"
    ...
    >
    "android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        "android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths" />
    
    ...

4.AndroidManifest.xmlに適切な権限を追加し、Providerを構成します.
"android.permission.WRITE_EXTERNAL_STORAGE" />
"@mipmap/ic_launcher"
    ...
    >
    "android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        "android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths" />
    
    ...

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 {
            //        
            Uri uri = photoFactory.FactoryFinish(requestCode,resultCode,data).GetUri();
            imgPhoto.setImageURI(uri);
        }
        super.onActivityResult(requestCode, resultCode, data);
    }
}

PhotoFactoryはここまで绍介して、具体的な実现は复雑ではありませんて、兴味があって内部がどのように実现したのが自分でソースコードを调べることができて、もし分からない地方あるいはコードを検査してどんな问题があるならば私に伝言を歓迎します~
更新
以前のコードは写真を選択する過程を簡略化したが、選択を取り消す処理もカプセル化することを考慮していなかった.ユーザーはonActivity Resultにキャンセル選択を処理するコードをたくさん書かなければならなかった.これは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);
}

でも...これで3行のコードだけじゃないみたい...