2010-04-14 151 views
42

我正在查看Android相機代碼,當我嘗試導入android.os.SystemProperties時,無法找到它。android.os.SystemProperties在哪裏?

這是我在看文件:
https://android.googlesource.com/platform/packages/apps/Camera/+/eclair-release/src/com/android/camera/VideoCamera.java

我創建了一個新的2.1的項目,並試圖再次導入這個命名空間,但它仍然無法找到。我檢查了https://developer.android.comSystemProperties未列出。

我錯過了什麼嗎?

回答

29

這是在Android源代碼的類:

https://android.googlesource.com/platform/frameworks/base/+/eclair-release/core/java/android/os/SystemProperties.java

請參閱類的JavaDoc {@hide}?這意味着這個類不會作爲公共SDK的一部分導出。

相機應用程序使用它作爲內部,他們不會使用公共SDK來構建它。

您仍然可以通過獲取源,消除@hide,使自己 定製的SDK在這個類

  1. 通過反射或

  2. 得到。

但是漂亮的定義現在你要去「off SDK」,因此您的應用程序很可能被打破或得到操作系統版本不同的行爲作爲Android的人會很少努力不改變版本之間的此類多。

+3

如果上面的源代碼鏈接不工作,你可以試試這個 http://androidxref.com/4.3_r2.1/xref/frameworks/base/core/java/android/os/SystemProperties.java – Vins 2013-08-29 10:20:54

+0

@Jim布萊克勒:能否請你解釋第二種解決方案。我如何製作自己的SDK? – 2014-12-18 08:17:21

12

你可以Exec的出到getprop命令:

String line = ""; 
try { 
Process ifc = Runtime.getRuntime().exec("getprop ro.hardware"); 
BufferedReader bis = new BufferedReader(new InputStreamReader(ifc.getInputStream())); 
line = bis.readLine(); 
} catch (java.io.IOException e) { 
} 
ifc.destroy(); 
+0

getprop中沒有IMEI/IMSI:https://guardianproject.info/wiki/Google_Nexus_S_I9023_running_stock_4.0.4 – 2013-04-22 07:25:11

+0

以下是accuya的示例:http://stackoverflow.com/a/11623309/4515489 – jk7 2017-02-28 02:22:27

55

如果使用「反射」選項,你可以使用下面

package com.etc.etc; 

import java.io.File; 
import java.lang.reflect.Method; 
import android.content.Context; 
import dalvik.system.DexFile; 


public class SystemPropertiesProxy 
{ 

/** 
* This class cannot be instantiated 
*/ 
private SystemPropertiesProxy(){ 

} 

    /** 
    * Get the value for the given key. 
    * @return an empty string if the key isn't found 
    * @throws IllegalArgumentException if the key exceeds 32 characters 
    */ 
    public static String get(Context context, String key) throws IllegalArgumentException { 

     String ret= ""; 

     try{ 

      ClassLoader cl = context.getClassLoader(); 
      @SuppressWarnings("rawtypes") 
      Class SystemProperties = cl.loadClass("android.os.SystemProperties"); 

      //Parameters Types 
      @SuppressWarnings("rawtypes") 
       Class[] paramTypes= new Class[1]; 
      paramTypes[0]= String.class; 

      Method get = SystemProperties.getMethod("get", paramTypes); 

      //Parameters 
      Object[] params= new Object[1]; 
      params[0]= new String(key); 

      ret= (String) get.invoke(SystemProperties, params); 

     }catch(IllegalArgumentException iAE){ 
      throw iAE; 
     }catch(Exception e){ 
      ret= ""; 
      //TODO 
     } 

     return ret; 

    } 

