Android पर startActivityForResult का प्रबंधन कैसे करें?


969

अपनी गतिविधि में, मैं मुख्य गतिविधि से दूसरी गतिविधि को बुला रहा हूं startActivityForResult। मेरी दूसरी गतिविधि में, कुछ विधियाँ हैं जो इस गतिविधि को समाप्त करती हैं (हो सकता है कि बिना परिणाम के), हालाँकि, उनमें से केवल एक परिणाम वापस आता है।

उदाहरण के लिए, मुख्य गतिविधि से, मैं एक दूसरे को कॉल करता हूं। इस गतिविधि में, मैं हैंडसेट की कुछ विशेषताओं की जाँच कर रहा हूँ जैसे कि इसमें एक कैमरा है। अगर यह नहीं है तो मैं इस गतिविधि को बंद कर दूंगा। इसके अलावा, तैयारी के दौरान MediaRecorderया MediaPlayerयदि कोई समस्या होती है तो मैं इस गतिविधि को बंद कर दूंगा।

यदि इसके उपकरण में कैमरा है और रिकॉर्डिंग पूरी तरह से की जाती है, तो वीडियो रिकॉर्ड करने के बाद यदि कोई उपयोगकर्ता किए गए बटन पर क्लिक करता है तो मैं परिणाम (रिकॉर्ड किए गए वीडियो का पता) को मुख्य गतिविधि पर वापस भेजूँगा।

मैं मुख्य गतिविधि से परिणाम की जांच कैसे करूं?


जवाबों:


2446

अपनी FirstActivityकॉल विधि का SecondActivityउपयोग करके startActivityForResult()

उदाहरण के लिए:

int LAUNCH_SECOND_ACTIVITY = 1
Intent i = new Intent(this, SecondActivity.class);
startActivityForResult(i, LAUNCH_SECOND_ACTIVITY);

अपने SecondActivityसेट में वह डेटा जिसे आप वापस करना चाहते हैं FirstActivity। यदि आप वापस नहीं लौटना चाहते हैं, तो कोई भी सेट न करें।

उदाहरण के लिए: SecondActivityयदि आप डेटा वापस भेजना चाहते हैं:

Intent returnIntent = new Intent();
returnIntent.putExtra("result",result);
setResult(Activity.RESULT_OK,returnIntent);
finish();

यदि आप डेटा वापस नहीं करना चाहते हैं:

Intent returnIntent = new Intent();
setResult(Activity.RESULT_CANCELED, returnIntent);
finish();

अब आपकी FirstActivityकक्षा में onActivityResult()विधि के लिए निम्नलिखित कोड लिखें ।

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (requestCode == LAUNCH_SECOND_ACTIVITY) {
        if(resultCode == Activity.RESULT_OK){
            String result=data.getStringExtra("result");
        }
        if (resultCode == Activity.RESULT_CANCELED) {
            //Write your code if there's no result
        }
    }
}//onActivityResult

1
जब एक उद्देश्य डालने का उद्देश्य क्या हो, जब RESUT_CANCELLED in setResult (RESULT_CANCELED, returnIntent);
इस्माइल साहिन

4
@ismail मान लीजिए कि SecondActivityकुछ अपवाद हुआ, उस स्थिति में भी आपको परिणाम वापस करने की आवश्यकता है FirstActivity, इसलिए आप परिणाम को "RESULT_CANCELLED"कैच ब्लॉक में सेट कर सकते हैं और वापस लौट सकते हैं FirstActivtyऔर FirstActivity's' 'onActivityResult()आप जांच कर सकते हैं कि आपको सफलता मिली या विफलता परिणाम।
निशांत

10
तो यह आपके ऊपर है, यदि आपको रद्द करने का कारण जानने की आवश्यकता नहीं है, तो आप बस सेट का उपयोग कर सकते हैं (RESULT_CANCELED); बिना किसी इरादे के
इस्माइल साहिन

2
@ लेई लेबा नो फिनिश () को स्टार्टिंग के बाद नहीं बुलाया जाता है। एक्टिविटीफॉरसेल्ट ()। फर्स्ट एक्टिविटी राज्य को थामने के लिए आगे बढ़ेगी।
निशांत

6
मेरे लिए यह काम नहीं कर रहा है - यह वही है जो मैं एंड्रॉइड के बारे में बहुत नफरत करता हूं - यह प्रणाली बहुत अविश्वसनीय है: - /
मार्टिन फाफर

50

मुख्य गतिविधि से परिणाम की जांच कैसे करें?

