Cài đặt ứng dụng một cách âm thầm với INSTALL_PACKAGES quyền được cấp


86

Tôi đang cố gắng âm thầm cài đặt apk vào hệ thống. Ứng dụng của tôi nằm trong / system / app và được cấp quyền thành công "android.permission.INSTALL_PACKAGES"

Tuy nhiên, tôi không thể tìm thấy bất kỳ nơi nào cách sử dụng quyền này. Tôi đã cố gắng sao chép tệp vào / data / app và không thành công. Ngoài ra, tôi đã thử sử dụng mã này

    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(
            Uri.parse("file:///sdcard/app.apk"),
            "application/vnd.android.package-archive");
    startActivity(intent);

Nhưng mã này mở hộp thoại cài đặt tiêu chuẩn. Làm cách nào tôi có thể cài đặt ứng dụng một cách im lặng mà không cần root được cấp phép android.permission.INSTALL_PACKAGES?

Tái bút Tôi đang viết một ứng dụng sẽ cài đặt nhiều apks từ thư mục vào hệ thống trong lần khởi động đầu tiên (thay thế Setup Wizard). Tôi cần nó để làm cho phần sụn nhẹ hơn.

Nếu bạn nghĩ rằng tôi đang viết vi-rút: Tất cả các chương trình đều được cài đặt vào / data / app. Quyền Install_packages chỉ có thể được cấp cho các chương trình cấp hệ thống nằm trong / system / app hoặc được ký bằng khóa hệ thống. Vì vậy, vi rút không thể đến được đó.

Như đã nói http://www.mail-archive.com/android-porting@googlegroups.com/msg06281.html ứng dụng CÓ THỂ được cài đặt im lặng nếu chúng có quyền install_packages. Hơn nữa, bạn không cần quyền Install_packages để cài đặt các gói không âm thầm. Cộng với http://www.androidzoom.com/android_application/tools/silent-installer_wgqi.html


9
@Fosco Giả sử anh ta đang sản xuất một thiết bị như nhà sản xuất thiết bị gốc?
dascandy

41
@Fosco Ai quan tâm? Đó là một câu hỏi hợp lệ như dascandy mô tả. Nói chung, nó không hiệu quả khi mọi người trả lời những câu hỏi như thế này với "Bạn không nên làm như vậy". Chúng ta đạt được hiểu biết gì với loại câu trả lời đó?
ZachM

3
Nói về việc không hiệu quả .. bạn đã đến bữa tiệc này muộn hơn 2 năm Zach, và câu hỏi có vẻ khác xa so với ban đầu.
Fosco

2
@Fosco LOL. Ngoài ra, tôi có thể xác nhận rằng điều này vẫn đang hoạt động trong hệ điều hành Android mới nhất.
POMATu

1
@LarsH Tôi vừa cài đặt ứng dụng F-Droid: Họ không cài đặt mọi thứ một cách âm thầm, Họ chỉ nhắc Trình quản lý gói của Android.
Joaquin Iurchuk 14/09/18

Câu trả lời:


60

Đặt cược đầu tiên của bạn là xem xét PackageInstaller gốc của Android . Tôi khuyên bạn nên sửa đổi ứng dụng đó theo cách bạn muốn hoặc chỉ trích xuất chức năng cần thiết.


Cụ thể, nếu bạn xem xét PackageInstallerActivity và phương pháp của nó onClickListener:

 public void onClick(View v) {
    if(v == mOk) {
        // Start subactivity to actually install the application
        Intent newIntent = new Intent();
        ...
        newIntent.setClass(this, InstallAppProgress.class);
        ...
        startActivity(newIntent);
        finish();
    } else if(v == mCancel) {
        // Cancel and finish
        finish();
    }
}

Sau đó, bạn sẽ nhận thấy rằng trình cài đặt thực sự nằm trong lớp InstallAppProgress . Kiểm tra rằng lớp bạn sẽ thấy rằng initViewlà chức năng cài đặt lõi, và điều cuối cùng nó là lời kêu gọi PackageManagercủa installPackagechức năng:

public void initView() {
...
pm.installPackage(mPackageURI, observer, installFlags, installerPackageName);
}

