Android -- 經驗分享

  • 代碼中安裝apk
  • 判斷某個apk是否已經安裝
  • 取得屏幕大小
  • 獲得 LayoutInflater 實例的三種方式
  • ContentResolver.query(),以及 Activity.managedQuery異同
  • 解鎖功能
  • 點亮屏幕
  • activity全屏顯示
  • 屏常亮代碼
  • SQL中 inner join、 left join 、right join、 outer join之間的區別
  • 包含button的item也能彈出菜單,回調click以及long click的監聽器
  • 背光亮度   /sys/class/leds/lcd-backlight/brightness
  • 判斷是否在鎖屏界面的函數
  • OnTouchListener實現雙擊事件
  • 回到待機界面
  • 定時器相關
  • sd卡和sim卡狀態判斷
  • 開機啓動,檢查sim卡是否發生變更

代碼中安裝apk                                                                             

Runtime.getRuntime().exec("pm install xxx.apk");

需要在manifest.xml文件中,加上INSTALL_PACKAGES的權限,可以用 Package install的receiver來處理安裝成功後的操作

或者:

複製代碼
/** 
     * 安裝apk 
     * @param url 
     */  
    private void installApk(String saveFileName){  
        File apkfile = new File(saveFileName);  
        if (!apkfile.exists()) {  
            return;  
        }      
        Intent i = new Intent(Intent.ACTION_VIEW);  
        i.setDataAndType(Uri.parse("file://" + apkfile.toString()), "application/vnd.android.package-archive");   
        mContext.startActivity(i);  
}
複製代碼

判斷某個APK是否已經安裝                                                             

複製代碼
private boolean isAppInstalled(String uri){  
      
    PackageManager pm = getPackageManager();  
    boolean installed =false;  
    try{  
        pm.getPackageInfo(uri,PackageManager.GET_ACTIVITIES);  
        installed =true;  
    }catch(PackageManager.NameNotFoundException e){  
        installed =false;  
    }  
      
    return installed;  
 }
複製代碼
//Just call the method by passing the package name of the application you need to check.
    if(isAppInstalled("com.yourpackage.package")){
     //app installed
    }else{
      //app not installed
    }

取得屏幕大小                                                                                

1、在非activity類中

WindowManager windowManager = (WindowManager)(mContext.getSystemService(Context.WINDOW_SERVICE));
 int screenWidth = windowManager.getDefaultDisplay().getWidth(); 
 int screenHeight = windowManager.getDefaultDisplay().getHeight();

2、在activity類中

int screenWidth  = getWindowManager().getDefaultDisplay().getWidth();       // 屏幕寬(像素,如:480px)  
int screenHeight = getWindowManager().getDefaultDisplay().getHeight();      // 屏幕高(像素,如:800px)

獲得 LayoutInflater 實例的三種方式                                             

LayoutInflater inflater = getLayoutInflater();  //調用Activity的getLayoutInflater()
LayoutInflater localinflater =(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LayoutInflater inflater = LayoutInflater.from(context);

示意代碼:

LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);    
View view = inflater.inflate(R.layout.custom, (ViewGroup)findViewById(R.id.test));

對於上面代碼,指定了第二個參數 ViewGroup root,當然你也可以設置爲 null 值。

ContentResolver.query(),以及 Activity.managedQuery異同

參數、返回值相同:都返回 Cursor 對象

參數:

URI:  Content Provider 需要返回的資源索引
Projection: 用於標識有哪些columns需要包含在返回數據中。
Selection: 作爲查詢符合條件的過濾參數,類似於SQL語句中Where之後的條件判斷。
SelectionArgs: 同上。
SortOrder: 用於對返回信息進行排序。

不同:

mContext.getContentResolver().query

ContentResolver.query(),以及 Activity.managedQuery()所以,我們看到一個是ContentResolver提供的查詢方法,位於android.content.ContextWrapper.getContentResolver(),另一個則爲Activity。  

Activity.managedQuery()  方法導致活動管理 Cursor 的生命週期

解鎖功能                                                                                      

KeyguardManager keyguardManager = (KeyguardManager)getSystemService(KEYGUARD_SERVICE);    
KeyguardLock keyguardLock = keyguardManager.newKeyguardLock(""); 
keyguardLock.disableKeyguard();
PowerManager pm = (PowerManager)getSystemService(POWER_SERVICE);

點亮屏幕                                                                                      

