" 須知少時凌云志,曾許人間第一流 "
在《風犬少年的天空》中劉聞欽下線時,嘴里念叨的就是這句,我們何嘗不是這樣的人呢,年輕時的凌云大志,曾決心要做人間第一流的人物,干出人間第一流的成績,但歲月蹉跎,依舊名利雙無收,
前言
本文重點講述如何實作Android設備重啟,這里的Android設備可不是我們用的手機哦,畢竟現在的手機越來越高級,好像除了蘋果系列的手機沒有定時開關機,Android手機都是有這個功能的,有的人喜歡睡前關機,早上四五點就定時開機,覺得這樣手機用起來才不會卡,當然這只是一小部分人的做法,好多人都是直接通宵玩手機的,玩到沒電就充電睡覺去,
好了,再說就跑題了,哈哈 ~~
進入正題,為什么需要重啟Android設備呢?因為現在好多生產安卓板的廠家用的Android系統大部分是閹割版的,自身硬體和服務需要用到什么功能就放進去,沒用到的就切掉,但是有些廠家對于這一塊處理得不夠好,導致系統長時間運行時,會出現不穩定情況,例如Android板長時間運行一款app的,比如廣告投放機、自動售賣機等,如果本身配置不夠高,系統做的又不好,就會出現卡死,黑屏或者卡屏閃屏問題出現,只要硬體沒壞,只需要重啟下Android系統就可以解決上述問題的,
一、利用系統廣播ACTION_REBOOT
這種方式非常簡單,只需要發送一個系統廣播ACTION_REBOOT,代碼如下:
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent reboot = new Intent(Intent.ACTION_REBOOT);
reboot.putExtra("nowait", 1);
reboot.putExtra("interval", 1);
reboot.putExtra("window", 0);
sendBroadcast(reboot);
}
});
但是這樣是不會重啟的,程式還會因此閃退,直接報錯:
com.xz.android72test E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.xz.android72test, PID: 3180
java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.intent.action.REBOOT from pid=3180, uid=10046
at android.os.Parcel.readException(Parcel.java:1546)
at android.os.Parcel.readException(Parcel.java:1499)
at android.app.ActivityManagerProxy.broadcastIntent(ActivityManagerNative.java:2831)
at android.app.ContextImpl.sendBroadcast(ContextImpl.java:1331)
at android.content.ContextWrapper.sendBroadcast(ContextWrapper.java:377)
at com.xz.android72test.MainActivity$2.onClick(MainActivity.java:115)
at android.view.View.performClick(View.java:4780)
at android.view.View$PerformClick.run(View.java:19866)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5293)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
最主要的錯誤是SecurityException: Permission Denial,權限不夠,默認的SDK并沒有提供應用開發者直接的Android系統關機或重啟的API介面,一般來講,實作Android系統的關機或重啟,需要較高的權限(系統權限甚至Root權限),在此,我們需要將app的權限提高至系統權限,找到AndroidManifest.xml,添加下面的代碼:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.xz.android72test" android:sharedUserId="android.uid.system">
..........
</manifest>
但是做到這里也是不會重啟的,程式還會安裝失敗,直接報錯:
Installation did not succeed.
The application could not be installed: INSTALL_FAILED_SHARED_USER_INCOMPATIBLE
Installation failed due to: 'null'
這是為什么呢? 因為這個apk沒有這個系統的簽名,如何簽名呢?
有三種方式:
第一種,這種方式比較經典傳統:
- 聯系安卓板廠家技識訓取主板系統的簽名檔案
platform.pk8與platform.x509.pem,每家安卓板廠家簽名檔案都不一樣,還需要signapk.jar這個檔案,一般廠家也會將這個檔案一起發送過來,網上也是可以下載的,jar包里面帶有簽名的程式, - 在windows下,啟動cmd.exe,進入命令列模式,通過
cd C:\Users\Administrator\Desktop\signapkApp進到帶有platform.pk8、platform.x509.pem和signapk.jar檔案的檔案夾, - 最后輸入下面命令進行簽名:
java -jar signapk.jar platform.x509.pem platform.pk8 C:\Users\Administrator\Desktop\signapkApp\app-release.apk signed_app-release.apk
其中C:\Users\Administrator\Desktop\signapk.jar\app-release.apk為需要簽名的apk路徑,signed_app-release.apk是簽名之后的apk,跟未簽名的apk在同一個目錄下,
最后直接通過adb push或者adb install把這個signed_app-release.apk安裝完即可實作重啟了,
第二種,這種方式跟第一種比較,更加簡單,也可以在debug版本或者release版本進行簽名:
只需要問安卓板廠家技術要一個檔案,或者自己根據主板系統的簽名檔案platform.pk8與 platform.x509.pem做一個出來,這個檔案就是platform.keystore簽名檔案,
然后在app\build.gradle檔案下添加下面代碼:
android {
......
signingConfigs {
debug {
storeFile file('platform.keystore檔案路徑')
storePassword 'keystore的密碼'
keyAlias '密鑰別名'
keyPassword '密鑰密碼'
}
release {
storeFile file('platform.keystore檔案路徑')
storePassword 'keystore的密碼'
keyAlias '密鑰別名'
keyPassword '密鑰密碼'
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
debug {
signingConfig signingConfigs.debug
}
}
}
至此,Build出來的apk無論是debug還是release版本都帶有系統簽名的,
第三種,這種方式基本算是白嫖了,利用廠家提供的簽名網站,只需要將未簽名的apk上傳到他們服務器,過一會簽完名之后會自動下載下來,而這個檔案就是已經簽完名了,

對比這三種方式,是不是最后這一種最省事呢?但是吶,人還是不可以太懶的,建議用第二種方式啦,
二、利用Linux-shell發送reboot指令
這種方式非常簡單,利用Runtime這個Java類可以直接呼叫并執行shell命令,直接貼代碼:
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
exec("reboot");
}
});
如果Android設備沒有root過,需要在AndroidManifest.xml下添加一下權限,從而使下面代碼獲取管理員權限:
<uses-permission android:name="android.permission.ACCESS_SUPERUSER" />
exec方法:
private String exec(String command) {
Process process = null;
BufferedReader reader = null;
InputStreamReader is = null;
DataOutputStream os = null;
try {
process = Runtime.getRuntime().exec("su");
is = new InputStreamReader(process.getInputStream());
reader = new BufferedReader(is);
os = new DataOutputStream(process.getOutputStream());
os.writeBytes(command + "\n");
os.writeBytes("exit\n");
os.flush();
int read;
char[] buffer = new char[4096];
StringBuilder output = new StringBuilder();
while ((read = reader.read(buffer)) > 0) {
output.append(buffer, 0, read);
}
process.waitFor();
return output.toString();
} catch (IOException | InterruptedException e) {
throw new RuntimeException(e);
} finally {
try {
if (os != null) {
os.close();
}
if (is != null) {
is.close();
}
if (reader != null) {
reader.close();
}
if (process != null) {
process.destroy();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
普通用戶是沒有權限執行reboot,所以使用的Android設備最好是root過的,不然會在獲取su管理員權限時,出現一個彈窗詢問你是否允許請求超級用戶訪問權限,非常影響用戶體驗,

非常感謝你能看到這里,如果能夠幫助到你是我的榮幸!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/181985.html
標籤:其他
上一篇:新一代構件工具Gradle
