国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Android11.0系統(tǒng)中實(shí)現(xiàn)靜默安裝并啟動(dòng)App以及靜默卸載

這篇具有很好參考價(jià)值的文章主要介紹了Android11.0系統(tǒng)中實(shí)現(xiàn)靜默安裝并啟動(dòng)App以及靜默卸載。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

靜默安裝并啟動(dòng)App以及靜默卸載

本文描述Android11中通過(guò)修改系統(tǒng)PackageInstaller應(yīng)用支持靜默安裝App,并啟動(dòng)安裝的App。

修改PackageInstaller

PackageInstaller是系統(tǒng)中專門負(fù)責(zé)app安裝的App,靜默安裝邏輯添加到此應(yīng)用中,應(yīng)用所在路徑 /frameworks/base/packages/PackageInstaller/src/com/android/packageinstaller/

  1. 添加SilenceInstallManager,路徑為 /frameworks/base/packages/PackageInstaller/src/com/android/packageinstaller/SilenceInstallManager.java;

package com.android.packageinstaller;

import android.annotation.SuppressLint;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.content.pm.PackageParser;
import android.content.pm.ResolveInfo;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.util.ArrayMap;
import android.util.Log;

import androidx.annotation.NonNull;

import com.android.internal.content.PackageHelper;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import android.content.pm.IPackageDeleteObserver;


final class SilenceInstallManager {
    private static final String TAG = "SilenceInstallManager";

    private static final int MSG_WHAT_INSTALL_FINISH_SUCCESS = 0;
    private static final int MSG_WHAT_INSTALL_FINISH_FAIL = 1;
    private static final int MSG_WHAT_UNINSTALL_COMPLETE = 2;

    private Context mContext;

    @SuppressLint("NewApi")
    private ArrayMap<Integer, InstallAppInfo> InstallAppInfoMap = new ArrayMap<>();


    private static volatile SilenceInstallManager INSTANCE;

    private SilenceInstallManager(Context context) {
        mContext = context;
    }

    public static SilenceInstallManager getInstance(Context context) {
        if (null == INSTANCE) {
            synchronized (SilenceInstallManager.class) {
                if (null == INSTANCE) {
                    INSTANCE = new SilenceInstallManager(context.getApplicationContext());
                }
            }
        }
        return INSTANCE;
    }


    @SuppressLint("NewApi")
    private PackageInstaller.SessionCallback mSessionCallback = new PackageInstaller.SessionCallback() {
        @Override
        public void onCreated(int sessionId) {
            Log.d(TAG, "onCreated---->" + sessionId);
        }

        @Override
        public void onBadgingChanged(int sessionId) {
//            Log.w(TAG, "SilenceInstallReceiver onBadgingChanged---->" + sessionId);
        }

        @Override
        public void onActiveChanged(int sessionId, boolean active) {
//            Log.w(TAG, "SilenceInstallReceiver onActiveChanged---->" + sessionId + "  active--->" + active);
        }

        @Override
        public void onProgressChanged(int sessionId, float progress) {
//            Log.w(TAG, "SilenceInstallReceiver onProgressChanged---->" + sessionId + "  progress--->" + progress);
        }

        @Override
        public void onFinished(int sessionId, boolean success) {
            Log.d(TAG, "onFinished---->" + sessionId + "  success--->" + success);
            Message msg = Message.obtain();
            msg.what = MSG_WHAT_INSTALL_FINISH_SUCCESS;
            msg.arg1 = sessionId;
            msg.obj = success;
            mHandler.sendMessage(msg);
        }
    };

    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler() {
        @Override
        public void dispatchMessage(@NonNull Message msg) {
            mContext.getPackageManager().getPackageInstaller().unregisterSessionCallback(mSessionCallback);
            if (msg.what == MSG_WHAT_INSTALL_FINISH_SUCCESS) {
                boolean result = (boolean) msg.obj;
                int sessionId = msg.arg1;
                InstallAppInfo info = InstallAppInfoMap.remove(sessionId);
                if (result) {
                    Log.d(TAG, "install success");
                    if (null != info) {
                        if (info.isLaunch && null != info.info && null != info.info.packageName && !"".equals(info.info.packageName)) {
                            launchApp(info.info.packageName);
                        }

                        File f = new File(info.filePath);
                        if (f.exists()) {
                            f.delete();
                        }
                    }
                } else {
                    Log.d(TAG, "install fail");
                }
            } else if (msg.what == MSG_WHAT_INSTALL_FINISH_FAIL) {
                int sessionId = msg.arg1;
                if (sessionId != -1) {
                    InstallAppInfoMap.remove(sessionId);
                }
                Log.d(TAG, "install fail");
            } else if (msg.what == MSG_WHAT_UNINSTALL_COMPLETE) {
                Log.d(TAG, "uninstall complete--->" + msg.arg1);
                if (msg.arg1 == PackageManager.DELETE_SUCCEEDED) {
                    Log.d(TAG, "delete succeeded");
                } else {
                    Log.d(TAG, "delete fail");
                }
            }
        }
    };

