从库中选择文件时不起作用

时间:2018-04-01 10:18:37

标签: android file-upload webview android-webview

晚上好,我请求帮助,谁可以遇到类似问题并找到解决方案。有一个典型的Android应用程序用于在WebView中打开页面,并且能够在此页面上下载文件。问题是应用程序在4.1,4.2,4.3 orroids上工作得很好,它适用于5,6,7甚至8个android,但是在android 6的控制下的一个特定设备上,它不想处理文件上传...具体来说,有问题的设备无法选择文件 - 小米Redmi Note3 Build / MMB29M Android 6.0.1如果你看一下这台机器上的代码,我们看到消息“mFilePathCallback == null”,具体推断,了解什么是故障 - 为什么这款手机我无法从活动中得到结果我无法理解,我需要帮助......什么?小米设备中的这样一个功能可以具有不同的功能吗?代码是典型的,无论我在哪里测试,除了这个设备......

可能是什么问题?

MainActivity

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.ClipData;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Parcelable;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.KeyEvent;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class MainActivity extends Activity {

WebView mWebView;

private static final int INPUT_FILE_REQUEST_CODE = 1;
private static final int FILECHOOSER_RESULTCODE = 1;
private static final String TAG = MainActivity.class.getSimpleName();
private ValueCallback<Uri> mUploadMessage;
private Uri mCapturedImageURI = null;
private ValueCallback<Uri[]> mFilePathCallback;
private String mCameraPhotoPath;

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        if (requestCode != INPUT_FILE_REQUEST_CODE || mFilePathCallback == null) {
            super.onActivityResult(requestCode, resultCode, data);
            Toast.makeText(getApplicationContext(), "mFilePathCallback == null", Toast.LENGTH_LONG).show();
            return;
        }
        Uri[] results = null;

        // Check that the response is a good one
        if (resultCode == Activity.RESULT_OK) {
            if (data == null) {
                // If there is not data, then we may have taken a photo
                if (mCameraPhotoPath != null) {
                    results = new Uri[]{Uri.parse(mCameraPhotoPath)};

                }
            } else {
                String dataString = data.getDataString();
                ClipData clipData = data.getClipData();

                if (clipData != null) {
                    results = new Uri[clipData.getItemCount()];
                    for (int i = 0; i < clipData.getItemCount(); i++) {
                        ClipData.Item item = clipData.getItemAt(i);
                        results[i] = item.getUri();
                    }
                    Toast.makeText(getApplicationContext(), "data CL: " + results[0], Toast.LENGTH_LONG).show();
                }else{
                    Toast.makeText(getApplicationContext(), "no data CL ", Toast.LENGTH_LONG).show();
                }

                if (dataString != null) {
                    results = new Uri[]{Uri.parse(dataString)};
                    Toast.makeText(getApplicationContext(), "data STR: " + results[0], Toast.LENGTH_LONG).show();
                }else{
                    Toast.makeText(getApplicationContext(), "no data STR ", Toast.LENGTH_LONG).show();

                }

            }
        }else{
            Toast.makeText(getApplicationContext(), "no result from activity", Toast.LENGTH_LONG).show();
        }
        mFilePathCallback.onReceiveValue(results);
        mFilePathCallback = null;
    } else if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
        if (requestCode != FILECHOOSER_RESULTCODE || mUploadMessage == null) {
            super.onActivityResult(requestCode, resultCode, data);
            return;
        }
        if (requestCode == FILECHOOSER_RESULTCODE) {
            if (null == this.mUploadMessage) {
                return;
            }
            Uri result = null;
            try {
                if (resultCode != RESULT_OK) {
                    result = null;
                } else {
                    // retrieve from the private variable if the intent is null
                    result = data == null ? mCapturedImageURI : data.getData();
                }
            } catch (Exception e) {
                Toast.makeText(getApplicationContext(), "activity :" + e, Toast.LENGTH_LONG).show();
            }
            mUploadMessage.onReceiveValue(result);
            mUploadMessage = null;
        }
    }
    return;
}

private File createImageFile() throws IOException {
    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = "JPEG_" + timeStamp + "_";
    File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
    File imageFile = File.createTempFile(imageFileName,  /* prefix */
            ".jpg",         /* suffix */
            storageDir      /* directory */);
    return imageFile;
}


