編輯:關於Android編程
Android系統信息的獲取 PackageManager的使用 ActivityManager的使用 Android安全機制本書也正式的進入尾聲了,在android的世界了,不同的軟件,硬件信息就像一個國家的經濟水平,軍事水平,不同的配置參數,代表著一個android帝國的強弱,所以廠商喜歡打配置戰,本節就要是講
android.os.Build SystemProperty由於android手機的開源性,手機的配置各種各樣,那些優化大師之類的東西,都可以跑分和看配置信息,那他們是從哪裡知道這些信息的呢?遙想獲取系統的配置信息,通常可以從以下兩個方面獲取
Build.BOARD——主板 Build.BRAND——Android系統定制商 Build.SUPPORTED_ABIS——CPU指令集 Build.DEVICE——設備參數 Build.DISPLAY——顯示屏參數 Build.FINGERPRINT——唯一編號 Build.SERIAL——硬件序列號 Build.ID——修訂版本列表 Build.MANUFACTURER——硬件制造商 Build.MODEL——版本 Build.HARDWARE——硬件名 Build.PRODUCT——手機產品名 Build.TAGS——描述Build的標簽 Build.TYPE——Builder類型 Build.VERSION.CODENAME——當前開發代號 Build.VERSION.INCREMENTAL——源碼控制版本號 Build.VERSION.RELEASE——版本字符串 Build.VERSION.SDK_INT——版本號 Build.HOST——host值 Build.USER——User名 Build.TIME——編譯時間android.os.Build類裡面的信息非常的豐富,它包含了系統編譯時的大量設備,配置信息,我們列舉一點
上面的一些參數沒有注釋,他們來自系統的RO值中,這些值都是手機生產商配置的只讀的參數值,根據廠家的配置不同而不同,接下來我們再來看一下另一個存儲設備軟硬件信息的類——SystemProperty
os.version——OS版本 os.name——OS名稱 os.arch——OS架構 user.home——home屬性 user.name——name屬性 user.dir——Dir屬性 user.timezone——時區 path.separator——路徑分隔符 line.separator——行分隔符 file.separator——文件分隔符 java.vendor.url——Java vender Url屬性 java.class.path——Java Class屬性 java.class.version——Java Class版本 java.vendor——Java Vender屬性 java.version——Java版本 java.home——Java Home屬性SystemProperty類包含了許多系統配置屬性值和參數,很多信息和上面通過android.os.Build獲取的值是相同的,我們列舉一些常用的
下面我們用一個簡單的實例來了解一下把
通過android.os.Build這個類,我們可以直接獲取到Build提供的系統信息,而通過System.getProperty(“xxx”),我們可以訪問到系統的屬性
在實例中獲取到的信息與上述的基本一致,運行如圖
tv_message.append("主板:"+ Build.BOARD+"\n");
tv_message.append("Android系統定制商:"+ Build.BRAND+"\n");
tv_message.append("CPU指令集:"+ Build.SUPPORTED_ABIS+"\n");
tv_message.append("設置參數:"+ Build.DEVICE+"\n");
tv_message.append("顯示屏參數:"+ Build.DISPLAY+"\n");
tv_message.append("唯一編號:"+ Build.SERIAL+"\n");
用System.getProperty
tv.append("OS版本:"+System.getProperty("os.version")+"\n");
tv.append("OS名稱:"+System.getProperty("os.name")+"\n");
tv.append("OS架構:"+System.getProperty("os.arch")+"\n");
tv.append("Home屬性:"+System.getProperty("user.home")+"\n");
tv.append("Name屬性:"+System.getProperty("user.name")+"\n");
代碼貼上一點就可以了
運行的實例程序中我們可以看到,我們已經獲取到了相當多的系統信息,那麼這些信息的來源又是哪兒呢?記得我們分析android系統目錄的時候提到過,在system/build.prop中,包含了很多的RO值,打開命令窗,通過cat build.prop可以看到
這裡我們可以看到很多前面通過android.os.Build所獲取到的系統信息,同時,在adb shell中,還可以通過getprop來獲取對應的值
除了上述的兩個方法,android系統還在另外一個非常重要的目錄來存儲系統信息——/proc目錄,在adb shell中進入/proc目錄,通過ll命令查看文件信息,
我們剛才把Android的系統翻了個遍,danshi8沒有找到apk的信息,在adb shell中PM和AM命令時我們的幫手,我們來看一下
我們看一張圖
最裡面的框就代表整個Activity的信息,系統提供了ActivityInfo類來進行封裝
而Android提供了PackageManager來負責管理所有已安裝的App,PackageManager可以獲得AndroidManifest中不同節點的封裝信息,下面是一些常用的封裝信息:
ActivityInfo
ActivityInfo封裝在了Mainfest文件中的< activity >和< eceiver>之間的所有信息,包括name、icon、label、launchMode等。
ServiceInfo<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxibG9ja3F1b3RlPg0KCTxwPlNlcnZpY2VJbmZv0+tBY3Rpdml0eUluZm/A4MvGo6y34tewwcsmbHQ7IHNlcnZpY2UmZ3Q71q685LXEy/nT0NDFz6KhozwvcD4NCjwvYmxvY2txdW90ZT4NCjxwPkFwcGxpY2F0aW9uSW5mbzwvcD4NCjxibG9ja3F1b3RlPg0KCTxwPsv8t+LXsMHLJmx0OyBhcHBsaWNhdGlvbiZndDvWrrzktcTQxc+io6zM2LHwtcTKx6OsQXBwbGljYXRpb25JbmZvsPy6rMHLuty24EZsYWejrEZMQUdfU1lTVEVNse3Kvs6qz7XNs9Om08OjrEZMQUdfRVhURVJOQUxfU1RPUkFHRbHtyr7OqrCy17DU2lNEY2FyZMnPtcTTptPDo6zNqLn91eLQqWZsYWe/ydLUuty3vbHjtcTF0LbP06bTw7XEwODQzaGjPC9wPg0KPC9ibG9ja3F1b3RlPg0KPHA+UGFja2FnZUluZm88L3A+DQo8YmxvY2txdW90ZT4NCgk8cD5QYWNrYWdlSW5mb7D8uqzBy8v509C1xEFjdGl2aXR5us1TZXJ2aWNl0MXPoqGjPC9wPg0KPC9ibG9ja3F1b3RlPg0KPHA+UmVzb2x2ZUluZm88L3A+DQo8YmxvY2txdW90ZT4NCgk8cD5SZXNvbHZlSW5mb7D8uqzByyZsdDsgaW50ZW50Jmd0O9DFz6K1xMnPvLbQxc+io6zL+dLUy/y/ydLUt7W72EFjdGl2aXR5SW5mb6GiU2VydmljZUluZm+1yLD8uqzByyZsdDsgaW50ZW50Jmd0O7XE0MXPoqOsvq2zo9PDwLSw79b61dK1vcTH0Kmw/LqszNi2qGludGVudMz1vP61xNDFz6KjrMjntPi31s/tuabE3KGisqW3xbmmxNy1xNOm08OhozxiciAvPg0KCdPQwcvV4tCpt+LXsLXE0MXPorrzo6y7udDo0qrT0MzYtqi1xLe9t6jAtLvxyKHL/MPHo6zPwsPmvs3Kx1BhY2thZ2VNYW5hZ2Vy1tC34tewtcTTw8C0u/HIodXi0KnQxc+itcS3vbeoo7o8L3A+DQo8L2Jsb2NrcXVvdGU+DQo8cD5nZXRQYWNrYWdlTWFuYWdlcigpJm1kYXNoOyZtZGFzaDvNqLn91eK49re9t6i/ydLUt7W72NK7uPZQYWNrYWdlTWFuYWdlcrbUz/OhozwvcD4NCmdldEFwcGxpY2F0aW9uSW5mbygpJm1kYXNoOyZtZGFzaDvS1EFwcGxpY2F0aW9uSW5mb7XE0M7Kvbe1u9jWuLaosPzD+7XEQXBwbGljYXRpb25JbmZvoaMgZ2V0QXBwbGljYXRpb25JY29uKCkmbWRhc2g7Jm1kYXNoO7e1u9jWuLaosPzD+7XESWNvbqGjIGdldEluc3RhbGxlZEFwcGxpY2F0aW9ucygpJm1kYXNoOyZtZGFzaDvS1EFwcGxpY2F0aW9uSW5mb7XE0M7Kvbe1u9iwstewtcTTptPDoaM8YnIgLz4NCmdldEluc3RhbGxlZFBhY2thZ2VzKCkmbWRhc2g7Jm1kYXNoO9LUUGFja2FnZUluZm+1xNDOyr23tbvYsLLXsLXE06bTw6GjIHF1ZXJ5SW50ZW50QWN0aXZpdGllcygpJm1kYXNoOyZtZGFzaDu3tbvY1ri2qEludGVudLXEUmVzb2x2ZUluZm+21M/zoaJBY3Rpdml0ebyvus+hoyBxdWVyeUludGVudFNlcnZpY2VzKCkmbWRhc2g7Jm1kYXNoO7e1u9jWuLaoSW50ZW50tcRSZXNvbHZlSW5mb7bUz/OholNlcnZpY2W8r7rPoaMgcmVzb2x2ZUFjdGl2aXR5KCkmbWRhc2g7Jm1kYXNoO7e1u9jWuLaoSW50ZW50tcRBY3Rpdml0eaGjIHJlc29sdmVTZXJ2aWNlKCkmbWRhc2g7Jm1kYXNoO7e1u9jWuLaoSW50ZW50tcRTZXJ2aWNloaMNCjxibG9ja3F1b3RlPg0KCTxwPrj5vt1BcHBsaWNhdGlvbkluZm+1xGZsYWfAtMXQts9BcHC1xMDg0M2jujwvcD4NCgk8cD7I57n7tbHHsNOm08O1xGZsYWdzICZhbXA7IEFwcGxpY2F0aW9uSW5mby5GTEFHX1NZU1RFTSAhPSAw1PLOqs+1zbPTptPDPC9wPg0KCTxwPsjnuftmbGFncyAmYW1wOyBBcHBsaWNhdGlvbkluZm8uRkxBR19TWVNURU0gJmx0Oz0gMCDU8s6qtdrI/be906bTwzwvcD4NCgk8cD7M2MritcS1sc+1zbPTptPDyf28trrz0rK74bPJzqq12sj9t73TptPDo6y0y8qxIGZsYWdzICZhbXA7IEFwcGxpY2F0aW9uSW5mby5GTEFHX1VQREFURURfU1lTVEVNX0FQUCAhPSAwOzwvcD4NCgk8cD7I57n7ZmxhZ3MgJmFtcDsgQXBwbGljYXRpb25JbmZvLkZMQUdfRVhURVJOQUxfU1RPUkFHRSAhPSAwINTyzqqwstew1NpTRENhcmTJz7XE06bTw6GjPC9wPg0KCTxwPs7Sw8fNqLn90ru49sq1wP3AtLfWzvajrM/It+LXsNK7uPZCZWFuwLSxo7TmztLDx9Do0qq1xNfWts48L3A+DQo8L2Jsb2NrcXVvdGU+DQo8cHJlIGNsYXNzPQ=="brush:java;">
package com.lgl.systemmesage;
import android.graphics.drawable.Drawable;
/**
* Bean
* Created by LGL on 2016/4/28.
*/
public class PMAPPInfo {
//應用名
private String appLabel;
//圖標
private Drawable appIcon;
//包名
private String pkgName;
//構造方法
public PMAPPInfo(){
}
public String getAppLabel() {
return appLabel;
}
public void setAppLabel(String appLabel) {
this.appLabel = appLabel;
}
public Drawable getAppIcon() {
return appIcon;
}
public void setAppIcon(Drawable appIcon) {
this.appIcon = appIcon;
}
public String getPkgName() {
return pkgName;
}
public void setPkgName(String pkgName) {
this.pkgName = pkgName;
}
}
接下來,我們通過上面的方法判斷各種類型的應用,我們的主布局
這裡有一個listview,所以我們需要一個adapter和一個item
package com.lgl.systemmesage;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
/**
* 數據源
* Created by LGL on 2016/4/28.
*/
public class PkgAdapter extends BaseAdapter {
private Context mContext;
private List mList;
public PkgAdapter(Context context) {
mContext = context;
mList = new ArrayList<>();
}
public void addAll(List list) {
mList.clear();
mList.addAll(list);
notifyDataSetChanged();
}
@Override
public int getCount() {
return mList.size();
}
@Override
public PMAPPInfo getItem(int position) {
return mList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
PMAPPInfo item = getItem(position);
if (convertView == null) {
holder = new ViewHolder();
convertView = LayoutInflater.from(mContext).inflate(R.layout.list_item, parent, false);
holder.mIcon = (ImageView) convertView.findViewById(R.id.iv_icon);
holder.mLabel = (TextView) convertView.findViewById(R.id.tv_label);
holder.mPkgName = (TextView) convertView.findViewById(R.id.tv_pkg_name);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.mIcon.setImageDrawable(item.getAppIcon());
holder.mLabel.setText(item.getAppLabel());
holder.mPkgName.setText(item.getPkgName());
return convertView;
}
static class ViewHolder {
ImageView mIcon;
TextView mLabel;
TextView mPkgName;
}
}
item就簡單了
那我們主程序的邏輯就是
package com.lgl.systemmesage;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
/**
* 軟件列表
* Created by LGL on 2016/4/28.
*/
public class APP extends AppCompatActivity implements View.OnClickListener{
private PackageManager mPackageManager;
private ListView mListView;
private PkgAdapter mAdapter;
List result;
protected void onCreate( Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_app);
mPackageManager = getPackageManager();
mListView = (ListView) findViewById(R.id.mListView);
mAdapter = new PkgAdapter(this);
mListView.setEmptyView(findViewById(R.id.empty));
mListView.setAdapter(mAdapter);
findViewById(R.id.btn_all).setOnClickListener(this);
findViewById(R.id.btn_other).setOnClickListener(this);
findViewById(R.id.btn_system).setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_all:
result = getAppInfo(R.id.btn_all);
break;
case R.id.btn_other:
result = getAppInfo(R.id.btn_other);
break;
case R.id.btn_system:
result = getAppInfo(R.id.btn_system);
break;
default:
result = new ArrayList<>();
}
mAdapter.addAll(result);
}
private List getAppInfo(int flag) {
List appInfos = mPackageManager.getInstalledApplications(
PackageManager.GET_UNINSTALLED_PACKAGES);
List list = new ArrayList<>();
//根據不同的flag來切換顯示不同的App類型
switch (flag) {
case R.id.btn_all:
list.clear();
for (ApplicationInfo appInfo : appInfos) {
list.add(makeAppInfo(appInfo));
}
break;
case R.id.btn_other:
list.clear();
for (ApplicationInfo appInfo : appInfos) {
if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) <= 0) {
list.add(makeAppInfo(appInfo));
} else if ((appInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0){
list.add(makeAppInfo(appInfo));
}
}
break;
case R.id.btn_system:
list.clear();
for (ApplicationInfo appInfo : appInfos) {
if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
list.add(makeAppInfo(appInfo));
}
}
break;
}
return list;
}
private PMAPPInfo makeAppInfo(ApplicationInfo appInfo) {
PMAPPInfo info = new PMAPPInfo();
info.setAppIcon(appInfo.loadIcon(mPackageManager));
info.setAppLabel(appInfo.loadLabel(mPackageManager).toString());
info.setPkgName(appInfo.packageName);
return info;
}
}
運行的結果
前面所使用的packagemanager獲取的是所有的應用包名,但是哼哈二將還有一名大獎沒有說道,那就是ActivityManager了,他的功能四號不遜色前者,事實上,他在使用上各有側重點,前者側重於獲取應用的包信息,後者獲取運行的應用程序信息
同packagemanager一樣,ActivityManager也封裝了不少的Bean對象,我們選幾個重點來說一下
ActivityManager.MemoryInfo——MemoryInfo有幾個非常重要的字段:availMem(系統可用內存),totalMem(總內存),threshold(低內存的阈值,即區分是否低內存的臨界值),lowMemory(是否處於低內存)。
Debug.MemoryInfo——這個MemoryInfo用於統計進程下的內存信息。
RunningAppProcessInfo——運行進程的信息,存儲的字段有:processName(進程名),pid(進程pid),uid(進程uid),pkgList(該進程下的所有包)
RunningServiceInfo——運行的服務信息,在它裡面同樣包含了一些服務進程信息,同時還有一些其他信息。activeSince(第一次被激活的時間、方式),foreground(服務是否在後台執行)。
我們同樣的用一個實例來講解
package com.lgl.systemmesage;
/**
* Created by LGL on 2016/4/28.
*/
public class AMProcessInfo {
private String pid;
private String uid;
private String memorySize;
private String processName;
public AMProcessInfo(){
}
public String getPid() {
return pid;
}
public void setPid(String pid) {
this.pid = pid;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getProcessName() {
return processName;
}
public void setProcessName(String processName) {
this.processName = processName;
}
public String getMemorySize() {
return memorySize;
}
public void setMemorySize(String memorySize) {
this.memorySize = memorySize;
}
}
然後我們用一個方法就可以獲取到了
/**
* 正在運行
* @return
*/
private List getRunningProcossInfo(){
mAMProcessInfo = new ArrayList<>();
ListappRunningList = activityManager.getRunningAppProcesses();
for (int i = 0;i
四.解析Packages.xml獲取系統信息
熟悉Android開機啟動流程的朋友大概知道,在系統初始化到時候,packagemanager的底層實現類packagemanagerService會去掃描系統的一些特定目錄,並且解析其中的Apk文件,同時Android把他獲取到的應用信息保存到xml中,做成一個應用的花名冊,就是data/system/apckages.xml,我們用adb pull命令把他導出來,裡面的信息也太多了,但是我們只要知道結果根節點就可以了
< permissions>標簽
permissions標簽定義了現在系統所有的權限,也分兩類,系統定義的和app定義的
< package>標簽
package代表的是一個apk的屬性
其中各節點的信息含義大致為
name:APK的包名 cadePath:APK安裝路徑,主要在system/app和data/app兩種,前者放系統級別的,後者放系統安裝的 userid:用戶ID
version:版本
< perms>標簽
對應apk的清單文件,記錄apk的權限信息
通過這個xml文件的標簽,可以獲取到很多手機應用的信息,通常在進行系統層開發的時候,可以通過這個xml獲取更多有意義的東西
五.Android安全機制
道高一尺魔高一丈,自古以來就沒有什麼絕對的安全,所以Google也建立起了一層層的壁壘,保護Android的核心安全,我們來詳細了解一下
1.Android安全機制介紹
安全不管在那個平台,哪個語言中,都是非常重要的一環,Android開發者在Android系統中簡歷了五道防線來保護Android的安全
-1.第一道防線
代碼安全機制——代碼混淆proguard
由於java語言的特殊性,即使是編譯成apk的應用程序也存在反編譯的風險,而proguard則是在代碼從上對app的第一道程序,他混淆關鍵代碼,替換命名,讓破壞者閱讀難,同樣也可以壓縮代碼,優化編譯後的字節
-2.第二道防線
應用接入權限控制——清單文件權限聲明,權限檢查機制,
任何app在使用Android受限資源的時候,都需要顯示向系統生命權限,只有當一個應用app具有相應的權限,才能申請相應的資源,通過權限機制的檢查並且使用並且使用系統的Binder對象完成對系統服務的調用,但是這道防線也有先天的不足,如以下幾項
被授予的權限無法停止 在應用聲明app使用權限的時候,用戶無法針對部分權限進行限制 權限的判斷機制與用戶的安全理念相關
Android系統通常按照以下順序來檢查操作者的權限.
首先,判斷permission名稱.如果為空則直接返回PERMISSION_DENIED
其次。判斷Uid,如果為0則為root權限,不做權限控制,如果為systyemsystem service的uid則為系統服務.不做權限控制:如果Uid與參數中的請求uid不同則返回PERMISSION_DENIED
最後,通過調用packagemanageservice.checkUidPermission()方法來判斷該uid是否具有相應的權限,該方法會去xml的權限列表和系統級的權限進行查找
通過上面的步驟Android就確定了使用者是否具有某項使用權限
-3. 第三道防線
應用簽名機制一數字證書。
Android中所有的app都會有個數字證書,這就是app的簽名.數字證書用於保護app的作者和其app的信任關系,只有擁有相同數字簽名的app,才會在升級時被認為是同一app,而且Android系統不會安裝沒有簽名的App
- 4. 第四道防線
Linux內核層安全機制一一Uid 訪問權限控制。
Animid本質是基於Linux內核開發的,所以Android同樣繼承了Linux的安全特性,比如Linux文件系統的權限控制是由user,group,other與讀,寫,執行的不同組合來實現的,同樣,Android也實現了這套機制”通常情況下.只有system,root用戶才有權限訪問到系統文件,而一般用戶無法訪問。
-5. 第五道防線
Android虛擬機沙箱機制——沙箱隔流
Android的App運行在虛擬機中 因此才有沙箱機制,可以讓應用之間相互隔離,通常情況下.不同的應用之間不能互相訪問.每個App都單獨的運行在虛似機中,與其他應用完全隔離.在實現安全機制的基礎上,也讓應用之間能夠互不影響,即時一個應用崩潰,,也不會導致其他應用異常
雖然通過以上的五道防線.仍然不能完全保證Android的核心安全”但卻可以在最大程度上給破壞者增加難度,從另一方面來說”這些破壞者的破解也真是推動Android安全機制逐漸健全的動力.
2.Android系統安全隱患
雖說Android建立起來了N道防線,但是沒有絕對的安全所以在Android中也有一些破解之法,
-1.代碼漏洞
這個問題存在世界上所有的程序中,沒有誰敢保證自己的程序沒有bug,有漏洞,如果遇到這種問題,大家只能盡快的升級版本,更新補丁,才能杜絕利用漏洞的攻擊裝,比如Android的LaunchAnyWhere,FakeId,這些都是bug,就是在編寫的時候產生的漏洞,只有期待官方的更新了
-2. root風險
Root權限是指Android的系統管理員權限,類似於windows系統中的Administrator。具有Root權限的用戶可以訪問和修改手機中幾乎所有的文件,“Root”在一段時間內一度成為Android的代名詞, 無Root,不Android”。的確,Root掉手機後,可以解鎖很多普通用戶無法完成的工作,如限制各個應用app的數據流量.系統文件管理丶自定義修改系統等,但同時手機的安全性也會因此大打折扣。隨著android系統越來越完善,root的必要性也越來越低普通用戶在不root的情況下,完全可以正常使用大部分App。需要Root權限的大多為一些開發者,由於開發的需要,不得不將手機root,而root後的手機,就少了一層Linux的天然屏障,整個系統核心就完全暴露在人侵者面前,在你沒有察覺的情況下大肆破壞。所以,針對普通用戶,希望都盡量不要Root手機以免帶來不必要的損失
-3. 安全機制不健全
由於Android的權限管理機制並不完美,所以很多手機開發商,通常會在RoM中增加自己的一套權限管理工具來幫助用戶控制手機中應用的權限,如應用許可
-4.用戶安全意識
用戶對於安全隱患的察覺裡也是保護手機安全的一個重要因素。用戶可以通過在正規的應用市場下載和安裝應用時通過列出來的應用權限申請信息來大致判斷一個應用的安全性,比如我們曾經十分喜歡用的xx神器”,其實沒有一點技術含量,無非就是在你安裝了應用之後遍歷一遍你的聯系人並發送帶有鏈接的短信而已當用戶在安裝不明來源的應用時如果一個娛樂類型的app生命權限的時候不僅要聯系人又要短信權限,這個時候就需要警惕了,用戶也可以在市場上下載一些安全類App,如LEB安全大師,360安全等, 雖然這些軟件會加重系統負擔,但是為了安全也是值得的
-5. Android開發原則與安全
眾所周知,Android與ioS系統一個非常顯著的區別就是_一個是開放系統,一個是封閉系統,開放自然有開放的好處,技術進步快,產品豐富,封閉也有封閉的好處,安全性高,可控性高,Google本著開源的精神開放了Android的源代碼,但隨之而來的各種安全問題也讓Android倍受诟病,過度的開放與可定制化,不僅造成了Android的碎片化嚴重, 同時也給很多不法應用以可乘之機,但可喜的是,隨著Android的發展日益壯大,Google也在著手處理開發與安全的問題,相信在不久的將來,這一矛盾會越來越小
3.Android Apk反編譯
Android的應用程序APk文件,說到底也是一個壓縮文件,那麼可以通過解壓縮, 獲得裡面的文件內容。讓我們先來找一個apk,然後使用解壓縮工具,最後就會得到一些文件.
解壓之後我們看見了不少熟悉的東西,但是當點進去的時候,你就會發現資源文件和xml文件,基本都無法打開,即使打開或者亂碼
這些亂碼就是經過Android加密過的文件女,更關鍵的是,竟然找不到源代碼文件夾src。只能在res文件夾中查看非XML的片資源文件,不過, 有些應用會把圖片也加密處理,這樣你就連圖片也看不見了
既然直接解壓Apk文件是無法獲得正常的應用,那麼來看看如何使用正確的方法反編譯應用程序
首先請出三個重量級的工具,
apktools:反編譯
下載地址:http://ibotpeaches.github.io/Apktool/install/
dex2jar 這個工具用於將dex文件轉換成jar文件
下載地址:http://sourceforge.net/projects/dex2jar/files/
jd-gui 這個工具用於將jar文件轉換成java代碼
下載地址:http://jd.benow.ca/
這三 個工具分別負責反編譯不同的部分
-1.apktool
首先我們來反編譯apk的xml文件,使用的是apktool,我們進入所在的目錄執行反編譯命令
格式非常的簡單,參數d是指decode,並寫入要反編譯的目錄,執行後,就會生成一個對應apk名字的文件夾,這個時候你進去看xml的代碼就不會有錯誤了
這個工具可以方便我們漢化們重新打包的命令是b,選擇文件夾即可
下面我們來解決源碼
-2.Dex2jar,jd-gui
現在需要這兩個工具了,我們回到apk的文件夾,裡面有一個非常重要的文件classes.dex,這個就是源代碼了,我們把它復制到Dex2jar的目錄下
並且執行如下命令
這裡就生成了一個jar文件,然後我們就可以用最後的jd-gui去查看了
通過以上的方式,我們就可以完美的編譯一個應用程序了,
4.Android APK 加密
由於java字節的特殊性,他很容易反編譯,為了能夠保護好代碼,我們通常會使用一些措施,比如說混淆,而在Android studio中,可以很方便的使用ProGuard,在Gradle Scripts目錄下
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
這裡的minifyEnabled屬性就是控制是否啟動ProGuard,這個屬性以前叫做runProgyard,在Android studio1.1的時候改成minifyEnabled,將他設置成true,就可以混淆了,他位於《SDK目錄下的tools/proguard/proguard-android.txt目錄下,大部分的情況下使用使用這個默認的混淆就好了,後面亦不過分是項目中自定義的混淆,可以在項目的app文件夾下找到這個文件,在這根文件裡可以定義引用的第三方依賴庫和混淆規則,配置好ProGuard之後,用AS到處apk即可,
好了,本章到這裡就完了
在Android開發過程中,ListView的Adapter是我們最常見的類型之一,我們需要使用Adapter加載Item View的布局,並且進行數據綁定、緩存復用等操
信息的發送,對於Mms應用程序來講主要就是在信息數據庫中創建並維護一條信息記錄,真正的發送過程交由底層(Frameworks層)函數來處理。總體的來講,當信息創建完成後,
注:Google 在自己文章中用了 Display Performance 來描述我們常說的流暢度,為了顯得有文化,本文主要用“顯示性能”一詞來
Android 自定義toast 寬高大小 背景圖片 RelativeLayout layout = (RelativeLayout) getLayoutInfl