    public void silenceInstall(String appFilePath, boolean launch) {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            mContext.getPackageManager().getPackageInstaller().registerSessionCallback(mSessionCallback);

            PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
                    PackageInstaller.SessionParams.MODE_FULL_INSTALL);
            params.setInstallAsInstantApp(false);
            params.setInstallReason(PackageManager.INSTALL_REASON_USER);

            File file = new File(appFilePath);
            if (!file.exists()) {
                sendFailMsg(-1);
                return;
            }

            try {
                PackageParser.PackageLite pkg = PackageParser.parsePackageLite(file, 0);
                params.setAppPackageName(pkg.packageName);
                params.setInstallLocation(pkg.installLocation);
                params.setSize(
                        PackageHelper.calculateInstalledSize(pkg, false, params.abiOverride));
            } catch (PackageParser.PackageParserException e) {
                Log.e(TAG, "Cannot parse package " + file + ". Assuming defaults.");
                Log.e(TAG,
                        "Cannot calculate installed size " + file + ". Try only apk size.");
                params.setSize(file.length());
            } catch (IOException e) {
                Log.e(TAG,
                        "Cannot calculate installed size " + file + ". Try only apk size.");
                params.setSize(file.length());
            }

            try {
                PackageInfo mPkgInfo = PackageUtil.getPackageInfo(mContext, file, PackageManager.GET_PERMISSIONS);
                int mSessionId = mContext.getPackageManager().getPackageInstaller().createSession(params);
                InstallAppInfo installAppInfo = new InstallAppInfo(mSessionId, appFilePath, mPkgInfo, launch);
                InstallAppInfoMap.put(mSessionId, installAppInfo);

                InstallingAsyncTask mInstallingTask = new InstallingAsyncTask(mContext, appFilePath, mSessionId);
                mInstallingTask.execute();
            } catch (IOException e) {
                e.printStackTrace();
                sendFailMsg(-1);
            }
        }
    }

    private void sendFailMsg(int sessionId) {
        Message msg = Message.obtain();
        msg.what = MSG_WHAT_INSTALL_FINISH_FAIL;
        msg.arg1 = sessionId;
        mHandler.sendMessage(msg);
    }


    @SuppressLint("NewApi")
    private final class InstallingAsyncTask extends AsyncTask<Void, Void,
            PackageInstaller.Session> {

        private Context mContext;
        private String mAppPath;
        private int mSessionId;

        public InstallingAsyncTask(Context context, String appPath, int sessionId) {
            mContext = context;
            mAppPath = appPath;
            mSessionId = sessionId;
        }

        @Override
        protected PackageInstaller.Session doInBackground(Void... params) {
            PackageInstaller.Session session;
            try {
                session = mContext.getPackageManager().getPackageInstaller().openSession(mSessionId);
            } catch (IOException e) {
                return null;
            }

            session.setStagingProgress(0);

            try {
                File file = new File(mAppPath);

                try (InputStream in = new FileInputStream(file)) {
                    long sizeBytes = file.length();
                    try (OutputStream out = session
                            .openWrite("PackageInstaller", 0, sizeBytes)) {
                        byte[] buffer = new byte[1024 * 1024];
                        while (true) {
                            int numRead = in.read(buffer);

                            if (numRead == -1) {
                                session.fsync(out);
                                break;
                            }

                            if (isCancelled()) {
                                session.close();
                                break;
                            }

                            out.write(buffer, 0, numRead);
                            if (sizeBytes > 0) {
                                float fraction = ((float) numRead / (float) sizeBytes);
                                session.addProgress(fraction);
                            }
                        }
                    }
                }

                return session;
            } catch (IOException | SecurityException e) {
                Log.e(TAG, "Could not write package", e);
                session.close();
                return null;
            }
        }

        @Override
        protected void onPostExecute(PackageInstaller.Session session) {
            if (session != null) {
                Intent broadcastIntent = new Intent();
                PendingIntent pendingIntent = PendingIntent.getBroadcast(
                        mContext,
                        1,
                        broadcastIntent,
                        PendingIntent.FLAG_UPDATE_CURRENT);

                session.commit(pendingIntent.getIntentSender());

                session.close();

                Log.d(TAG, "send install PendingIntent----->");
            } else {
                mContext.getPackageManager().getPackageInstaller().abandonSession(mSessionId);
                sendFailMsg(mSessionId);

                File f = new File(mAppPath);
                if (f.exists()) {
                    f.delete();
                }

                Log.e(TAG, "copy fail delete file----->");
            }

            mContext = null;
            mAppPath = "";
            mSessionId = -1;
        }
    }


    private class InstallAppInfo {
        private int sessionId;
        private String filePath;
        private PackageInfo info;
        private boolean isLaunch;

        public InstallAppInfo(int sessionId, String filePath, PackageInfo info, boolean isLaunch) {
            this.sessionId = sessionId;
            this.filePath = filePath;
            this.info = info;
            this.isLaunch = isLaunch;
        }

        public int getSessionId() {
            return sessionId;
        }

        public String getFilePath() {
            return filePath;
        }

        public PackageInfo getInfo() {
            return info;
        }

        public boolean isLaunch() {
            return isLaunch;
        }
    }


    private void launchApp(String appPackageName) {
        Intent mLaunchIntent = mContext.getPackageManager().getLaunchIntentForPackage(appPackageName);
        if (mLaunchIntent != null) {
            List<ResolveInfo> list = mContext.getPackageManager().queryIntentActivities(mLaunchIntent, 0);
            if (list != null && list.size() > 0) {
                Log.d(TAG, "launch app--->");
                mContext.startActivity(mLaunchIntent);
            }
        }
    }


    public void silenceUninstall(String packageName) {
        Log.i(TAG, "silenceUninstall--->" + packageName);
        PackageDeleteObserver observer = new PackageDeleteObserver();
        mContext.getPackageManager().deletePackage(packageName, observer, PackageManager.DELETE_ALL_USERS);
    }

    private class PackageDeleteObserver extends IPackageDeleteObserver.Stub {
        public void packageDeleted(String packageName, int returnCode) {
            Message msg = mHandler.obtainMessage(MSG_WHAT_UNINSTALL_COMPLETE);
            msg.arg1 = returnCode;
            msg.obj = packageName;
            mHandler.sendMessage(msg);
        }
    }
}

  1. 添加SilenceInstallReceiver,路徑為 /frameworks/base/packages/PackageInstaller/src/com/android/packageinstaller/SilenceInstallReceiver.java;