@Override
protected void onCreate(Bundle savedInstanceState) {
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mWebView = (WebView) findViewById(R.id.activity_main_webview);
    WebSettings webSettings = mWebView.getSettings();
    webSettings.setJavaScriptEnabled(true);
    mWebView.getSettings().setAllowFileAccess(true);
    mWebView.loadUrl("http://site.ru");

    mWebView.setWebViewClient(new WebViewClient() {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return false;
        }
    });


    mWebView.setWebChromeClient(new WebChromeClient() {


        // For Android 5.0
        public boolean onShowFileChooser(WebView view, ValueCallback<Uri[]> filePath, WebChromeClient.FileChooserParams fileChooserParams) {
            // Double check that we don't have any existing callbacks
            if (mFilePathCallback != null) {
                mFilePathCallback.onReceiveValue(null);
            }
            mFilePathCallback = filePath;
            Intent takePictureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
                // Create the File where the photo should go
                File photoFile = null;
                try {
                    photoFile = createImageFile();
                    takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
                } catch (IOException ex) {
                    // Error occurred while creating the File
                    Log.e(TAG, "Unable to create Image File", ex);
                }
                // Continue only if the File was successfully created
                if (photoFile != null) {
                    mCameraPhotoPath = "file:" + photoFile.getAbsolutePath();
                    takePictureIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
                } else {
                    takePictureIntent = null;
                }
            }
            Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
            contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
            contentSelectionIntent.setType("image/*;video/*");

            Intent[] intentArray;
            if (takePictureIntent != null) {
                intentArray = new Intent[]{takePictureIntent};
            } else {
                intentArray = new Intent[0];
            }
            Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
            chooserIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, false);
            chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
            chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");
            chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
            startActivityForResult(chooserIntent, INPUT_FILE_REQUEST_CODE);
            return true;
        }

        // openFileChooser for Android 3.0+
        public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
            mUploadMessage = uploadMsg;
            // Create AndroidExampleFolder at sdcard
            // Create AndroidExampleFolder at sdcard
            File imageStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "AndroidExampleFolder");
            if (!imageStorageDir.exists()) {
                // Create AndroidExampleFolder at sdcard
                imageStorageDir.mkdirs();
            }
            // Create camera captured image file path and name
            File file = new File(imageStorageDir + File.separator + "IMG_" + String.valueOf(System.currentTimeMillis()) + ".jpg");
            mCapturedImageURI = Uri.fromFile(file);
            // Camera capture image intent
            final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedImageURI);
            Intent i = new Intent(Intent.ACTION_GET_CONTENT);
            i.addCategory(Intent.CATEGORY_OPENABLE);
            i.setType("image/*;video/*");
            // Create file chooser intent
            Intent chooserIntent = Intent.createChooser(i, "Image Chooser");
            // Set camera intent to file chooser
            chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Parcelable[]{captureIntent});
            // On select image call onActivityResult method of activity
            startActivityForResult(chooserIntent, FILECHOOSER_RESULTCODE);
        }

        // openFileChooser for Android < 3.0
        public void openFileChooser(ValueCallback<Uri> uploadMsg) {
            openFileChooser(uploadMsg, "");
        }

        //openFileChooser for other Android versions
        public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
            openFileChooser(uploadMsg, acceptType);
        }

    });

}

@Override
public boolean onKeyDown(int keyCode, @NonNull KeyEvent event){
    String webUrl = mWebView.getUrl();

    if(event.getAction() == KeyEvent.ACTION_DOWN){
        switch(keyCode){
            case KeyEvent.KEYCODE_BACK:
                if(mWebView.canGoBack()){
                    if((webUrl.contains("url"))){
                        new AlertDialog.Builder(this).setTitle("Attention")
                                .setIcon(R.mipmap.ic_launcher)
                                .setMessage("Are you sure?")
                                .setPositiveButton("yes", new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {

                                        Intent intent = new Intent(Intent.ACTION_MAIN);
                                        intent.addCategory(Intent.CATEGORY_HOME);
                                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                        startActivity(intent);
                                        finish();
                                    }
                                }).setNegativeButton("no", null).show();
                    }
                    else
                    if((webUrl.contains("url"))){
                        Toast.makeText(this, "нажмите X кнопку.",
                                Toast.LENGTH_SHORT).show();
                    }
                    else
                    if((webUrl.contains("url")||(webUrl.contains("file:///android_asset/error_page.html")||webUrl.contains("url")))) {
                        new AlertDialog.Builder(this).setTitle("Attention")
                                .setIcon(R.mipmap.ic_launcher)
                                .setMessage("Are you sure?")
                                .setPositiveButton("yes", new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog, int which) {

                                        Intent intent = new Intent(Intent.ACTION_MAIN);
                                        intent.addCategory(Intent.CATEGORY_HOME);
                                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                        startActivity(intent);
                                        finish();
                                    }
                                }).setNegativeButton("no", null).show();
                    }else {
                        mWebView.goBack();
                    }
                }else {
                    new AlertDialog.Builder(this).setTitle("Attention")
                            .setIcon(R.mipmap.ic_launcher)
                            .setMessage("Are you sure?")
                            .setPositiveButton("yes", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {

                                    Intent intent = new Intent(Intent.ACTION_MAIN);
                                    intent.addCategory(Intent.CATEGORY_HOME);
                                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                    startActivity(intent);
                                    finish();
                                }
                            }).setNegativeButton("no", null).show();
                }
                return true;
        }
    }
    return super.onKeyDown(keyCode, event);
}


}

清单

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.application">

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:logo="@mipmap/ic_launcher"
    android:label="Application"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:screenOrientation="portrait"
    android:theme="@style/Theme.AppCompat.NoActionBar">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>

2 个答案:

答案 0 :(得分:0)

Android Marshmallow(6.0)之后,您还需要在运行时询问特殊权限(文件读取/写入)。 点击此链接 https://developer.android.com/training/permissions/requesting.html#java

之前,Android 6.0, <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

这曾经有用,但6.0以后却没有。

答案 1 :(得分:0)

  

问题是应用程序在4.1,4.2,4.3 orroids上工作得很好,它适用于5,6,7甚至8个android,但是在android 6的控制下的一个特定设备上,它不想工作文件上传

它有时会在这些Android版本上运行。它不会一直有效。

  

我们看到消息“mFilePathCallback == null”

当您的应用在后台时,您的流程已终止。这是完全正常的。如果在开始的活动位于前台时进行配置更改,则应该会出现相同的症状。在任何一种情况下,当控件返回到您的所有内容时,您最终会使用新活动,因此您的字段(例如mFilePathCallback)将为null