java - 两个应用程序使用 Intent 进行通信,传递数据
问题描述
我正在尝试解决使用 Intent 在不同应用程序之间传递数据的问题。场景是这样的:
Main
(App 1):用户点击Register
Main
应用程序在(应用程序 2)中启动Register
活动(表单)Register
- 用户输入名字、姓氏等,点击
Send Back
Register
Main
应用程序向应用程序返回值Main
应用显示用户数据
注意Register
activity不是activity中的主要Register
activity。我想在没有额外课程和广播的情况下解决这个问题。
我的主应用程序代码,用户单击注册方法:
/* 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);
}
}
Manifest
Register
应用程序中的活动文件Register
:
<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
clickSend 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
来自第二个应用程序的传入的代码,然后就完成了!
参考:
有关使用意图发送/接收数据的更多信息。
这是一个示例代码:
第一个应用程序的主要活动
@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>
快乐编码!
编辑:我为我的答案添加了解释。
推荐阅读
- messagekit - 如何创建和显示最简单的短信?
- excel - 基于其他列创建列
- javascript - 如何在猫鼬中使用基本模式到子模式
- perl - 在 Perl 中检查文件是否处于打开状态
- c# - DateTimeOffset.TryParse 不会在 .Net 5.0 中格式化俄罗斯 RFC 日期,但它可以在 .Net 3.1 中使用。为什么?
- scala - Scala:在单行中调用具有另一个纯函数作为参数(HOF)的纯函数
- r - 如何使用R中的变量访问数据框?
- java - 单过滤器的奇数和偶数?
- python - 如何从条件选择的值中有效地生成百分比差异序列?
- excel - VBA问题,将值影响到excel列