package com.android.packageinstaller;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;


public class SilenceInstallReceiver extends BroadcastReceiver {
    public static final String SILENCE_INSTALL_APP = "com.android.packageinstaller.ACTION_SILENCE_INSTALL";
    public static final String SILENCE_INSTALL_KEY = "silence_install";
    public static final String IS_LAUNCH_KEY = "is_launch";
    public static final String APP_URI_KEY = "app_uri";


    @Override
    public void onReceive(Context context, Intent intent) {
        if (SILENCE_INSTALL_APP.equals(intent.getAction())) {
            Uri uri = intent.getParcelableExtra(APP_URI_KEY);
            boolean isLaunch = intent.getBooleanExtra(IS_LAUNCH_KEY, false);
            SilenceInstallManager.getInstance(context).silenceInstall(uri.getPath(), isLaunch);
        }

    }

}

  1. InstallStart是PackageInstaller程序安裝app的入口activity,修改InstallStart,添加靜默安裝邏輯分支,路徑為 /frameworks/base/packages/PackageInstaller/src/com/android/packageinstaller/InstallStart.java;
//********省略代碼******

  protected void onCreate(@Nullable Bundle savedInstanceState) {

        //********省略代碼******
        if (isSessionInstall) {
            nextActivity.setClass(this, PackageInstallerActivity.class);
        } else {
            Uri packageUri = intent.getData();

            if (packageUri != null && packageUri.getScheme().equals(
                    ContentResolver.SCHEME_CONTENT)) {
                // [IMPORTANT] This path is deprecated, but should still work. Only necessary
                // features should be added.

                // Copy file to prevent it from being changed underneath this process
                nextActivity.setClass(this, InstallStaging.class);
            } else if (packageUri != null && packageUri.getScheme().equals(
                    PackageInstallerActivity.SCHEME_PACKAGE)) {
                nextActivity.setClass(this, PackageInstallerActivity.class);
            } else {
                Intent result = new Intent();
                result.putExtra(Intent.EXTRA_INSTALL_RESULT,
                        PackageManager.INSTALL_FAILED_INVALID_URI);
                setResult(RESULT_FIRST_USER, result);

                nextActivity = null;
            }
        }

       //安裝請(qǐng)求中如果帶靜默安裝標(biāo)識(shí),執(zhí)行靜默安裝操作
        if (intent.getBooleanExtra(SilenceInstallReceiver.SILENCE_INSTALL_KEY, false)) {
            StagingAsyncAppTask mStagingTask = new StagingAsyncAppTask(intent.getBooleanExtra(SilenceInstallReceiver.IS_LAUNCH_KEY, false));
            mStagingTask.execute(getIntent().getData());
            return;
        }

        if (nextActivity != null) {
            startActivity(nextActivity);
        }
        finish();
}


    @SuppressLint("NewApi")
    private final class StagingAsyncAppTask extends AsyncTask<Uri, Void, File> {

        private boolean mIsLaunch;

        public StagingAsyncAppTask(boolean isLaunch){
            mIsLaunch = isLaunch;
        }


        @Override
        protected File doInBackground(Uri... params) {
            Log.d(LOG_TAG, "copy file from user app start");
            if (params == null || params.length <= 0) {
                return null;
            }
            Uri packageUri = params[0];
            try (InputStream in = getContentResolver().openInputStream(packageUri)) {
                // Despite the comments in ContentResolver#openInputStream the returned stream can
                // be null.
                if (in == null) {
                    return null;
                }

                File mStagedFile = TemporaryFileManager.getStagedFile(InstallStart.this);

                try (OutputStream out = new FileOutputStream(mStagedFile)) {
                    byte[] buffer = new byte[1024 * 1024];
                    int bytesRead;
                    while ((bytesRead = in.read(buffer)) >= 0) {
                        // Be nice and respond to a cancellation
                        out.write(buffer, 0, bytesRead);
                    }
                }
                return mStagedFile;
            } catch (IOException | SecurityException | IllegalStateException e) {
                Log.w(LOG_TAG, "Error staging apk from content URI", e);
            }
            return null;
        }

        @Override
        protected void onPostExecute(File installFile) {
            if (null != installFile) {
                // Now start the installation again from a file
                Log.d(LOG_TAG, "copy file from user app finish");

                Intent installIntent = new Intent(SilenceInstallReceiver.SILENCE_INSTALL_APP);
                installIntent.putExtra(SilenceInstallReceiver.APP_URI_KEY, Uri.fromFile(installFile));
                installIntent.putExtra(SilenceInstallReceiver.IS_LAUNCH_KEY, mIsLaunch);
                installIntent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
                installIntent.setPackage("com.android.packageinstaller");
                sendBroadcast(installIntent);

                Log.d(LOG_TAG, "send to install");
            } else {
                Log.d(LOG_TAG, "copy file from user app fail");
            }

            finish();
        }
    }

