从另一个程序安装 apk

发布于 2024-12-20 15:49:57 字数 492 浏览 2 评论 0原文

我正在尝试创建一个应用程序,自动从特定服务器下载 apk 并将其安装在系统上。我的安装代码如下所示,但不起作用。

File f = new File("/mnt/sdcard/download/", "Demo.apk");
Log.i("Demo", "f "+f.getAbsoluteFile());
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(f), "application/vnd.android.package_archive");
intent.addFlags(intent.FLAG_ACTIVITY_NEW_TASK);
m_context.startActivity(intent);            

我需要在 Manifest.xml 中授予安装权限吗?我知道这个问题以前曾被问过,但到目前为止,没有一个答案对我有帮助。

I'm trying to create an application that automatically downloads an apk from a specific server and install it on the system. My code for the installation looks like the following, but does not work.

File f = new File("/mnt/sdcard/download/", "Demo.apk");
Log.i("Demo", "f "+f.getAbsoluteFile());
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(f), "application/vnd.android.package_archive");
intent.addFlags(intent.FLAG_ACTIVITY_NEW_TASK);
m_context.startActivity(intent);            

Do i need to give any rights in Manifest.xml for installation? I know that question has been asked before, but none of the answers have helped me so far.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

北音执念 2024-12-27 15:49:57

这就是我在我的例子中所做的,

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(path+"/<application_name>.apk")), "application/vnd.android.package-archive");
startActivity(intent);

这些是权限..

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

This what I do in my case,

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(path+"/<application_name>.apk")), "application/vnd.android.package-archive");
startActivity(intent);

And these are the permissions..

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
秋日私语 2024-12-27 15:49:57

感谢大家的帮助,终于成功了。我分享我的工作代码和工作 Manifest.xml。

package test.installer;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;

public class InstallToolActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.i("Demo", "onCreate");
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(Uri.parse("file://"+"/mnt/sdcard/HelloWorld.apk"), "application/vnd.android.package-archive");
    intent.addFlags(intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);
    }
}

清单.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="test.installer"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk android:minSdkVersion="11" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.INSTALL_PACKAGES"/>
<uses-permission android:name="android.permission.RESTART_PACKAGES"/>


<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >
    <activity
        android:label="@string/app_name"
        android:name=".InstallToolActivity" >
        <intent-filter >
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

//弗雷德里克

Thanks for all help, made it work at last. I share my working code and working Manifest.xml.

package test.installer;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;

public class InstallToolActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.i("Demo", "onCreate");
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(Uri.parse("file://"+"/mnt/sdcard/HelloWorld.apk"), "application/vnd.android.package-archive");
    intent.addFlags(intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);
    }
}

Manifext.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="test.installer"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk android:minSdkVersion="11" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.INSTALL_PACKAGES"/>
<uses-permission android:name="android.permission.RESTART_PACKAGES"/>


<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >
    <activity
        android:label="@string/app_name"
        android:name=".InstallToolActivity" >
        <intent-filter >
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

//Fredrik

小女人ら 2024-12-27 15:49:57

我也这样做

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

,我的安装看起来像这样,

intent.setDataAndType(Uri.parse("file://"+path), "application/vnd.android.package-archive");

我的 path 是一个字符串,就像你的 f

i also do

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

and my install lookd like this

intent.setDataAndType(Uri.parse("file://"+path), "application/vnd.android.package-archive");

my path is a String, like your f

御弟哥哥 2024-12-27 15:49:57

你需要这样做

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(f), "application/vnd.android.package-archive");

在你的代码中,你提到了“package_archive”,它应该是“package-archive”。

您需要以下权限。

<uses-permission android:name="android.permission.INSTALL_PACKAGES"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>

You need to do this

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(f), "application/vnd.android.package-archive");

In your code, you have mentioned "package_archive", it should be "package-archive".

You would need the following permissions.

<uses-permission android:name="android.permission.INSTALL_PACKAGES"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
甜点 2024-12-27 15:49:57

如果您的 targetSdkVersion 等于或高于 24,那么您需要为 Android N 及更高版本的 Android 版本使用 FileProvider 实现。

整个实现如下:

// utility method
private void openAppInstaller(Context context, File toInstall) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        Uri apkUri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", toInstall);
        Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
        intent.setData(apkUri);
        intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        context.startActivity(intent)
    } else {
        Uri apkUri = Uri.fromFile(toInstall);
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    }
}

将provider FileProvider添加到AndroidManifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    <application
        ...
        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="${applicationId}.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"/>
        </provider>
    </application>
</manifest>

,并在xml资源下创建provider_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path name="external_files" path="."/>
</paths>

有关 FileProvider 配置的更多信息,您可以阅读此处此处

所有积分均归 @just_user 因为我的答案基于 他的回复

If your targetSdkVersion is equal or higher than 24, then you need to use FileProvider implementation for Android N and newer Android versions.

Here is the whole implementation:

// utility method
private void openAppInstaller(Context context, File toInstall) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        Uri apkUri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", toInstall);
        Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
        intent.setData(apkUri);
        intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        context.startActivity(intent)
    } else {
        Uri apkUri = Uri.fromFile(toInstall);
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    }
}

Add provider FileProvider to AndroidManifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    <application
        ...
        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="${applicationId}.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"/>
        </provider>
    </application>
</manifest>

And create provider_paths.xml under xml resources.

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path name="external_files" path="."/>
</paths>

More info about FileProvider configuration you can read here and here.

All credits go to @just_user because my answer based on his reply.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文