两个应用程序使用 Intent 进行通信,传递数据
Two apps communicating using Intent, passing data
我正在尝试解决使用 Intent 在不同应用程序之间传递数据的问题。
场景是这样的:
Main
(App 1):用户点击Register
Main
应用程序在 Register
(应用程序 2) 中启动 Register
activity(表单)
- 用户输入名字、姓氏等,点击
Send Back
Register
应用返回值到 Main
应用
Main
应用程序显示用户数据
注意Register
activity不是Register
activity中的主要activity。
我想在没有额外 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);
}
}
Manifest
文件 Register
activity 在 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
activity 中单击 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:
To advertise which implicit intents your app can receive, declare one or more intent filters for each of your app components with an element in your manifest file.
从第一个应用程序创建一个 Intent
,它将带您进入第二个应用程序。如果您不想打开 Android share sheet
那么我建议您使用 PackageManager
获取所有可以接收您的数据的活动,然后在列表中找到您的第二个应用程序并使用 setComponent()
和你的 intent
。 (检查下面我的代码)
在我们的第二个应用程序中,执行与第一个应用程序相同的操作,但现在您可以添加 extras
或名字和第二个名字等数据。
回到我们的第一个应用程序,编写代码来接收来自我们第二个应用程序的传入 intent
,然后就完成了!
参考:
有关 sending/receiving 具有意图的数据的更多信息。
这是一个示例代码:
第一个应用程序的主要 Activity
@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>
第二个应用程序的接收器Activity(在本例中,您的注册应用程序)
注意:如您所愿,这不是主要的 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
/* 用户在寄存器中点击发送回 activity */
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)
因为它是多余的。有关意图的更多信息,您可以查看 this
但是,本指南对任何试图将数据从一个 activity 解析到另一个的人应该有用。
我正在尝试解决使用 Intent 在不同应用程序之间传递数据的问题。 场景是这样的:
Main
(App 1):用户点击Register
Main
应用程序在Register
(应用程序 2) 中启动 - 用户输入名字、姓氏等,点击
Send Back
Register
应用返回值到Main
应用Main
应用程序显示用户数据
Register
activity(表单)
注意Register
activity不是Register
activity中的主要activity。
我想在没有额外 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);
}
}
Manifest
文件 Register
activity 在 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
activity 中单击 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:
To advertise which implicit intents your app can receive, declare one or more intent filters for each of your app components with an element in your manifest file.
从第一个应用程序创建一个 Intent
,它将带您进入第二个应用程序。如果您不想打开 Android share sheet
那么我建议您使用 PackageManager
获取所有可以接收您的数据的活动,然后在列表中找到您的第二个应用程序并使用 setComponent()
和你的 intent
。 (检查下面我的代码)
在我们的第二个应用程序中,执行与第一个应用程序相同的操作,但现在您可以添加 extras
或名字和第二个名字等数据。
回到我们的第一个应用程序,编写代码来接收来自我们第二个应用程序的传入 intent
,然后就完成了!
参考:
有关 sending/receiving 具有意图的数据的更多信息。
这是一个示例代码:
第一个应用程序的主要 Activity
@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>
第二个应用程序的接收器Activity(在本例中,您的注册应用程序) 注意:如您所愿,这不是主要的 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
/* 用户在寄存器中点击发送回 activity */
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)
因为它是多余的。有关意图的更多信息,您可以查看 this
但是,本指南对任何试图将数据从一个 activity 解析到另一个的人应该有用。