将程序变成system app 实现home、back、menu等按键模拟

本文介绍如何将普通应用程序转变为系统级应用的方法,包括配置系统权限、模拟系统按键操作、添加系统签名等步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.使一个程序成为系统程序

我们必须在manifest 中配置android:sharedUserId="android.uid.system"

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.flyaudio.floatwindows"
    android:versionCode="1"
    android:sharedUserId="android.uid.system" 
    android:versionName="1.0" >
加上权限:<uses-permission android:name="android.permission.INJECT_EVENTS" />

这个权限就是为了允许一个程序截获用户事件如按键、触摸、轨迹球等等到一个时间流。


2.模拟home、back、menu

	private void homePress()
	{
		Intent mHomeIntent = new Intent(Intent.ACTION_MAIN);
        mHomeIntent.addCategory(Intent.CATEGORY_HOME);
        mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
        getContext().startActivity(mHomeIntent);
	}
	
	private void backPress()
	{
        Runtime runtime = Runtime.getRuntime();
        try {
			runtime.exec("input keyevent " + KeyEvent.KEYCODE_BACK);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private void menuPress()
	{ 
        Runtime runtime = Runtime.getRuntime();
        try {
			runtime.exec("input keyevent " + KeyEvent.KEYCODE_MENU);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
其实还有一种方法就是:

		new Thread(){
			   public void run() {
			    try{
			     Instrumentation inst = new Instrumentation();
			     inst.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
			    }
			    catch (Exception e) {
			                 Log.e("Exception when onBack", e.toString());
			             }
			   }
			  }.start();
inst.sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);
这里可以传入任何键值。


3.添加系统签名

完成上面2个步骤之后,安装程序发现会出现Failure [INSTALL_FAILED_SHARED_USER_INCOMPATIBLE]错误。因为使用eclipse编译后的程序不带有platform签名,所以作为系统程序安装不了。

所以需要对apk进行签名

    将签名工具(signapk.jar)、签名证书(platform.pk8和platform.x509.pem)及编译出来的apk文件都放到同一目录

    终端进入该目录执行java -jar signapk.jar -w platform.x509.pem platform.pk8 XXX.apk out/XXX.apk

    拿出out目录下被签名后的apk进行安装


4.附上签名工具

下载签名工具


把一下PyQt5的代码变成PyQt6的代码 代码: from PyQt5.QtCore import QUrl, Qt, QTranslator, QLocale, QLibraryInfo from PyQt5.QtGui import QFont, QIcon, QKeySequence from PyQt5.QtWidgets import (QApplication, QMainWindow, QToolBar, QLineEdit, QAction, QStatusBar, QMessageBox, QTabWidget) from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage, QWebEngineSettings from datetime import datetime import sys,os os.environ["QT_MULTIMEDIA_PREFERRED_PLUGINS"] = "windowsmediafoundation" os.environ["QTWEBENGINE_CHROMIUM_FLAGS"] = "--enable-gpu-rasterization --enable-zero-copy" os.environ["QT_MEDIA_BACKEND"] = "ffmpeg" class CustomWebView(QWebEngineView): def __init__(self, parent=None,window=None): super().__init__(parent) # 捕获链接悬停事件获取URL self.window = window self.page().linkHovered.connect(self.save_hovered_url) self.hovered_url = QUrl() self.page().profile().setHttpUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36") settings = self.settings() settings.setAttribute(QWebEngineSettings.PlaybackRequiresUserGesture, False) # 允许自动播放 settings.setAttribute(QWebEngineSettings.JavascriptEnabled, True) settings.setAttribute(QWebEngineSettings.PluginsEnabled, True) # 启用插件 settings.setAttribute(QWebEngineSettings.WebGLEnabled, True) # 支持WebGL settings.setAttribute(QWebEngineSettings.LocalStorageEnabled, True) # 启用本地存储 settings.setAttribute(QWebEngineSettings.JavascriptCanOpenWindows, True) def save_hovered_url(self, url): """保存鼠标悬停的链接地址""" self.hovered_url = QUrl(url) def createWindow(self, type): """重写窗口创建方法""" url = QUrl(self.url().toString()) if self.hovered_url.isValid(): try: self.window.add_new_tab(self.hovered_url) self.load(url) except: self.load(self.hovered_url) return self # 返回当前视图实例 def save_screenshot(self): current_time = datetime.now() photo_name = current_time.strftime("%Y%m%d_%H%M%S_%f") + '.png' save_folder = r'save\photo' os.makedirs(save_folder, exist_ok=True) save_path = os.path.join(save_folder, photo_name) photo = self.grab() photo.save(rf'save\photo\{photo_name}') class BrowserWindow(QMainWindow): def __init__(self): super().__init__() self.setWindowTitle("PyQt5 浏览器") self.setGeometry(100, 100, 1200, 800) # 创建标签页 self.tabs = QTabWidget() self.tabs.setTabsClosable(True) self.tabs.tabCloseRequested.connect(self.close_tab) self.setCentralWidget(self.tabs) # 创建初始标签页 self.add_new_tab(QUrl('https://www.baidu.com'), "主页") # 创建工具栏 self.create_toolbar() # 创建菜单栏 self.create_menus() # 创建状态栏 self.status_bar = QStatusBar() self.setStatusBar(self.status_bar) # 显示窗口 self.show() def add_new_tab(self, url=None, label="新标签页"): """添加新标签页""" if url is None: url = QUrl('https://www.baidu.com') browser = CustomWebView(window=self) settings = browser.settings() settings.setFontFamily(QWebEngineSettings.StandardFont, 'Microsoft YaHei UI') settings.setFontFamily(QWebEngineSettings.FixedFont, "Courier New") browser.setUrl(url) browser.urlChanged.connect(self.update_urlbar) browser.loadProgress.connect(self.update_progress) browser.loadFinished.connect(self.update_title) index = self.tabs.addTab(browser, label) self.tabs.setCurrentIndex(index) return browser def close_tab(self, index): """关闭标签页""" if self.tabs.count() < 2: return self.tabs.removeTab(index) def create_toolbar(self): """创建工具栏""" toolbar = QToolBar("导航工具栏") toolbar.setMovable(False) self.addToolBar(toolbar) # 后退按钮 back_btn = QAction(QIcon("back.png"), "后退", self) back_btn.setStatusTip("后退到上一页") back_btn.triggered.connect(lambda: self.current_browser().back()) toolbar.addAction(back_btn) # 前进按钮 forward_btn = QAction(QIcon("forward.png"), "前进", self) forward_btn.setStatusTip("前进到下一页") forward_btn.triggered.connect(lambda: self.current_browser().forward()) toolbar.addAction(forward_btn) # 刷新按钮 reload_btn = QAction(QIcon("reload.png"), "刷新", self) reload_btn.setStatusTip("刷新当前页面") reload_btn.triggered.connect(lambda: self.current_browser().reload()) toolbar.addAction(reload_btn) # 主页按钮 home_btn = QAction(QIcon("home.png"), "主页", self) home_btn.setStatusTip("返回主页") home_btn.triggered.connect(self.navigate_home) toolbar.addAction(home_btn) toolbar.addSeparator() # 地址栏 self.urlbar = QLineEdit() self.urlbar.returnPressed.connect(self.navigate_to_url) toolbar.addWidget(self.urlbar) # 停止加载按钮 stop_btn = QAction(QIcon("stop.png"), "停止", self) stop_btn.setStatusTip("停止加载当前页面") stop_btn.triggered.connect(lambda: self.current_browser().stop()) toolbar.addAction(stop_btn) def create_menus(self): """创建菜单栏""" # 文件菜单 file_menu = self.menuBar().addMenu("文件(&F)") new_tab_action = QAction(QIcon("new-tab.png"), "新建标签页", self) new_tab_action.setShortcut(QKeySequence.AddTab) new_tab_action.triggered.connect(lambda: self.add_new_tab()) file_menu.addAction(new_tab_action) new_window_action = QAction(QIcon("new-window.png"), "新建窗口", self) new_window_action.setShortcut("Ctrl+N") new_window_action.triggered.connect(self.new_window) file_menu.addAction(new_window_action) file_menu.addSeparator() save_page_action = QAction(QIcon("save.png"), "保存页面", self) save_page_action.setShortcut("Ctrl+S") save_page_action.triggered.connect(self.save_page) file_menu.addAction(save_page_action) file_menu.addSeparator() exit_action = QAction(QIcon("exit.png"), "退出", self) exit_action.setShortcut("Ctrl+Q") exit_action.triggered.connect(self.close) file_menu.addAction(exit_action) # 编辑菜单 edit_menu = self.menuBar().addMenu("编辑(&E)") copy_action = QAction(QIcon("copy.png"), "复制", self) copy_action.setShortcut("Ctrl+C") copy_action.triggered.connect(self.copy) edit_menu.addAction(copy_action) paste_action = QAction(QIcon("paste.png"), "粘贴", self) paste_action.setShortcut("Ctrl+V") paste_action.triggered.connect(self.paste) edit_menu.addAction(paste_action) cut_action = QAction(QIcon("cut.png"), "剪切", self) cut_action.setShortcut("Ctrl+X") cut_action.triggered.connect(self.cut) edit_menu.addAction(cut_action) # 查看菜单 view_menu = self.menuBar().addMenu("查看(&V)") zoom_in_action = QAction(QIcon("zoom-in.png"), "放大", self) zoom_in_action.setShortcut("Ctrl++") zoom_in_action.triggered.connect(self.zoom_in) view_menu.addAction(zoom_in_action) zoom_out_action = QAction(QIcon("zoom-out.png"), "缩小", self) zoom_out_action.setShortcut("Ctrl+-") zoom_out_action.triggered.connect(self.zoom_out) view_menu.addAction(zoom_out_action) reset_zoom_action = QAction(QIcon("zoom-reset.png"), "重置缩放", self) reset_zoom_action.setShortcut("Ctrl+0") reset_zoom_action.triggered.connect(self.reset_zoom) view_menu.addAction(reset_zoom_action) # 历史菜单 history_menu = self.menuBar().addMenu("历史(&H)") back_action = QAction(QIcon("back.png"), "后退", self) back_action.setShortcut("Alt+Left") back_action.triggered.connect(lambda: self.current_browser().back()) history_menu.addAction(back_action) forward_action = QAction(QIcon("forward.png"), "前进", self) forward_action.setShortcut("Alt+Right") forward_action.triggered.connect(lambda: self.current_browser().forward()) history_menu.addAction(forward_action) # 帮助菜单 help_menu = self.menuBar().addMenu("帮助(&H)") about_action = QAction(QIcon("about.png"), "关于", self) about_action.triggered.connect(self.show_about) help_menu.addAction(about_action) def current_browser(self): """获取当前标签页的浏览器实例""" return self.tabs.currentWidget() def navigate_home(self): """导航到主页""" self.current_browser().setUrl(QUrl("https://www.baidu.com")) def navigate_to_url(self): """导航到地址栏中的URL""" url = self.urlbar.text() if not url.startswith(('http://', 'https://')): url = 'http://' + url self.current_browser().setUrl(QUrl(url)) def update_urlbar(self, q): """更新地址栏显示""" self.urlbar.setText(q.toString()) self.urlbar.setCursorPosition(0) def update_progress(self, progress): """更新加载进度""" if progress < 100: self.status_bar.showMessage(f"加载中: {progress}%") else: self.status_bar.clearMessage() def update_title(self): """更新标签页标题""" title = self.current_browser().page().title() self.setWindowTitle(f"{title} - PyQt5 浏览器") self.tabs.setTabText(self.tabs.currentIndex(), title[:15] + '...' if len(title) > 15 else title) def new_window(self): """创建新窗口""" new_window = BrowserWindow() new_window.show() def save_page(self): """保存页面""" self.current_browser().save_screenshot() self.status_bar.showMessage("保存成功", 3000) def copy(self): """复制操作""" self.current_browser().page().triggerAction(QWebEnginePage.Copy) def paste(self): """粘贴操作""" self.current_browser().page().triggerAction(QWebEnginePage.Paste) def cut(self): """剪切操作""" self.current_browser().page().triggerAction(QWebEnginePage.Cut) def zoom_in(self): """放大页面""" self.current_browser().setZoomFactor(self.current_browser().zoomFactor() + 0.1) def zoom_out(self): """缩小页面""" self.current_browser().setZoomFactor(self.current_browser().zoomFactor() - 0.1) def reset_zoom(self): """重置缩放""" self.current_browser().setZoomFactor(1.0) def show_about(self): """显示关于对话框""" QMessageBox.about(self, "关于 PyQt5 浏览器", "这是一个使用 PyQt5 创建的浏览器\n\n" "版本: 1.0\n" "支持基本浏览功能、多标签页和菜单栏操作") if __name__ == "__main__": app = QApplication(sys.argv) app.setApplicationName("PyQt5 浏览器") app.setWindowIcon(QIcon("browser.png")) app.setFont(QFont('Microsoft YaHei UI', 10, QFont.Normal)) translator = QTranslator() locale = QLocale.system().name() if translator.load("qt_"+ locale, QLibraryInfo.location(QLibraryInfo.TranslationsPath)): app.installTranslator(translator) # 设置默认样式 app.setStyle("Fusion") window = BrowserWindow() sys.exit(app.exec_())
最新发布
07-16
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值