2016年3月24日 星期四

Difference between setRepeating and setInexactRepeating of AlarmManager

Reference:

http://stackoverflow.com/questions/21232984/difference-between-setrepeating-and-setinexactrepeating-of-alarmmanager


Example:

alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
                AlarmManager.INTERVAL_FIFTEEN_MINUTES, alarmIntent);
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
                AlarmManager.INTERVAL_DAY, alarmIntent);

There are two differences between these calls. The simpler one is that the intent will be sent every fifteen minutes on the first call, and every day on the second call (as you can see in the third parameter). The more complicated difference is the function call itself: setRepeating will schedule the first alarm for exactly every fifteen minutes; setInexactRepeating will schedule the second alarm for approximately every 24 hours, meaning it might deviate from that interval - with the advantage of consuming less power.

Illustration:

setRepeating(int type, long triggerAtMillis, long intervalMillis, PendingIntent operation)
setInexactRepeating(int type, long triggerAtMillis, long intervalMillis, PendingIntent operation)

setRepeating在第一次啟動 alarm後,會每隔 intervalMillis啟動一次alarm
setInexactRepeating則是第一次啟動 alarm後,會每隔大約 intervalMillis啟動一次alarm,目的是為了省電,啟動時間相近的 alarm會同時啟動

2016年3月15日 星期二

Get ringtone list from android settings

References:

http://stackoverflow.com/questions/2724871/how-to-bring-up-list-of-available-notification-sounds-on-android

Code snippet:

private static final int RINGTONE_REQUEST_CODE = 5;
public void requestProfileRingtone(){
 
    Intent ringtoneListIntent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
                    ringtoneListIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE,     RingtoneManager.TYPE_RINGTONE);
    ringtoneListIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, "Select Tone");
    ringtoneListIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, (Uri) null);
    startActivityForResult(ringtoneListIntent, RINGTONE_REQUEST_CODE);
}



@Override
    protected void onActivityResult(final int requestCode, final int resultCode, final Intent intent){
        if (resultCode == Activity.RESULT_OK && requestCode == RINGTONE_REQUEST_CODE){
            Uri uri = intent.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);

            if (uri != null){
                Toast.makeText(this, "chosenRingtone: " + uri.toString(), toast.LENGTH_SHORT).show();
                Log.d(TAG, "chosenRingtone: " + uri.toString());
            } else{
                Toast.makeText(this, "chosenRingtone is null", Toast.LENGTH_SHORT).show();
                Log.d(TAG, "chosenRingtone is null");
            }
        }
    }

2016年3月7日 星期一

Send android broadcast by adb

Reference:

http://blog.csdn.net/yelangjueqi/article/details/43231425

Command:

adb shell am broadcast:

[-a <ACTION>]
[-d <DATA_URI>]
[-t <MIME_TYPE>]
[-c <CATEGORY> [-c <CATEGORY>] ...]
[-e|--es <EXTRA_KEY> <EXTRA_STRING_VALUE> ...]
[--ez <EXTRA_KEY> <EXTRA_BOOLEAN_VALUE> ...]
[-e|--ei <EXTRA_KEY> <EXTRA_INT_VALUE> ...]
[-n <COMPONENT>]
[-f <FLAGS>] [<URI>]

Example:
adb shell am broadcast -a com.android.test --es test_string "this is test string" --ei test_int 100 --ez test_boolean true

2016年3月6日 星期日

How to animate a TextView using TextSwitcher

Reference:
http://www.learn-android-easily.com/2013/06/android-textswitcher.html
http://www.cnblogs.com/over140/archive/2010/10/22/1857991.html
http://never-say-never.iteye.com/blog/976886


Code snippet:

public class MainActivity implements ViewSwitcher.ViewFactory{
    private TextSwitcher mTextSwitcher;
    private Button mButton;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ........
        mTextSwitcher = (TextSwitcher) findViewById(R.id.text_switcher);
        mTextSwitcher.setFactory(this);

       // Declare the in and out animations and initialize them
       Animation in = AnimationUtils.loadAnimation(this,android.R.anim.slide_in_left);
       Animation out = AnimationUtils.loadAnimation(this,android.R.anim.slide_out_right);
                     
       // set the animation type of textSwitcher
       mSwitcher.setInAnimation(in);
       mSwitcher.setOutAnimation(out);

        mButton = (Button) findViewById(R.id.button);
        mButton.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {
                // TODO Auto-generated method stub
                mSwitcher.setText(myTextString);
            }
        });
    }

    // 重寫 ViewSwitcher.ViewFactory makeView()方法,返回一個 ViewTextSwitcher 交換時 使用  
    @Override 
    public View makeView() {  
        TextView textView = new TextView(this);  
        textView.setTextSize(36);
        textView.setColor(Color.White);
        textView.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL);
        return textView;  
    }
}

IllegalArgumentException: View not attached to window manager

Reference:

http://stackoverflow.com/questions/22924825/view-not-attached-to-window-manager-crash
http://www.2cto.com/kf/201202/119310.html

Scenario:

UI thread產生另一個 thread(Ex: AsyncTask)來顯示一個 Dialog,當 thread任務完成了再 dismiss dialog,如果在此期間 Activity因為某種原因被殺掉且又重新啟動了,那麼當  Dismiss的時候, WindowManager檢查發現  Dialog所屬的  Activity已經不存在了,就會跳出這個 Exception

Code snippet:

@Override
protected void onDestroy() {
    dismissProgressDialog();
    super.onDestroy();
}

protected void onPostExecute(String file_url)
{
    if (YourActivity.this.isDestroyed()) { // or call isFinishing() if min sdk version < 17
        return;
    }
    dismissProgressDialog();
    something(note);
}

private void dismissProgressDialog() {
    if (mDialog != null && mDialog.isShowing()) {
        mDialog.dismiss();
    }
}