簡體   English   中英

兩個應用程序使用 Intent 進行通信,傳遞數據

[英]Two apps communicating using Intent, passing data

我正在嘗試解決使用 Intent 在不同應用程序之間傳遞數據的問題。 場景是這樣的:

  1. Main (App 1): 用戶點擊Register
  2. Main應用在Register (應用 2)中啟動Register活動(表單)
  3. 用戶輸入名字、姓氏等,點擊Send Back
  4. 將應用返回值RegisterMain應用
  5. Main應用顯示用戶數據

請注意, Register活動不是Register活動中的主要活動。 我想在沒有額外的 class 並且沒有廣播的情況下解決這個問題。

我的主應用程序代碼,用戶單擊注冊方法:

    /* User clicks Register */
public void clickRegister(View view) {
    Intent intent = new Intent(Intent.ACTION_SEND);
    // Verify it resolves
    PackageManager packageManager = getPackageManager();
    List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0);
    boolean isIntentSafe = activities.size() > 0;

    // Start an activity if it's safe
    if (isIntentSafe) {
        startActivity(intent);
    }
}

Register應用程序中Register活動的Manifest文件:

        <activity android:name="com.example.register.Register">
        <intent-filter>
            <action android:name="android.intent.action.SEND"/>
            <category android:name="android.intent.category.DEFAULT"/>
            <data android:mimeType="text/plain"/>
        </intent-filter>
    </activity>

現在,這是Register活動中的代碼,點擊Send Back方法:

    /* User clicks Send Back in register activity */
public void clickSendBack(View view) {
    // Create an Intent for Register class
    // Intent myIntent = new Intent(this, MainActivity.class);
    Intent myIntent = new Intent(Intent.ACTION_SEND);

    final EditText firstNameInput = (EditText) findViewById(R.id.firstNameEditText);
    final EditText secondNameInput = (EditText) findViewById(R.id.secondNameEditText);

    String firstName = firstNameInput.getText().toString();
    String secondName = secondNameInput.getText().toString();

    myIntent.setAction(Intent.ACTION_SEND);
    myIntent.putExtra("firstName",firstName);
    myIntent.putExtra("secondName",secondName);
    myIntent.setType("text/plain");

    // Starts activity
    startActivity(myIntent);

    finish();
}

在這里我被困住了。 希望聽到對此主題的任何澄清,並且解決方案的示例也很棒。

謝謝!

在第一個應用程序中,添加一個intent-filter以從第二個應用程序(即您的Register應用程序)接收數據。 現在,對您的Register應用程序執行相同的操作,我們需要這樣做,以便我們可以從我們的第一個應用程序調用它。

intent-filter是為了確保我們可以發回數據。 根據https://developer.android.com/guide/components/intents-filters

要宣傳您的應用可以接收哪些隱式 Intent,請使用清單文件中的一個元素為您的每個應用組件聲明一個或多個 Intent 過濾器。

從第一個應用程序創建一個Intent ,將您帶到第二個應用程序。 如果您不想打開Android share sheet ,那么我建議您使用PackageManager獲取所有可以接收您的數據的活動,然后在列表中找到您的第二個應用程序並使用setComponent()以您的intent打開它。 (檢查我下面的代碼)

在我們的第二個應用程序中,執行與第一個應用程序相同的操作,但現在您可以添加extras信息或數據,例如名字和名字。

回到我們的第一個應用程序,編寫將從我們的第二個應用程序接收傳入intent的代碼,然后就完成了!

參考:

https://developer.android.com/training/sharing

有關使用意圖發送/接收數據的更多信息。


這是一個示例代碼:

第一個應用程序的主要活動

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

    // Receive your data here from your Register app
    Intent receivedIntent = getIntent();
    String action = receivedIntent.getAction();
    String type = receivedIntent.getType();

    if (Intent.ACTION_SEND.equals(action) && type != null) {
        if ("text/plain".equals(type)) {
            handleReceivedData(receivedIntent);
        }
    }
}

private void handleReceivedData(Intent intent) {
    String firstName = intent.getStringExtra("first_name");
    String secondName = intent.getStringExtra("second_name");
    if (firstName == null || secondName == null) {
        Toast.makeText(this, "Cannot received data!", Toast.LENGTH_SHORT).show();
        return;
    }
    // Do here what you want with firstName and secondName
    // ...
    Toast.makeText(this, "First name: " + firstName +
            " Second name: " + secondName, Toast.LENGTH_SHORT).show();
}

public void open(View view) {
    Intent sendIntent = new Intent();
    sendIntent.setAction(Intent.ACTION_SEND);
    sendIntent.putExtra(Intent.EXTRA_TEXT,
            "Here you can put a message for your 'register' application");
    sendIntent.setType("text/plain");

    PackageManager packageManager = getPackageManager();
    List<ResolveInfo> activities = packageManager.queryIntentActivities(sendIntent,
            PackageManager.MATCH_DEFAULT_ONLY);

    ////////////////// Get the other application package name //////////////////
    // This is so the user cannot choose other apps to send your data
    // In order words, this will send the data back to the other
    // application without opening the Android Share sheet
    ActivityInfo activityInfo = null;
    for (ResolveInfo activity: activities) {
        // Specify here the package name of your register application
        if (activity.activityInfo.packageName.equals("com.example.registerapp")) {
            activityInfo = activity.activityInfo;
            break;
        }
    }

    // If the other application is not found then activityInfo will be null
    // So make sure you add the correct intent-filter there!
    if (activityInfo != null) {
        // This will open up your register application
        ComponentName name = new ComponentName(activityInfo.applicationInfo.packageName,
                activityInfo.name);
        sendIntent.setComponent(name);

        startActivity(sendIntent);
    }
    else {
        Toast.makeText(this,
                "Receiver app doesn't exist or not installed on this device!",
                Toast.LENGTH_SHORT).show();
    }
}