Bước tiếp theo là kiểm tra PackageManager , là lớp trừu tượng. Bạn sẽ tìm thấy installPackage(...)chức năng ở đó. Tin xấu là nó được đánh dấu bằng @hide. Điều này có nghĩa là nó không có sẵn trực tiếp (bạn sẽ không thể biên dịch bằng lệnh gọi tới phương thức này).

 /**
  * @hide
  * ....
  */
  public abstract void installPackage(Uri packageURI,
             IPackageInstallObserver observer, 
             int flags,String installerPackageName); 

Nhưng bạn sẽ có thể truy cập các phương pháp này thông qua phản chiếu.

Nếu bạn đang quan tâm như thế nào PackageManager's installPackagechức năng được thực hiện, hãy nhìn vào PackageManagerService .

Tóm lược

Bạn sẽ cần lấy đối tượng trình quản lý gói qua Context's getPackageManager(). Sau đó, bạn sẽ gọi installPackagechức năng thông qua phản chiếu.


2
Cứu giúp! Kỹ thuật này dẫn đến: Gây ra bởi: java.lang.SecurityException: Cả người dùng 10101 và quy trình hiện tại đều không có android.permission.INSTALL_PACKAGES. Mặc dù ứng dụng của tôi có quyền đó
gregm

13
Ứng dụng của bạn yêu cầu quyền đó nhưng Android không cấp quyền đó cho các ứng dụng của bên thứ ba. Xem LogCatcác bản ghi liên quan đến quyền.
inazaruk

@inazaruk, tôi đọc rằng các ứng dụng được cài đặt trong / system / app sẽ tự động có quyền sử dụng install_pakages nhưng như được mô tả trong bài đăng này, nó có vẻ không hoạt động. bạn có thể cho tôi một số gợi ý?
Zorb

3
Làm cách nào để gọi installPackage qua phản chiếu? thực sự tôi không thể thực hiện được Phương thức method = aPackageManagerClass.getMethod ("installPackage", new Class [] {Uri.class, IPackageInstallObserver.class, Integer.TYPE, String.class}); do IPackageInstallObserver cũng bị ẩn, ai đó có thể giúp tôi xin vui lòng, đăng mã chính xác để thực hiện phản ánh ở đây.
Shilaghae

7
Tất cả các liên kết trong câu trả lời đã chết.
Mayur Gangurde

13

Tôi đã kiểm tra cách ADB cài đặt ứng dụng.
- Nó sao chép APK sang / data / local / tmp
- nó chạy 'shell: pm install /data/local/tmp/app.apk'

Tôi đã cố gắng tái tạo hành vi này bằng cách thực hiện: (trên máy tính, sử dụng cáp USB)
adb push app.apk /sdcard/app.apk
adb shell
$ pm install /sdcard/app.apk
Điều này hoạt động. Ứng dụng đã được cài đặt.

Tôi đã tạo một ứng dụng (có tên AppInstall) sẽ cài đặt ứng dụng khác.
(cài đặt bình thường, thiết bị chưa root)
Nó có:
Runtime.getRuntime().exec("pm install /sdcard/app.apk").waitFor();
Nhưng điều này gây ra lỗi:
java.lang.SecurityException: Neither user 10019 nor current process has android.permission.INSTALL_PACKAGES.
Có vẻ như lỗi do pm, không phải do AppInstall.
Vì SecurityException không được cài đặt bởi AppInstall và ứng dụng không bị lỗi.

Tôi đã thử điều tương tự trên một thiết bị đã root (cùng một ứng dụng và AppInstall) và nó hoạt động như một sự quyến rũ.
(Cũng được cài đặt bình thường, không phải trong / system hay bất cứ thứ gì)
AppInstall thậm chí không yêu cầu quyền root.
Nhưng đó là bởi vì vỏ luôn #thay vì $trên thiết bị đó.

Btw, bạn cần root để cài đặt ứng dụng trong / system, đúng không?
Tôi đã thử truy cập lại adb trên thiết bị không được root và nhận được:
remount failed: Operation not permitted.
Đó là lý do tại sao tôi không thể thử điều / hệ thống trên thiết bị không root.