    /** 
    * Get the value for the given key. 
    * @return if the key isn't found, return def if it isn't null, or an empty string otherwise 
    * @throws IllegalArgumentException if the key exceeds 32 characters 
    */ 
    public static String get(Context context, String key, String def) throws IllegalArgumentException { 

     String ret= def; 

     try{ 

      ClassLoader cl = context.getClassLoader(); 
      @SuppressWarnings("rawtypes") 
      Class SystemProperties = cl.loadClass("android.os.SystemProperties"); 

      //Parameters Types 
      @SuppressWarnings("rawtypes") 
       Class[] paramTypes= new Class[2]; 
      paramTypes[0]= String.class; 
      paramTypes[1]= String.class;   

      Method get = SystemProperties.getMethod("get", paramTypes); 

      //Parameters 
      Object[] params= new Object[2]; 
      params[0]= new String(key); 
      params[1]= new String(def); 

      ret= (String) get.invoke(SystemProperties, params); 

     }catch(IllegalArgumentException iAE){ 
      throw iAE; 
     }catch(Exception e){ 
      ret= def; 
      //TODO 
     } 

     return ret; 

    } 

    /** 
    * Get the value for the given key, and return as an integer. 
    * @param key the key to lookup 
    * @param def a default value to return 
    * @return the key parsed as an integer, or def if the key isn't found or 
    *   cannot be parsed 
    * @throws IllegalArgumentException if the key exceeds 32 characters 
    */ 
    public static Integer getInt(Context context, String key, int def) throws IllegalArgumentException { 

     Integer ret= def; 

     try{ 

      ClassLoader cl = context.getClassLoader(); 
      @SuppressWarnings("rawtypes") 
      Class SystemProperties = cl.loadClass("android.os.SystemProperties"); 

      //Parameters Types 
      @SuppressWarnings("rawtypes") 
       Class[] paramTypes= new Class[2]; 
      paramTypes[0]= String.class; 
      paramTypes[1]= int.class; 

      Method getInt = SystemProperties.getMethod("getInt", paramTypes); 

      //Parameters 
      Object[] params= new Object[2]; 
      params[0]= new String(key); 
      params[1]= new Integer(def); 

      ret= (Integer) getInt.invoke(SystemProperties, params); 

     }catch(IllegalArgumentException iAE){ 
      throw iAE; 
     }catch(Exception e){ 
      ret= def; 
      //TODO 
     } 

     return ret; 

    } 

    /** 
    * Get the value for the given key, and return as a long. 
    * @param key the key to lookup 
    * @param def a default value to return 
    * @return the key parsed as a long, or def if the key isn't found or 
    *   cannot be parsed 
    * @throws IllegalArgumentException if the key exceeds 32 characters 
    */ 
    public static Long getLong(Context context, String key, long def) throws IllegalArgumentException { 

     Long ret= def; 

     try{ 

      ClassLoader cl = context.getClassLoader(); 
      @SuppressWarnings("rawtypes") 
       Class SystemProperties= cl.loadClass("android.os.SystemProperties"); 

      //Parameters Types 
      @SuppressWarnings("rawtypes") 
       Class[] paramTypes= new Class[2]; 
      paramTypes[0]= String.class; 
      paramTypes[1]= long.class; 

      Method getLong = SystemProperties.getMethod("getLong", paramTypes); 

      //Parameters 
      Object[] params= new Object[2]; 
      params[0]= new String(key); 
      params[1]= new Long(def); 

      ret= (Long) getLong.invoke(SystemProperties, params); 

     }catch(IllegalArgumentException iAE){ 
      throw iAE; 
     }catch(Exception e){ 
      ret= def; 
      //TODO 
     } 

     return ret; 

    } 

