【问题标题】:How to pass data both ways between different android applications?如何在不同的android应用程序之间双向传递数据?
【发布时间】:2013-09-23 18:12:27
【问题描述】:

将字符串变量从一个应用程序传递到另一个应用程序并返回值的最简单方法是什么?我可以访问这两个应用程序的源代码,但它必须是两个不同的应用程序。

我尝试使用 startActivityForResult,但这似乎只适用于同一应用程序的活动之间。从不同的包调用活动时,startActivityForResult 立即返回 RESULT_CANCELED。似乎有可能通过服务来解决这个问题,但是对于一些字符串变量来说是不是有点过大了?

有没有简单干净的方法来做到这一点?

这是我尝试用于 startActivityForResult 的代码:

//App A:
            Intent intent = new Intent();
            intent.setAction("com.example.testapp.MESSAGE");
            Bundle b = new Bundle();
            b.putString("loginToken", "263bhqw3jhf6as4yf8j0agtz8h2hj2z9j3hg3g3ggh34uzh2h2ui78h3i9wdnj89x");
            intent.putExtra("MyData", b);

            startActivityForResult(intent, TEST_REQUEST);

    @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d("pairing", "onActivityResult called");
    // Check which request we're responding to
    if (requestCode == TEST_REQUEST) {
        // Make sure the request was successful
        Log.d("pairing", "got result, resultCode: " + resultCode);
        if (resultCode == RESULT_OK) {
            // The Intent's data Uri identifies which contact was selected.
            if (data.hasExtra("returnMessage")) {
                Toast.makeText(this, data.getExtras().getString("returnMessage"), Toast.LENGTH_LONG).show();
            }

        }
    }
}


            // App B:
        Intent result = new Intent();
        Bundle b = new Bundle();
        b.putString("returnValue", "this is the returned value");
        result.putExtra("MyData", b);
        setResult(Activity.RESULT_OK, result);
        Log.d("pairing", "RESULT_OK set");
        finish();


//App B Manifest
        <activity
        android:name="com.example.testapp"
        android:launchMode="singleTop"
        android:screenOrientation="portrait"
        android:windowSoftInputMode="adjustPan" >
        <intent-filter>
            <action android:name="com.example.testapp.MESSAGE" />

            <category android:name="android.intent.category.DEFAULT" />

            <data android:mimeType="text/plain" />
        </intent-filter></activity>

有人看到错误了吗?应用 B 总是立即返回 RESULT_CANCELED

编辑: 现在我得到一个 android.content.activitynotfoundexception no activity found to handle intent { act=com.example.testapp.MESSAGE (has extras) } 错误。我做错了什么?

【问题讨论】:

  • 可以把这两个活动的代码贴出来吗?
  • startActivityForResult 应该可以工作...问题似乎在您的代码中
  • 对我来说这似乎用 startActivityForResult() 是不可能的。它适用于同一应用程序的活动之间,即使使用不同的包,但不适用于两个不同的应用程序。见link
  • 从清单中删除 &lt;data android:mimeType="text/plain" /&gt; 部分

标签: android android-intent android-activity


【解决方案1】:

AIDL 是使用接口在两个不同应用程序之间进行通信的一种方式

http://developer.android.com/guide/components/aidl.html

您可以在以下教程中找到一个工作示例 http://manishkpr.webheavens.com/android-aidl-example/

【讨论】:

    【解决方案2】:

    你可以使用ContentProvider。这是比其他人更好的方法。

    【讨论】:

    • 对我来说似乎有点难过,我必须设置一个 ContentProvider 来发送两个或三个字符串。然而,这似乎是最优雅的解决方案。
    • 这只是对您的建议方式。您也可以尝试其他答案。 sharedpreference 也是一个好方法。这取决于您要使用什么以及如何使用的要求。谢谢
    【解决方案3】:

    SharedPreferences 可能会在这方面为您提供帮助。

    【讨论】:

    • 嗯,这会是一种干净的方式来传递(无需存储)数据吗?那么只需在一个应用程序中声明一个 SharedPreference 并将其用于两个应用程序?
    • 如果您使用SharedPreferences,数据将在本地存储。对于任何特定的首选项集,所有客户端共享此类的单个实例。因此修改一次,修改后的值反映在任何地方。这样可以访问数据。我更喜欢这个而不是数据传递(使用意图、putExtra 等)。
    【解决方案4】:

    我有两个应用程序可以将数据传入/传出。

    App1...
    Intent i = new Intent("com.xxx.yyy.MESSAGE");
    Bundle b = new Bundle();
    b.putString("AAA", getAAA());
    i.putExtra("MyData", b);
    startActivityForResult(i, "myProcess");
    

    没什么好看的...

    App2...in onResume()...

     Intent i = getIntent();
     if (i != null && i.getAction().equals("com.xxx.yyy.MESSAGE") {
        ...get the data from the bundle
     }
    

    请注意,AndroidManifest.xml(适用于 App2)包含以下活动之一的条目

     <intent-filter>
        <action android:name="com.xxx.yyy.MESSAGE"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain"/>
     </intent-filter>
    

    【讨论】:

    • 当您将数据传递给 App2 时,这是有效的,但是您不能将某些东西传回来,对吗?当我尝试这样做时,onActivityResult 处的 RESULT_CANCELED 事件立即返回
    • 是的...我处理数据(在 App2 中)并将其传递回 App1。再次,捆绑在一起...我已经关闭了我的开发机器,所以我不记得我这样做的确切方式...但它是standard(在文档中)。 App1 在onActivityResult(xxx, yyy, data)中接听
    • app1 和 app2 不在同一个包中?我尝试了你的方法,但它对我不起作用。我将在上面提供我的代码
    • 在 App2 的 onFinish() 中,我创建了另一个 Intent,其中包含我要传回的数据。返回调用应用程序(App1)然后我调用setResult(RESULT_OK, returnIntent);,当然,除非我遇到错误然后我返回到App1 setResult(RESULT_CANCELED);
    • 我不确定我做错了什么......你能否提供所有相关的清单和清单?我真的很想知道,我做错了什么......
    【解决方案5】:

    您可以在属于这些应用的两个服务之间交换信使(即使这些应用来自两个不同的包)并使用这些信使进行通信。

    【讨论】:

      【解决方案6】:
      public class MyParcelable implements Parcelable {
          // You can include parcel data types
          private int mData;
          private String mName;
      
          // We can also include child Parcelable objects. Assume MySubParcel is such a Parcelable:
          private MySubParcelable mInfo;
      
          // This is where you write the values you want to save to the `Parcel`.  
          // The `Parcel` class has methods defined to help you save all of your values.  
          // Note that there are only methods defined for simple values, lists, and other Parcelable objects.  
          // You may need to make several classes Parcelable to send the data you want.
          @Override
          public void writeToParcel(Parcel out, int flags) {
              out.writeInt(mData);
              out.writeString(mName);
              out.writeParcelable(mInfo, flags)
          }
      
          // Using the `in` variable, we can retrieve the values that 
          // we originally wrote into the `Parcel`.  This constructor is usually 
          // private so that only the `CREATOR` field can access.
          private MyParcelable(Parcel in) {
              mData = in.readInt();
              mName = in.readString();
              mInfo = in.readParcelable(MySubParcelable.class.getClassLoader());
          }
      
          public MyParcelable() {
              // Normal actions performed by class, since this is still a normal object!
          }
      
          // In the vast majority of cases you can simply return 0 for this.  
          // There are cases where you need to use the constant `CONTENTS_FILE_DESCRIPTOR`
          // But this is out of scope of this tutorial
          @Override
          public int describeContents() {
              return 0;
          }
      
          // After implementing the `Parcelable` interface, we need to create the 
          // `Parcelable.Creator<MyParcelable> CREATOR` constant for our class; 
          // Notice how it has our class specified as its type.  
          public static final Parcelable.Creator<MyParcelable> CREATOR
                  = new Parcelable.Creator<MyParcelable>() {
      
              // This simply calls our new constructor (typically private) and 
              // passes along the unmarshalled `Parcel`, and then returns the new object!
              @Override
              public MyParcelable createFromParcel(Parcel in) {
                  return new MyParcelable(in);
              }
      
              // We just need to copy this and change the type to match our class.
              @Override
              public MyParcelable[] newArray(int size) {
                  return new MyParcelable[size];
              }
          };
      }
      

      READ HERE

      【讨论】:

      • 问题很清楚。如何在两个不同的应用程序之间传递数据。您的案例将适用于两种不同的活动。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-21
      • 2017-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-15
      相关资源
      最近更新 更多