आपको Activity.onActivityResult()इसके मापदंडों की जांच करने की आवश्यकता है :

  • requestCodeपहचानता है कि किस ऐप ने इन परिणामों को वापस किया। जब आप कॉल करते हैं तो यह आपके द्वारा परिभाषित किया जाता है startActivityForResult()
  • resultCode आपको सूचित करता है कि यह ऐप सफल हुआ, असफल हुआ या कुछ अलग हुआ
  • dataइस ऐप द्वारा दी गई कोई भी जानकारी रखता है। यह हो सकता है null

इसका मतलब यह है कि RequestCode का उपयोग केवल पहली गतिविधि में किया जाता है, और इसे कभी भी 2 गतिविधि के लिए उपयोग नहीं किया जाता है? यदि दूसरी गतिविधि के पास अलग-अलग दृष्टिकोण हैं, तो यह बदल जाएगा, लेकिन इरादे एक्स्ट्रा में आधारित है और अनुरोध द्वारा नहीं, सही है? संपादित करें: हाँ, stackoverflow.com/questions/5104269/…
JCarlosR

44

@ निशांत के जवाब को लागू करते हुए, गतिविधि परिणाम वापस करने का सबसे अच्छा तरीका है:

Intent returnIntent = getIntent();
returnIntent.putExtra("result",result);
setResult(RESULT_OK,returnIntent);
finish();

मुझे समस्या हो रही थी

new Intent();

तब मुझे पता चला कि सही तरीका उपयोग कर रहा है

getIntent();

वर्तमान इरादे को पाने के लिए


यह एक नया बनाने के लिए थोड़ा अजीब लगता है Intentजो केवल एक को पकड़ने के लिए मौजूद है Bundleऔर इसमें किसी क्रिया या घटक जैसे सामान्य मान नहीं हैं। लेकिन यह भी थोड़ा अजीब लगता है (और संभावित रूप से खतरनाक?) को संशोधित Intentकरने के लिए जो वर्तमान गतिविधि को लॉन्च करने के लिए उपयोग किया गया था। इसलिए मैंने खुद एंड्रॉइड के लिए स्रोत खोजा और पाया कि वे Intentपरिणाम के रूप में उपयोग करने के लिए हमेशा एक नया बनाते हैं । उदाहरण के लिए, github.com/aosp-mirror/platform_frameworks_base/blob/…
Spaaarky21

नमस्कार Spaaarky21, आपकी टिप्पणी के लिए धन्यवाद। मुझे खेद है कि मैं ठीक से समझाने में स्पष्ट नहीं था कि मैं उस समाधान के साथ कैसे समाप्त हुआ। यह तीन साल पहले था, और मैं केवल यह याद रख सकता हूं कि मेरा ऐप "नए इरादे" के कारण दुर्घटनाग्रस्त हो गया था, यही मेरा मतलब था जब मैंने कहा "मुझे समस्या हो रही थी"। वास्तव में मैंने सिर्फ "getIntent" के साथ कोशिश की, क्योंकि यह उस समय समझ में आया, और यह काम किया! इसकी वजह से मैंने अपना समाधान साझा करने का फैसला किया। शायद "सबसे अच्छा तरीका" या "सही तरीका" कहने के लिए शब्दों का सबसे अच्छा विकल्प नहीं है, लेकिन मैं अपने समाधान से खड़ा हूं। यह वही है जो मेरी समस्या को हल करता है और अन्य लोगों को भी। धन्यवाद
जूलियन अल्बर्टो

1
वाह! बहुत अच्छा काम करता है। getIntent()गतिविधि को डेटा को वापस करने का एक सही तरीका प्रतीत होता है, जहाँ से गतिविधि को बुलाया गया है। धन्यवाद!
सैम

43

उदाहरण

संपूर्ण प्रक्रिया को संदर्भ में देखने के लिए, यहां एक पूरक उत्तर दिया गया है। अधिक स्पष्टीकरण के लिए मेरा फुलर उत्तर देखें ।

यहां छवि विवरण दर्ज करें

MainActivity.java

public class MainActivity extends AppCompatActivity {

    // Add a different request code for every activity you are starting from here
    private static final int SECOND_ACTIVITY_REQUEST_CODE = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    // "Go to Second Activity" button click
    public void onButtonClick(View view) {

        // Start the SecondActivity
        Intent intent = new Intent(this, SecondActivity.class);
        startActivityForResult(intent, SECOND_ACTIVITY_REQUEST_CODE);
    }