    /** 
    * Get the value for the given key, returned as a boolean. 
    * Values 'n', 'no', '0', 'false' or 'off' are considered false. 
    * Values 'y', 'yes', '1', 'true' or 'on' are considered true. 
    * (case insensitive). 
    * If the key does not exist, or has any other value, then the default 
    * result is returned. 
    * @param key the key to lookup 
    * @param def a default value to return 
    * @return the key parsed as a boolean, or def if the key isn't found or is 
    *   not able to be parsed as a boolean. 
    * @throws IllegalArgumentException if the key exceeds 32 characters 
    */ 
    public static Boolean getBoolean(Context context, String key, boolean def) throws IllegalArgumentException { 

     Boolean ret= def; 

     try{ 

      ClassLoader cl = context.getClassLoader(); 
      @SuppressWarnings("rawtypes") 
      Class SystemProperties = cl.loadClass("android.os.SystemProperties"); 

      //Parameters Types 
      @SuppressWarnings("rawtypes") 
       Class[] paramTypes= new Class[2]; 
      paramTypes[0]= String.class; 
      paramTypes[1]= boolean.class; 

      Method getBoolean = SystemProperties.getMethod("getBoolean", paramTypes); 

      //Parameters   
      Object[] params= new Object[2]; 
      params[0]= new String(key); 
      params[1]= new Boolean(def); 

      ret= (Boolean) getBoolean.invoke(SystemProperties, params); 

     }catch(IllegalArgumentException iAE){ 
      throw iAE; 
     }catch(Exception e){ 
      ret= def; 
      //TODO 
     } 

     return ret; 

    } 

    /** 
    * Set the value for the given key. 
    * @throws IllegalArgumentException if the key exceeds 32 characters 
    * @throws IllegalArgumentException if the value exceeds 92 characters 
    */ 
    public static void set(Context context, String key, String val) throws IllegalArgumentException { 

     try{ 

      @SuppressWarnings("unused") 
      DexFile df = new DexFile(new File("/system/app/Settings.apk")); 
      @SuppressWarnings("unused") 
      ClassLoader cl = context.getClassLoader(); 
      @SuppressWarnings("rawtypes") 
      Class SystemProperties = Class.forName("android.os.SystemProperties"); 

      //Parameters Types 
      @SuppressWarnings("rawtypes") 
       Class[] paramTypes= new Class[2]; 
      paramTypes[0]= String.class; 
      paramTypes[1]= String.class; 

      Method set = SystemProperties.getMethod("set", paramTypes); 

      //Parameters   
      Object[] params= new Object[2]; 
      params[0]= new String(key); 
      params[1]= new String(val); 

      set.invoke(SystemProperties, params); 

     }catch(IllegalArgumentException iAE){ 
      throw iAE; 
     }catch(Exception e){ 
      //TODO 
     } 

    } 
} 
+0

這是行不通的嗎?我試過SystemPropertiesProxy.get(this,「android.telephony.TelephonyProperties.PROPERTY_IMSI」);但空了。 – 2013-04-22 07:19:04

+0

@ bruno.braga,它不是從SystemProperties獲得的那種屬性。要以這種方式查看您的設備可以獲得哪些屬性,請運行'adb shell getprop'。 – lapis 2013-05-29 05:13:01

+0

@Psycho,是的,我知道......這就是重點......對於我測試的所有設備,這都可以在getprop中找到。這就是爲什麼我認爲這根本行不通。 – 2013-05-30 03:41:38

14

班上亂搞我的後我終於得到了上面的反射代碼,以設置和創建新的本地系統屬性,有一些注意事項:

  1. 您需要成爲系統用戶,在清單中添加:android:sharedUserId =「android.uid.system」。

  2. 您需要與平臺關鍵簽署APK,我被騙了,只是推翻默認的調試簽名密鑰在Eclipse作爲顯示在這裏: http://stoned-android.blogspot.co.uk/2012_01_01_archive.html

  3. 本機的系統屬性服務具有控制所有的ACL寫入對屬性的訪問可以破壞一個密鑰空間(如系統或調試)。見 /system/core/init/property_service.c:

    { 「淨」,AID_SYSTEM,0},{ 「開發」,AID_SYSTEM,0},{ 「運行」,AID_SYSTEM,0 }, {「hw。「,AID_SYSTEM,0}, {」sys。「,AID_SYSTEM,0}, {」service。「,AID_SYSTEM,0}, {」wlan。「,AID_SYSTEM,0}, {」dhcp。「, AID_SYSTEM,0},

或者,如果你正在推出自己的身材,如果你真的想要,但它似乎更容易重用上面的一個,你可以添加自己的密鑰。

21

類貼作爲來自用戶的回答Void有一堆不必要的東西,下面是我使用android.os.SystemProperties反思的課程:

