我正在制作一个需要上传文件的webview应用。我实现了包括文件选择器或选择用相机拍照的选项。打开文件选择器或选择摄像机时,应用程序会冻结并关闭。
我在网上看了很多,无法找到解决方案。有人可以帮我解决这个问题吗?代码示例如下:
public class MainActivity extends Activity {
private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
private static final String TAG = "MainActivity";
private BroadcastReceiver mRegistrationBroadcastReceiver;
private ProgressBar mRegistrationProgressBar;
public String regToken;
public class GeoWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
public class GeoWebChromeClient extends WebChromeClient {
@Override
public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
callback.invoke(origin, true, false);
}
}
public static final int INPUT_FILE_REQUEST_CODE = 1;
public static final String EXTRA_FROM_NOTIFICATION = "EXTRA_FROM_NOTIFICATION";
WebView mWebView;
private ValueCallback<Uri[]> mFilePathCallback;
private String mCameraPhotoPath;
private ValueCallback<Uri> mUploadMessage;
private final static int FILECHOOSER_RESULTCODE=1;
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
android.Manifest.permission.READ_EXTERNAL_STORAGE,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE
};
public static void verifyStoragePermissions(Activity activity) {
int permission = ActivityCompat.checkSelfPermission(activity, android.Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
activity,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
}
}
public MainActivity() {
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRegistrationBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
SharedPreferences sharedPreferences =
PreferenceManager.getDefaultSharedPreferences(context);
boolean sentToken = sharedPreferences
.getBoolean(QuickstartPreferences.SENT_TOKEN_TO_SERVER, false);
Log.i(TAG, "++++++++++++++++++++++++++++++++++ REGID " + sharedPreferences
.getString(QuickstartPreferences.TOKEN_REGISTER, "registrationComplete"));
regToken = sharedPreferences.getString(QuickstartPreferences.TOKEN_REGISTER, "registrationComplete");
Log.i(TAG, "++++++++++++++++++++++++++++++++++ REGID " + regToken);
mWebView = (WebView) findViewById(R.id.activity_main_webview);
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setGeolocationEnabled(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
mWebView.setWebViewClient(new GeoWebViewClient());
webSettings.setGeolocationEnabled(true);
mWebView.setWebChromeClient(new GeoWebChromeClient());
mWebView.setWebViewClient(new myWebClient());
mWebView.setWebChromeClient(new WebChromeClient() {
public boolean onShowFileChooser(
WebView webView, ValueCallback<Uri[]> filePathCallback,
WebChromeClient.FileChooserParams fileChooserParams) {
if (mFilePathCallback != null) {
mFilePathCallback.onReceiveValue(null);
}
mFilePathCallback = filePathCallback;
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile();
takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
} catch (IOException ex) {
Log.e(TAG, "Unable to create Image File", ex);
}
if (photoFile != null) {
mCameraPhotoPath = "file:" + photoFile.getAbsolutePath();
takePictureIntent.putExtra(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/*");
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_INTENT, contentSelectionIntent);
chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, intentArray);
startActivityForResult(chooserIntent, INPUT_FILE_REQUEST_CODE);
return true;
}
});
Bundle extras = getIntent().getExtras();
String urltje;
if(extras != null && extras.getString("url") != null){
urltje = extras.getString("url");
Log.i(TAG, "++++++++++++++++++++++++++++++++++ URL " + urltje);
mWebView.loadUrl(urltje);
}else {
mWebView.loadUrl("http://www.elevent.nl/?page=15®ID=" + regToken);
}
mWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return false;
}
});
}
};
if (checkPlayServices()) {
Intent intent = new Intent(this, RegistrationIntentService.class);
startService(intent);
}
}
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;
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void setUpWebViewDefaults(WebView webView) {
WebSettings settings = webView.getSettings();
// Enable Javascript
settings.setJavaScriptEnabled(true);
// Use WideViewport and Zoom out if there is no viewport defined
settings.setUseWideViewPort(true);
settings.setLoadWithOverviewMode(true);
// Enable pinch to zoom without the zoom buttons
settings.setBuiltInZoomControls(true);
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) {
// Hide the zoom controls for HONEYCOMB+
settings.setDisplayZoomControls(false);
}
// Enable remote debugging via chrome://inspect
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
// We set the WebViewClient to ensure links are consumed by the WebView rather
// than passed to a browser if it can
mWebView.setWebViewClient(new WebViewClient());
}
@Override
public void onActivityResult (int requestCode, int resultCode, Intent data) {
if(requestCode != INPUT_FILE_REQUEST_CODE || mFilePathCallback == null) {
super.onActivityResult(requestCode, resultCode, data);
return;
}
Uri[] results = null;
// Check that the response is a good one
if(resultCode == Activity.RESULT_OK) {
if(data == null || data.getData() == 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();
if (dataString != null) {
results = new Uri[]{Uri.parse(dataString)};
}
}
}
mFilePathCallback.onReceiveValue(results);
mFilePathCallback = null;
return;
}
public class myWebClient extends WebViewClient
{
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
// TODO Auto-generated method stub
super.onPageStarted(view, url, favicon);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// TODO Auto-generated method stub
view.loadUrl(url);
return true;
}
@Override
public void onPageFinished(WebView view, String url) {
// TODO Auto-generated method stub
super.onPageFinished(view, url);
}
}
@Override
public void onConfigurationChanged(Configuration newConfig){
super.onConfigurationChanged(newConfig);
}
@Override
public void onBackPressed() {
// Pop the browser back stack or exit the activity
if (mWebView.canGoBack()) {
mWebView.goBack();
}
else {
super.onBackPressed();
}
}
@Override
protected void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver,
new IntentFilter(QuickstartPreferences.REGISTRATION_COMPLETE));
}
@Override
protected void onPause() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mRegistrationBroadcastReceiver);
super.onPause();
}
/**
* Check the device to make sure it has the Google Play Services APK. If
* it doesn't, display a dialog that allows users to download the APK from
* the Google Play Store or enable it in the device's system settings.
*/
private boolean checkPlayServices() {
GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
int resultCode = apiAvailability.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
if (apiAvailability.isUserResolvableError(resultCode)) {
apiAvailability.getErrorDialog(this, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST)
.show();
} else {
Log.i(TAG, "This device is not supported.");
finish();
}
return false;
}
return true;
}
可能是一个重复的问题。但我是新手制作Android应用程序而我无法找到解决方案!
抱歉,我忘了包含logcat。这是我点击文件输入后获得的logcat。
03-16 08:29:35.485 3153-3153/webdesign.jk.elevent E/MainActivity: Unable to create Image File
java.io.IOException: open failed: EACCES (Permission denied)
at java.io.File.createNewFile(File.java:939)
at java.io.File.createTempFile(File.java:1004)
at webdesign.jk.elevent.MainActivity.createImageFile(MainActivity.java:214)
at webdesign.jk.elevent.MainActivity.access$100(MainActivity.java:39)
at webdesign.jk.elevent.MainActivity$1$1.onShowFileChooser(MainActivity.java:142)
at com.android.webview.chromium.WebViewContentsClientAdapter.showFileChooser(WebViewContentsClientAdapter.java:1104)
at org.chromium.android_webview.AwWebContentsDelegateAdapter.runFileChooser(AwWebContentsDelegateAdapter.java:219)
at org.chromium.base.SystemMessageHandler.nativeDoRunLoopOnce(Native Method)
at org.chromium.base.SystemMessageHandler.handleMessage(SystemMessageHandler.java:53)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: android.system.ErrnoException: open failed: EACCES (Permission denied)
at libcore.io.Posix.open(Native Method)
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:186)
at java.io.File.createNewFile(File.java:932)
at java.io.File.createTempFile(File.java:1004)
at webdesign.jk.elevent.MainActivity.createImageFile(MainActivity.java:214)
at webdesign.jk.elevent.MainActivity.access$100(MainActivity.java:39)
at webdesign.jk.elevent.MainActivity$1$1.onShowFileChooser(MainActivity.java:142)
at com.android.webview.chromium.WebViewContentsClientAdapter.showFileChooser(WebViewContentsClientAdapter.java:1104)
at org.chromium.android_webview.AwWebContentsDelegateAdapter.runFileChooser(AwWebContentsDelegateAdapter.java:219)
at org.chromium.base.SystemMessageHandler.nativeDoRunLoopOnce(Native Method)
at org.chromium.base.SystemMessageHandler.handleMessage(SystemMessageHandler.java:53)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
下面我将包括我的清单文件。
<?xml version="1.0" encoding="utf-8"?>
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- gcm permissions -->
<permission
android:name="webdesign.jk.elevent.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="webdesign.jk.elevent.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_GPS" />
<uses-permission android:name="android.permission.ACCESS_ASSISTED_GPS" />
<uses-permission android:name="android.permission.ACCESS_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-feature android:name="android.hardware.camera"
android:required="true" />
答案 0 :(得分:1)
在createImageFile()
方法中尝试将其更改为
File storageDir = this.getCacheDir();
File imageFile = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
看看它是否有效。还要确保storageDir
目录存在。
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);