    // This method is called when the second activity finishes
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // check that it is the SecondActivity with an OK result
        if (requestCode == SECOND_ACTIVITY_REQUEST_CODE) {
            if (resultCode == RESULT_OK) { // Activity.RESULT_OK

                // get String data from Intent
                String returnString = data.getStringExtra("keyName");

                // set text view with string
                TextView textView = (TextView) findViewById(R.id.textView);
                textView.setText(returnString);
            }
        }
    }
}

SecondActivity.java

public class SecondActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
    }

    // "Send text back" button click
    public void onButtonClick(View view) {

        // get the text from the EditText
        EditText editText = (EditText) findViewById(R.id.editText);
        String stringToPassBack = editText.getText().toString();

        // put the String to pass back into an Intent and close this activity
        Intent intent = new Intent();
        intent.putExtra("keyName", stringToPassBack);
        setResult(RESULT_OK, intent);
        finish();
    }
}

क्या यह दो अलग-अलग ऐप ए और ऐप बी द्वारा किया जा सकता है? stackoverflow.com/questions/52975645/…
जेरी अब्राहम

12

उन लोगों के लिए जिन्हें गलत अनुरोध के साथ समस्या है onActivityResult

यदि आप startActivityForResult()अपने पास से कॉल कर रहे हैं Fragment, तो फ्रैक्मेंट के स्वामित्व वाली गतिविधि द्वारा अनुरोधकोड बदल दिया जाता है।

यदि आप अपनी गतिविधि में सही परिणाम प्राप्त करना चाहते हैं, तो यह प्रयास करें:

परिवर्तन:

startActivityForResult(intent, 1); सेवा:

getActivity().startActivityForResult(intent, 1);


10

यदि आप उपयोगकर्ता इंटरफ़ेस को गतिविधि के परिणाम के साथ अपडेट करना चाहते हैं, तो आप इसका उपयोग नहीं कर सकते हैं this.runOnUiThread(new Runnable() {} यह UI नए मान के साथ ताज़ा नहीं होगा। इसके बजाय, आप यह कर सकते हैं:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (resultCode == RESULT_CANCELED) {
        return;
    }

    global_lat = data.getDoubleExtra("LATITUDE", 0);
    global_lng = data.getDoubleExtra("LONGITUDE", 0);
    new_latlng = true;
}

@Override
protected void onResume() {
    super.onResume();

    if(new_latlng)
    {
        PhysicalTagProperties.this.setLocation(global_lat, global_lng);
        new_latlng=false;
    }
}

यह मूर्खतापूर्ण लगता है लेकिन बहुत अच्छा काम करता है।


2

सबसे पहले आप का उपयोग startActivityForResult()पहले में मानकों के साथ Activityऔर यदि आप दूसरे से डेटा भेजना चाहते हैं Activityपहले Activityतो का उपयोग कर मान पास Intentके साथ setResult()विधि और अंदर है कि डेटा प्राप्त onActivityResult()पहले में विधि Activity


1

Android में बहुत आम समस्या
यह 3 टुकड़ों में टूट सकती है
1) गतिविधि बी शुरू करें (गतिविधि ए में होता है)
2) अनुरोधित डेटा सेट करें (गतिविधि बी में होता है)
3) अनुरोधित डेटा प्राप्त करें (गतिविधि ए में होता है)

1) स्टार्टअक्टिविटी बी

Intent i = new Intent(A.this, B.class);
startActivity(i);

2) अनुरोधित डेटा सेट करें

इस भाग में, आप तय करते हैं कि आप किसी विशेष घटना के होने पर डेटा वापस भेजना चाहते हैं या नहीं।
जैसे: गतिविधि B में एक EditText और दो बटन b1, b2 है।
बटन बी 1 पर क्लिक करने से डेटा वापस गतिविधि
पर आ जाता है बटन बी 2 पर क्लिक करने से कोई डेटा नहीं भेजा जाता है।

डेटा भेज रहा है

b1......clickListener
{
   Intent resultIntent = new Intent();
   resultIntent.putExtra("Your_key","Your_value");
   setResult(RES_CODE_A,resultIntent);
   finish();
}

डेटा नहीं भेज रहा है

b2......clickListener
    {
       setResult(RES_CODE_B,new Intent());
       finish();
    }

उपयोगकर्ता वापस बटन पर क्लिक करता है
डिफ़ॉल्ट रूप से, परिणाम गतिविधि के साथ सेट होता है। RESULT_CANCEL प्रतिक्रिया कोड

3) परिणाम प्राप्त करें

इसके लिए onActivityResult विधि को ओवरराइड करें

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