//********省略代碼******
  1. UninstallerActivity是PackageInstaller程序卸載app的入口activity,修改UninstallerActivity,添加靜默卸載邏輯分支,路徑為 /frameworks/base/packages/PackageInstaller/src/com/android/packageinstaller/UninstallerActivity.java;

//********省略代碼******
public void onCreate(Bundle icicle){
         //********省略代碼******
        
        //添加靜默卸載邏輯
        if (intent.getBooleanExtra(SilenceInstallReceiver.SILENCE_INSTALL_KEY, false)) {
            SilenceInstallManager.getInstance(this).silenceUninstall(mPackageName);
            return;
        }

        showConfirmationDialog();
}

//********省略代碼******
  1. 修改PackageInstallerApplication,路徑為 /frameworks/base/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerApplication.java;
//********省略代碼******

public class PackageInstallerApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        PackageItemInfo.forceSafeLabels();

		//添加管理類初始化
        SilenceInstallManager.getInstance(this);
    }
}

//********省略代碼******
  1. 修改AndroidManifest.xml,路徑為 /frameworks/base/packages/PackageInstaller/AndroidManifest.xml;
//********省略代碼******

//添加后臺(tái)啟動(dòng)activity權(quán)限
<uses-permission android:name="android.permission.START_ACTIVITIES_FROM_BACKGROUND" />

