繁体   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