/* 
* Copyright (C) 2015 Jared Rummler 
* 
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at 
* 
*  http://www.apache.org/licenses/LICENSE-2.0 
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed under the License is distributed on an "AS IS" BASIS, 
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License. 
*/ 

/** 
* Gives access to the system properties store. The system properties store contains a list of 
* string key-value pairs. 
*/ 
public class SystemProperties { 

    private static final Class<?> SP = getSystemPropertiesClass(); 

    /** 
    * Get the value for the given key. 
    */ 
    public static String get(String key) { 
    try { 
     return (String) SP.getMethod("get", String.class).invoke(null, key); 
    } catch (Exception e) { 
     return null; 
    } 
    } 

    /** 
    * Get the value for the given key. 
    * 
    * @return if the key isn't found, return def if it isn't null, or an empty string otherwise 
    */ 
    public static String get(String key, String def) { 
    try { 
     return (String) SP.getMethod("get", String.class, String.class).invoke(null, key, def); 
    } catch (Exception e) { 
     return def; 
    } 
    } 

    /** 
    * Get the value for the given key, returned as a boolean. Values 'n', 'no', '0', 'false' or 
    * 'off' are considered false. Values 'y', 'yes', '1', 'true' or 'on' are considered true. (case 
    * sensitive). If the key does not exist, or has any other value, then the default result is 
    * returned. 
    * 
    * @param key 
    *  the key to lookup 
    * @param def 
    *  a default value to return 
    * @return the key parsed as a boolean, or def if the key isn't found or is not able to be 
    * parsed as a boolean. 
    */ 
    public static boolean getBoolean(String key, boolean def) { 
    try { 
     return (Boolean) SP.getMethod("getBoolean", String.class, boolean.class) 
      .invoke(null, key, def); 
    } catch (Exception e) { 
     return def; 
    } 
    } 

    /** 
    * Get the value for the given key, and return as an integer. 
    * 
    * @param key 
    *  the key to lookup 
    * @param def 
    *  a default value to return 
    * @return the key parsed as an integer, or def if the key isn't found or cannot be parsed 
    */ 
    public static int getInt(String key, int def) { 
    try { 
     return (Integer) SP.getMethod("getInt", String.class, int.class).invoke(null, key, def); 
    } catch (Exception e) { 
     return def; 
    } 
    } 

    /** 
    * Get the value for the given key, and return as a long. 
    * 
    * @param key 
    *  the key to lookup 
    * @param def 
    *  a default value to return 
    * @return the key parsed as a long, or def if the key isn't found or cannot be parsed 
    */ 
    public static long getLong(String key, long def) { 
    try { 
     return (Long) SP.getMethod("getLong", String.class, long.class).invoke(null, key, def); 
    } catch (Exception e) { 
     return def; 
    } 
    } 

    private static Class<?> getSystemPropertiesClass() { 
    try { 
     return Class.forName("android.os.SystemProperties"); 
    } catch (ClassNotFoundException shouldNotHappen) { 
     return null; 
    } 
    } 

    private SystemProperties() { 
    throw new AssertionError("no instances"); 
    } 

} 
+0

我看到set方法不起作用。我的設備已經紮根。當我運行你的代碼時,SuperSU應用程序不會出現獲得許可的對話框。所以我認爲你的代碼並沒有真正觸發su的權限。 – hqt 2016-12-26 02:42:27

+0

@hqt你需要在shell中運行setprop。我應該刪除setprop方法。 – 2016-12-26 05:28:15

1

經過大量搜索後,我找到了一種設置Android系統屬性的方法。 我無法找到Android棒棒糖版本的解決方案。但我成功地這樣做了。爲了設置系統屬性,我們需要使用:

import android.os.SystemProperties 
SystemProperties.set(key, value). 

例如, SystemProperties.set("sys.android", 5.0)

現在你需要給權限的新系統屬性 轉到/home/inkkashy04/Android_Lollypop/external/sepolicy/property_contexts 和你的財產給予適當的權限

sys.android U:object_r:system_prop:S0

現在閃爍圖像後,您可以看到您的系統屬性按命令列出:

adb shell getprop