Kết luận: bạn nên sử dụng thiết bị đã root
Hy vọng điều này sẽ giúp ích :)


Tôi dường như không thể làm cho việc này hoạt động. Thật thú vị khi lệnh hoạt động tốt trong ADB shell và sau đó dường như không hoạt động khi tôi cố gắng chạy nó theo chương trình.
saulpower

Yep, tôi có cùng một vấn đề - công trình trong vỏ, nhưng không phải khi gọi từ ứng dụng của tôi, ngay cả khi tôi gọi nó qua su)
Velis

Có cách nào khác để hoạt động trong các thiết bị của Google như nhận quyền quản trị viên cấp cao không?
Ramesh Kumar

Nếu bạn muốn có quyền quản trị viên cấp cao, bạn nên: 1) root thiết bị của mình, 2) cài đặt ứng dụng trên phân vùng hệ thống, 3) hoặc ứng dụng phải được ký bằng khóa giống như chính hệ điều hành.
FrankkieNL

1
Điều này xảy ra vì người dùng ADB và người dùng ứng dụng của bạn có các quyền khác nhau
PHPoenX

11

Gần đây, tôi đã triển khai cài đặt mà không có sự đồng ý của người dùng - đó là một ứng dụng kiosk cho API cấp 21+, nơi tôi có toàn quyền kiểm soát môi trường.

Các yêu cầu cơ bản là

  • API cấp 21+
  • quyền truy cập root để cài đặt trình cập nhật như một ứng dụng đặc quyền của hệ thống.

Phương pháp sau đọc và cài đặt APK từ InputStream:

public static boolean installPackage(Context context, InputStream in, String packageName)
            throws IOException {
        PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();
        PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
                PackageInstaller.SessionParams.MODE_FULL_INSTALL);
        params.setAppPackageName(packageName);
        // set params
        int sessionId = packageInstaller.createSession(params);
        PackageInstaller.Session session = packageInstaller.openSession(sessionId);
        OutputStream out = session.openWrite("COSU", 0, -1);
        byte[] buffer = new byte[65536];
        int c;
        while ((c = in.read(buffer)) != -1) {
            out.write(buffer, 0, c);
        }
        session.fsync(out);
        in.close();
        out.close();

        Intent intent = new Intent(context, MainActivity.class);
        intent.putExtra("info", "somedata");  // for extra data if needed..

        Random generator = new Random();

        PendingIntent i = PendingIntent.getActivity(context, generator.nextInt(), intent,PendingIntent.FLAG_UPDATE_CURRENT);
            session.commit(i.getIntentSender());


        return true;
    }

Đoạn mã sau gọi cài đặt

 try {
     InputStream is = getResources().openRawResource(R.raw.someapk_source);
                    installPackage(MainActivity.this, is, "com.example.apk");
     } catch (IOException e) {
                    Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
     }

để toàn bộ công việc hoạt động mà bạn thực sự cần sự INSTALL_PACKAGEScho phép, nếu không đoạn mã trên sẽ bị lỗi một cách âm thầm

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

để có được quyền này, bạn phải cài đặt APK của mình dưới dạng ứng dụng Hệ thống YÊU CẦU root (tuy nhiên SAU KHI bạn đã cài đặt ứng dụng trình cập nhật của mình, ứng dụng này có vẻ hoạt động KHÔNG root)

Để cài đặt làm ứng dụng hệ thống, tôi đã tạo APK đã ký và đẩy nó bằng

adb push updater.apk /sdcard/updater.apk

và sau đó di chuyển nó đến system/priv-app- yêu cầu điều chỉnh lại FS (đây là lý do tại sao root được yêu cầu)

adb shell
su
mount -o rw,remount /system
mv /sdcard/updater.apk /system/priv-app
chmod 644 /system/priv-app/updater.apk

vì một số lý do nó không hoạt động với phiên bản gỡ lỗi đơn giản, nhưng logcat hiển thị thông tin hữu ích nếu ứng dụng của bạn priv-appkhông được chọn vì lý do nào đó.


