首页 > 解决方案 > 既然不允许后台任务,那么处理图片上传的正确方法是什么?

问题描述

首先,让我明确一点,我没有开发 Android 的经验,这是我第一个使用它的项目。

我正在使用 Cordova 制作一个在我的公司内使用的简单应用程序,并且作为一项要求,必须拍摄几张照片并将其上传到我们的服务器。

刚开始可以,测试机一直在用Android 7,但是升级到Android 8.1后,上传图片就不行了,或者只上传了第一张图片。

检查 adb logcat,我发现诸如“ActivityManager:不允许后台启动”和“BroadcastQueue:不允许后台执行”之类的消息。

在网上搜索,似乎针对较旧的 SDK 应该有效,但到目前为止我没有运气。

我也尝试过应该启动前台服务作为解决方法的插件,但它也不起作用。

由于寻找解决方法不起作用,而且它们可能会在以后停止工作,我想知道是否有一种新的、正确的方法来处理我尚未找到的上传。

这不适用于公司以外的客户,所以即使我必须让用户保持在显示上传进度的加载屏幕中,这也不是问题,甚至可能有用,所以他们肯定知道上传成功

澄清一下:上传已经使用过,并且仍然适用于 Android 7,我不需要为此的库。我的问题是 Android 8 不允许将上传作为后台服务完成,而且我还没有弄清楚如何避免在 Cordova 中使用后台服务。

标签: androidcordovabackground-task

解决方案


我没有和科尔多瓦合作过。我建议使用 OKHTTP 进行图片上传。在这个例子中,我展示了我的应用程序如何将图片发送到服务器端的 PHP 脚本。在您的活动中进行设置:

private File tmpDir;
tmpDir = new File(getFilesDir(),"Your Android File Directory");
if (!tmpDir.exists()) tmpDir.mkdirs();

String fpath = "Directory_path_of_your_picture";
String fname = "Filename_of_your_picture";
File fbody = new File(tmpDir, fname);

// Upload the file by making a call to the Uploader class
Uploader(fbody, fname, fpath);

Uploader 类如下所示:

    // Upload Class
    public static int Uploader(File file, String fname, String fpath) throws Exception {
        int statusCode = -1;
        final URL url = new URL("Your_Upload_Script");

        OkHttpClient.Builder b = new OkHttpClient.Builder();
        b.readTimeout(5000, TimeUnit.MILLISECONDS);
        b.writeTimeout(5000, TimeUnit.MILLISECONDS);
        b.connectTimeout(5000, TimeUnit.MILLISECONDS);
        final OkHttpClient client = b.build();

        RequestBody requestBody = new MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            .addFormDataPart("filename", fname)
            .addFormDataPart("MAX_FILE_SIZE","300000")
            .addFormDataPart("filepath", fpath)
            .addFormDataPart("uploadedfile", fname,
                    RequestBody.create(MEDIA_TYPE_TEXT, file))
            .build();

        Request request = new Request.Builder()
            .url(url)
            .post(requestBody)
            .build();

        Response response = client.newCall(request).execute();
        if (response.isSuccessful()) {
            // Successful Upload
            statusCode = response.code();
        }
        return statusCode;
    }

最后,像这样在服务器上设置接收器脚本(PHP 版本,但您可能有不同的后端,具体取决于您的设置):

// PHP script on the server
<?php
    $fname = $_POST['filename'];
    $fpath = $_POST['filepath'];
    $target_path = $_SERVER['DOCUMENT_ROOT'] . "/" . $fpath . "/" . $fname;
    $upload_path = $_FILES['uploadedfile']['tmp_name'];
    if(move_uploaded_file($upload_path, $target_path)) {
        echo "Moved";
    } else {
        echo "Not Moved";
    }
?>

推荐阅读