Android 使用 FileProvider 分享应用的 apk
Android share app's apk using FileProvider
我已尝试通过清单文件中的 intent.The 提供商共享应用程序的 apk 文件:
`<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="package name"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/mypaths" />
mypaths 文件是:
<paths>
<external-path name="apk_folder"/>
</paths>
我将意图和文件路径设置如下:
String packageName = getContext().getPackageName();
PackageManager pm = getContext().getPackageManager();
String apk = null;
try {
ApplicationInfo ai = pm.getApplicationInfo(packageName, 0);
apk = ai.publicSourceDir;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
File apkFile = new File(apk);
Uri uri = FileProvider.getUriForFile(getContext(), "package name", apkFile);
Intent intent = ShareCompat.IntentBuilder.from(getActivity())
.setType("*/*")
.setStream(uri)
.setChooserTitle("Share via")
.createChooserIntent()
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
我得到 IllegalArgumentException :
Failed to find configured root that contains /data/app/package name.edu-1/base.apk
请帮我找出错误。
FileProvider
中没有可处理您指定位置的可用根目录。您需要为此创建自己的 ContentProvider
。
我完全可以解决这个问题,只需要使用:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<root-path path="data/app/" name="external_files"/>
</resources>
将代码中的 "package name" 更改为 activity.getPackageName() 并将路径更改为 根路径
或尝试此代码:
在清单
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"/>
</provider>
在res/xml/file_paths.xml
<paths>
<root-path
name="app"
path="/"/>
</paths>
代码 :
public static void sendApkFile(Activity activity) {
try {
PackageManager pm = activity.getPackageManager();
ApplicationInfo ai = pm.getApplicationInfo(activity.getPackageName(), 0);
File srcFile = new File(ai.publicSourceDir);
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("*/*");
Uri uri = FileProvider.getUriForFile(context, activity.getPackageName(), srcFile);
intent.putExtra(Intent.EXTRA_STREAM, uri);
activity.grantUriPermission(activity.getPackageManager().toString(), uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
activity.startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
}
如果你想让 APK 文件有任何其他名称,而不仅仅是 base.APK,试试这个
public static void sendApplication(Activity activity) {
ApplicationInfo app = activity.getApplicationContext().getApplicationInfo();
String filePath = app.sourceDir;
Intent intent = new Intent(Intent.ACTION_SEND);
// MIME of .apk is "application/vnd.android.package-archive".
// but Bluetooth does not accept this. Let's use "*/*" instead.
intent.setType("*/*");
// Append file and send Intent
File originalApk = new File(filePath);
try {
//Make new directory in new location
File tempFile = new File(activity.getExternalCacheDir() + "/ExtractedApk");
//If directory doesn't exists create new
if (!tempFile.isDirectory()) {
if (!tempFile.mkdirs()) {
return;
}
}
//Get application's name and convert to lowercase
tempFile = new File(tempFile.getPath() + "/" + activity.getString(app.labelRes).replace(" ", "").toLowerCase() + ".apk");
//If file doesn't exists create new
if (!tempFile.exists()) {
if (!tempFile.createNewFile()) {
return;
}
}
//Copy file to new location
InputStream in = new FileInputStream(originalApk);
OutputStream out = new FileOutputStream(tempFile);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
System.out.println("File copied.");
//Open share dialog
Uri uri = FileProvider.getUriForFile(context, activity.getPackageName(), tempFile);
intent.putExtra(Intent.EXTRA_STREAM, uri);
activity.grantUriPermission(activity.getPackageManager().toString(), uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
activity.startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
}
我已尝试通过清单文件中的 intent.The 提供商共享应用程序的 apk 文件:
`<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="package name"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/mypaths" />
mypaths 文件是:
<paths>
<external-path name="apk_folder"/>
</paths>
我将意图和文件路径设置如下:
String packageName = getContext().getPackageName();
PackageManager pm = getContext().getPackageManager();
String apk = null;
try {
ApplicationInfo ai = pm.getApplicationInfo(packageName, 0);
apk = ai.publicSourceDir;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
File apkFile = new File(apk);
Uri uri = FileProvider.getUriForFile(getContext(), "package name", apkFile);
Intent intent = ShareCompat.IntentBuilder.from(getActivity())
.setType("*/*")
.setStream(uri)
.setChooserTitle("Share via")
.createChooserIntent()
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
我得到 IllegalArgumentException :
Failed to find configured root that contains /data/app/package name.edu-1/base.apk
请帮我找出错误。
FileProvider
中没有可处理您指定位置的可用根目录。您需要为此创建自己的 ContentProvider
。
我完全可以解决这个问题,只需要使用:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<root-path path="data/app/" name="external_files"/>
</resources>
将代码中的 "package name" 更改为 activity.getPackageName() 并将路径更改为 根路径
或尝试此代码:
在清单
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"/>
</provider>
在res/xml/file_paths.xml
<paths>
<root-path
name="app"
path="/"/>
</paths>
代码 :
public static void sendApkFile(Activity activity) {
try {
PackageManager pm = activity.getPackageManager();
ApplicationInfo ai = pm.getApplicationInfo(activity.getPackageName(), 0);
File srcFile = new File(ai.publicSourceDir);
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("*/*");
Uri uri = FileProvider.getUriForFile(context, activity.getPackageName(), srcFile);
intent.putExtra(Intent.EXTRA_STREAM, uri);
activity.grantUriPermission(activity.getPackageManager().toString(), uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
activity.startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
}
如果你想让 APK 文件有任何其他名称,而不仅仅是 base.APK,试试这个
public static void sendApplication(Activity activity) {
ApplicationInfo app = activity.getApplicationContext().getApplicationInfo();
String filePath = app.sourceDir;
Intent intent = new Intent(Intent.ACTION_SEND);
// MIME of .apk is "application/vnd.android.package-archive".
// but Bluetooth does not accept this. Let's use "*/*" instead.
intent.setType("*/*");
// Append file and send Intent
File originalApk = new File(filePath);
try {
//Make new directory in new location
File tempFile = new File(activity.getExternalCacheDir() + "/ExtractedApk");
//If directory doesn't exists create new
if (!tempFile.isDirectory()) {
if (!tempFile.mkdirs()) {
return;
}
}
//Get application's name and convert to lowercase
tempFile = new File(tempFile.getPath() + "/" + activity.getString(app.labelRes).replace(" ", "").toLowerCase() + ".apk");
//If file doesn't exists create new
if (!tempFile.exists()) {
if (!tempFile.createNewFile()) {
return;
}
}
//Copy file to new location
InputStream in = new FileInputStream(originalApk);
OutputStream out = new FileOutputStream(tempFile);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
System.out.println("File copied.");
//Open share dialog
Uri uri = FileProvider.getUriForFile(context, activity.getPackageName(), tempFile);
intent.putExtra(Intent.EXTRA_STREAM, uri);
activity.grantUriPermission(activity.getPackageManager().toString(), uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
activity.startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
}