//********省略代碼******

<receiver android:name=".SilenceInstallReceiver"
            android:exported="false">
            <intent-filter android:priority="1">
                <action android:name="com.android.packageinstaller.ACTION_SILENCE_INSTALL" />
            </intent-filter>
        </receiver>

//********省略代碼******
  1. Android10開(kāi)始,系統(tǒng)限制在沒(méi)有用戶交互的情況下在后臺(tái)啟動(dòng)Activity,會(huì)輸出如下信息

Background activity start [callingPackage: com.android.packageinstaller; callingUid: 10069; isCallingUidForeground: false; callingUidHasAnyVisibleWindow: false; callingUidProcState: CACHED_EMPTY; isCallingUidPersistentSystemProcess: false; realCallingUid: 10069; isRealCallingUidForeground: false; realCallingUidHasAnyVisibleWindow: false; realCallingUidProcState: CACHED_EMPTY; isRealCallingUidPersistentSystemProcess: false; originatingPendingIntent: null; isBgStartWhitelisted: false; intent: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 pkg=com.qiyi.video cmp=com.qiyi.video/.WelcomeActivity }; callerApp: ProcessRecord{ba2b2ca 2471:com.android.packageinstaller/u0a69}]

Abort background activity starts from 10069

當(dāng)開(kāi)發(fā)的App切換到后臺(tái)后,就無(wú)法進(jìn)行應(yīng)用安裝請(qǐng)求,ActivityStarter.java中的shouldAbortBackgroundActivityStart()方法在判斷是否能夠啟動(dòng)activity,在這里添加修改邏輯處理,路徑為 /frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java;文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-773259.html

//********省略代碼******

boolean shouldAbortBackgroundActivityStart(int callingUid, int callingPid,
            final String callingPackage, int realCallingUid, int realCallingPid,
            WindowProcessController callerApp, PendingIntentRecord originatingPendingIntent,
            boolean allowBackgroundActivityStart, Intent intent) {

//********省略代碼******

        // don't abort if the callingUid has SYSTEM_ALERT_WINDOW permission
        if (mService.hasSystemAlertWindowPermission(callingUid, callingPid, callingPackage)) {
            Slog.w(TAG, "Background activity start for " + callingPackage
                    + " allowed because SYSTEM_ALERT_WINDOW permission is granted.");
            return false;
        }
        
        //添加判斷邏輯,通過(guò)allowed_Background標(biāo)識(shí)決定是能夠啟動(dòng)
        if (intent.getBooleanExtra("allowed_Background", false)) {
            Slog.w(TAG, "allowed_Background.");
            return false;
        }
    
       //********省略代碼******
}

//********省略代碼******

第三方App請(qǐng)求靜默安裝及卸載

  1. 在開(kāi)發(fā)的app中使用下面方法請(qǐng)求安裝

    private void installTest() {
        String appPath = getExternalFilesDir(null).getAbsolutePath() + File.separator + "aiqiyi.apk";

        File appFile = new File(appPath);
        if (!appFile.exists()) {
            showToast("請(qǐng)?jiān)? + getExternalFilesDir(null).getAbsolutePath() + File.separator + "目錄中放置升級(jí)文件");
            return;
        }

        Uri uri = FileProvider.getUriForFile(getApplicationContext(), getPackageName() + ".file_provider", appFile);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            Intent installApkIntent = new Intent();
            installApkIntent.setAction(Intent.ACTION_VIEW);
            installApkIntent.addCategory(Intent.CATEGORY_DEFAULT);
            installApkIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            installApkIntent.setDataAndType(uri, "application/vnd.android.package-archive");
            installApkIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            //設(shè)置靜默安裝標(biāo)識(shí)
            installApkIntent.putExtra("silence_install", true);
            //設(shè)置安裝完成是否啟動(dòng)標(biāo)識(shí)
            installApkIntent.putExtra("is_launch", true);
            //設(shè)置后臺(tái)中啟動(dòng)activity標(biāo)識(shí)
            installApkIntent.putExtra("allowed_Background", true);
            if (getPackageManager().queryIntentActivities(installApkIntent, 0).size() > 0) {
                startActivity(installApkIntent);
            }
        }
    }

  1. 在開(kāi)發(fā)的app中使用下面方法請(qǐng)求卸載
    public boolean requestSilenceUninstall(Context context, String packageName) {
        if (null == packageName || "".equals(packageName)) {
            return false;
        }

        try {
            PackageInfo packinfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_PERMISSIONS);
            String[] list = packinfo.requestedPermissions;
            boolean hasPermission = false;
            if (null != list) {
                for (int i = 0; i < list.length; i++) {
                    if (Manifest.permission.QUERY_ALL_PACKAGES.equals(list[i])) {
                        hasPermission = true;
                        break;
                    }
                }
            }
            if (!hasPermission) {
                throw new RuntimeException("need permission " + Manifest.permission.QUERY_ALL_PACKAGES);
            }
        } catch (PackageManager.NameNotFoundException e) {
            throw new RuntimeException(e);
        }

        if (!checkExistForApp(context, packageName)) {
            return false;
        }

        Intent intent = new Intent(Intent.ACTION_DELETE);
        intent.setData(Uri.parse("package:" + packageName));
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.putExtra("allowed_Background", true);
        intent.putExtra("silence_install", true);
        context.startActivity(intent);

        return true;
    }