"vì lý do nào đó mà nó không hoạt động với phiên bản gỡ lỗi đơn giản" Bạn có nghĩa là nó đã hoạt động trong phiên bản phát hành hay một số phiên bản gỡ lỗi ít "đơn giản" hơn?
JM Lord

1
@JMLord Nó hoạt động với phiên bản phát hành có chữ ký và không hoạt động với cả phiên bản gỡ lỗi đã ký và chưa ký - Tôi thấy lạ là nó không hoạt động với phiên bản gỡ lỗi đã ký mà tôi không có thời gian để điều tra. Tuy nhiên, nhật ký logcat hệ thống rất quan trọng để tìm hiểu xem APK đã được cài đặt hay chưa.
Boris Treukhov

Thật vậy, vì một số lý do, cài đặt dưới dạng bản phát hành là chìa khóa để nhận quyền INSTALL_PACKAGES. Ứng dụng có thể chạy trong gỡ lỗi đã ký từ ứng dụng priv, nhưng yêu cầu cấp quyền đã bị từ chối. Cảm ơn rất nhiều!
JM Lord

@BorisTreukhov Này, tôi có thể kiểm tra với bạn về thông số packageName dùng để làm gì không? Tôi đã thay đổi InputStream để FileInputStream nhưng tôi nhận được thông điệp này lỗi: Không thể phân tích cú pháp /data/app/vmdl676191029.tmp/COSU

làm thế nào để cài đặt ứng dụng priv hệ thống sau các lệnh này?
user2323471

8

Bạn nên xác định

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

trong tệp kê khai của bạn, sau đó nếu bạn đang ở trong phân vùng hệ thống (/ system / app) hay bạn có ứng dụng của mình được nhà sản xuất ký, bạn sẽ có quyền INSTALL_PACKAGES.

Đề xuất của tôi là tạo một dự án android nhỏ với mức tương thích 1,5 được sử dụng để gọi installPackages thông qua phản chiếu và để xuất một jar với các phương thức cài đặt gói và gọi các phương thức thực. Sau đó, bằng cách nhập jar trong dự án của bạn, bạn sẽ sẵn sàng cài đặt các gói.


5

Tôi đã thử trên Android 4.2.2 đã root và phương pháp này phù hợp với tôi:

private void installApk(String filename) {
    File file = new File(filename); 
    if(file.exists()){
        try {   
            final String command = "pm install -r " + file.getAbsolutePath();
            Process proc = Runtime.getRuntime().exec(new String[] { "su", "-c", command });
            proc.waitFor();
        } catch (Exception e) {
            e.printStackTrace();
        }
     }
}

2
Câu hỏi là về việc cài đặt ứng dụng mà không cần root, nhưng có quyền "INSTALL_PACKAGES" của hệ thống. Tôi thấy "su" trong câu trả lời của bạn, vì vậy nó yêu cầu root.
POMATu

Cảm ơn bạn rất nhiều vì câu trả lời này! Tôi có cùng một mã nhưng tôi đang sử dụng "adb install -r" thay vì "pm install -r" và nó sẽ KHÔNG hoạt động với tôi. Bạn đã tiết kiệm cho tôi rất nhiều thời gian ở đây!
Jeff.H

@Vladmir tôi cần bạn giúp đỡ. Bạn có thể cho tôi một thời gian. Tôi sẽ rất biết ơn bạn
twana eng

4

Tôi không biết làm thế nào để thực hiện việc này, bởi vì không ai trả lời vào thời điểm đó, và tôi không tìm thấy tài liệu nào về sự cho phép này. Vì vậy, tôi đã tìm ra giải pháp cho riêng mình. Còn tệ hơn là của bạn, nhưng dù sao đây cũng là một giải pháp.

Tôi đã cài đặt busybox, đặt 777 quyền đối với / data / app (tôi không quan tâm đến bảo mật). Sau đó, chỉ cần thực hiện "cài đặt busybox" từ ứng dụng. Điều này hoạt động, nhưng có một rò rỉ bảo mật lớn. Nếu bạn đặt quyền 777, không cần root.


3
bạn đã sử dụng mã như thế này? Process install; install = Runtime.getRuntime().exec("/system/bin/busybox install " + myAPK.getAbsolutePath()); int iSuccess = install.waitFor();
Ai đó ở đâu đó

