for (var i = 0; i < 3; i++) {
createfunc(i)();
}
function createfunc(i) {
return function(){console.log("My value: " + i);};
}
Хостинг переопределяет onActivityResult()
, но он не сделал вызов super.onActivityResult()
для необработанных кодов результатов. По-видимому, несмотря на то, что фрагмент является тем, кто делает вызов startActivityForResult()
, действие получает первый снимок при обработке результата. Это имеет смысл, если учесть модульность фрагментов. После того, как я выполнил super.onActivityResult()
для всех необработанных результатов, фрагмент получил шанс обработать результат.
А также из ответа @siqing:
Чтобы получить результат в вашем фрагменте, сделайте уверенный, что вы вызываете startActivityForResult(intent,111);
вместо getActivity().startActivityForResult(intent,111);
внутри вашего фрагмента.
Моя проблема была с хост-активностью, я нашел ее с набором android:launchMode="standard"
, я удалил ее временно, и она работает!
Ваш код имеет вложенный фрагмент. Вызов super.onActivityForResult не работает
Вы не хотите изменять каждое действие, из которого может быть вызван ваш фрагмент, или сделать работу вокруг вызова каждого фрагмента в цепочке фрагментов.
Вот одно из многих рабочих решений. создать фрагмент «на лету» и связать его непосредственно с активностью с помощью менеджера фрагментов поддержки. Затем вызовите startActivityForResult из вновь созданного фрагмента.
private void get_UserEmail() {
if (view == null) {
return;
}
((TextView) view.findViewById(R.id.tvApplicationUserName))
.setText("Searching device for user accounts...");
final FragmentManager fragManager = getActivity().getSupportFragmentManager();
Fragment f = new Fragment() {
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
startActivityForResult(AccountPicker.newChooseAccountIntent(null, null,
new String[]{"com.google"}, false, null, null, null, null), REQUEST_CODE_PICK_ACCOUNT);
}
@Override
public void onActivityResult(int requestCode, int resultCode,
Intent data) {
if (requestCode == REQUEST_CODE_PICK_ACCOUNT) {
String mEmail = "";
if (resultCode == Activity.RESULT_OK) {
if (data.hasExtra(AccountManager.KEY_ACCOUNT_NAME)) {
mEmail = data
.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
}
}
if (mActivity != null) {
GoPreferences.putString(mActivity, SettingApplication.USER_EMAIL, mEmail);
}
doUser();
}
super.onActivityResult(requestCode, resultCode, data);
fragManager.beginTransaction().remove(this).commit();
}
};
FragmentTransaction fragmentTransaction = fragManager
.beginTransaction();
fragmentTransaction.add(f, "xx" + REQUEST_CODE_PICK_ACCOUNT);
fragmentTransaction.commit();
}
Короче говоря,
В фрагменте объявите Fragment fragment = this
;
после этого используйте fragment.startActivityForResult
.
Результат вернется в activityResult.
Если вы не знаете фрагментов в своей деятельности, просто перечислите их все и отправьте аргументы результата активности:
// In your activity
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
for (Fragment fragment : getSupportFragmentManager().getFragments()) {
fragment.onActivityResult(requestCode, resultCode, data);
}
}
Я могу добавить два совета, если кто-то еще не сможет это сделать. В файле Manifest.xml убедитесь, что активность хостинга не завершилась при обратном вызове, и для запуска активности в качестве стандартного режима запуска. См. Подробности, как показано ниже:
Для активности хостинга установите свойство no history как false, если у вас есть
android:noHistory="false"
. Для запуска операции установите режим запуска в качестве стандарта, если у вас
android:launchMode="standard"
public class takeimage extends Fragment {
private Uri mImageCaptureUri;
private static final int PICK_FROM_CAMERA = 1;
private static final int PICK_FROM_FILE = 2;
private String mPath;
private ImageView mImageView;
Bitmap bitmap = null;
View view;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.activity_send_image, container, false);
final String[] items = new String[] { "From Camera", "From SD Card" };
mImageView = (ImageView)view.findViewById(R.id.iv_pic);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.select_dialog_item, items);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Select Image");
builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
if (item == 0) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File file = new File(Environment.getExternalStorageDirectory(), "tmp_avatar_"
+ String.valueOf(System.currentTimeMillis())
+ ".jpg");
mImageCaptureUri = Uri.fromFile(file);
try {
intent.putExtra(
android.provider.MediaStore.EXTRA_OUTPUT,
mImageCaptureUri);
intent.putExtra("return-data", true);
getActivity().startActivityForResult(intent,
PICK_FROM_CAMERA);
} catch (Exception e) {
e.printStackTrace();
}
dialog.cancel();
} else {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
getActivity().startActivityForResult(
Intent.createChooser(intent,
"Complete action using"), PICK_FROM_FILE);
}
}
});
final AlertDialog dialog = builder.create();
Button show = (Button) view.findViewById(R.id.btn_choose);
show.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// Switch the tab content to display the list view.
dialog.show();
}
});
return view;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != Activity.RESULT_OK)
return;
if (requestCode == PICK_FROM_FILE) {
mImageCaptureUri = data.getData();
// mPath = getRealPathFromURI(mImageCaptureUri); //from Gallery
if (mPath == null)
mPath = mImageCaptureUri.getPath(); // from File Manager
if (mPath != null)
bitmap = BitmapFactory.decodeFile(mPath);
} else {
mPath = mImageCaptureUri.getPath();
bitmap = BitmapFactory.decodeFile(mPath);
}
mImageView.setImageBitmap(bitmap);
}
public String getRealPathFromURI(Uri contentUri) {
String [] proj = {MediaStore.Images.Media.DATA};
Cursor cursor = managedQuery(contentUri, proj, null, null,null);
if (cursor == null) return null;
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
}
onActivityResult
на фрагменте baseActivity.startActivityForResult
. private OnBaseActivityResult baseActivityResult;
public static final int BASE_RESULT_RCODE = 111;
public interface OnBaseActivityResult{
void onBaseActivityResult(int requestCode, int resultCode, Intent data);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(getBaseActivityResult() !=null && requestCode == BASE_RESULT_RCODE){
getBaseActivityResult().onBaseActivityResult(requestCode, resultCode, data);
setBaseActivityResult(null);
}
OnBaseActivityResult
@Override
public void onBaseActivityResult(int requestCode, int resultCode, Intent data) {
Log.d("RQ","OnBaseActivityResult");
if (data != null) {
Log.d("RQ","OnBaseActivityResult + Data");
Bundle arguments = data.getExtras();
}
}
Это обходное решение сделает трюк.
Это одна из самых популярных проблем. Мы можем найти много сообщений об этой проблеме. Но ни один из них не полезен для меня.
Итак, я решил эту проблему с помощью этого решения.
Давайте сначала поймем, почему это происходит.
Мы можем называть startActivityForResult
непосредственно из
После того, как вы назовете startActivityForResult
из фрагмента, requestCode будет изменен, чтобы привязать идентификатор Fragment к коду. Это позволит Activity отслеживать, кто отправляет этот запрос после получения результата.
После того, как активность была перенесена обратно, результат будет отправлен в Activity onActivityResult с измененным кодом запроса, который будет декодирован в оригинале Идентификатор requestCode + Fragment. После этого Activity отправит результат активности на этот фрагмент через onActivityResult.
Проблема заключается в следующем:
Активность может отправить результат только фрагменту, который был прикреплен непосредственно к Activity, но не к вложенному. Это причина, по которой onActivityResult вложенного фрагмента никогда не вызывался независимо от того, что.
Решение:
1) Запустите Intent в вашем фрагменте по нижнему коду:
/** Pass your fragment reference **/
frag.startActivityForResult(intent, REQUEST_CODE); // REQUEST_CODE = 12345
2) Теперь в вашем переопределении родительской активности ** onActivityResult()
: **
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
Вы должны вызвать это в родительской активности, чтобы заставить его работать.
3 ) В вызове фрагмента:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
}
}
Вот и все. С помощью этого решения он может применяться для любого отдельного фрагмента, независимо от того, является он вложенным или нет. И да, это также охватывает весь случай! Кроме того, коды также приятны и чисты.
В одной точке никто не имеет
blockquote>mention
, чтобы убедиться, что режим запуска Host Activity не установлен наsingleInstance
илиsingleTask
.onActivityResult не будет работать, если ваш режим запуска установлен на SingleInstance или SingleTask. или вы вызываете свою активность с использованием этих режимов IntentFilters
standard
илиsingleTop
, которые будут работать нормально.
Просто используйте приведенный ниже код для фрагмента.
@Override
public void onOtherButtonClick(ActionSheet actionSheet, int index) {
if (index == 1)
{
Intent intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/*");
startActivityForResult(Intent.createChooser(intent,
"Select Picture"), 1);
}
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == 1) {
if (requestCode == 1) {
Uri selectedImageUri = data.getData();
//selectedImagePath = getPath(selectedImageUri);
}
}
}
onActivityResult вызывается без вызова его родителя.
Если вы используете вложенные фрагменты, это также работает:
getParentFragment().startActivityForResult(intent, RequestCode);
В дополнение к этому вы должны вызвать super.onActivityResult
из родительской активности и заполнить метод onActivityResult
фрагмента .
Большинство этих ответов продолжают говорить, что вы должны называть super.onActivityResult(...)
в своем хосте Activity
для вашего Fragment
. Но, похоже, это не работало для меня.
Итак, в вашем хосте Activity
вместо этого вы должны называть свой Fragments
onActivityResult(...)
. Вот пример.
public class HostActivity extends Activity {
private MyFragment myFragment;
protected void onActivityResult(...) {
super.onActivityResult(...);
this.myFragment.onActivityResult(...);
}
}
В какой-то момент вашего HostActivity
вам нужно будет назначить this.myFragment
Fragment
, который вы используете. Или используйте FragmentManager
, чтобы получить Fragment
вместо сохранения ссылки на него в HostActivity
. Кроме того, проверьте null
, прежде чем пытаться вызвать this.myFragment.onActivityResult(...);
.
Один из самых простых способов - начать работу с вашего фрагмента.
startActivity(ActivityName);
Затем добавьте ваш вызов startActivityForResult(intent,"1");
из своей активности и добавьте onActivityResult
в свою активность
startActivityForResult(intent,"1");
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.dualPane);
fragment.onActivityResult(requestCode, resultCode, data);
// perform other activity result like fetching from Uris or handling cursors
finish(); // finish the activity will get to back to your fragment.
}
У меня также была проблема с той же проблемой, как только я переместил этот блок кода за пределы фрагмента в Utility Class , причем parentActivity
передан как аргумент ,
Intent intent = new Intent(parentActivity, CameraCaptureActivity.class);
parentActivity.startActivityForResult(intent,requestCode);
Тогда я не получал никакого значения в методе onActivityResult
этого фрагмента, после чего я изменил аргумент на фрагмент, поэтому пересмотренное определение метода выглядело как
Intent intent = new Intent(fragment.getContext(), CameraCaptureActivity.class);
fragment.startActivityForResult(intent,requestCode);
После этого мне удалось получить значение в onActivityResult
на фрагменте
Вариант 1:
Если вы вызываете startActivityForResult()
из фрагмента, вы должны вызвать startActivityForResult()
, а не getActivity().startActivityForResult()
, так как это приведет к фрагменту onActivityResult ().
Если вы не знаете, где вы звоните startActivityForResult()
и как будете вызывать методы.
Вариант 2:
] Поскольку Activity получает результат onActivityResult()
, вам нужно будет переопределить onActivityResult()
активности и вызвать super.onActivityResult()
для распространения на соответствующий фрагмент для необработанных кодов результатов или для всех.
Если выше два параметра не работают, обратитесь к опции 3, поскольку она определенно будет работать.
Вариант 3:
Явный вызов из фрагмента функции onActivityResult следующим образом.
В родительском классе Activity переопределите метод onActivityResult () и даже переопределите его в классе Fragment и вызовите в качестве следующего кода.
В родительском классе:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.dualPane);
fragment.onActivityResult(requestCode, resultCode, data);
}
В дочернем классе:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// In fragment class callback
}
Я думаю, вы вызвали getActivity().startActivityForResult(intent,111);
. Вы должны называть startActivityForResult(intent,111);
.
Я просто создаю метод обхода:
public static Fragment _tempFragment = null;
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(_tempFragment != null)
_tempFragment.onActivityResult(requestCode, resultCode, data);
}
В вашем фрагменте перед startActivityforResult установите
MainActivity._tempFragment = this;
После того, как onActivityResult & lt; - in Fragment
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Do your job
{
}
MainActivity._tempFragment = null;
}
Если существует проблема с методом onActivityResult
, который находится внутри класса фрагмента, и вы хотите обновить то, что находится внутри класса фрагмента, используйте:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode == Activity.RESULT_OK)
{
// If the user had agreed to enabling Bluetooth,
// populate the ListView with all the paired devices.
this.arrayDevice = new ArrayAdapter<String>(this.getContext(), R.layout.device_item);
for(BluetoothDevice bd : this.btService.btAdapater.getBondedDevices())
{
this.arrayDevice.add(bd.getAddress());
this.btDeviceList.setAdapter(this.arrayDevice);
}
}
super.onActivityResult(requestCode, resultCode, data);
}
Просто добавьте this.variable
, как показано в приведенном выше коде. В противном случае метод будет вызван внутри родительского действия, и переменная не будет обновляться в текущем экземпляре.
Я также протестировал его, поместив этот блок кода в MainActivity
, заменив this
на HomeFragment
и переменные статические. Я получил результаты, как я ожидал.
Итак, если вы хотите, чтобы класс фрагмента имел свою собственную реализацию onActivityResult
, приведенный выше пример кода является ответом.