if (resultCode == RES_CODE_A) {

     // b1 was clicked 
   String x = data.getStringExtra("RES_CODE_A");

}
else if(resultCode == RES_CODE_B){

   // b2 was clicked

}
else{
   // back button clicked 
}
}

1

ActivityResultRegistry अनुशंसित दृष्टिकोण है

ComponentActivityअब एक प्रदान करता है ActivityResultRegistryआप को संभाल देता है कि startActivityForResult()+ onActivityResult()के रूप में रूप में अच्छी तरह requestPermissions()+ onRequestPermissionsResult()अपने में तरीकों अधिभावी बिना बहती है Activityया Fragment, के माध्यम से वृद्धि हुई प्रकार सुरक्षा लाता है ActivityResultContract, और परीक्षण इन बहती के लिए हुक प्रदान करता है।

AndroidX गतिविधि 1.2.0-Alpha02 और Fragment 1.3.0-Alpha22 में शुरू की गई गतिविधि परिणाम एपीआई का उपयोग करने के लिए दृढ़ता से अनुशंसा की जाती है।

इसे अपने में जोड़ें build.gradle

def activity_version = "1.2.0-alpha03"

// Java language implementation
implementation "androidx.activity:activity:$activity_version"
// Kotlin
implementation "androidx.activity:activity-ktx:$activity_version"

पूर्व-निर्मित अनुबंध का उपयोग कैसे करें?

इस नए एपीआई में निम्नलिखित पूर्व निर्मित कार्य हैं

  1. वीडियो बनाओ
  2. PickContact
  3. सामग्री लो
  4. GetContents
  5. OpenDocument
  6. OpenDocuments
  7. OpenDocumentTree
  8. CreateDocument
  9. डायल
  10. तस्वीर ले लो
  11. अनुमति का अनुरोध करें
  12. RequestPermissions

एक उदाहरण जो takePicture अनुबंध का उपयोग करता है:

private val takePicture = prepareCall(ActivityResultContracts.TakePicture()) 
     { bitmap: Bitmap? ->
        // Do something with the Bitmap, if present
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        button.setOnClickListener { takePicture() }
       }

तो यहां क्या हो रहा है? चलो इसे थोड़ा नीचे तोड़ो। takePictureबस एक कॉलबैक है जो एक अशक्त बिटमैप को लौटाता है - यह शून्य है या नहीं यह इस बात पर निर्भर करता है कि onActivityResultप्रक्रिया सफल थी या नहीं । prepareCallफिर इस कॉल को एक नई सुविधा में पंजीकृत करता है ComponentActivityजिसे कहा जाता है ActivityResultRegistry- हम इसके बाद वापस आएंगे। ActivityResultContracts.TakePicture()उन अंतर्निहित मददगारों में से एक है जो Google ने हमारे लिए बनाए हैं, और अंत में आह्वान takePictureवास्तव में उसी तरह से आशय को ट्रिगर करता है जैसे आप पहले करते थे Activity.startActivityForResult(intent, REQUEST_CODE)

कस्टम अनुबंध कैसे लिखें?

सरल अनुबंध जो इंट को एक इनपुट के रूप में लेता है और स्ट्रिंग का रिटर्न करता है जो परिणाम के उद्देश्य से गतिविधि रिटर्न का अनुरोध करता है।

    class MyContract : ActivityResultContract<Int, String>() {

    companion object {
        const val ACTION = "com.myapp.action.MY_ACTION"
        const val INPUT_INT = "input_int"
        const val OUTPUT_STRING = "output_string"
    }

    override fun createIntent(input: Int): Intent {
        return Intent(ACTION)
            .apply { putExtra(INPUT_INT, input) }
    }

    override fun parseResult(resultCode: Int, intent: Intent?): String? {
        return when (resultCode) {
            Activity.RESULT_OK -> intent?.getStringExtra(OUTPUT_STRING)
            else -> null
        }
    }
}



    class MyActivity : AppCompatActivity() {

    private val myActionCall = prepareCall(MyContract()) { result ->
        Log.i("MyActivity", "Obtained result: $result")
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ...
        button.setOnClickListener {
            myActionCall(500)
        }
    }
}

अधिक जानकारी के लिए इस आधिकारिक दस्तावेज की जाँच करें


0
You need to override Activity.onActivityResult()

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

if (resultCode == RESULT_CODE_ONE) {


   String a = data.getStringExtra("RESULT_CODE_ONE");

}
else if(resultCode == RESULT_CODE_TWO){

   // b was clicked

}
else{

}
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.