问题
I have a webview and on one of the pages there is an Upload Photo button. I found some code to implement the file chooser (Android, why so hard????) and if I pick the gallery everything works fine. If I choose camera 1 of 10 times it works. But most of the time when I take the picture and click save (this is all in the camera activity) the webview loads the first page loaded when the app was started. It seems that the onActivityResult()
is not called but instead of it onCreate()
is and this messes up my app. Can you give me an example of how to restore the webView state after I take the picture? (maybe I should mention that I am logged in in the WebView).
This is the WebChromeClient class:
public class WebViewChromeClient extends WebChromeClient {
private Activity activity;
public Uri imageUri;
private static final int FILECHOOSER_RESULTCODE = 1;
private Uri mCapturedImageURI = null;
private Context context;
private MainActivity mainActivity;
public WebViewChromeClient(Context context, Activity activity,
MainActivity mainActivity) {
this.activity = activity;
this.context = context;
this.mainActivity = mainActivity;
}
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
// Update message
((Audi) activity.getApplication()).setmUploadMessage(uploadMsg);
if (uploadMsg == null) {
Log.d("UPLOAD MESSAGE", "NULL");
}
try {
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);
mainActivity.setmCapturedImageURI(mCapturedImageURI);
Log.d("Line", "57");
// Camera capture image intent
final Intent captureIntent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedImageURI);
mainActivity.setmCapturedImageURI(mCapturedImageURI);
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("image/*");
// 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
activity.startActivityForResult(chooserIntent,
FILECHOOSER_RESULTCODE);
} catch (Exception e) {
Toast.makeText(context, "Exception:" + e, Toast.LENGTH_LONG).show();
}
}
// 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);
}
// The webPage has 2 filechoosers and will send a
// console message informing what action to perform,android wml_siso init
// taking a photo or updating the file
public boolean onConsoleMessage(ConsoleMessage cm) {
onConsoleMessage(cm.message(), cm.lineNumber(), cm.sourceId());
return true;
}
public void onConsoleMessage(String message, int lineNumber, String sourceID) {
Log.d("androidruntime", "Show console messages, Used for debugging: "
+ message);
}
}
And this is the onActivityResult method:
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
webView.requestFocus();
if (requestCode == FILECHOOSER_RESULTCODE) {
Log.d("MainActivity", "onActivityResult");
if (null == ((Audi) getApplication()).getmUploadMessage()) {
Log.d("FileChooser Result", "58");
return;
}
Log.d("MainActivity", "onActivityResult");
Uri result = null;
try {
if (resultCode != RESULT_OK) {
result = null;
} else {
// retrieve from the private variable if the intent is null
result = intent == null ? mCapturedImageURI : intent
.getData();
}
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "activity :" + e,
Toast.LENGTH_LONG).show();
}
((Audi) getApplication()).getmUploadMessage().onReceiveValue(result);
((Audi) getApplication()).setmUploadMessage(null);
}
Log.d("MainActivity", "onActivityResult");
}
回答1:
Your activity is probably being paused/stopped by the system while you run the file chooser.
You need to handle onResume()
and restore your activity's previous state. The onResume
method is invoked when your activity is restarted, so this is a good place to reload whatever WebView you were displaying before launching the file chooser.
回答2:
Fixed by adding this line in the Manifest android:configChanges="keyboardHidden|orientation|screenSize"
回答3:
Looking at your posted code, here is a dangerous line:
webView.requestFocus();
is first in onActivityResult()
. If MainActivity is being recreated, this could cause NullPointerException. The system will seamlessly re-launch your app, possibly producing the reported behavior.
Add another Log.d() to the beginning of onActivityResult()
, put try/catch around this dangerous line, and use onSaveInstanceState() and onRestoreInstanceState().
Note that if your MainActivity is Portrait, you face extra trouble, with Camera app forcing Landscape.
来源:https://stackoverflow.com/questions/24781818/android-openfilechooser-oncreate-called-after-onactivityresult