zoukankan      html  css  js  c++  java
  • android 系统重启与关机:java 代码实现

    在应用层如何通过代码实现 android 系统的重启,分享给大家。

    这篇博客是在 android 系统开发的基础之上进行实践的,所以如果你是纯粹的 app 开发,可能要让你失望了。


    该代码在真机上测试成功,在模拟器上面测试失败。


    在 linux 下面,重启 pc,非 root 用户需要执行 sudo reboot,所以在 android 下重启机器也需要一定的权限。


    应用程序界面:




    1. 新建一个 android 工程 reboot




    2. 编写 Android.mk 


    LOCAL_PATH:= $(call my-dir)
    include $(CLEAR_VARS)

    LOCAL_MODULE_TAGS := optional

    LOCAL_SRC_FILES := $(call all-java-files-under, src)

    LOCAL_PACKAGE_NAME := reboot
    LOCAL_CERTIFICATE := platform

    include $(BUILD_PACKAGE)

    # Use the folloing include to make our test apk.
    include $(call all-makefiles-under,$(LOCAL_PATH))


    具体含义可自行查阅资料。注意:LOCAL_CERTIFICATE := platform


    3. 编写补充 AndroidMenifest.xml


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

        <uses-sdk android:minSdkVersion="7" />

        <application
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:sharedUserId="android.uid.system" >


            <activity
                android:label="@string/app_name"
                android:name=".RebootActivity" >
                <intent-filter >
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>


        </application>

    </manifest>


    注意:android:sharedUserId="android.uid.system"


    4. 编写逻辑代码 RebootActivity.java


    package mark.zhang;

    import android.app.Activity;
    import android.content.Intent;
    import android.os.Bundle;
    import android.view.View;

    public class RebootActivity extends Activity {
        // 是否显示关机确认的对话框
        // false 不显示确认关机的对话框,直接关机
        // true 显示确认关机的对话框,让用户选择是否确认关机
        public static final boolean showShutdownDialog = false;

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
        }

        /**
         * 发送广播.
         * 
         * @param view
         */
        public void onReboot(View view) {
            Intent reboot = new Intent(Intent.ACTION_REBOOT);
            reboot.putExtra("nowait", 1);
            reboot.putExtra("interval", 1);
            reboot.putExtra("window", 0);
            sendBroadcast(reboot);
        }

        /**
         * 启动 Activity.
         * 
         * @param view
         */
        public void onShutdown(View view) {
            public void onShutdown(View view) {
            Intent shutdown = new Intent(Intent.ACTION_REQUEST_SHUTDOWN);
            shutdown.putExtra(Intent.EXTRA_KEY_CONFIRM, showShutdownDialog);
            shutdown.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(shutdown);
        }
        }

    }


    注意:


    Intent.ACTION_REQUEST_SHUTDOWN

    Intent.EXTRA_KEY_CONFIRM


    会报错,这是因为该属性是  {@hide}的。

    不要担心放到系统编译就可以了,注意下面的步骤即可。


    5. 将整个工程放到 android 源码里面编译


    a. 手动复制 reboot 到 src/packages/app 下面


    b. mm -j4 开始编译(可以参考 http://blog.csdn.net/androidbluetooth/article/details/7058717


    如果编译成功,在 /out/target/product/generic/system/app 目录下面,会多一个 reboot.apk 文件。


    6. 安装 apk


    该 apk 必须放到 system/app 下面,即 adb push reboot.apk /system/app



    思考:


    关机或者重启,一个是发送广播,一个是启动 Activity。

    通过查找相应的 action 或者 string 资源(如关机关键字)就可以找到对应的类。


    我们知道,framwork 的 mk 文件、资源文件等都在:

    /frameworks/base/core/res、frameworks/base/core/res/res


    比如关机的那个 Activity 就是 ShutDownActiviy,其又调用 ShutdownThread.shutdown。


    重启的相关的类在 WatchDog.java(定义了相关的量), 其内部类 RebootRequestReceiver 是主要代码。


    继续追踪你就会了解整个流程了。



    粘贴一篇关于权限的文章:

    http://www.5bay.cn/android%E7%AC%94%E8%AE%B0/androidquanxianzhishareduseridheqianming.html


    最近在做个东西,巧合碰到了sharedUserId 的问题,所以收集了一些资料,存存档备份。

    安装在设备中的每一个apk文件,Android 给每个 APK 进程分配一个单独的用户空间,

    其 manifest 中的 userid 就是对应一个 Linux 用户都会被分配到一个属于自己的统一的 Linux 用户 ID,

    并且为它创建一个沙箱,以防止影响其他应用程序(或者其他应用程序影响它)。

    用户 ID 在应用程序安装到设备中时被分配,并且在这个设备中保持它的永久性。

    通过 Shared User id 拥有同一个User id的多个APK可以配置成运行在同一个进程中.

    所以默认就是可以互相访问任意数据. 也可以配置成运行成不同的进程,

    同时可以访问其他APK的数据目录下的数据库和文件.就像访问本程序的数据一样.


    对于一个 APK 来说,如果要使用某个共享 UID 的话,必须做三步:


    1、在 Manifest 节点中增加 android:sharedUserId 属性。


    2、在 Android.mk 中增加 LOCAL_CERTIFICATE 的定义。


    如果增加了上面的属性但没有定义与之对应的 LOCAL_CERTIFICATE 的话,APK是安装不上去的。

    提示错误是:

    Package com.test.MyTest has no signatures that match those in shared user .uid.system; ignoring!

    也就是说,仅有相同签名和相同 sharedUserID 标签的两个应用程序签名都会被分配相同的用户ID。

    例如所有和 media/download 相关的 APK 都使用 android.media 作为 sharedUserId 的话,

    那么它们必须有相同的签名 media。


    3、把 APK 的源码放到 packages/apps/ 目录下,用 mm 进行编译。


    举例说明一下。


    系统中所有使用android.uid.system作为共享UID的APK,都会首先在manifest节点中增加

    android:sharedUserId=”android.uid.system”,

    然后在 Android.mk 中增加 LOCAL_CERTIFICATE := platform。可以参见Settings等。


    系统中所有使用 android.uid.shared 作为共享 UID 的 APK,都会在 manifest 节点中增加

    android:sharedUserId=”android.uid.shared”,

    然后在 Android.mk 中增加 LOCAL_CERTIFICATE := shared。可以参见Launcher等


    系统中所有使用 android.media 作为共享 UID 的 APK,都会在 manifest 节点中增加

    android:sharedUserId=”android.media”,

    然后在 Android.mk 中增加 LOCAL_CERTIFICATE := media。可以参见Gallery等。


    另外,应用创建的任何文件都会被赋予应用的用户标识,并且正常情况下不能被其他包访问。

    当通过 getSharedPreferences(String,int)、openFileOutput(String、int)

    或者 openOrCreate Database(String、int、SQLiteDatabase.CursorFactory)

    创建一个新文件时,开发者可以同时或分别使用 

    MODE_WORLD_READABLE 和MODE_WORLD_RITEABLE 标志允许其他包读/写此文件。

    当设置了这些标志后,这个文件仍然属于自己的应用程序,但是它的全局读/写和读/写权限已经设置,

    所以其他任何应用程序可以看到它。


    关于签名:


    build/target/product/security 目录中有四组默认签名供 Android.mk 在编译APK使用:

    1、testkey:  普通 APK,默认情况下使用。


    2、platform:该 APK 完成一些系统的核心功能。经过对系统中存在的文件夹的访问测试,

                            这种方式编译出来的 APK 所在进程的 UID 为 system。


    3、shared:   该APK需要和home/contacts进程共享数据。


    4、media:该APK是media/download系统中的一环。


    应用程序的 Android.mk 中有一个 LOCAL_CERTIFICATE 字段,

    由它指定用哪个 key 签名,未指定的默认用 testkey.

  • 相关阅读:
    T450的Fn lock
    移民,不应该是走投无路后的选择
    门槛低的行业看天赋,门槛高的行业看毅力
    个人是时代的一朵浪花
    转载:XPath基本语法
    爪哇国新游记之三十四----Dom4j的XPath操作
    常去的论坛今天两个传统行业的坛友要下岗了
    异常中要了解的Throwable类中的几个方法
    感觉JVM的默认异常处理不够好,既然不好那我们就自己来处理异常呗!那么如何自己处理异常呢?
    JVM对异常的默认处理方案
  • 原文地址:https://www.cnblogs.com/chengliu/p/4130615.html
Copyright © 2011-2022 走看看