PowerManager pm = (PowerManager)getSystemService(POWER_SERVICE); 
WakeLock mWakelock = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP|PowerManager.SCREEN_DIM_WAKE_LOCK,"SimpleTimer"); 
mWakeLock.acquire();//點亮 
mWakeLock.release();//關閉

activity全屏顯示                                                                          

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);

注意;要在setContentView(R.layout.layout)語句之前調用才行。

屏常亮代碼                                                                                   

getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);//屏常亮

SQL中 inner join、 left join 、right join、 outer join之間的區別

舉例說明

A表(a1,b1,c1)      B表(a2,b2)
a1   b1   c1        a2    b2
01   數學 95         01    張三
02   語文 90         02    李四
03   英語 80         04    王五
select A.*,B.* from A  inner join B on(A.a1=B.a2)
結果是:
a1   b1   c1       a2    b2
01   數學 95       01    張三
02   語文 90       02    李四
select A.*,B.* from A  left outer join B on(A.a1=B.a2)
結果是:
a1   b1   c1       a2    b2
01   數學 95       01    張三
02   語文 90       02    李四
03   英語 80       NULL  NULL
select A.*,B.* from A  right outer join B on(A.a1=B.a2)
結果是:
a1   b1   c1       a2    b2
01   數學 95       01    張三
02   語文 90       02    李四
NULL NULL NULL     04    王五
select A.*,B.* from A  full outer join B on(A.a1=B.a2)
結果是:
a1   b1   c1       a2    b2
01   數學 95       01    張三
02   語文 90       02    李四
03   英語 80       NULL  NULL
NULL NULL NULL     04    王五

聽器  

設置button屬性:

android:focusable="false"

外還要設置 listview屬性:

android:longClickable="true"

PS: 如果包含的Button是ImageButton,那麼在xml中設置了android:focusable="false"屬性在當前版本是無效的,必須在代碼中,再次呼叫函數ImageButton.setFocusable(false)設置一次。 

或者在父Item裏面加上

android:descendantFocusability="blocksDescendants"

背光亮度

例如

echo 255 > /sys/class/leds/lcd-backlight/brightness

代碼修改亮度:

Settings.System.putInt(getContentResolver(), SCREEN_BRIGHTNESS, brightness);    //brightness 背光亮度 0~255
Settings.System.putInt(getContentResolver(),SCREEN_OFF_TIMEOUT, timeoutValues);//timeoutValues 滅屏時間 ms

判斷是否在鎖屏界面的函數                                                              

KeyguardManager: inKeyguardRestrictedInputMode();

例:

KeyguardManager km = (KeyguardManager)getSystemService(Context.KEYGUARD_SERVICE);
boolean keyguardexist = km.inKeyguardRestrictedInputMode();

OnTouchListener實現雙擊事件                                                    

複製代碼
class MyOnTouchListener implements View.OnTouchListener{
    private long mLastTime = 0;
    private long mCurTime = 0;

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if(MotionEvent.ACTION_DOWN == event.getAction()){  
            mLastTime = mCurTime; 
            mCurTime = System.currentTimeMillis();
            if (mCurTime - mLastTime < 1000) {
                // 雙擊事件  關閉activity
                FullBlackActivity.this.finish();
                return true;
            }
        }
        return false;
    }
}
複製代碼

回到待機界面                                                                                

Intent home = new Intent(Intent.ACTION_MAIN);  
home.addCategory(Intent.CATEGORY_HOME);  
this.startActivity(home);

定時器相關                                                                                   

  • 採用Handler與線程的sleep(long)方法

Handler主要用來處理接受到的消息。

1. 定義一個Handler類,用於處理接受到的Message。

Handler handler = new Handler() {
    public void handleMessage(Message msg) {
        // 要做的事情
        super.handleMessage(msg);
    }
};

新建一個實現Runnable接口的線程類,如下:

複製代碼
public class MyThread implements Runnable {
    @Override
    public void run() {
        // TODO Auto-generated method stub
        while (true) {
            try {
                Thread.sleep(10000);// 線程暫停10秒,單位毫秒
                Message message = new Message();
                message.what = 1;
                handler.sendMessage(message);// 發送消息
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}
複製代碼

3. 在需要啓動線程的地方加入下面語句:

new Thread(new MyThread()).start();

4. 啓動線程後,線程每10s發送一次消息。

  • 採用Handler的postDelayed(Runnable, long)方法

1. 定義一個Handler類

複製代碼
Handler handler=new Handler();
Runnable runnable=new Runnable() {
    @Override
    public void run() {
        // TODO Auto-generated method stub
        //要做的事情
        handler.postDelayed(this, 2000);
    }
};
複製代碼

2. 啓動計時器

handler.postDelayed(runnable, 2000);//每兩秒執行一次runnable.

3. 停止計時器

handler.removeCallbacks(runnable);
  • 採用Handler與timer及TimerTask結合的方法

1. 定義定時器、定時器任務及Handler句柄

複製代碼
private final Timer timer = new Timer();
private TimerTask task;
Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        // TODO Auto-generated method stub
        // 要做的事情
        super.handleMessage(msg);
    }
};
複製代碼

2. 初始化計時器任務

複製代碼
task = new TimerTask() {
    @Override
    public void run() {
        // TODO Auto-generated method stub
        Message message = new Message();
        message.what = 1;
        handler.sendMessage(message);
    }
};
複製代碼

3. 啓動定時器

timer.schedule(task, 2000, 2000);

簡要說一下上面三步提到的一些內容:

1. 定時器任務(TimerTask)顧名思義,就是說當定時器到達指定的時間時要做的工作,這裏是想Handler發送一個消息,由Handler類進行處理。

2. java.util.Timer.schedule(TimerTask task, long delay, long period):這個方法是說,delay/1000秒後執行task,然後進過period/1000秒再次執行task,這個用於循環任務,執行無數次,當然,你可以用timer.cancel();取消計時器的執行。

  • 鬧鐘定時
AlarmManager am = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(SEND_SMS_BEGIN), 0);
am.set(AlarmManager.RTC_WAKEUP, 60*1000, pendingIntent);

耳機狀態                                                                                      

複製代碼
private static final String HEADSET_STATE_PATH = "/sys/class/switch/h2w/state";    //保存狀態文件位置

private boolean isHeadsetExists(){       //判斷耳機是否插入的函數    FM源碼 FMplayService.java  
        char[] buffer = new char[1024];
        int newState = 0;
        try {
            FileReader file = new FileReader(HEADSET_STATE_PATH);
            int len = file.read(buffer, 0, 1024);
            newState = Integer.valueOf((new String(buffer, 0, len)).trim());
        } catch (FileNotFoundException e) {
            Log.e(LOGTAG, "This kernel does not have wired headset support");
        } catch (Exception e) {
            Log.e(LOGTAG, "" , e);
        }
        return newState != 0;
   }
複製代碼
複製代碼
未插入耳機:

# cat /sys/class/switch/h2w/state
cat /sys/class/switch/h2w/state
0

插入耳機:
# cat /sys/class/switch/h2w/state
cat /sys/class/switch/h2w/state
1
複製代碼

sd卡和sim卡狀態判斷                                                                   

複製代碼
//sdcard是否可讀寫 
public boolean IsCanUseSdCard() { 
    try { 
        return Environment.getExternalStorageState().equals( 
                Environment.MEDIA_MOUNTED); 
    } catch (Exception e) { 
        e.printStackTrace(); 
    } 
    return false; 
} 

//sim卡是否可讀 
public boolean isCanUseSim() { 
    try { 
        TelephonyManager mgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); 
         return TelephonyManager.SIM_STATE_READY == mgr.getSimState(); 
    } catch (Exception e) { 
        e.printStackTrace(); 
    } 
    return false; 
}
複製代碼

開機啓動,檢查sim卡是否發生變更                                                  

(1)註冊receiver,設置意圖過濾器

<receiver android:name=".receiver.BootCompleteReceiver" >
    <intent-filter android:priority="1000" >
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>

(2)接受開機廣播,並判斷sim卡時候發生更改

複製代碼
public class BootCompleteReceiver extends BroadcastReceiver {
    private static final String TAG = "BootCompleteReceiver";
    private SharedPreferences sp;
    private TelephonyManager tm;
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i(TAG,"手機重啓了");
        sp = context.getSharedPreferences("config", Context.MODE_PRIVATE);
        boolean protecting = sp.getBoolean("protecting", false);
        //如果防盜保護開啓
        if(protecting){
                //判斷sim卡是否發生了變化
        tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            String currentSim = tm.getSimSerialNumber();
            String savedSim= sp.getString("sim", "");
            if(savedSim.equals(currentSim)){
                    // sim卡爲發生變化, do nothint
            }else{
                //sim卡發生了變化
                //發送報警短信 給安全號碼
                SmsManager smsManager = SmsManager.getDefault();
                String destinationAddretss = sp.getString("safenumber", "");
                smsManager.sendTextMessage(destinationAddretss, null, "sim change !!!", null, null);
            }
        }
    }
}
複製代碼
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章