第一個應用程序的清單

    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.intent.action.SEND" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="text/plain" />
        </intent-filter>
    </activity>

第二個應用程序的接收器活動(在這種情況下,您的注冊應用程序)注意:如您所願,這不是主要活動

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_receiver);
    // This is NOT the main activity!
}

public void send(View view) {
    // I just want to note that I am calling the receiving application: "other application"

    EditText firstNameEditText = findViewById(R.id.firstNameEditText);
    EditText secondNameEditText = findViewById(R.id.secondNameEditText);
    String firstName = firstNameEditText.getText().toString().trim();
    String secondName = secondNameEditText.getText().toString().trim();
    // Check if any of the inputs are empty
    if (firstName.isEmpty() || secondName.isEmpty()) {
        Toast.makeText(this, "Text boxes cannot be empty!", Toast.LENGTH_SHORT).show();
        return;
    }

    // Send data back to the other application
    Intent sendBackIntent = new Intent();
    sendBackIntent.setAction(Intent.ACTION_SEND);
    sendBackIntent.putExtra("first_name", firstName);
    sendBackIntent.putExtra("second_name", secondName);
    sendBackIntent.setType("text/plain");

    // Get all the available applications that can receive your data
    // (in this case, first name and second name)
    PackageManager packageManager = getPackageManager();
    List<ResolveInfo> activities = packageManager.queryIntentActivities(sendBackIntent,
            PackageManager.MATCH_DEFAULT_ONLY);

    ////////////////// Get the other application package name //////////////////
    ActivityInfo activityInfo = null;
    for (ResolveInfo activity: activities) {
        // Specify here the package name of the other application
        if (activity.activityInfo.packageName.equals("com.example.mainapp")) {
            activityInfo = activity.activityInfo;
            break;
        }
    }

    if (activityInfo != null) {
        // Same as before, this will open up the other application
        ComponentName name = new ComponentName(activityInfo.applicationInfo.packageName,
                activityInfo.name);
        sendBackIntent.setComponent(name);

        startActivity(sendBackIntent);
    }
    else {
        Toast.makeText(this,
                "Receiver app doesn't exist or not installed on this device!",
                Toast.LENGTH_SHORT).show();
    }
}

第二個應用程序的清單

<activity android:name=".ReceiverActivity">
        <intent-filter>
            <action android:name="android.intent.action.SEND" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="text/plain" />
        </intent-filter>
    </activity>

快樂編碼!


編輯:我為我的答案添加了解釋。

您的RegisterActivity應該看起來像這樣 RegisterActivity 正在將用戶數據解析到 MainActivity

/* 用戶在注冊活動中點擊發回 */

public void clickSendBack(View view) {
   // Create an Intent for Register class

   final EditText firstNameInput =
   findViewById(R.id.firstNameEditText);
   final EditText secondNameInput =
   findViewById(R.id.secondNameEditText);

   String firstName = firstNameInput.getText().toString();
   String secondName = secondNameInput.getText().toString();

   Intent i = new Intent(RegisterActiivty.this, MainActivity.class);
   i.putExtra("firstName", firstName);
   i.putExtra("secondName", secondName);
   startActivity(i);

    }
 #################################################################

你的 MainActivity 應該是這樣的。 MainActivity 負責接收數據 這行代碼應該在你的 MainActivity 的 onCreate 方法中調用

    String firstName = getIntent().getStringExtra("firstName");
    String secondName = getIntent().getStringExtra("firstName")

    // if you have a TextView on MainActivity you could display the data you have 
    //gotten from the RegisterActivity like so

    Textview firstName = findViewById(R.id.firstName);
    firstName.setText(firstName);

    Textview secondName = findViewById(R.id.secondName);
    secondName.setText(secondName);

       /* User clicks Register */
    public void clickRegister(View view) {

      startActivity(Intent(this, RegisterActivity.class))

     }
 ##########################################################

您的清單應如下所示

     <activity android:name="com.example.register.Register"/>

我試圖理解您所說的主應用程序和注冊的含義。 聽起來好像它們是兩個不同的應用程序,或者可能是兩個不同的項目模塊。 但是,如果您要說的是 MainActivity 和 RegisterActivity 那么上述解決方案應該能夠解決您的問題。

你做錯了什么:

不需要您試圖在清單中解析的意圖。 如果我正確理解你想要達到的目標。 MainActivity 和 RegisterActivity 也是如此。 您使用的是隱式意圖而不是顯式意圖。 並且在調用 findViewById 時不需要這個額外的(EditText) ,因為它是多余的。 有關意圖的更多信息,您可以查看

但是,本指南應該對任何尋求將數據從一個活動解析到另一個活動的人有用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM