Android不同应用之间的数据传值

前言

不同应用之间的传值可以使用以下几种方式:

  • Intent传值:使用隐式Intent,但需要确保接收方应用可以响应该Intent。

  • Content Provider 通过Content Provider可以在不同的应用之间共享数据。

    一个应用可以将数据暴露给其他应用,并提供读写权限,其他应用可以通过ContentResolver访问这些数据。

  • 文件共享:两个应用之间可以通过文件共享的方式传递数据。

    一个应用可以将数据写入文件,另一个应用可以读取该文件来获取数据。

怎样选择:

假如A是数据的提供方,B是数据的接收方,

如果B一定是A唤起的并且传值的可以使用Intent传值方式

如果B也能自己打开,还要获取A的值,就使用Content Provider方式。

最后再考虑文件共享的方式。

Intent传值

使用Intent在不同的应用之间传递数据,可以通过Intent的putExtra()方法添加数据,并通过startActivity()或startActivityForResult()方法启动另一个应用。对于跨应用传值,可以使用隐式Intent,但需要确保接收方应用可以响应该Intent。

示例代码:

发送方应用:

1
2
3
4
Intent intent = new Intent();
intent.setAction("com.example.ACTION_SEND_DATA");
intent.putExtra("key", "value");
startActivity(intent);

接收方应用(在AndroidManifest.xml中声明接收Intent的过滤器):

1
2
3
4
5
<receiver android:name=".MyBroadcastReceiver">
<intent-filter>
<action android:name="com.example.ACTION_SEND_DATA" />
</intent-filter>
</receiver>

在接收方应用中的BroadcastReceiver中处理传递过来的数据:

1
2
3
4
5
6
7
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String value = intent.getStringExtra("key");
// 处理传递过来的数据
}
}

Content Provider

Content Provider:通过Content Provider可以在不同的应用之间共享数据。

一个应用可以将数据暴露给其他应用,并提供读写权限,其他应用可以通过ContentResolver访问这些数据。

这里使用ContentProvider来作为数据的存储地方。

注意:

Content Provider 提供数据的时候,如果提供方APP没有启动,获取方也是获取不到数据的。

提供方配置

在数据提供方应用中,定义一个Content Provider并在AndroidManifest.xml中注册:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.net.Uri;
import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.util.Iterator;
import java.util.Objects;

public class ZSpProvider extends ContentProvider {
private static final String AUTHORITY = "com.xhkjedu.mc.sharedpreferencesprovider";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/spData");

public static final String PARAM_KEY = "key";

public static final String PARAM_VALUE = "value";

private SharedPreferences mStore;

public static Cursor query(Context context, String... keys) {
return context.getContentResolver().query(CONTENT_URI, keys, null, null, null);
}

public static String getString(Context context, String key) {
return getString(context, key, null);
}

public static String getString(Context context, String key, String defValue) {
Cursor cursor = query(context, key);
if (cursor == null) {
return "";
}
String ret = defValue;
if (cursor.moveToNext()) {
ret = cursor.getString(0);
if (TextUtils.isEmpty(ret)) {
ret = defValue;
}
}
cursor.close();
return ret;
}

public static int getInt(Context context, String key, int defValue) {
Cursor cursor = query(context, key);
int ret = defValue;
if (cursor.moveToNext()) {
try {
ret = cursor.getInt(0);
} catch (Exception ignored) {

}
}
cursor.close();
return ret;
}

public static Uri save(Context context, ContentValues values) {
return context.getContentResolver().insert(CONTENT_URI, values);
}

public static Uri save(Context context, String key, String value) {
ContentValues values = new ContentValues(1);
values.put(key, value);
return save(context, values);
}

public static Uri save(Context context, String key, int value) {
ContentValues values = new ContentValues(1);
values.put(key, value);
return save(context, values);
}

public static Uri remove(Context context, String key) {
return save(context, key, null);
}

private Cursor createSingleCursor(String key, String value) {
MatrixCursor cursor = new MatrixCursor(new String[]{key}, 1);
if (!TextUtils.isEmpty(value)) {
cursor.addRow(new Object[]{value});
}
return cursor;
}

private Cursor createCursor(String[] keys, String[] values) {
MatrixCursor cursor = new MatrixCursor(keys, 1);
cursor.addRow(values);
return cursor;
}


private String getValue(String key, String defValue) {
return mStore.getString(key, defValue);
}

private void save(ContentValues values) {
String key;
String value;
Iterator<String> iterator = values.keySet().iterator();
SharedPreferences.Editor editor = mStore.edit();
while (iterator.hasNext()) {
key = iterator.next();
value = values.getAsString(key);
if (!TextUtils.isEmpty(key)) {
if (value != null) {
editor.putString(key, value);
} else {
editor.remove(key);
}
}
}
editor.apply();
}

private void save(String key, String value) {
SharedPreferences.Editor editor = mStore.edit();
if (value != null) {
editor.putString(key, value);
} else {
editor.remove(key);
}
editor.apply();
}

private void remove(String key) {
SharedPreferences.Editor editor = mStore.edit();
editor.remove(key);
editor.apply();
}

@Override
public boolean onCreate() {
String DB_NAME = "SPData";
mStore = Objects.requireNonNull(getContext()).getSharedPreferences(DB_NAME, Context.MODE_PRIVATE);
return true;
}

@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
int size = projection == null ? 0 : projection.length;
if (size > 0) {
String[] values = new String[size];
for (int i = 0; i < size; i++) {
values[i] = getValue(projection[i], null);
}
return createCursor(projection, values);
}
String key = uri.getQueryParameter(PARAM_KEY);
String value = null;
if (!TextUtils.isEmpty(key)) {
value = getValue(key, null);
}
return createSingleCursor(key, value);
}

@Nullable
@Override
public String getType(@NonNull Uri uri) {
return "";
}

@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
if (values != null && values.size() > 0) {
save(values);
} else {
String key = uri.getQueryParameter(PARAM_KEY);
String value = uri.getQueryParameter(PARAM_VALUE);
if (!TextUtils.isEmpty(key)) {
save(key, value);
}
}
return null;
}

@Override
public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
String key = selection != null ? selection : uri.getQueryParameter(PARAM_KEY);
if (!TextUtils.isEmpty(key)) {
remove(key);
return 1;
}
return 0;
}

@Override
public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
if (values != null && values.size() > 0) {
save(values);
return values.size();
}
String key = uri.getQueryParameter(PARAM_KEY);
String value = uri.getQueryParameter(PARAM_VALUE);
if (!TextUtils.isEmpty(key)) {
save(key, value);
return 1;
}
return 0;
}
}

在AndroidMenifest.xml中使用<provider>标签来设置ContentProvider

1
2
3
4
5
<provider
android:exported="true"
android:name="com.xhkjedu.xh_control_appstore.provider.ZSpProvider"
android:authorities="cn.psvmc.myapp.sharedpreferencesprovider">
</provider>

注:

android:exported="true"后才能在其他应用中访问。

AUTHORITY配置要和android:authorities保持一致即可,不一定要和项目包名一致。

提供方保存数据

1
ZSpProvider.save(this, "myblog", "www.psvmc.cn");

获取方配置

获取方同样添加上面的类,不用添加到AndroidMenifest.xml

但是要在AndroidMenifest.xmlapplication同级添加提供方的包名

1
2
3
<queries>
<package android:name="com.xhkjedu.manageapp"/>
</queries>

其中com.xhkjedu.manageapp是提供方的包名,一定要添加该配置否则获取不到数据。

获取数据

1
2
val vaue = ZSpProvider.getString(this, "myblog")
Log.i(TAG, "onCreate: $vaue")

文件共享

文件共享:两个应用之间可以通过文件共享的方式传递数据。一个应用可以将数据写入文件,另一个应用可以读取该文件来获取数据。

示例代码:

发送方应用:

1
2
3
4
5
6
7
8
9
String data = "Hello, this is data to be shared";
File file = new File(getExternalFilesDir(null), "shared_data.txt");
try {
FileOutputStream fos = new FileOutputStream(file);
fos.write(data.getBytes());
fos.close();
} catch (IOException e) {
e.printStackTrace();
}

接收方应用:

1
2
3
4
5
6
7
8
9
10
11
File file = new File(getExternalFilesDir(null), "shared_data.txt");
try {
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[(int) file.length()];
fis.read(buffer);
fis.close();
String data = new String(buffer);
// 处理读取到的数据
} catch (IOException e) {
e.printStackTrace();
}