Android如何添加图片

版权声明:个人原创,欢迎转载。 https://blog.csdn.net/chuyangchangxi/article/details/85319712

一、目标

通过在文章中插入图片,实现图文混排的功能。

二、下载地址

神马笔记最新版本:【神马笔记Version1.1.0_beta.apk

三、获取图片

有2种途径可以获取图片

  1. 拍照(创建新的照片)
  2. 照片图库(选择手机上的照片)

在Android平台,有2种方式可以用来实现这2种途径

  1. 调用第三方应用
  2. 编写拍照与图库代码,自己实现之

前者在功能上可能会遇到一些限制,但工作量小。

后者更加灵活,可以随意发挥,但工作量较大。虽然可以在Github上找到不错的实现方案,终归需要一些调试的事件。

神马笔记采用的是第一种方式——调用第三方应用

四、调用第三方应用

Android通过startActivityForResult调用地方应用,并且通过onActivityResult处理返回结果。这2个方法分别存在于ActivityFragment中。

  • Activity#startActivityForResult
  • Activity#onActivityResult
  • Fragment#startActivityForResult
  • Fragment#onActivityResult

1. 调用拍照应用

public boolean request() {
    SoftInputUtils.hide(context);

    Uri imageUri;
    {
        File file = target.getFile();
        file.getAbsoluteFile().getParentFile().mkdirs();

        imageUri = UriUtils.fromFile(context, file);
    }

    Intent intent = new Intent();
    {
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
        intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
    }

    try {

        parent.startActivityForResult(intent, requestCode);

        return true;
    } catch (Exception e) {
        e.printStackTrace();
    }

    return false;
}

2. 调用照片图库应用

public boolean request() {
    SoftInputUtils.hide(context);

    Intent intent = new Intent(Intent.ACTION_PICK, null);
    intent.setDataAndType(
        MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
        "image/*");
    intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);

    try {
        parent.startActivityForResult(intent, requestCode);

        return true;
    } catch (Exception e) {

    }

    return false;
}

五、优化调用过程

startActivityForResultonActivityResult这2个接口通过requestCode识别请求及结果。为了避免定义常量发送请求以及使用switch语法处理结果,采用面向对象的方法来优化调用过程。

1. 定义调用处理类

public abstract class BaseRequestDelegate implements BiConsumer<Integer, Intent> {

    private static int COUNTER = 1;

    protected int requestCode;

    protected Fragment parent;
    protected Activity context;

    public BaseRequestDelegate(Fragment f) {
        this.context = f.getActivity();
        this.parent = f;

        this.requestCode = COUNTER;

        {
            int counter = COUNTER;
            ++counter;
            counter %= 1000;
            COUNTER = counter;
        }
    }

    public int getRequestCode() {
        return requestCode;
    }

    public abstract boolean request();

    public abstract void accept(Integer resultCode, Intent data);
}

BaseRequestDelegate会自动产生requestCode,避免定义常量。这里使用了是COUNTER的方式,每次创建一个新的请求,计数器累加1作为下一次的requestCode,并且限定在1000以内。

BaseRequestDelegate封装了2个方法request用与发送请求,以及accept用于处理结果。

2. 定义调用管理类

public class RequestResultManager {

    HashMap<Integer, BiConsumer<Integer, Intent>> map;

    public RequestResultManager() {
        this.map = new HashMap<>();
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        BiConsumer delegate = map.remove(requestCode);
        if (delegate != null) {
            delegate.accept(resultCode, data);
        }
    }

    public void request(BaseRequestDelegate delegate) {
        boolean result = delegate.request();
        if (result) {
            map.put(delegate.getRequestCode(), delegate);
        }
    }

}

RequestResultManager负责管理BaseRequestDelegate,通过request方法发送请求。在onActivityResult处理结果。

3. 优化调用过程

  • 调用第三方应用
void requestInsertion() {

    MenuItemClickListener listener = new MenuItemClickListener();

    {

        listener.put(R.id.menu_insert_paragraph, e ->
                     new ParagraphInsertion(insertionCallback).execute()
                    );

        listener.put(R.id.menu_camera, e -> {
            CameraDelegate delegate = new CameraDelegate(this, insertionCallback);
            requestResultManager.request(delegate);
        });

        listener.put(R.id.menu_photo, e -> {
            PhotoDelegate delegate = new PhotoDelegate(this, insertionCallback);
            requestResultManager.request(delegate);
        });

    }

    PopupMenuDialogFragment dialogFragment = new PopupMenuDialogFragment();
    dialogFragment.setTheme(R.style.DialogDimTheme);
    dialogFragment.setMenuResource(R.menu.menu_compose_insertion);
    dialogFragment.setOnMenuItemClickListener(listener);
    dialogFragment.showNow(getFragmentManager(), "insertion");
}
  • 处理调用结果
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    requestResultManager.onActivityResult(requestCode, resultCode, data);
}

六、Final

通过调用第三方拍照及图库应用,可以快速实现文章中插入图片的功能。但是无法进一步操作第三方应用,使用灵活性较低。比如,调用图库应用添加某一相册下的图片,需要多次选择,无法记录最近一次使用的相册就颇为麻烦。

猜你喜欢

转载自blog.csdn.net/chuyangchangxi/article/details/85319712