Can't get Android App installed as System App

2019-08-08 19:58发布

I have an Android app which I want to use to set the APN settings. This requires the android.permission.WRITE_APN_SETTINGS permission, which is only granted to System apps or apps signed with the same private key as the OS itself. I'm only going to be using this on an emulator (or maybe a rooted device), so being able to actually deploy it to devices outside of my control isn't a concern. I'm building against and pushing to API 19.

Despite pushing my APK to the /system/app/ directory and setting chmod 0644, I still get java.lang.SecurityException: No permission to write APN settings: Neither user 10052 nor current process has android.permission.WRITE_APN_SETTINGS. in adb logcat when I try to run the app.

I've also tried running the app using db shell "su -c am start -n com.example.proxysetter/.MainActivity" with no luck.

Any suggestions other than compiling and signing my own Android image from source? (Not ideal.) I'm pretty sure I don't need to provide a .odex file even though everything else in /system/app/ has it.

Here are the steps I've been following so far when pushing the APK to the emulator:

ant debug
adb remount
adb push bin/MainActivity-debug.apk /system/app/
adb shell chmod 0644 /system/app/MainActivity-debug.apk

I don't reboot the emulator using adb reboot because it doesn't work for emulators, and if I manually kill the emulator and relaunch it, the app doesn't appear in my app list.

And my manifest:

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

    <uses-sdk
        android:minSdkVersion="18"
        android:targetSdkVersion="19" />
    <uses-permission android:name="android.permission.WRITE_APN_SETTINGS"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

And the stack trace:

I/ActivityManager(  384): Start proc com.example.proxysetter for activity com.example.proxysetter/.MainActivity: pid=1082 uid=10052 gids={50052}
D/dalvikvm( 1082): Not late-enabling CheckJNI (already on)
D/dalvikvm(  384): GC_FOR_ALLOC freed 340K, 15% free 6420K/7468K, paused 91ms, total 93ms
D/dalvikvm( 1082): GC_FOR_ALLOC freed 70K, 10% free 3571K/3968K, paused 30ms, total 32ms
E/DatabaseUtils(  535): Writing exception to parcel
E/DatabaseUtils(  535): java.lang.SecurityException: No permission to write APN settings: Neither user 10052 nor current process has android.permission.WRITE_APN_SETTINGS.
E/DatabaseUtils(  535):     at android.app.ContextImpl.enforce(ContextImpl.java:1685)
E/DatabaseUtils(  535):     at android.app.ContextImpl.enforceCallingOrSelfPermission(ContextImpl.java:1714)
E/DatabaseUtils(  535):     at com.android.providers.telephony.TelephonyProvider.checkPermission(TelephonyProvider.java:735)
E/DatabaseUtils(  535):     at com.android.providers.telephony.TelephonyProvider.query(TelephonyProvider.java:462)
E/DatabaseUtils(  535):     at android.content.ContentProvider.query(ContentProvider.java:857)
E/DatabaseUtils(  535):     at android.content.ContentProvider$Transport.query(ContentProvider.java:200)
E/DatabaseUtils(  535):     at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:112)
E/DatabaseUtils(  535):     at android.os.Binder.execTransact(Binder.java:404)
E/DatabaseUtils(  535):     at dalvik.system.NativeStart.run(Native Method)
D/AndroidRuntime( 1082): Shutting down VM
W/dalvikvm( 1082): threadid=1: thread exiting with uncaught exception (group=0xb1a41ba8)
E/AndroidRuntime( 1082): FATAL EXCEPTION: main
E/AndroidRuntime( 1082): Process: com.example.proxysetter, PID: 1082
E/AndroidRuntime( 1082): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.proxysetter/com.example.proxysetter.MainActivity}: java.lang.SecurityException: No permission to write APN settings: Neither user 10052 nor current process has android.permission.WRITE_APN_SETTINGS.
E/AndroidRuntime( 1082):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
E/AndroidRuntime( 1082):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
E/AndroidRuntime( 1082):    at android.app.ActivityThread.access$800(ActivityThread.java:135)
E/AndroidRuntime( 1082):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
E/AndroidRuntime( 1082):    at android.os.Handler.dispatchMessage(Handler.java:102)
E/AndroidRuntime( 1082):    at android.os.Looper.loop(Looper.java:136)
E/AndroidRuntime( 1082):    at android.app.ActivityThread.main(ActivityThread.java:5017)
E/AndroidRuntime( 1082):    at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 1082):    at java.lang.reflect.Method.invoke(Method.java:515)
E/AndroidRuntime( 1082):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
E/AndroidRuntime( 1082):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
E/AndroidRuntime( 1082):    at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime( 1082): Caused by: java.lang.SecurityException: No permission to write APN settings: Neither user 10052 nor current process has android.permission.WRITE_APN_SETTINGS.
E/AndroidRuntime( 1082):    at android.os.Parcel.readException(Parcel.java:1465)
E/AndroidRuntime( 1082):    at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:185)
E/AndroidRuntime( 1082):    at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:137)
E/AndroidRuntime( 1082):    at android.content.ContentProviderProxy.query(ContentProviderNative.java:413)
E/AndroidRuntime( 1082):    at android.content.ContentResolver.query(ContentResolver.java:461)
E/AndroidRuntime( 1082):    at android.content.ContentResolver.query(ContentResolver.java:404)
E/AndroidRuntime( 1082):    at com.example.proxysetter.MainActivity.setAPN(MainActivity.java:28)
E/AndroidRuntime( 1082):    at com.example.proxysetter.MainActivity.onCreate(MainActivity.java:19)
E/AndroidRuntime( 1082):    at android.app.Activity.performCreate(Activity.java:5231)
E/AndroidRuntime( 1082):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
E/AndroidRuntime( 1082):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
E/AndroidRuntime( 1082):    ... 11 more
W/ActivityManager(  384):   Force finishing activity com.example.proxysetter/.MainActivity

1条回答
叼着烟拽天下
2楼-- · 2019-08-08 20:12

For those wondering:

a) I made a typo; for API 19+ you want to push to /system/priv-app.

b) I was able to install the app by mounting system.img as ext4 and installing the app on the system image. I copied the system image directory into a new location, modified system.img and then edited foo.avd/config.ini to point to my modified system image directory.

查看更多
登录 后发表回答