Android系統參數的讀取

 1.手機信息查看助手可行性分析

  

  
    開始進進編寫程序前,需要對需求的功能做一些可行性分析,以做到有的放矢,假如有些無法實現的功能,可以儘快調整。

  這裏分析一下項目需要的功能,主要是信息查看和信息收集,如版本信息、硬件信息等,這些都可以通過讀取系統文件或者運行系統命令獲取,而像獲取安裝的軟件信息和運行時信息則需要通過API提供的接口獲取。實現API接口不是什麼題目,主要把精力集中在如何實現運行系統命令,獲取其返回的結果功能實現上。具體實現代碼如下所示:

  public class CMDExecute {

  public synchronized String run ( String [] cmd,String workdirectory)

  throws IOException {

  String result = “ ” ;

  try {

  processBuilder builder = new ProcessBuilder ( cmd );

  //設置一個路徑

  if ( workdirectory ! = null )

  builder.directory ( new File ( workdirectory ) ) ;

  builder.redirectErrorStream (true) ;

  Process process = builder.start ( ) ;

  InputStream in = process.getInputStream ( ) ;

  byte[] re = new byte[1024] ;

  while ( in.read ( re ) ) ;

  result = result + new String ( re ) ;

  }

  in.close ( ) ;

  } catch ( Exception ex ) {

  Ex.printStackTrace ( ) ;

  }

  Return result ;

  }

  }

  1.2手機信息查看助手功能實現

  

  
    1.2.1手機信息查看助手主界面

      按照預設的規劃,將4類信息的查看進口放在主界面上,其佈局文件爲mail.xml,基本上是用一個列表組件組成的,實現代碼如下所示:

  <?xml version=”1.0″ encoding=”utf-8″?>

  <LinearLayout xmlns:android=”schemas.android/apk/res/android”

  android:/orientation=”vertical” android:layout_width=”fill_parent”

  android:layout_height=”fill_parent”>

  <ListView

  android:layout_width=”fill_parent”

  android:layout_height=”fill_parent”

  android:id=”@+id/itemlist” />

  </LinearLayout>

  在這裏mail.xml中使用的是LinearLayout佈局,其中放置了一個ListView組件。

      1.2.2查看系統信息實現

      當在運行的主界面單擊第一行時,也就是“系統信息”這一行,將執行代碼如下:

  case 0;

  intent.setClass(eoeInfosAssistant.this, System.class);

  startActivity(intent);

  break;

  代碼運行後將顯示系統(System)這個界面,這就是查看系統信息的主界面,其和主界面差未幾,也就是列表顯示幾個需要查看的系統信息,

  1.2.2.1操縱系統版本

  單擊圖9所示的界面第一行“操縱系統版本”項,則會打開一個新的界面,其對應的是ShowInfo.java文件,然後需要顯示該設備的操縱系統版本信息,而這個信息在/proc/version中有,可以直接調用。在可行性分析中給出的CMDExencute類來調用系統的cat命令獲取該文件的內容,實現代碼如下:

  Public static String fetch_version_info( ) {

  String result = null;

  CMDExecute cmdexe = new CMDExecute ( );

  Try {

  String[ ] args = {”/system/bin/cat”, “/proc/version” };

  result = cmdexe.run(args, “system/bin/”);

  } catch (IOException ex) {

  ex.printStackTrace( );

  }

  Return result;

  }

  上述代碼使用的是CMDExecute類,調用系統的“”/system/bin/cat””工具,獲取“”/proc/version””中內容。其運行效果如圖9。從圖中顯示的查尋結果可以看到,這個設備的系統版本是Linux version 2.6.25-0-gfea26b0。

  1.2.2.2系統信息

  在Android中,想要獲取系統信息,可以調用其提供的方法System.getProperty(propertyStr),而系統信息諸如用戶根目錄(user.home)等都可以通過這個方法獲取,實現代碼如下:

  private static String initProperty(String description,String propertyStr) {

  if (buffer == null) {

  buffer = new StringBuffer();

  }

  buffer.append(description).append(”:”);

  buffer.append (System.getProperty(propertyStr)).append(”\n”);

  return buffer.toString();

  }

  private static String getSystemProperty() {

  buffer = new StringBuffer();

  initProperty(”java.vendor.url”,”java.vendor.url”);

  initProperty(”java.class.path”,”java.class.path”);

  . . .

  return buffer.toString();

  }

  上述代碼主要是通過調用系統提供的System.getProperty方法獲取指定的系統信息,並合併成字符串返回。

  1.2.2.3運營商信息

  運營商信息中包含IMEI、手機號碼等,在Android中提供了運營商治理類(TelephonyManager),可以通過TelephonyManager來獲取運營商相關的信息,實現的關鍵代碼如下:

  public static String fetch_tel_status(Context cx) {

  String result = null;

  TelephonyManager tm = (TelephonyManager) cx

  .getSystemService(Context.TELEPHONY_SERVICE);//

  string str = ” “;

  str += “DeviceId(IMEI) = ” + tm.getDetDeviceId() + “\n”;

  str += “DeviceSoftwareVersion = ” + tm.getDeviceSoftwareVersion()+”\n”;

  . . .

  int mcc = cx.getResources().getConfiguration().mcc;

  int mcc = cx.getResources().getConfiguration().mcc;

  str +=”IMSI MCC (Mobile Country Code): ” +String.valueOf(mcc) + “\n”;

  str +=”IMSI MCC (Mobile Country Code): ” +String.valueOf(mnc) + “\n”;

  result = str;

  return result;

  }

  在上述的代碼中,首先調用系統的getSystemService (Context.TELEPHONY_SERVICE)方法獲取一個TelephonyManager對象tm,進而調用其方法getDeviceId()獲取DeviceId信息,調用getDeviceSoftware Version()獲取設備的軟件版本信息等。

      1.2.3查看硬件信息

  1.2.3.1獲取CPU信息

  可以在手機設備的/proc/cpuinfo中獲取CPU信息,調用CMDEexecute執行系統的cat的命令,讀取/proc/cpuinfo的內容,顯示的就是其CPU信息,實現代碼如下:

  public static String fetch_cpu_info() {

  String result = null;

  CMDExecute cmdexe = new CMDExecute();

  try {

  String[ ] args = { “/system/bin/cat”, “/proc/cpuinfo” }

  result = cmdexe.run(args, “/system/bin/”);

  Log.i(”result”,”result=” + result);

  } catch (IOException ex) {

  ex.printStackTrace();

  }

  return result;

  }

  上述代碼使用CMDExecute,調用系統中的”/system/bin/cat”命令查看”/proc/cpuinfo”中的內容,即可得到CPU信息。

  1.2.3.2獲取內存信息

  獲取內存信息的方法和獲取CPU信息的實現差未幾,可以讀取/proc/meminfo信息,另外還可以通過getSystemService(Context.ACTIVIT_SERV-

  ICE)獲取ActivityManager.MemoryInfo對象,進而獲取可用內存信息,主要代碼如下:

  /**

  *系統內存情況查看

  */

  public static String getMemoryInfo(Context context) {

  StringBuffer memoryInfo = new StringBuffer();

  final ActivityManager activityManager = (AcctivityManager) context

  .getSystemService(Context.ACTIVITY_SERVICE);

  ActivityManager. MemoryInfo outInfo = new ActivityManager. MemoryInfo();

  activityManager.getMemoryInfo(outInfo);

  memoryInfo.append(”\nTotal Available Memory :”).append(

  outInfo.availMem >> 10).append(”k”);

  memoryInfo.append(”\nTotal Available Memory :”).append(

  outInfo.availMem >> 20).append(”k”);

  memoryInfo.append(”\nIn low memory situation:”).append(

  outInfo. Lowmemory);

  String result = null;

  CMDExecute cmdexe = new CMDExecute();

  try {

  String[ ] args = { “/system/bin/cat”, “/proc/meminfo” };

  result = cmdexe.run(args, “/system/bin/”);

  } catch (IOException ex) {

  Log.i(”fetch_process_info”,”ex=” + ex.toString());

  }

  Return memoryInfo.toString()+”\n\n”+result;

  }

  上述代碼中首先通過ActivityManager對象獲取其可用的內存,然後通過查看“/proc/meminfo”內容獲取更具體的信息。

  1.2.3.3獲取磁盤信息

  手機設備的磁盤信息可以通過df命令獲取,所以,這裏獲取磁盤信息的方法和前面類似,惟一不同的是,這個是直接執行命令,獲取其命令的返回就可以了,關鍵代碼如下:

  //磁盤信息

  public static String fetch_disk_info() {

  String result = null;

  CMDExecute cmdexe = new CMDExecute();

  try {

  String[ ] args = { “/system/bin/df”}

  result = cmdexe.run(args, “/system/bin/”);

  Log.i(”result”,”result=” + result);

  } catch (IOException ex) {

  ex.printStackTrace();

  }

  return result;

  }

  1.2.3.4獲取網絡信息

  要獲取手機設備的網絡信息,只要讀取/system/bin/netcfg中的信息就可以了,關鍵代碼如下:

  public static String fetch_netcfg_info() {

  String result = null;

  String result = null;

  CMDExecute cmdexe = new CMDExecute();

  try {

  String[ ] args = { “/system/bin/netcfg”}

  result = cmdexe.run(args, “/system/bin/”);

  } catch (IOException ex) {

  Log.i(”fetch_process_info”,”ex=” + ex.toString());

  }

  return result;

  }

  1.2.3.5獲取顯示頻信息

  除了顯示手機的CPU、內存、磁盤信息外,還有個非常重要的硬件,顯示頻。在Android中,它提供了DisplayMetrics類,可以通過getApplication Context()、getResources()、getDisplayMetrics()初始化,進而讀取其屏幕寬(widthPixels)、高(heightPixels)等信息,實現的關鍵代碼如下:

  public static String getDisplayMetrics(Context cx) {

  String str = ” “;

  DisplayMetrics dm = new DisplayMetrics();

  dm = cx.getApplicationContext().getResources().getDisplayMetrics();

  int screenWidth = dm.widthPixels;

  int screenHeight = dm.heightPixels;

  float density = dm.density;

  float xdpi = dm.xdpi;

  float ydpi = dm.ydpi;

  str += “The absolute width: ” + String.valueOf(screenWidth) + “pixels\n”;

  str += “The absolute heightin: ” + String.valueOf(screenHeight) + “pixels\n”;

  str += “The logical density of the display. : ” + String.valueOf(density) + “\n”;

  str += “X dimension : ” + String.valueOf(xdpi) +”pixels per inch\n”;

  str += “Y dimension : ” + String.valueOf(ydpi) +”pixels per inch\n”;

  renturn str;

  }

      1.2.4查看軟件信息

      在Android上,可以在手機上隨便安裝自己喜歡的應用軟件,查看軟件信息的功能就是收集並顯示已經安裝的應用軟件信息。

  在Android中,它提供了getPackageManager()、getInstalledApplications(0)方法,可以直接返回全部已經安裝的應用列表。這個功能就是只需要獲取列表,再進行顯示在列表中就可以了。但是,假如安裝的軟件比較多,那麼獲取信息所花費的時間會比較多,爲了更好地完善用戶使用的體驗,在獲取列表時,需要在界面提示用戶耐心等待,這就需要用到Android提供的另外一個功能Runnable。

  引進Runnable比較簡單,只需要在定義類的時候實現Runnable接口就可以了,所以,這裏的軟件信息查看界面對應的Software.java類聲明代碼如下:

  public class Software extends Activity implements Runnable {

  . . .

  }

  然後需要在這個Activity啓動的時候,引進進度條ProgressDialog來顯示一個提示界面,onCreate代碼如下所示:

  Public void onCreate(Bundle icicle) {

  Super.onCreate(icicle);

  setContentView(R.layout.softwares);

  setTitle(”軟件信息”)

  itemlist = (ListView) findViewById(R.id.itemlist);

  pd = ProgressDialog.show(this, “請稍候. .”, “正在收集你已經安裝的軟件信息. . .”, true,flase);

  Thread thread = new Thread(this);

  Thread.start();

  }

  該方法創建了一個ProgressDialog,並設定其提示信息。然後實現其線程的run()方法,該方法實現其真正執行的邏輯,實現代碼如下:

  @Override

  Public void run() {

  fetch_installed_apps();

  handler.sendEmptyMessage(0);

  }

  上述代碼調用自定義的fetch_installed_app()方法獲取已經安裝的應用信息,這個方法是比較消耗時間的,實現代碼如下:

  public List fetch_installed_apps () {

  List<ApplicationInfo> packages = getPackageManager().getInstalledApplications(0);

  list = new ArrayList<Ma<String, Object>>(

  packages.size());

  Iterator<ApplicationInfo> l = packages.iterator();

  while (l.hasNext()) {

  Map<String, Object> map = new HashMap<String, Object>();

  ApplicationInfo app = (ApplicationInfo) l.next();

  String packageName = app.packageName;

  String label = ” “;

  try {

  label = getPackageManager().getApplicationLabel(app).toString();

  } catch (Exception e) {

  Log.i(”Exception”, e.toString());

  }

  map = new HashMap<String, Object>();

  map.put(”name”, label);

  map.put(”desc”, packageName);

  list.add(map);

  }

  Return list;

  }

  上述代碼使用getPackageManager().getInstalledApplications(0)獲取已經安裝的軟件信息,進而構造用來顯示的列表(List)對象,同時,界面通過進度條(ProgressDialog)顯示提示信息,運行效果如圖18所示。

  當這個方法運行完成後,會調用handler.sendEmptyMessage(0)語句給handler發送一個通知消息,使其執行下面的動作,下面就是這個handler的實現方法:

  private Handler handler = new Handler() {

  public void handleMessage msg) {

  refreshListItems();

  pd.dismiss();

  }; }

  上述代碼中,當其接收到run()線程傳遞的消失後,先調用refreshListItems()方法顯示列表,最後調用進度條ProgressDialog的dismiss方法使其等待提示消失。而refreshListItems()的實現代碼如下:

  private void refreshListItems() {

  list = fetch_installed_apps();

  SimpleAdapter notes = new SimpleAdater(this, list, R.layout_row,

  New String[ ] { “name”, “desc” },new int[ ] { R.id.name,

  R.id.desc });

  Itemlist.setAdapter(notes);

  setTitle(”軟件信息,已經安裝”+list.size()+”款應用.”);

  }

  這些代碼,顯示已經安裝的應用列表的同時,在Title上顯示一共安裝了多少款應用

      1.2.5獲取運行時信息

      運行時的一些信息,包括後臺運行的Service、Task,以及進程信息,其運行界面如圖20。

  1.2.5.1獲取正在運行的Service信息

  可以通過調用context.getSystemService(Context.ACTIVITY_SERVICE)獲取ActivityManager,進而通過系統提供的方法getRunningServices(int maxNum)獲取正在運行的服務列表(RunningServiceInfo),再對其結果進一步分析,得到服務對應的進程名及其他信息,實現的關鍵代碼如下:

  //正在運行的服務列表

  public static String getRunningServicesInfo(Context context) {

  StringBuffer serviceInfo = new StringBuffer();

  final ActivityManager activityManager = (ActivityManager) context

  .getSystemService(Context. ACTIVITY_SERVICE);

  List<RunningServiceInfo> services = activityManager.getRunningServices(100);

  Iterator<RunningserviceInfo> l = services.iterator();

  while (l.hasNext()) {

  RunningServiceInfo si = (RunningServiceInfo) l.next();

  serviceInfo.append(”pid: “).append(si.pid);

  serviceInfo.append(”\nprocess: “).append(si. process);

  serviceInfo.append(”\nservice: “).append(si. service);

  serviceInfo.append(”\ncrashCount: “).append(si. crashCount);

  serviceInfo.append(”\nclicentCount: “).append(si. clicentCount);

  serviceInfo.append(”\nactiveSince:”).append(ToolHelper.formatData(si.activeSince));

  serviceInfo.append(”\nlastActivityTime: “).append(ToolHelper.formatData(si.lastAct-

  ivityTime));

  serviceInfo.append(”\n\n “);

  }

  return serviceInfo.toString();

  }

  上述代碼調用activityManager.getRunningServices(100)獲取正在運行的服務,並依次遍歷得到每個服務對應的pid,進程等信息,

  1.2.5.2獲取正在運行的Task信息

  獲取正在運行的Task信息調用的是activityManager.getRunningTasks(int maxNum)來獲取對應的正在運行的任務信息列表(RunningTaskInfo),進而分析、顯示任務信息,其關鍵代碼如下:

  public static String getRunningTaskInfo(Context context) {

  StringBuffer sInfo = new StringBuffer();

  final ActivityManager activityManager = (ActivityManager) context

  .getSystemService(Context. ACTIVITY_SERVICE);

  List<RunningTaskInfo> tasks = activityManager.getRunningTasks(100);

  Iterator<RunningTaskInfo> l = tasks.iterator();

  while (l.hasNext()) {

  RunningTaskInfo ti = (RunningTaskInfo) l.next();

  sInfo.append(”id: “).append(ti.id);

  sInfo.append(”\nbaseActivity: “).append(ti. baseActivity.flattenToString());

  sInfo.append(”\nnumActivities: “).append(ti. nnumActivities);

  sInfo.append(”\nnumRunning: “).append(ti. numRunning);

  sInfo.append(”\ndescription: “).append(ti. description);

  sInfo.append(”\n\n);

  }

  Return sInfo.toString();

  }

  上述代碼調用系統提供的activityManager.getRunningTasks(100)方法獲取任務列表,依次獲取對應的id等信息,運行效果如圖22。從圖中顯示可以看出,獲取手機上正在運行的Task的列表和其對應的進程信息,這對用戶瞭解設備運行情況非常有用。

  1.2.5.3獲取正在運行的進程信息

  該段程序是通過CMD Executo的方式來運行系統命令。關鍵代碼如下:

  public static String fetch_process_info() {

  Log.i(”fetch_process_info”,”start. . . . “);

  String result = null;

  CMDExecutr cmdexe = new CMDExecute();

  try {

  String [ ] args = { “/system/bin/top”, “-n”, “l” };

  result = cmdexe.run(args, “/system/bin/”);

  } catch (IOException ex) {

  Log.i(”fetch_process_info”,”ex=” + ex.toString());

  }

  return result;

  }

  通過這個功能可以非常具體地瞭解到正在運行的進程和各個進程所消耗的資源情況。

      1.2.6文件瀏覽器

      文件瀏覽器的這個功能,用戶可以遍歷瀏覽整個文件系統,以便更好地瞭解手機設備狀況。在主界面單擊最後一行將執行下列代碼:

  case 4:

  intent.setClass(eoeInfosAssistant.this, FSExplorer.class);

  startActivity(intent);

  break;

  對於如何進進子目錄,並獲取和顯示其內部的文件夾和文件,也就是單擊每行時響應的實現,代碼如下:

  @Override

  public void onItemClick(AdapterView<?> parent, View v, int position, long id) {

  Log.i(TAG, “item clicked! [" + position + "]“);

  if (position == 0) {

  path = “/”;

  refreshListItems(path);

  }else if(position ==1) {

  goToParent();

  } else {

  path = (String) list.get(position).get(”path”);

  File file = new File(path);

  if (file.isDirectory())

  refreshListItems(path);

  else

  Toast.makeText(FSExplorer.this,

  getString(R.string.is_file)’

  Toast.LENGTH_SHORT).show();

  }

  }

  2. Android編程獲取手機型號,網絡類型,本機電話號碼,sdk版本及firmware版本號(即系統版本號)

  Android開發平臺中,可通過TelephonyManager獲取本機號碼。

  TelephonyManager phoneMgr=(TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);

  txtPhoneNumber.setText(phoneMgr.getLine1Number()); //txtPhoneNumber是一個EditText 用於顯示手機號

  注:

  根據Android的安全機制,在使用TelephonyManager時,必須在AndroidManifest.xml中添加<uses-permission android:name=”READ_PHONE_STATE” /> 否則無法獲得系統的許可。

  private void loadPhoneStatus()

  {

  TelephonyManager phoneMgr=(TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);

  int mNetworkType = mManager.getNetworkType();//獲取網絡類型

  txtPhoneModel.setText(Build.MODEL); //手機型號

  txtPhoneNumber.setText(phoneMgr.getLine1Number());//本機電話號碼

  txtSdkVersion.setText(Build.VERSION.SDK);//SDK版本號

  txtOsVersion.setText(Build.VERSION.RELEASE);//Firmware/OS 版本號

  }

  Build能向我們提供包括 硬件廠商,硬件編號,序列號等很多信息 調用方法也都同上.

  3. 得到系統的一些相關的屬性,通過調用 System.getProperties(); 來獲取

  02-09 02:24:55.863: INFO/Tag(661): System Property: {java.vm.version=1.2.0

  02-09 02:24:55.863: INFO/Tag(661): System Property: java.vendor.url=android/

  02-09 02:24:55.863: INFO/Tag(661): System Property: java.vm.vendor.url=android/

  02-09 02:24:55.863: INFO/Tag(661): System Property: user.dir=/

  02-09 02:24:55.872: INFO/Tag(661): System Property: java.vm.name=Dalvik

  02-09 02:24:55.872: INFO/Tag(661): System Property: java.home=/system

  02-09 02:24:55.872: INFO/Tag(661): System Property: user.region=US

  02-09 02:24:55.872: INFO/Tag(661): System Property: javax.ssl.trustStore=/system/etc/security/cacerts.bks

  02-09 02:24:55.872: INFO/Tag(661): System Property: java.runtime.name=Android Runtime

  02-09 02:24:55.882: INFO/Tag(661): System Property: user.home=

  02-09 02:24:55.882: INFO/Tag(661): System Property: java.io.tmpdir=/sdcard

  02-09 02:24:55.882: INFO/Tag(661): System Property: http.agent=Dalvik/1.2.0 (Linux; U; Android 2.2; google_sdk Build/FRF91)

  02-09 02:24:55.882: INFO/Tag(661): System Property: java.preferIPv6Addresses=true

  02-09 02:24:55.882: INFO/Tag(661): System Property: java.version=0

  02-09 02:24:55.882: INFO/Tag(661): System Property: java.boot.class.path=/system/framework/core.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar

  02-09 02:24:55.882: INFO/Tag(661): System Property: java.library.path=/system/lib

  02-09 02:24:55.882: INFO/Tag(661): System Property: file.separator=/

  02-09 02:24:55.882: INFO/Tag(661): System Property: java.specification.vendor=The Android Project

  02-09 02:24:55.894: INFO/Tag(661): System Property: file.encoding=UTF-8

  02-09 02:24:55.894: INFO/Tag(661): System Property: line.separator=

  02-09 02:24:55.894: INFO/Tag(661): System Property: java.vm.specification.version=0.9

  02-09 02:24:55.894: INFO/Tag(661): System Property: java.vm.specification.vendor=The Android Project

  02-09 02:24:55.894: INFO/Tag(661): System Property: os.name=Linux

  02-09 02:24:55.894: INFO/Tag(661): System Property: java.vm.vendor=The Android Project

  02-09 02:24:55.894: INFO/Tag(661): System Property: path.separator=:

  02-09 02:24:55.904: INFO/Tag(661): System Property: android.vm.dexfile=true

  02-09 02:24:55.904: INFO/Tag(661): System Property: java.ext.dirs=

  02-09 02:24:55.904: INFO/Tag(661): System Property: java.class.path=.

  02-09 02:24:55.904: INFO/Tag(661): System Property: os.version=2.6.29-00261-g00-dirty

  02-09 02:24:55.904: INFO/Tag(661): System Property: java.specification.name=Dalvik Core Library

  02-09 02:24:55.904: INFO/Tag(661): System Property: javapiler=

  02-09 02:24:55.913: INFO/Tag(661): System Property: user.language=en

  02-09 02:24:55.913: INFO/Tag(661): System Property: user.name=

  02-09 02:24:55.913: INFO/Tag(661): System Property: os.arch=armv5tejl

  02-09 02:24:55.913: INFO/Tag(661): System Property: java.runtime.version=0.9

  02-09 02:24:55.913: INFO/Tag(661): System Property: java.class.version=46.0

  02-09 02:24:55.913: INFO/Tag(661): System Property: java.vendor=The Android Project

  02-09 02:24:55.923: INFO/Tag(661): System Property: java.vm.specification.name=Dalvik Virtual Machine Specification

  02-09 02:24:55.923: INFO/Tag(661): System Property: java.specification.version=0.9}

  4. 得到鍵盤信息,使用的語言,iphone pc transfer手機的網絡代碼(mnc),手機的國家代碼(mcc),手機的模式,手機的方向,觸摸屏的判斷等,通過以下語句獲取: Configuration config = getResources().getConfiguration();

  這些屬性都在config的屬性變量中進行判斷。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章