4

Bạn có thể sử dụng API ẩn android.content.pm.IPackageInstallObserverbằng cách phản ánh:

public class PackageManagement {
    public static final int INSTALL_REPLACE_EXISTING = 0x00000002;
    public static final int INSTALL_SUCCEEDED = 1;

    private static Method installPackageMethod;
    private static Method deletePackageMethod;

    static {
        try {
            installPackageMethod = PackageManager.class.getMethod("installPackage", Uri.class, IPackageInstallObserver.class, Integer.TYPE, String.class);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

    public static void installPackage(PackageManager pm, Uri mPackageUri, IPackageInstallObserver observer, int installFlags, String installerPackageName) {
        try {
            installPackageMethod.invoke(pm, mPackageUri, observer, installFlags, installerPackageName);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Nhập android.content.pm.IPackageInstallObservervào dự án của bạn. Ứng dụng của bạn phải là hệ thống. Bạn phải kích hoạt quyền android.permission.INSTALL_PACKAGEStrong tệp kê khai của mình.


Bạn đã thử nghiệm mã này trên Lollipop và Marshamallow chưa? Có vẻ như một cách tiếp cận tuyệt vời đối với tôi và tôi muốn sử dụng nó
Farhad Faghihi

Tôi đã thử nghiệm từ ICS để Lollipop
Hermann Poilpre

Dòng cần xem là "ứng dụng của bạn phải là hệ thống". Tôi khá chắc chắn rằng điều này sẽ hoạt động trên kẹo mút hoặc bất cứ thứ gì - được cấp là ứng dụng của bạn là "hệ thống", tức là ứng dụng của bạn có quyền hệ thống (về cơ bản là root). Tuy nhiên, trong trường hợp đó, bạn cũng có thể sử dụng trình cài đặt dòng lệnh.
Lassi Kinnunen

1
làm cách nào để gọi phương thức installPackage? Có nghĩa là, làm cách nào để lấy IPackageInstallObserver chẳng hạn?
phoebus

Giá trị của installFlags là gì?
Shivam Kumar

3

Bạn chỉ cần sử dụng lệnh adb install để cài đặt / cập nhật APK âm thầm. Mã mẫu bên dưới

public static void InstallAPK(String filename){
    File file = new File(filename); 
    if(file.exists()){
        try {   
            String command;
            filename = StringUtil.insertEscape(filename);
            command = "adb install -r " + filename;
            Process proc = Runtime.getRuntime().exec(new String[] { "su", "-c", command });
            proc.waitFor();
        } catch (Exception e) {
        e.printStackTrace();
        }
     }
  }

Đây là ý nghĩa của StringUtils là gì? Đang đối mặt với lỗi như không thể được giải quyết?
AndroidOptimist

xin lỗi, tôi nên giải thích. đây là lớp tùy chỉnh của tôi cho các chuỗi và phương thức này làm cho các yêu cầu rằng đường dẫn là chính xác. bạn có thể bỏ qua điều đó
ZeeShaN AbbAs

3
lớp StringUtil là gì. bạn có thể đăng phương thức StringUtil.insertEscape () không ?. beuause nếu tôi nhận xét rằng dòng đó tôi nhận được ngoại lệ. Lỗi chạy thi hành (). Lệnh: [su, -c, adb cài đặt -r /storage/sdcard0/Android/data/com.install.file Cảm ơn trước
sandeepmaaram

java.io.IOException: Lỗi chạy thi hành (). Lệnh: [su, -c, adb install -r /storage/emulated/0/download/SwipeAnimation.apk] Thư mục làm việc: null Môi trường: null - bạn có thể giải thích lỗi ..? và nếu có bất kỳ quyền nào trong tệp kê khai
Sandeep P

1
@ZeeShaNAbbAs sau rễ vấn đề giải quyết .. cảm ơn
Sandeep P

1

Điều kiện tiên quyết:

APK của bạn cần được ký bởi hệ thống như đã chỉ ra một cách chính xác trước đó. Một cách để đạt được điều đó là tự xây dựng hình ảnh AOSP và thêm mã nguồn vào bản dựng.

Mã:

Sau khi được cài đặt làm ứng dụng hệ thống, bạn có thể sử dụng các phương pháp của trình quản lý gói để cài đặt và gỡ cài đặt APK như sau:

Tải về:

public boolean install(final String apkPath, final Context context) {
    Log.d(TAG, "Installing apk at " + apkPath);
    try {
        final Uri apkUri = Uri.fromFile(new File(apkPath));
        final String installerPackageName = "MyInstaller";
        context.getPackageManager().installPackage(apkUri, installObserver, PackageManager.INSTALL_REPLACE_EXISTING, installerPackageName);
        return true;
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}

Gỡ cài đặt:

public boolean uninstall(final String packageName, final Context context) {
    Log.d(TAG, "Uninstalling package " + packageName);
    try {
        context.getPackageManager().deletePackage(packageName, deleteObserver, PackageManager.DELETE_ALL_USERS);
        return true;
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}

Để gọi lại sau khi APK của bạn được cài đặt / gỡ cài đặt, bạn có thể sử dụng cách này:

/**
 * Callback after a package was installed be it success or failure.
 */
private class InstallObserver implements IPackageInstallObserver {

    @Override
    public void packageInstalled(String packageName, int returnCode) throws RemoteException {

        if (packageName != null) {
            Log.d(TAG, "Successfully installed package " + packageName);
            callback.onAppInstalled(true, packageName);
        } else {
            Log.e(TAG, "Failed to install package.");
            callback.onAppInstalled(false, null);
        }
    }

    @Override
    public IBinder asBinder() {
        return null;
    }
}

/**
 * Callback after a package was deleted be it success or failure.
 */
private class DeleteObserver implements IPackageDeleteObserver {

    @Override
    public void packageDeleted(String packageName, int returnCode) throws RemoteException {
        if (packageName != null) {
            Log.d(TAG, "Successfully uninstalled package " + packageName);
            callback.onAppUninstalled(true, packageName);
        } else {
            Log.e(TAG, "Failed to uninstall package.");
            callback.onAppUninstalled(false, null);
        }
    }

    @Override
    public IBinder asBinder() {
        return null;
    }
}

/**
 * Callback to give the flow back to the calling class.
 */
public interface InstallerCallback {
    void onAppInstalled(final boolean success, final String packageName);
    void onAppUninstalled(final boolean success, final String packageName);
}

===> Đã test trên Android 8.1 và hoạt động tốt.


tôi cần bạn giúp. Bạn có thể cho tôi một thời gian. Tôi sẽ rất biết ơn bạn
twana eng

Tôi muốn bạn giúp đỡ. Tôi cần biết cách chúng tôi có thể tạo AOSP của riêng mình
twana eng

0

Tôi đã tạo một ứng dụng thử nghiệm cho các lượt cài đặt im lặng, sử dụng phương pháp PackageManager.installPackage.

Tôi nhận được phương thức installPackage thông qua phản chiếu và tạo giao diện android.content.pm.IPackageInstallObserver trong thư mục src của tôi (vì nó bị ẩn trong gói android.content.pm).

Khi tôi chạy installPackage, tôi nhận được SecurityException với chỉ báo chuỗi, rằng ứng dụng của tôi không có android.permission.INSTALL_PACKAGES, nhưng nó được xác định trong AndroidManifest.xml.

Vì vậy, tôi nghĩ, không thể sử dụng phương pháp này.

Tái bút. Tôi đã thử nghiệm trên Android SDK 2.3 và 4.0. Có thể nó sẽ hoạt động với các phiên bản trước đó.


Nó hoạt động trong 4.1 và 4.0 cũng như trong bất kỳ phiên bản Android nào cao hơn 2.1 (bao gồm cả 2.1). Tôi đang sử dụng 4.0 SDK bây giờ. Bạn cần thêm nó vào thư mục / system / app, nếu không ứng dụng của bạn sẽ không có quyền yêu cầu cấp hệ thống (không phải root). Ngoài ra, tôi có thể xóa ứng dụng một cách âm thầm bằng phương pháp này, hãy kiểm tra câu hỏi khác của tôi liên quan đến xóa.
POMATu

Có, nó hoạt động, nhưng chỉ với quyền của root. Và không thể cài đặt ứng dụng vào hệ thống / ứng dụng trên thiết bị chưa root.
Андрей Москвичёв

Không phải với root, nhưng với các quyền cấp hệ thống. Bạn có thể thêm nó vào / system / app nếu bạn là nhà sản xuất firmware. Trong trường hợp của tôi - tôi (Tôi yêu cầu các nhà sản xuất thiết bị thêm các ứng dụng của tôi vào phần sụn). Bạn sẽ không thể cài đặt ứng dụng một cách âm thầm theo bất kỳ cách nào khác - nếu không, đó sẽ là một lỗ hổng bảo mật lớn.
POMATu

Về lỗ hổng bảo mật - tôi hoàn toàn đồng ý với bạn. Và sẽ rất ngạc nhiên cho tôi, nếu phương pháp này hoạt động với bất kỳ ứng dụng nào. Làm cách nào để cài đặt ứng dụng vào / system / app mà không cần root? Tôi không phải là nhà sản xuất.
Андрей Москвичёв

1
Nếu không có root hoặc reflashing bạn không thể.
POMATu

0

Hãy thử điều này LD_LIBRARY_PATH=/vendor/lib:/system/libtrước khi cài đặt. Nó hoạt động tốt.


0

Ứng dụng của bên thứ 3 không thể cài đặt Ứng dụng Android một cách dễ dàng. Tuy nhiên, ứng dụng của bên thứ 3 có thể yêu cầu hệ điều hành Android cài đặt một ứng dụng.

Vì vậy, bạn nên xác định điều này:

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file:///sdcard/app.apk", "application/vnd.android.package-archive");
startActivity(intent);

Bạn cũng có thể thử cài đặt nó như một ứng dụng hệ thống để cấp quyền và bỏ qua xác định này. (Yêu cầu gốc)

Bạn có thể chạy lệnh sau trên ứng dụng của bên thứ 3 để cài đặt ứng dụng trên thiết bị gốc.

Mã là:

private void installApk(String filename) {
File file = new File(filename); 
if(file.exists()){
    try {   
        final String command = "pm install -r " + file.getAbsolutePath();
        Process proc = Runtime.getRuntime().exec(new String[] { "su", "-c", command });
        proc.waitFor();
    } catch (Exception e) {
        e.printStackTrace();
    }
 }
}

Tôi hy vọng rằng câu trả lời này là hữu ích cho bạn.


0

Nó có thể thực hiện cài đặt im lặng trên Android 6 trở lên. Sử dụng hàm được cung cấp trong câu trả lời bởi Boris Treukhov, bỏ qua mọi thứ khác trong bài đăng, root cũng không bắt buộc.

Cài đặt ứng dụng của bạn với tư cách là quản trị viên thiết bị, bạn có thể có chế độ kiosk đầy đủ với cài đặt im lặng các bản cập nhật trong nền.


0

Tôi đã kiểm tra tất cả các câu trả lời, kết luận dường như là bạn phải có quyền truy cập root vào thiết bị trước tiên để làm cho nó hoạt động.

Nhưng sau đó tôi thấy những bài viết này rất hữu ích. Vì tôi đang làm các thiết bị "do công ty sở hữu".

Cách cập nhật ứng dụng Android một cách âm thầm mà không cần sự tương tác của người dùng

Chủ sở hữu thiết bị Android - Ứng dụng tối thiểu

Đây là tài liệu của google về "thiết bị được quản lý"

Thiết bị được quản lý hoàn toàn



-6

! / bin / bash

f=/home/cox/myapp.apk   #or $1 if input from terminal.

#backup env var
backup=$LD_LIBRARY_PATH
LD_LIBRARY_PATH=/vendor/lib:/system/lib
myTemp=/sdcard/temp.apk
adb push $f $myTemp
adb shell pm install -r $myTemp
#restore env var
LD_LIBRARY_PATH=$backup

Điều này làm việc cho tôi. Tôi chạy điều này trên ubuntu 12.04, trên thiết bị đầu cuối shell.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.