到了這里,關(guān)于Android11.0系統(tǒng)中實(shí)現(xiàn)靜默安裝并啟動(dòng)App以及靜默卸載的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Android11.0 生成系統(tǒng)簽名.jks文件并對(duì)Apk進(jìn)行簽名

    V2簽名 對(duì)應(yīng)用手動(dòng)進(jìn)行系統(tǒng)簽名,需要platform.pk8,platform.x509.pem,signapk.jar這三個(gè)文件,應(yīng)用的AndroidManifest.xml中需要添加 android:sharedUserId=“android.uid.system” ,然后輸入以下命令就可得到簽名后的apk文件: 如果你的應(yīng)用 targetSdkVersion=30 ,在7.0以上的設(shè)備上安裝不成功,會(huì)報(bào)以

    2024年02月07日
    瀏覽(93)
  • Android 11.0 動(dòng)態(tài)修改SystemProperties中ro開(kāi)頭系統(tǒng)屬性的值

    需求: 在11.0的產(chǎn)品開(kāi)發(fā)中,對(duì)于定制功能的需求很多,有些機(jī)型要求可以修改系統(tǒng)屬性值,對(duì)于系統(tǒng)本身在10.0以后為了系統(tǒng)安全性,不允許修改ro開(kāi)頭的SystemProperties的值,所以如果要求修改ro的相關(guān)系統(tǒng)屬性,就得看在設(shè)置SystemProperties的相關(guān)值的要求,修改這部分要求就可

    2024年02月05日
    瀏覽(144)
  • Android 11.0 系統(tǒng)修改usb連接電腦mtp和PTP的顯示名稱

    ? 在11.0的系統(tǒng)產(chǎn)品rom定制化開(kāi)發(fā)中,在usb模塊otg連接電腦,調(diào)整為mtp文件傳輸模式的時(shí)候,這時(shí)可以在電腦看到手機(jī)的內(nèi)部存儲(chǔ) 顯示在電腦的盤(pán)符中,會(huì)有一個(gè)mtp名稱做盤(pán)符,所以為了統(tǒng)一這個(gè)名稱,就需要修改這個(gè)名稱,接下來(lái)分析下處理的方法來(lái)解決這個(gè)問(wèn)題 MTP的全稱

    2024年01月17日
    瀏覽(96)
  • Android 11.0 系統(tǒng)限制上網(wǎng)系統(tǒng)之iptables用IOemNetd實(shí)現(xiàn)創(chuàng)建子鏈功能的實(shí)現(xiàn)

    在11.0的系統(tǒng)rom定制化開(kāi)發(fā)中,對(duì)于限制系統(tǒng)上網(wǎng)功能中,需要在system中netd網(wǎng)絡(luò)這塊的產(chǎn)品開(kāi)發(fā)中,會(huì)要求設(shè)置屏蔽ip地址之內(nèi)的功能, liunx中iptables命令也是比較重要的,接下來(lái)就來(lái)在IOemNetd這塊實(shí)現(xiàn)創(chuàng)建子鏈的相關(guān)功能 在android原生系統(tǒng)中,iptables是在網(wǎng)絡(luò)過(guò)濾包模塊非常重

    2024年02月13日
    瀏覽(90)
  • Android 11.0 系統(tǒng)限制上網(wǎng)系統(tǒng)之iptables用IOemNetd實(shí)現(xiàn)刪除子鏈功能的實(shí)現(xiàn)

    在11.0的系統(tǒng)rom定制化開(kāi)發(fā)中,對(duì)于限制系統(tǒng)上網(wǎng)功能中,在system中netd網(wǎng)絡(luò)這塊的產(chǎn)品開(kāi)發(fā)中,會(huì)要求設(shè)置屏蔽ip地址之內(nèi)的功能, liunx中iptables命令也是比較重要的,接下來(lái)就來(lái)在IOemNetd這塊實(shí)現(xiàn)刪除創(chuàng)建子鏈的相關(guān)功能 在android原生系統(tǒng)中,iptables是在網(wǎng)絡(luò)過(guò)濾包模塊非常重

    2024年02月16日
    瀏覽(92)
  • 【干貨】Android系統(tǒng)定制基礎(chǔ)篇:第三部分(Android靜默安裝、Android支持usb打印機(jī))

    一些產(chǎn)品要求APP在升級(jí)時(shí)能夠?qū)崿F(xiàn)靜默安裝,而無(wú)需彈出安裝界面讓用戶確認(rèn)。這里提出兩種實(shí)現(xiàn)方案: 方案一 APP調(diào)用『pm』命令實(shí)現(xiàn)靜默安裝,此方案無(wú)須修改Android源碼,但需要root權(quán)限。 方案二 修改Android PackageInstaller 源碼,增加Intent參數(shù)來(lái)指定是否要靜默安裝,同時(shí)支

    2024年02月10日
    瀏覽(29)
  • Android11.0 launcher修改為單層

    OS: RK3568 Android11.0 現(xiàn)在的產(chǎn)品基本都是按照手機(jī)樣式去做,所以需要把系統(tǒng)默認(rèn)的Launcher樣式,去掉抽屜改為單層顯示,也就是把所有的app添加到workspace中。 以下修改是在設(shè)備橫屏模式下進(jìn)行 。 1.添加一個(gè)宏開(kāi)關(guān)控制Launcher單雙層顯示 源碼: /packages/apps/Launcher3/src/com/android/

    2024年02月08日
    瀏覽(96)
  • Android11.0 導(dǎo)航欄添加圖標(biāo)截屏

    Android11.0 導(dǎo)航欄添加圖標(biāo)截屏

    需求: 導(dǎo)航欄添加截屏和電源鍵圖標(biāo),控制截屏和用于設(shè)備重啟關(guān)機(jī)功能。設(shè)置中添加延時(shí)截屏和控制截屏圖標(biāo)顯示開(kāi)關(guān)。 1. 導(dǎo)航欄添加圖標(biāo) 1.1 添加布局文件和圖標(biāo)icon 在layout目錄下添加nav_power.xml和screenshot.xml文件 frameworks/base/packages/SystemUI/res/layout/nav_power.xml frameworks/base

    2024年02月15日
    瀏覽(161)
  • Android 11.0 SystemUI下拉狀態(tài)欄禁止QuickQSPanel展開(kāi)

    ?? 在11.0系統(tǒng)rom產(chǎn)品定制化開(kāi)發(fā)中,對(duì)于SystemUI定制開(kāi)發(fā)功能也有不少的,增加快捷功能模塊,隱藏狀態(tài)欄圖標(biāo)項(xiàng)目開(kāi)發(fā)需要要求定制QSPanel相關(guān)UI和開(kāi)發(fā)功能, 要求首次下拉后展示快捷功能模塊以后就是顯示QuickQSPanel而不展開(kāi)QSPanel,接下來(lái)要從下滑手勢(shì)下拉出狀態(tài)欄分析功能

    2024年02月08日
    瀏覽(99)
  • Android 11.0 以太網(wǎng)設(shè)置默認(rèn)靜態(tài)ip地址

    在11.0的系統(tǒng)rom開(kāi)發(fā)過(guò)程中,在進(jìn)行以太網(wǎng)產(chǎn)品開(kāi)發(fā)的過(guò)程中,有功能要求設(shè)置默認(rèn)靜態(tài)ip地址的功能,不使用動(dòng)態(tài)ip, 方便ip地址管理所以就需要熟悉以太網(wǎng)的ip設(shè)置流程,然后設(shè)置對(duì)應(yīng)的ip地址就可以了

    2024年02月16日
    瀏覽(120)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包