[关闭]
@guhuizaifeiyang 2015-10-29T10:12:41.000000Z 字数 71729 阅读 2314

每日学习笔记

Android开发 JAVA学习


20150728

1 学习Ubuntu常用命令。

2 熟悉eclipse程序使用界面。

3 学习Git常用命令,并将每日工作总结保存到repository,通过Git来管理工作总结。


20150729

1 学习JAVA基础。

2 编译ANDROID源码。

执行全编译时,输入source build/envsetup.sh,显示“bash: build/envsetup.sh: 没有那个文件或目录”。
* 原因:没有CD到源码所在目录。
* 解决方案:cd ~/Pro/5030/baseline切换到build/envsetup.sh的所在目录。

20150730

1 熟悉Android源码目录结构。

2 Android应用开发详解/Android中的资源访问。


20150731

1 Android应用开发详解/Android用户界面。

2 烧机

3 adb的使用

4 Log.d()的使用,可以用来过滤log信息,跟踪程序


20150803

1 软件测试概述培训

2 Android开发环境培训

3 动手编写Android CommonWidget.apk

* 从MainActivity跳转到ResultActivity时,程序stopped。
原因:have you declared this activity in your AndroidManifest.xml?
解决:将ResultActivity写进AndroidManifest.xml

4 git format-patch

* 在用git am提交patch时,有时在提交失败后,继续提交时会出现/.git/rebase-apply still exists but mbox given错误。
原因:错误的提交导致git内部的数据出现了错误。
解决:使用git am --abort命令将git的状态恢复后就可以继续提交patch了。

20150804

1 软件黑盒测试评估规范

2 Android 基本组件练习

* The method setOnClickListener(View.OnClickListener) in the type View is not applicable for 
 the arguments (new OnClickListener(){})
解决:把 import android.content.DialogInterface.OnClickListener;  改成    import android.view.View.OnClickListener;

* saveB = (Button).findViewById(R.id.button);提示Button cannot be resolved to a variable
原因:(Button)后面多写了个.
解决:改成saveB = (Button)super.findViewById(R.id.button)或saveB = (Button)findViewById(R.id.button);

3 eclipse调试


20150805

1 配置管理培训

2 Android[timePicker/DatePicker]

* 按照源码编写程序正常运行,但再移动layout文件中组件的位置后,再Run出现"Unfortunately,timePicker has stopped"
原因:不明
解决:未知

3 Android基于监听器的事件处理:OnClickListener/OnCheckChangeListener/OnItemSelectedListener/OnFocusChangeListener/OnLongClickListener/OnTouchListener


20150806

1 客户软件需求管理程序培训

2 党组织关系转移

3 Android[ListView/AlertDialog/DatePickDialog/ProgressDialog/SeekBar/RatingBar/Toast/ImageSwitcher&Gallery/Switch&ToggleButton]

* 设置监听事件还非常生疏。

* intent.setType("vnd.android.cursor.item/phone")字符串常量如何写?改成其它字符串常量之后APP运行stopped。

20150807

1 Android Intent

* Intent的Action属性
* Intent的Data属性
* Intent的Category属性
* Intent的Extras属性
* 系统标准Activity Action应用
* 隐式查找:通过Intent Filter实现
    * 6.3 1.Action测试--->  <intent-filter>***</intent-filter>中,如果漏写<category **/>,则无法通过Action测试。
    原因:在Intent对象中出现的Category属性在Intent Filter中必须出现,否则不能通过测试。其中"android.intent.category.DEFAULT"属性是启动Activity默认的属性,这个必须添加,否则Category测试失败。

2 Android短信模块分析之Mms功能

* 查找Massaging>>Setting的Activity文件,并尝试修改。
1、打开Massaging>>Setting。
2、输入adb logcat ActivityManager:I *:s  显示Displayed Displayed com.android.mms/.ui.SettingListActivity  
3、在Packages/apps/Mms/src/com/android/mms/ui目录下找到SettingListActivity.java文件

3 adb uninstall

* 删除系统应用:adb uninstall com.android.mms        出现Failure [DELETE_FAILED_INTERNAL_ERROR]
  删除自安装应用:adb uninstall com.example.timepicker   Success

4 打开flash_tool烧机工具

1、在终端中进入flash_tool所在目录,输入sudo ./flash_tool.sh
2、Scatter-Loading:/out/target/product/s5030/MT6580_Android_scatter.txt
3、选择Firmware Upgrade

20150808

1 Android系统应用(Mms)修改

1、修改源码(.java .xml等)
2、AOSP编译Mms模块
3、如果需要永久修改,则adb shell进入到./system/priv-app/Mms下删除Mms.apk。然后adb push将out目录中Mms.apk复制到手机system/priv-app/Mms/。
4、如果不需要永久修改(开机后恢复),则直接adb install -r ./out/target/product/s5030/system/priv-app/Mms/Mms.apk  (注:如果不加-r(指重新安装),会出现Failure [INSTALL_FAILED_ALREADY_EXISTS]错误)

2 导入Android源码Project

1、new->project->select General下的Project->Next->输入Project name(和源码Project相同)和Location(源码位置)
* 导入的源码无法修改,出现错误This compilation unit is not on the build path of a java project.
解决:重新导入后未出现该问题。

20150810

1 共基线开发指南培训

2 Android第一行代码

*掌握部分:
    1、向下一个活动传递数据
    2、创建菜单项
    3、保存活动被回收时的临时数据
    4、活动的生命周期
    5、四种布局
    6、单位和尺寸
*未掌握部分:
    1、创建自定义控件
    2、创建自定义适配器
    3、LayoutInflater
    4、ViewHolder

20150811

1 android实战一(ListView)

2 Android第一行代码(第9章 Service)

* Eclipse workspace is in use or cannot be created, choose a different one错误。
原因:workspace配置文件中出现了.lock文件(workspace/.metadata/.lock),锁定了workspace。
解决:删除.lock文件

3 Google Android SDK

* 3.10 不同Activity之间的数据传递——Bundle对象的实现
    intent.getExtras()和intent.getBundleExtra()的区别?
    intent.putExtras()和intent.putExtra()的区别?
    答:intent.putExtras(bundle)和intent.getExtras()配套使用;
        intent.putExtra("TAG",bundle)和intent.getBundleExtra("TAG")配套使用

20150812

1 Android应用程序培训

2 Pinoy项目之音乐播放器开发。进度:界面基本雏形

20150814

1 Android应用界面培训

2 手机基带基础知识培训

3 Pinoy_MediaPlayer:添加MediaPlayerReceiver

* 监听PHONT_STATE和NEW_OUTGOING_CALL,当来电时onpause()->onstop()。再进入程序onResume,点击play则继续播放;锁屏和HOME响应过程类似。

20150815

1 Pinoy:添加Notification

2 SDK文档:MediaPlayer(android.media)、Handler(android.os)

3 List和ArrayList的区别


20150819

1 Pinoy_MediaPlayer:添加了Handler多线程处理play/pause,stop和焦点事件监听。

* 从Notification重新回到Activity,重新启动了Activity,而不是原来的Activity。
原因:运行了onCreate()
解决:创建Notification对象后,添加
        Intent intent = new Intent(this,MediaPlayerActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

2 Pinoy_MediaPlayer:添加Gallery(尚未完成)

3 Pinoy_MediaPlayer:将Notification设置为常驻通知。

* 添加notification.flags = Notification.FLAG_ONGOING_EVENT;

4 Pinoy_MediaPlayer:播放其他音乐应用时,该MediaPlayer应该pause,改变焦点。
当其他音乐应用OnDestroy时,MediaPlayer应该play,重新获得焦点。

* 监听case AudioManager.AUDIOFOCUS_LOSS:
  然后将音乐pasue。
  监听case AudioManager.AUDIOFOCUS_GAIN:
  然后将音乐start
  onDestroy()中应该释放焦点:mAudioManager.abandonAudioFocus(mAudioFocusListener);

5 Pinoy_MediaPlayer:禁止横屏

* 在AndroidManifest.xml文件中<activity下面加入
  android:screenOrientation="portrait"

6 Pinoy_MediaPlayer:MediaPlayer在播放的时候,按back键应该继续播放。

*Override onKeyDown方法
public boolean onKeyDown(int keyCode, KeyEvent event) {
    // TODO Auto-generated method stub
    if(keyCode==KeyEvent.KEYCODE_BACK && myPlayer.isPlaying()){
        moveTaskToBack(false);
        return true;
    }
    return super.onKeyDown(keyCode, event);
}
// moveTaskToBack(false)当有多个Activity时,按back则不会跳转。改为true则直接跳到桌面,类似于最小化;

20150820

1 Pinoy_Gallery:实现图片浏览,上方显示缩略图,下方显示图片。

2 Pinoy_Gallery:进入程序时,应自动更新图片。

* 将读取文件方法写入onResume()

3 Pinoy_Gallery:读取图片格式文件

* List<String> fileList = new ArrayList<String>();
    File fileDir = new File(strPath);    
    File[] files = fileDir.listFiles();    
    if(files!=null){    
        for(File file:files){    
            String fileName = file.getName();    
            if(fileName.endsWith(".jpg")||fileName.endsWith(".png")||fileName.endsWith(".bmp")){
                fileList.add(file.getPath());
            }
        }       
    }  

4 Pinoy_Gallery:进入程序时,显示第一张图片

5 Pinoy_Gallery:需要增加简单动画效果。滑动图片时,图片能左右拖动。

6 Pinoy_Gallery:图片缩略图随图片一起滑动

* Gallery.setSelection(int Position)

7 Pinoy_Gallery:进入程序时读取图片文件,速度比较慢,要采用多线程处理。

* 结果仍旧不理想

20150821

1 Pinoy_Reader:实现txt文本阅读

* public class ReaderActivity extends Activity {

private final String TAG = "[HcReader]";
private String fileName;

public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.readerlayout);

// fileName = this.getIntent().getStringExtra("file");
fileName = "/storage/sdcard0/Bible01-Genesis.txt";
updateView( fileName,"UTF8" );
}

public void updateView( String fileName,String encoding ){
    byte[] data = openFile(fileName);
    String display = EncodingUtils.getString(data, encoding);
    TextView tv = (TextView)findViewById(R.id.tvTxt);
    tv.setText(display);
}

public byte[] openFile(String fileName){
    try {
        File file = new File(fileName);
        FileInputStream in = new FileInputStream(file);
        int length = (int)file.length();
        byte[] temp = new byte[length];
        in.read(temp, 0, length);
        return temp;
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        Log.d(TAG, e.toString());
        return null;
    }
}

}

2 Pinoy_AlarmClock:源码研究

2.1 AlarmManager

2.2 alarmManager.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pi);        //设置闹钟

@Override
protected Dialog onCreateDialog(int id) {
    Dialog dialog=null;
    switch (id) {
    case DIALOG_TIME:
        dialog=new TimePickerDialog(
                this, 
                new TimePickerDialog.OnTimeSetListener(){
                    public void onTimeSet(TimePicker timePicker, int hourOfDay,int minute) {
                        Calendar c=Calendar.getInstance();//获取日期对象    
                        c.setTimeInMillis(System.currentTimeMillis());        //设置Calendar对象
                        c.set(Calendar.HOUR, hourOfDay);        //设置闹钟小时数
                        c.set(Calendar.MINUTE, minute);            //设置闹钟的分钟数
                        c.set(Calendar.SECOND, 0);                //设置闹钟的秒数
                        c.set(Calendar.MILLISECOND, 0);            //设置闹钟的毫秒数
                        Intent intent = new Intent(MainActivity.this, AlarmReceiver.class);    //创建Intent对象
                        PendingIntent pi = PendingIntent.getBroadcast(MainActivity.this, 0, intent, 0);    //创建PendingIntent
                        //alarmManager.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pi);        //设置闹钟
                        alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), pi);        //设置闹钟,当前时间就唤醒
                        Toast.makeText(MainActivity.this, "闹钟设置成功", Toast.LENGTH_LONG).show();//提示用户
                    }
                }, 
                cal.get(Calendar.HOUR_OF_DAY), 
                cal.get(Calendar.MINUTE),
                false);

        break;
    }
    return dialog;
}

2.3 PendingIntent.getBroadcast();

    * 要得到一个pendingIntent对象,使用方法类的静态方法
        getActivity(),getBroadcast(),getService(),分别对应着Intent的3个行为,跳转到一个Activity,打开一个广播组件和打开一个服务组件。
    * 主要使用地方和例子:Notofication,SmsManager,AlarmManager

20150822

1 Pinoy_AlarmClock:

1.1 Divier分割线
    * <style name="Divider">
    <item name="android:layout_width">match_parent</item>
    <item name="android:layout_height">1dp</item>
    <item name="android:background">?android:attr/listDivider</item>
    </style>
1.2 android自带属性:android:textAppearance="?android:attr/textAppearanceSmall" 

1.3 pick ring tone:
    final LinearLayout ringToneContainer = (LinearLayout) findViewById(R.id.alarm_ringtone_container
    ringToneContainer.setOnClickListener(new OnClickListener() {

    @Override

    public void onClick(View v) {

    Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);

    startActivityForResult(intent , 1);

    }

     });

    private AlarmModel alarmDetails;
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // TODO Auto-generated method stub
    if(resultCode==RESULT_OK){
        switch (requestCode) {
        case 1:
            alarmDetails.alarmTone = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
            TextView txtToneSelection = (TextView)findViewById(R.id.alarm_label_tone_selection);
            txtToneSelection.setText(RingtoneManager.getRingtone(this, alarmDetails.alarmTone).getTitle(this));
            break;

        default:
            break;
        }
    }
    super.onActivityResult(requestCode, resultCode, data);
}

1.4 android:orderInCategory="100"表示item优先级,数值越大,优先级越高。

1.5 CRUD:Create、Retriveve、Update、Delete

20150824

  1. Pinoy_AlarmClock:设置固定闹钟名称和铃声

  2. Pinoy_AlarmClock:闹铃响起后按HOME键推出,应设置发送通知。

  3. Pinoy_MediaPlayer:back后无法继续播放,需用Service来实现。


20150825

  1. Pinoy_MediaPlayer:改用Service和BroadcastReceiver实现。

    • back后Activity销毁,从通知栏进入Activity会从onCreate()运行,重新播放音乐。我们希望可以继续播放the last music。
    • idea 1:通过重写onSaveInstanceState方法在Activity销毁时保存数据(path)。Activity进入onCreate()方法时判断path是否相同。==============>当某个Activity变得“容易”被系统销毁时,onSaveInstanceState会被执行,除非activity是被用户主动销毁的,如back。
    • idea 2:在上级ListActivity中就启动Service,添加BroadcastReceiver接受Service传来Music是否播放的消息。
    • idea 3:声明private static String lastPath;判断lastPath?=Path。因为lastPath是static型,oncreate后不会销毁。(可行)
  2. Pinoy_MediaPlayer:界面优化


20150826

  1. Fragment的学习

    1.1 // activity layout must include a container View in which you can insert the fragment.

    1.2 All Fragment-to-Fragment communication is done through the associated Activity. Two Fragments should never communicate directly. You can define an interface in the Fragment class and implement it within the Activity.

    • AnotherRightFragment fragment = new AnotherRightFragment();
      FragmentManager fragmentManager = getFragmentManager();
      FragmentTransaction transaction = fragmentManager
      .beginTransaction();
      transaction.replace(R.id.right_layout, fragment);
      transaction.addToBackStack(null); // To allow the user to navigate backward through the fragment transactions
      transaction.commit();
  2. SQLite的学习

  3. Android中string-array数据源使用


20150827

  1. SimpleAdapter的学习

    • SimpleAdapter的核心代码:

      for (int i = 0; i < 10; i++) {
      Map map = new HashMap();
      map.put("PIC", R.drawable.pic);
      map.put("TITLE", "Test Title");
      map.put("CONTENT", "Test Content");
      contents.add(map);
      }
      SimpleAdapter adapter = new SimpleAdapter(this,
      (List>) contents, R.layout.listitem,
      new String[] { "PIC", "TITLE", "CONTENT" }, new int[] {
      R.id.listitem_pic, R.id.listitem_title,
      R.id.listitem_content });

      listView.setAdapter(adapter);

  2. adh push文件夹:

    • adb push -p ./pinoy/Pinoy/Gallery/ ./storage/sdcard0/Gallery/
  3. android:用getIdentifier()获取资源Id

    • .getIdentifier(String name, String defType, String defPackage)

20150828

  1. Pinoy项目:完成属性

  2. 重命名快捷键:F2

3.判断字符串数组是否包括目标字符串:

* // decide stringArray contains source string ?
public boolean contains(String[] stringArray, String source){
    List<String>tempList = Arrays.asList(stringArray);
    if(tempList.contains(source)){
        return true;
    }else{
        return false;
    }
}

4.JAVA list排序:

* Collections.sort(list);
* 自定义排序?

5.优化界面布局,将myfaith_list.xml上面的FrameLayout替换为RelativeLayout。


20150829

1.List>排序

* /排序算法
 public void sort(List<Map<String, Object>> list) {
  Collections.sort(list, new Comparator<Map<String, Object>>(){
   public int compare(Map<String, Object> o1, Map<String, Object> o2) {
    return  o1.get("text").toString().compareTo(o2.get("text").toString());
   } 
  });
 }

2.合并MyFaith和MyCountry

3.如何修改ListView SimpleAdapter里面的TextView的颜色?

* 自定义Adapter extends BaseAdapter

20150831

1.自定义Adapter中的getView没有执行

* 原因:setAdapter 时,首先会执行getCount(),当getCount()  返回的是0时,就不会去执行getView()方法
* 解决:重写getCount()

2.解决listView item 字体颜色无法调整的问题

* 原因:setTextColor(int color):color为int型,而不是color的ID。

* 解决:getResources().getColor(int id)

3.増加音乐文件是否存在的判断。

* File file = new File(strMusicPath);
    if(file.exists()){
        playMusic();
    }else{
        Log.d(TAG, "file doesn't exit");
        finish();
    }

4.如何加载大分辨率图片

* 有时候我们确实会需要加载一些大分辨率的图片,但是对于移动设备而言,哪怕加载能成功那么大的内存也是一种浪费(屏幕分辨率限制),所以就需要想办法把图片按照一定比率压缩,使分辨率降低,以至于又不需要耗费很大的堆内存空间,又可以最大的利用设备屏幕的分辨率来显示图片。这里就用到一个BitmapFactory.Options对象,下面来介绍它。

  BitmapFactory.Options为BitmapFactory的一个内部类,它主要用于设定与存储BitmapFactory加载图片的一些信息。下面是Options中需要用到的属性:

inJustDecodeBounds:如果设置为true,将不把图片的像素数组加载到内存中,仅加载一些额外的数据到Options中。
outHeight:图片的高度。
outWidth:图片的宽度。
inSampleSize:如果设置,图片将依据此采样率进行加载,不能设置为小于1的数。例如设置为4,分辨率宽和高将为原来的1/4,这个时候整体所占内存将是原来的1/16。

  1. android获取屏幕的高度和宽度

    • android获取屏幕的高度和宽度用到WindowManager这个类,两种方法:

    1、WindowManager wm = (WindowManager) getContext()
    .getSystemService(Context.WINDOW_SERVICE);

     int width = wm.getDefaultDisplay().getWidth(); 
     int height = wm.getDefaultDisplay().getHeight(); 
    

    2、WindowManager wm = this.getWindowManager();

     int width = wm.getDefaultDisplay().getWidth(); 
     int height = wm.getDefaultDisplay().getHeight(); 
    

20150901

1.Bundle和Intent

* Bundle对数据进行封装,方便传递。

2.getApplicationContext和getBaseContext

* getApplicationContext() 返回应用的上下文,生命周期是整个应用,应用摧毁它才摧毁

Activity.this的context 返回当前activity的上下文,属于activity ,activity 摧毁他就摧毁

getBaseContext() 返回由构造函数指定或setBaseContext()设置的上下文

3.优化Gallery图片加载速度

* public static Bitmap decodeSampledBitmapFromResource(String pathName, int reqWidth, int reqHeight){
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    Bitmap bitmap = BitmapFactory.decodeFile(pathName, options);

    options.inSampleSize = calculateInSampleSize(options, reqHeight, reqWidth);
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeFile(pathName, options);
}

public static int calculateInSampleSize(BitmapFactory.Options opt, int reqHeight, int reqWidth){
    final int height = opt.outHeight;
    final int width = opt.outWidth;
    int inSampleSize = 1;

    if(height > reqHeight || width > reqWidth){
        final int halfHeight = height/2;
        final int halfWidth = width/2;

        while((halfHeight/inSampleSize)>reqHeight && (halfWidth/inSampleSize)>reqWidth){
            inSampleSize *= 2;
        }
    }

    return inSampleSize;
}

4.Progress Dialog构造方法

* .ProgressDialog.show(Context context, CharSequence title, CharSequence message, boolean indeterminate)

* Progress Dialog必须要在后台程序运行完毕前,以dismiss()方法来关闭取得焦点(focus)的对话框,否则程序会陷入无限循环中。

5.线程和进程

* 线程和进程的主要差别体现在以下两个方面:
    (1)同样作为基本的执行单元,线程是划分得比进程更小的执行单位。
    (2)每个进程都有一段专用的内存区域。与此相反,线程却共享内存单元(包括代码和数据),通过共享的内存单元来实现数据交换、实时通信与必要的同步操作。

* 线程的基本用法
    (1)class MyThread extends Thread{
        @override
        public void run(){
        }
      }
    启动线程:new MyThread().start();
    (2)class MyThread implements Runnable{

        @Override
        public void run() {
            // TODO Auto-generated method stub

        }

      }
    启动线程:MyThread myThread = new MyThread();
        new Thread(MyThread).start();
    (3)new Thread(new Runnable() {

        @Override
        public void run() {
            // TODO Auto-generated method stub

        }
    }).start();
  1. 页面全屏显示:

    • 不显示标题栏:

      requestWindowFeature(Window.FEATURE_NO_TITLE);

    • 不显示状态栏:

      getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

  2. ViewFlipper

    • ViewFilpper 是Android官方提供的一个View容器类,继承于ViewAnimator类,用于实现页面切换,也可以设定时间间隔,让它自动播放。
      又ViewAnimator继承至于FrameLayout的,所以ViewFilpper的Layout里面可以放置多个View。

20150902

1.调用系统摄像头Action:

* Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

2.从相册选取图片Action:

* Intent intent = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

3.优化Gallery图片加载速度

* 进入GalleryActivity时,先将图片黑底显示,再用子线程更新图片。

问题:可能是逻辑问题,UI更新后没有显示出图片黑底,直接运行了子线程。

4.使用用AsyncTask

* 由于AsyncTask是一一个抽象类,所以如果我们想使用用它,就必须要创建一一个子子类去继承它。在继承时我们可以为AsyncTask类指定三个泛型参数,这三个参数的用用途如下。

1. Params
    在执行行AsyncTask时需要传入入的参数,可用用于在后台任务中使用用。
2. Progress
    后台任务执行行时,如果需要在界面面上显示示当前的进度,则使用用这里里指定的泛型作为进度单位。
3. Result
    当任务执行行完毕后,如果需要对结果进行行返回,则使用用这里里指定的泛型作为返回值类型。

因此,一一个最简单的自自定义AsyncTask就可以写成如下方方式:

class DownloadTask extends AsyncTask<Params, Progress, Result> {}

* 一个异步任务的执行一般包括以下几个步骤:

1.execute(Params... params),执行一个异步任务,需要我们在代码中调用此方法,触发异步任务的执行。execute(param1,param2,...)
2.onPreExecute(),在execute(Params... params)被调用后立即执行,一般用来在执行后台任务前对UI做一些标记。
3.doInBackground(Params... params),在onPreExecute()完成后立即执行,用于执行较为费时的操作,此方法将接收输入参数和返回计算结果。在执行过程中可以调用publishProgress(Progress... values)来更新进度信息。params[0],params[1],...
4.onProgressUpdate(Progress... values),在调用publishProgress(Progress... values)时,此方法被执行,直接将进度信息更新到UI组件上。
5.onPostExecute(Result result),当后台操作结束时,此方法将会被调用,计算结果将做为参数传递到此方法中,直接将结果显示到UI组件上。
  1. Handler

    • Handler模式需要为每一个任务创建一个新的线程,任务完成后通过Handler实例向UI线程发送消息,完成界面的更新.
  2. 重启Ubuntu输入法:
    killall ibus-daemon (结束进程)
    ibus-daemon -d (重启ibus)

  3. WeakReference: 防止内存泄漏,要保证内存被虚拟机回收。如果你希望能随时取得某对象的信息,但又不想影响此对象的垃圾收集,那么你应该用 Weak Reference 来记住此对象,而不是使用一般的 reference。

  4. 调用系统图片浏览器:

    • Intent intent = new Intent();
      intent.setAction(android.content.Intent.ACTION_VIEW);
      intent.setDataAndType(Uri.fromFile(file), "image/*");
      startActivity(intent);

20150903

  1. BaseAdapter中getView()没有被调用的问题。

    • 必须重写getCount()方法
    • getCount()返回0则不调用getView()
  2. MATRIX矩阵动态缩小放大图片来显示

    • //获得Bitmap的高和宽
      int bmpWidth=bmp.getWidth();
      int bmpHeight=bmp.getHeight();

      //设置缩小比例
      double scale=0.8;
      //计算出这次要缩小的比例
      scaleWidth=(float)(scaleWidth*scale);
      scaleHeight=(float)(scaleHeight*scale);

      //产生resize后的Bitmap对象
      Matrix matrix=new Matrix();
      matrix.postScale(scaleWidth, scaleHeight);
      Bitmap resizeBmp=Bitmap.createBitmap(bmp, 0, 0, bmpWidth, bmpHeight, matrix, true);

  3. dp转px

    • public static int Dp2Px(Context context, float dp) {
      final float scale = context.getResources().getDisplayMetrics().density;
      return (int) (dp * scale + 0.5f);
      }
  4. 优化Gallery图片加载速度

    • 采用线程池+缓存
    • DisplayBitmap03

20150904

  1. 文字复制粘贴(undone)

  2. 如何将字串 String 转换成整数 int?

    A. 有两个方法:

    1). int i = Integer.parseInt([String]); 或
    i = Integer.parseInt([String],[int radix]);

    2). int i = Integer.valueOf(my_str).intValue();

    注: 字串转成 Double, Float, Long 的方法大同小异.

    2 如何将整数 int 转换成字串 String ?

    A. 有叁种方法:

    1.) String s = String.valueOf(i);

    2.) String s = Integer.toString(i);

    3.) String s = "" + i;

  3. 获取手机屏幕高度,宽度,密度

    • 1.
      DisplayMetrics metric = new DisplayMetrics();
      getWindowManager().getDefaultDisplay().getMetrics(metric);
      int width = metric.widthPixels; // 屏幕宽度(像素)
      int height = metric.heightPixels; // 屏幕高度(像素)
      float density = metric.density; // 屏幕密度(0.75 / 1.0 / 1.5)
      int densityDpi = metric.densityDpi; // 屏幕密度DPI(120 / 160 / 240)

    • 2.(recommend)
      DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
      int width = displayMetrics.widthPixels; // 屏幕宽度(像素)
      int height = displayMetrics.heightPixels; // 屏幕高度(像素)
      float density = displayMetrics.density; // 屏幕密度(0.75 / 1.0 / 1.5)

    • 设定多分辨率支持:AndroidManifest.xml文件中,加入supports-screens节点

    android:smallScreens="true"
    android:normalScreens="true"
    android:largeScreens="true"
    android:resizeable="true"
    android:anyDensity="true"/>

  4. TypedArray获取颜色或drawable。有没有获取整个drawable数组的方法???

    Resources res = getResources();
    TypedArray icons = res.obtainTypedArray(R.array.icons);
    Drawable drawable = icons.getDrawable(0);

    TypedArray colors = res.obtainTypedArray(R.array.colors);
    int color = colors.getColor(0,0);

6.文件查找

* # grep ‘energywise’ *           #在当前目录搜索带'energywise'行的文件

# grep -r ‘energywise’ *        #在当前目录及其子目录下搜索'energywise'行的文件

# grep -l -r ‘energywise’ *     #在当前目录及其子目录下搜索'energywise'行的文件,但是不显示匹配的行,只显示匹配的文件
  1. dp的意义是按照mdpi下px:dp = 1:1换算,其他分辨率按照density比例算出来(xhdpi=320,hdpi=240,mdpi=160,ldpi=120),如果不想记density值,则按照标注屏幕宽度比例换算也可以(对large-*dpi无效),也就是说:
    mdpi下屏幕宽度为320px,所以就是320dp,半个屏幕自然就是160dp
    hdpi下dp:px = 1:1.5 (按照屏幕宽480/320=1.5算出来),所以160dp也等于半个屏幕宽
    ldpi下dp:px = 3:4 = 1:0.75 (按照240/320=0.75算出来),所以160dp也等于半个屏幕

20150906

    1.
  1. /**
  2. * read the file by line
  3. * @param path path
  4. * @return ArrayList
  5. */
  6. public static ArrayList<String> readFile(String path) {
  7. mList.clear();
  8. File file = new File(path);
  9. FileReader fr = null;
  10. BufferedReader br = null;
  11. try {
  12. if (file.exists()) {
  13. fr = new FileReader(file);
  14. } else {
  15. Log.d(TAG, "file in " + path + " does not exist!");
  16. return null;
  17. }
  18. br = new BufferedReader(fr);
  19. String line;
  20. while ((line = br.readLine()) != null) {
  21. Log.d(TAG, " read line " + line);
  22. mList.add(line);
  23. }
  24. return mList;
  25. } catch (IOException io) {
  26. Log.d(TAG, "IOException");
  27. io.printStackTrace();
  28. } finally {
  29. try {
  30. if (br != null) {
  31. br.close();
  32. }
  33. if (fr != null) {
  34. fr.close();
  35. }
  36. } catch (IOException io) {
  37. io.printStackTrace();
  38. }
  39. }
  40. return null;
  41. }
  1. adb devices no permissions

  2. 进入vi(vim)的命令

    vi filename :打开或新建文件,并将光标置于第一行首
    vi n filename :打开文件,并将光标置于第n行首
    vi filename :打开文件,并将光标置于一行首
    vi /pattern filename:打开文件,并将光标置于第一个与pattern匹配的串处
    vi -r filename :在上次正用vi编辑时发生系统崩溃,恢复filename
    vi filename....filename :打开多个文件,依次进行编辑

    移动光标类命令
    G : 到结尾
    gg : 到开头
    0 : 到行首
    ctrl+4 : 到行尾
    h :光标左移一个字符
    l :光标右移一个字符
    space:光标右移一个字符
    Backspace:光标左移一个字符
    k或Ctrl p:光标上移一行
    j或Ctrl n :光标下移一行
    Enter :光标下移一行
    w或W :光标右移一个字至字首
    b或B :光标左移一个字至字首
    e或E :光标右移一个字至字尾
    ) :光标移至句尾
    ( :光标移至句首
    }:光标移至段落开头
    {:光标移至段落结尾
    nG:光标移至第n行首
    n :光标下移n行
    n-:光标上移n行
    nnHML0:光标移至当前行尾

    屏幕翻滚类命令

    Ctrl u:向文件首翻半屏
    Ctrl d:向文件尾翻半屏
    Ctrl f:向文件尾翻一屏
    Ctrl+b;向文件首翻一屏
    nz:将第n行滚至屏幕顶部,不指定n时将当前行滚至屏幕顶部.

    插入文本类命令

    i :在光标前
    I :在当前行首
    a:光标后
    A:在当前行尾
    o:在当前行之下新开一行
    O:在当前行之上新开一行
    r:替换当前字符
    R:替换当前字符及其后的字符,直至按ESC键
    s:从当前光标位置处开始,以输入的文本替代指定数目的字符

    保存命令

    按ESC键 跳到命令模式,然后:

    :w 保存文件但不退出vi
    :w file 将修改另外保存到file中,不退出vi
    :w! 强制保存,不推出vi
    :wq 保存文件并退出vi
    :wq! 强制保存文件,并退出vi
    :q 不保存文件,退出vi
    :q! 不保存文件,强制退出vi
    :e! 放弃所有修改,从上次保存文件开始再编辑

  3. 调用系统HTML Viewer打开文档

    Intent intent = new Intent(Intent.ACTION_VIEW);
    File f=new File("/storage/sdcard0/Vote/Admin_2013_01_02_15_16_01.txt");
    intent.setDataAndType(Uri.fromFile(f), "text/html");
    startActivity(intent);


20150907

  1. Source Insight

  2. 调用系统闹钟

    Intent intent = new Intent();
    intent.setAction("android.intent.action.SET_ALARM");
    startActivity(intent);

  3. 《Android第一行代码》

    10.2.1 使用HttpURLConnection

    • 在Android上发送HTTP请求的方方式一般有两种,HttpURLConnection和HttpClient

    1.获取HttpURLConnection实例:
    URL url = new URL("http://www.baidu.com");
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();

    2.设置HTTP请求所使用的方法:GET和POST
    connection.setRequestMethod("GET");

    3.自由定制
    connection.setConnectTimeout(8000);
    connection.setReadTimeout(8000);

    4.获取服务器返回的输入流
    InputStream in = connection.getInputStream();

    5.关闭HTTP连接
    connection.disconnect();

    10.2.2 使用Httpclient

    • HttpClient是Apache提供的HTTP网网络访问接口。

    1.创建一个DefaultHttpClient的实例
    HttpClient httpClient = new DefaultHttpClient();

    2.发起一条GET请求
    HttpGet httpGet = new HttpGet("http://www.baidu.com");
    httpClient.execute(httpGet);

    3.Or 发起一条POST请求
    HttpPost httpPost = new HttpPost("http://www.baidu.com");
    List params = new ArrayList();
    params.add(new BasicNameValuePair("username", "admin"));
    params.add(new BasicNameValuePair("password", "123456"));
    UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, "utf-8");
    httpPost.setEntity(entity);
    httpClient.execute(httpPost);

    4.取出服务返回的具体内容
    if (httpResponse.getStatusLine().getStatusCode() == 200) {
    // 请求和响应都成功了
    HttpEntity entity = httpResponse.getEntity();
    String response = EntityUtils.toString(entity, "utf-8");
    parseJSONWithGSON(response);
    }

  4. 寻找类快捷键Ctrl+Shift+T

  5. ViewFlipper:屏幕切换

  6. Serializable

    • 作用:类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。可序列化类的所有子类型本身都是可序列化的。序列化接口没有方法或字段,仅用于标识可序列化的语义。
    • 实现了此接口的类有:String, Integer, Boolean, Long, ArrayList, List, File 等等。
    • 当java内存有一个对象的时候,我们想把它持久化保存起来,以后又可以从保存的数据中恢复成对象,这种情况经常在java中出现;sun公司为了方便实现这种功能,为用户提供了java.io.Serializable这个接口,这个接口中没有方法(又称为mini接口);

    • 将对象保存到输出流中
      Student stu = new Student(981036, "LiuMing", 18, "CSD");

      FileOutputStream fo = new FileOutputStream("data.ser");

      ObjectOutputStream so = new ObjectOutputStream(fo);

      try {

      so.writeObject(stu);     
      
      so.close();     
      

      } catch (IOException e) {
      System.out.println(e);
      }

    • 读取一个对象
      FileInputStream fi = new FileInputStream("data.ser");

      ObjectInputStream si = new ObjectInputStream(fi);

      try {

      stu = (Student) si.readObject();     
      
      si.close();     
      

      } catch (IOException e)

      {
      System.out.println(e);
      }

7.自定义View必须要重写三个构造函数:

  1. public MyView(Context context) {
  2. super(context);
  3. // TODO Auto-generated constructor stub
  4. }
  5. public MyView(Context context, AttributeSet attrs) {
  6. super(context);
  7. }
  8. public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
  9. super(context);
  10. }

20150908

  1. android sd卡路径正确获取 双sd卡获取(见Pinoy中的SDCardScanner类)

    • 5030和5420不插SD卡时,手机内存显示为sdcard0。当插上SD卡时,SD卡显示为sdcard0,手机内存显示为sdcard1。

20150909

  1. 为了提高Pinoy中listview加载速度:
  1. public View getView(int position, View convertView, ViewGroup parent) {
  2. // TODO Auto-generated method stub
  3. ViewHolder viewHolder;
  4. if(convertView == null){
  5. convertView = LayoutInflater.from(myContext).inflate(resourceId, null);
  6. viewHolder = new ViewHolder();
  7. viewHolder.name = (TextView)convertView.findViewById(R.id.tvTitleItem);
  8. viewHolder.image = (ImageView)convertView.findViewById(R.id.ivIconItem);
  9. viewHolder.pos = position;
  10. convertView.setTag(viewHolder);
  11. }else
  12. {
  13. viewHolder = (ViewHolder) convertView.getTag();
  14. }
  15. textTile = listViewItems.get(position).get("text").toString();
  16. textColor = listViewItems.get(position).get("textColor").toString();
  17. viewHolder.name.setText(textTile);
  18. viewHolder.name.setTextColor(myContext.getResources().getColor(Integer.parseInt(textColor)));
  19. new DownloadAsyncTask().execute(viewHolder);
  20. // viewHolder.image.setImageResource(Integer.parseInt(listViewItems.get(position).get("img").toString()));
  21. return convertView;
  22. }
  23. private static class ViewHolder{
  24. public TextView name;
  25. public ImageView image;
  26. public int pos;
  27. }
  28. @Override
  29. public int getCount() {
  30. // TODO Auto-generated method stub
  31. return listViewItems.size();
  32. }
  33. @Override
  34. public Object getItem(int position) {
  35. // TODO Auto-generated method stub
  36. return listViewItems.get(position);
  37. }
  38. @Override
  39. public long getItemId(int position) {
  40. // TODO Auto-generated method stub
  41. return position;
  42. }
  43. private class DownloadAsyncTask extends AsyncTask<ViewHolder, Void, ViewHolder> {
  44. @Override
  45. protected ViewHolder doInBackground(ViewHolder... params) {
  46. // TODO Auto-generated method stub
  47. //load image directly
  48. ViewHolder viewHolder = params[0];
  49. return viewHolder;
  50. }
  51. @Override
  52. protected void onPostExecute(ViewHolder result) {
  53. // TODO Auto-generated method stub
  54. int position = result.pos;
  55. result.image.setImageResource(Integer.parseInt(listViewItems.get(position).get("img").toString()));
  56. }
  57. }
* 不过最后发现,加载速度慢的主要原因是图片加载错了,换成小尺寸的即可。
  1. android:label:静态修改title

    • activity和application里都可以设置android:label标签,activity的优先级高于application,也就是说两者都设置这个标签的话,activity的值覆盖application

    application里设置了此标签,其他activity没有设置的情况下,应用程序名在桌面上的名字和所有activity的title是这个设置的标签

    application里设置了此标签,主activity中也设置了此标签,则应用程序名和主activity的title都是主activity中设置的标签,其他非主activity的title如果没有自己设置此标签,还是使用application中设置的标签,如果其他非主activity也设置了此标签,则其title就是自己设置的这个标签

  2. getActionBar().setTitle();动态修改title

  3. Notification.FLAG_ONGOING_EVENT标志位可以让Notification成为持续或正在进行的Notification(即非一闪而过)。
    Notification.FLAG_NO_CLEAR标志位可以让Notification常驻任务栏;

    • Intent.FLAG_ACTIVITY_NEW_TASK:当Intent对象包含这个标记时,系统会寻找或创建一个新的task来放置目标Activity,寻找时依据目标Activity的taskAffinity属性进行匹配,如果找到一个task的taskAffinity与之相同,就将目标Activity压入此task中,如果查找无果,则创建一个新的task,并将该task的taskAffinity设置为目标Activity的taskActivity,将目标Activity放置于此task。注意,如果同一个应用中Activity的taskAffinity都使用默认值或都设置相同值时,应用内的Activity之间的跳转使用这个标记是没有意义的,因为当前应用task就是目标Activity最好的宿主。见:http://blog.csdn.net/liuhe688/article/details/6761337

    • FLAG_ACTIVITY_SINGLE_TOP:当task中存在目标Activity实例并且位于栈的顶端时,不再创建一个新的,直接利用这个实例。

  4. Activity

    6.1 Activity一共有以下四种launchMode:

    1.standard:跳转时系统都会在task中生成一个新的FirstActivity实例,并且放于栈结构的顶部.
    
    2.singleTop:跳转时系统会先在栈结构中寻找是否有一个FirstActivity实例正位于栈顶,如果有则不再生成新的,而是直接使用。
    
    3.singleTask:如果发现有对应的Activity实例,则使此Activity实例之上的其他Activity实例统统出栈,使此Activity实例成为栈顶对象,显示到幕前。
    
    4.singleInstance:(最为复杂)
    
  5. release version要修改android:versionName

  6. android setLayoutparams

    • 问题:在用ivTop.setLayoutParams(new RelativeLayout.LayoutParams())修改控件的大小后,发现控件属性不再受XML文件影响。

    • “Set the layout parameters associated with this view. These supply parameters to the parent of this view specifying how it should be arranged. There are many subclasses of
      ViewGroup.LayoutParams, and these correspond to the different subclasses of ViewGroup that are responsible for arranging their children.

* 实例:
RelativeLayout.LayoutParams layoutParams= new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);

layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);

view.setLayoutParams(layoutParams);

20150910

  1. menu

    • option menu图标为正方形时,显示正常。长方形图片会缩小。

    • the sizes of menu icons are:

      1. ldpi:36*36
      2. mdpi:48*48
      3. hdpi:72*72
      4. xhdpi:96*96
      5. xxhdpi:144*144
    • logo图尺寸为77*190,屏幕为hdpi,所以缩小了。

  2. Didn't find class "com.tinno.pinoy.MainActivity" on path: DexPathList错误

    • 删掉工程中support-v4
  3. 下载git repo代码

    3.1 mkdir

    3.2 repo init -u git@192.168.10.207:mt6753/platform/manifest.git -b sw -m ALPS.L1.MP3.V2.21_TINNO6753_65C_G_KERNEL_SW1_V1.1.xml

    3.3 repo sync

  4. SQLiteOpenHelper的使用方法

    • 所有继承了这个类的类都必须实现下面这样的一个构造方法:
      public DatabaseHelper(Context context, String name, CursorFactory factory, int version)
      第一个参数:Context类型,上下文对象。
      第二个参数:String类型,数据库的名称
      第三个参数:CursorFactory类型
      第四个参数:int类型,数据库版本

    • SQLiteDatabase的常用方法

    openOrCreateDatabase(String path,SQLiteDatabase.CursorFactory factory)

    打开或创建数据库

    insert(String table,String nullColumnHack,ContentValues values)

    添加一条记录

    delete(String table,String whereClause,String[] whereArgs)

    删除一条记录

    query(String table,String[] columns,String selection,String[] selectionArgs,String groupBy,String having,String orderBy)

    查询一条记录

    update(String table,ContentValues values,String whereClause,String[] whereArgs)

    修改记录

    execSQL(String sql)

    执行一条SQL语句

    close()

    关闭数据库


20150911

  1. 切换java版本

    • ~/l5460/baseline$ ./mbldenv.sh
  2. 下载网络图像
    private static Bitmap getBitmapFromUrl(String urlString) {
    Bitmap bitmap;
    InputStream is = null;
    try {
    URL url = new URL(urlString);
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    is = new BufferedInputStream(conn.getInputStream());
    bitmap = BitmapFactory.decodeStream(is);
    conn.disconnect();
    return bitmap;
    } catch (Exception e) {
    e.printStackTrace();
    } finally {
    try {
    if (is != null)
    is.close();
    } catch (IOException e) {
    }
    }
    return null;
    }

  3. 《android群英传》http://blog.csdn.net/column/details/synctask.html

    3.1 Android异步加载全解析之开篇瞎扯淡

    3.2 Android异步加载全解析之使用多线程

    3.3 Android异步加载全解析之使用AsyncTask

    3.4 Android异步加载全解析之大图处理

    3.5 Android异步加载全解析之引入一级缓存

    3.6 Android异步加载全解析之引入二级缓存

    3.7 Android异步加载全解析之IntentService

    3.8 Android异步加载全解析之Bitmap

  4. touch命令:创建文件

    • touch read.txt
  5. remote repository
    ■git clone

    $ git clone http[s]://example.com/path/to/repo.git/
    		$ git clone ssh://example.com/path/to/repo.git/
    $ git clone git://example.com/path/to/repo.git/
    		$ git clone /opt/git/project.git 
    $ git clone file:///opt/git/project.git
    		$ git clone ftp[s]://example.com/path/to/repo.git/
    $ git clone rsync://example.com/path/to/repo.git/
    

    ■git remote

    1. git remote:命令列出所有远程主机。
    
    2. git remote -v:查看远程主机网址
    
    3. git clone -o jQuery https://github.com/jquery/jquery.git:将远程主机命名为jQuery
    
    4. git remote show <主机名>:查看该主机的详细信息。
    
    5. git remote add <主机名> <网址>:添加远程主机。git remote add remoteRepo android@172.16.21.27:/home/android/remoteRepo
    
    6. git remote rm <主机名>:删除远程主机。
    
    7. git remote rename <原主机名> <新主机名>:远程主机的改名。
    

    ■git fetch:将远程主机更新取回本地

    1. git fetch <远程主机名>:将某个远程主机的更新,全部取回本地。
    
    2. git fetch <远程主机名> <分支名>:取回特定分支的更新。
    

    ■git pull:取回远程主机某个分支的更新,再与本地的指定分支合并。

    1. git pull <远程主机名> <远程分支名>:<本地分支名>
    
    2. git pull -p:在本地删除远程已经删除的分支。
    

    ■git push

    1. git push <远程主机名> <本地分支名>:<远程分支名>
    
    2. git push:如果当前分支只有一个追踪分支,那么主机名都可以省略。
    
    3. git push origin:将当前分支推送到origin主机的对应分支。
    
    • git clone ../remote-repository.git .
    • git push origin
  6. 获得包名和类名

    • getPackageName()
    • [MainActivity].class.getName();
  7. setComponent

    • 问题:系统MediaPlayerService中代码同时显示和隐式启动activity,为什么?

    ComponentName rec = new ComponentName(getPackageName(),
    MediaButtonIntentReceiver.class.getName());
    Intent i = new Intent(Intent.ACTION_MEDIA_BUTTON);
    i.setComponent(rec);

    • 用法一:

    ComponentName是用来打开其他应用程序中的Activity或服务的。

    Intent i=new Intent();
    i.setComponent(new ComponentName(String packageName,String activityName ));
    startActivity(i);
    用法二:

    Intent中可以直接使用Intent.setClass(),也可以使用组件Component

  8. HandlerThread

    • 介绍:HandlerThread继承自Thread,当线程开启时,也就是它run方法运行起来后,线程同时创建了一个含有消息队列的Looper,并对外提供自己这个Looper对象的get方法,这就是它和普通Thread唯一不同的地方。

    • 用法:
      1.开发中如果多次使用类似new Thread(){...}.start()这种方式开启一个子线程,会创建多个匿名线程,使得程序运行起来越来越慢,而HandlerThread自带Looper使他可以通过消息来多次重复使用当前线程,节省开支;

      2.android系统提供的Handler类内部的Looper默认绑定的是UI线程的消息队列,对于非UI线程又想使用消息机制,那么HandlerThread内部的Looper是最合适的,它不会干扰或阻塞UI线程。

    • 步骤:

      1. 创建一个HandlerThread,即创建了一个包含Looper的线程。

      HandlerThread handlerThread = new HandlerThread("leochin.com");

      handlerThread.start(); //创建HandlerThread后一定要记得start()

      1. 获取HandlerThread的Looper

      Looper looper = handlerThread.getLooper();

      1. 创建Handler,通过Looper初始化

      Handler handler = new Handler(looper);

    通过以上三步我们就成功创建HandlerThread。通过handler发送消息,就会在子线程中执行。如果想让HandlerThread退出,则需要调用handlerThread.quit();。


20150912

  1. 应用android自带颜色属性:@android:color/

  2. Your content must have a ListView whose id attribute is 'android.R.id.list'???

    • 原因:MyActivity extends ListActivity,而ListActivity中必须有一个ListView。
    • 解决:

      1. MyActivity exends Activity

      2. 在MyActivity的XML布局文件中,


20150914

  1. Android SQLite数据库判断某张表是否存在的语句

    1、可以在创建表之前判断,这样就不会重新创建,create table if not exists Student(name text primary key, code integer); 比平时多了if not exists

    2、

    Cursor cursor = db.rawQuery("select name from sqlite_master where type='table';", null);
    while(cursor.moveToNext()){
    //遍历出表名
    String name = cursor.getString(0);
    Log.i("System.out", name);
    }

    3、

    String sql = "select count(*) as c from sqlite_master where type ='table' and name ='Student';";
    cursor = db.rawQuery(sql, null);
    if(cursor.moveToNext()){
    int count = cursor.getInt(0);
    if(count>0){
    result = true;
    }
    }

    1. db = dbHelper.getReadableDatabase();

      Cursor c = db.query(Alarm.TABLE_NAME, null, null, null, null, null, null);

      Log.d(TAG, "c count: "+c.getCount());
      if(c.getCount()>0){
      return;
      }else{
      }


20150915

  1. ExpandableListView

  2. Android 之SparseArray:SparseArray是android里为这样的Hashmap而专门写的class,目的是提高效率,其核心是折半查找函数(binarySearch)

  3. AlarmManager.set()设置闹钟精确度

    • alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pIntent);
      alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pIntent);
      setExact方法要更精确。
  4. getApplicationContext():返回应用的上下文,生命周期是整个应用,应用摧毁它才摧毁

  5. OnClickListener

    • public class MainActivity extends Activity implements OnClickListener{}导入OnClickListener所在包名时应选import android.view.View.OnClickListener;
  6. 在一个Service中启动一个Acitivity:加上 FLAG_ACTIVITY_NEW_TASK

    • 代码:

      Intent dialogIntent = new Intent(getBaseContext(), YourActivity.class);
      dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
      getApplication().startActivity(dialogIntent);
      // 或者隐式启动

    • Error: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag.

    • 解决: dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);


20150916

  1. ubuntu输入法 没有输入窗口

  2. ActionBar custom

    ActionBar actionbar = getActionBar();
    actionbar.setBackgroundDrawable(getResources().getDrawable(R.color.main_background_color));
    actionbar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_CUSTOM );
    LayoutInflater inflater = LayoutInflater.from(getApplicationContext());
    ViewGroup view = (ViewGroup) inflater.inflate(R.layout.actionbar_main, null);
    actionbar.setCustomView(view);

  3. share action

    Intent intentShare = new Intent(android.intent.action.SEND);
    intentShare.setType("audio/*");
    startActivity(intentShare);

  4. 彩信/邮件分享

    • Intent intentShare = new Intent(SEND_ACTION);
      intentShare.setType("audio/*");
      intentShare.putExtra("sms_body", bundle.getString("title"));
      intentShare.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
      intentShare.putExtra(Intent.EXTRA_TEXT, bundle.getString("title"));
      intentShare.putExtra(Intent.EXTRA_SUBJECT, "Share Radio Record");
      startActivity(Intent.createChooser(intentShare, "My share item"));

20150917

  1. find

    • 使用格式 : find [指定查找目录] [查找规则] [查找完后执行的action]

    • find . -name "*.cpp" | xargs grep 'efg':在当前目录下所有.cpp文件中查找efg函数
      xargs展开find获得的结果,使其作为grep的参数

    • 1.使用name选项:

    想要在自己的根目录HOME.log使 pathname HOME目录。
    find ~ -name "*.log" -print

    想要在当前目录及子目录中查找所有的‘ *.log‘文件,可以用:

    find . -name "*.log" -print  
    

    不想要在当前目录及子目录中查找所有的‘ *.log‘文件,可以用:

    find . ! -name "*.log" -print
    

    想要的当前目录及子目录中查找文件名以一个大写字母开头的文件,可以用:

    find . -name "[A-Z]*" -print  
    

    想要在/etc目录中查找文件名以host开头的文件,可以用:

    find /etc -name "host*" -print  
    

    想要查找$HOME目录中的文件,可以用:

    find ~ -name "*" -print 或find . -print  
    

    要想让系统高负荷运行,就从根目录开始查找所有的文件。

    find / -name "*" -print  
    

    如果想在当前目录查找文件名以一个个小写字母开头,最后是4到9加上.log结束的文件:

    find . -name "[a-z]*[4-9].log" -print
    

    将文件路径作为一个整体进行匹配

    fine . -path "*tinno/pinoy"
    

    过淲掉所有.xml文件

    find . \( -name ".xml" -prune \)  -o -name "*Activity*"
    

    只在目录中递归搜索所有的.c和.cpp文件:

    $ grep "main()" . -r --include *.{c,cpp}
    

    在搜索中排除所有的README文件:

    $ grep "main()" . -r --exclude "README"
    

    使用-mindepth参数设置最小深度,使用-maxdepth参数设置最大深度:

    $ find . -maxdepth 1 -type f -print
    
    • 2.-a 连接两个不同的条件(两个条件必须同时满足)

    • 3.-o 连接两个不同的条件(两个条件满足其一即可)
      find . ( -name ".txt" -o -name ".pdf" ) -print

    • 4.根据文件类型来查找文件

          -type
      
                f     // 普通文件 
      
                d     //目录文件
      
                l     //链接文件
      
                b     //块设备文件
      
                c     //字符设备文件
      
                p     //管道文件
      
                s     //socket文件
      
    • 5.根据大小来查找文件

         -size
      

      #find /tmp -size 2M //查找在/tmp 目录下等于2M的文件

      #find /tmp -size +2M //查找在/tmp 目录下大于2M的文件

      #find /tmp -size -2M //查找在/tmp 目录下小于2M的文件

    • 6.xargs命令:应该紧跟在管道操作符之后。它以标准输入作为主要的源数据流。

    用-d选项为输入指定一个定制的定界符

    $ echo "split.split.split.split" | xargs -d . -n 2
    split split
    split split

  2. 查看IP:ifconfig

  3. 3.
  1. create Spinner(file:///home/android/Adt-eclipse/sdk/docs/guide/topics/ui/controls/spinner.html)
  2. 1. add Spinner in XML:
  3. <Spinner
  4. android:id="@+id/planets_spinner"
  5. android:layout_width="fill_parent"
  6. android:layout_height="wrap_content" />
  7. 2. define an string array in a string resource file:
  8. <?xml version="1.0" encoding="utf-8"?>
  9. <resources>
  10. <string-array name="planets_array">
  11. <item>Mercury</item>
  12. <item>Venus</item>
  13. <item>Earth</item>
  14. <item>Mars</item>
  15. <item>Jupiter</item>
  16. <item>Saturn</item>
  17. <item>Uranus</item>
  18. <item>Neptune</item>
  19. </string-array>
  20. </resources>
  21. 3. supply the spinner with the array using an instance of ArrayAdapter:
  22. Spinner spinner = (Spinner) findViewById(R.id.spinner);
  23. // Create an ArrayAdapter using the string array and a default spinner layout
  24. ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
  25. R.array.planets_array, android.R.layout.simple_spinner_item);
  26. // Specify the layout to use when the list of choices appears
  27. adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
  28. // Apply the adapter to the spinner
  29. spinner.setAdapter(adapter);
  30. 4. an implementation of the interface in an Activity:
  31. public class MainActivity extends Activity implements OnItemSelectedListener{
  32. private Spinner mSpinner;
  33. @Override
  34. protected void onCreate(Bundle savedInstanceState) {
  35. super.onCreate(savedInstanceState);
  36. setContentView(R.layout.activity_main);
  37. mSpinner = (Spinner)findViewById(R.id.spinner1);
  38. ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.planets_array, android.R.layout.simple_spinner_item);
  39. adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
  40. mSpinner.setAdapter(adapter);
  41. mSpinner.setOnItemSelectedListener(this);
  42. }
  43. @Override
  44. public void onItemSelected(AdapterView<?> parent, View view, int position,
  45. long id) {
  46. // TODO Auto-generated method stub
  47. Toast.makeText(getApplicationContext(), mSpinner.getItemAtPosition(position).toString(), Toast.LENGTH_LONG).show();
  48. }
  49. @Override
  50. public void onNothingSelected(AdapterView<?> parent) {
  51. // TODO Auto-generated method stub
  52. }
  53. }
  1. throws和throw的区别

    • throws使用在函数上,是方法可能抛出异常的声明,表示此方法不处理异常,而交给方法的调用处进行处理。。

      throw使用在函数内,是语句抛出一个异常。

  2. 好的编程习惯:

    1.在写程序时,对可能会出现异常的部分通常要用try{...}catch{...}去捕捉它并对它进行处理;

    2.用try{...}catch{...}捕捉了异常之后一定要对在catch{...}中对其进行处理,那怕是最简单的一句输出语句,或栈输入e.printStackTrace();

    3.如果是捕捉IO输入输出流中的异常,一定要在try{...}catch{...}后加finally{...}把输入输出流关闭;

    4.如果在函数体内用throw抛出了某种异常,最好要在函数名中加throws抛异常声明,然后交给调用它的上层函数进行处理。

  3. Gallery_5030 String to Type

    public static final int MEDIA_TYPE_IMAGE = 2;
    public static final int MEDIA_TYPE_VIDEO = 4;
    public static final int MEDIA_TYPE_ALL = MEDIA_TYPE_IMAGE | MEDIA_TYPE_VIDEO;

    public static final String MEDIA_TYPE_IMAGE_STRING = "image";
    public static final String MEDIA_TYPE_VIDEO_STRING = "video";
    public static final String MEDIA_TYPE_ALL_STRING = "all";

    public static int getTypeFromString(String s) {
    if (MEDIA_TYPE_ALL_STRING.equals(s)) return MediaObject.MEDIA_TYPE_ALL;
    if (MEDIA_TYPE_IMAGE_STRING.equals(s)) return MediaObject.MEDIA_TYPE_IMAGE;
    if (MEDIA_TYPE_VIDEO_STRING.equals(s)) return MediaObject.MEDIA_TYPE_VIDEO;
    throw new IllegalArgumentException(s);
    }

    public static String getTypeString(int type) {
    switch (type) {
    case MEDIA_TYPE_IMAGE: return MEDIA_TYPE_IMAGE_STRING;
    case MEDIA_TYPE_VIDEO: return MEDIA_TYPE_VIDEO_STRING;
    case MEDIA_TYPE_ALL: return MEDIA_TYPE_ALL_STRING;
    }
    throw new IllegalArgumentException();
    }

  4. android中的ellipsize

    • 在xml中

    android:ellipsize = "end"   省略号在结尾

    android:ellipsize = "start"   省略号在开头

    android:ellipsize = "middle" 省略号在中间

    android:ellipsize = "marquee" 跑马灯

    最好加一个约束android:singleline = "true"

    • 当然也可以用代码语句

    tv.setEllipsize(TextUtils.TruncateAt.valueOf("END"));

    tv.setEllipsize(TextUtils.TruncateAt.valueOf("START"));

    tv.setEllipsize(TextUtils.TruncateAt.valueOf("MIDDLE"));

    tv.setEllipsize(TextUtils.TruncateAt.valueOf("MARQUEE"));

    最好再加一个约束tv.setSingleLine(true);


20150918

  1. 自定义adb push脚本
  1. #!/bin/bash
  2. direc="$1" #$(pwd)
  3. OLDIFS=$IFS
  4. IFS=:
  5. # 以一个文件夹的框架在另一个目录下创建文件夹和空文件
  6. # chmod +x ./my_adb_push.sh #使脚本具有执行权限
  7. # ./my_adb_push.sh <local dir> <remote dir> #执行脚本
  8. # example: ./my_adb_push.sh ./local_dir ./storage/sdcard0/remote_dir
  9. for path in $( find $direc -type d -printf "%p$IFS")
  10. do
  11. echo adb shell mkdir -p "$2/${path:${#direc}+1}"
  12. adb shell mkdir -p "$2/${path:${#direc}+1}"
  13. #adb shell exit
  14. done
  15. IFS=$OLDIFS
  16. #cp -a "%%1" "%%2"
  17. adb push "$1" "$2"
  18. adb push "$1" "$2"
  1. cat 拼接数据
    cat f - g 先输出f 的内容,然后输出标准输入的内容,最后输出g 的内容。

20150921

  1. Android之TabHost布局

    1.概念
    盛放Tab的容器就是TabHost,包含TabWidget和FrameLayout两个部分,TabWidget是每个Tab的标签,FrameLayout是Tab内容。

      TabHost的实现有两种方式:
    
      第一种继承TabActivity,从TabActivity中用getTabHost()方法获取TabHost。各个Tab中的内容在布局文件中定义就行了。
    
    * 细节分析:
    
          1.主类继承TabActivity
    
          public class Pagination extends TabActivity
    
          2.获取当前TabHost对象
    
          TabHost tabHost = getTabHost();
    
          3.添加Tab分页标签
          tabHost.addTab(tabHost.newTabSpec("Tab1")        
    
          .setIndicator("Tab1", getResources().getDrawable(R.drawable.a1))   
          .setContent(this));  
    
      第二种方式,不继承TabActivity,在布局文件中定义TabHost即可,布局:
    
    1、TabHost    必须设置android:id为@android:id/tabhost
    2、TabWidget   必须设置android:id为@android:id/tabs
    3、FrameLayout   必须设置android:id为@android:id/tabcontent
    

    2.用法
    TabHost mTabHost = (TabHost) findViewById(android.R.id.tabhost);
    mTabHost.setup();
    mTabHost.addTab(TabSpec spec);

    3.使用Fragment实现tabhost效果(http://blog.csdn.net/u013412220/article/details/41241855)Project:fragmentdemo

  2. git reset版本前切记要备份

  3. Pinoy->Library:当文本过长时,每一行的首字没有对齐

    • 原因:布局文件属性错误
    • 解决:将android:gravity="center"删除
  4. 修改pinoy目录结构,将pinoy目录下的Pinoy和Prayer文件夹置于根目录下.

  5. android:visibility

    • Android中控件或者布局的可见性android:visibility有3中情况,如View.VISIBLE,View.UNVISIBLE,View.GONE这3中情况。

    View.VISIBLE很显然就是可见,View.UNVISIBLE是不是可见,但是在这种情况下它会占据空间。就是说如果控件的android:visibility

    设置为View.UNVISIBLE的话,虽然控件隐藏了,但是它还是占着画面中它布局的位置,这一点和C#中的意义不一样。而View.GONE则

    是指该控件的不可见,也不占用系统布局中的空间。

  6. android:splitMotionEvents:定义布局是否传递触摸事件(touch)到子布局,true表示传递给子布局,false表示不传递。

  7. Android PagerAdapter的用法

    • PageAdapter是一个抽象类,直接继承于Object,导入包android.support.v4.view.PagerAdapter即可使用。

    • 要使用PagerAdapter,首先要继承PagerAdapter类,然后至少覆盖以下方法instantiateItem(ViewGroup, int)
      /这个方法,return一个对象,这个对象表明了PagerAdapter适配器选择哪个对象放在当前的ViewPager中/
      destroyItem(ViewGroup, int, Object)/这个方法,是从ViewGroup中移出当前View/
      getCount() /这个方法,是获取当前窗体界面数/
      isViewFromObject(View, Object) /这个方法,在帮助文档中原文是could be implemented as return view == object,
      也就是用于判断是否由对象生成界面/

  8. Music_5030: TabHost+ViewPager


20150922

  1. 修改客户反馈BUG。主要有:
    1、播放音乐时通知栏图标显示不完整。
    将图片换成四周空白的图片
    2、音乐播放界面Back后,音乐停止。
    3、修改闹钟默认时间和格式
    4、将默认闹钟在开机启动应用时便写入数据库

  2. Android应用经典主界面框架:仿网易新闻客户端、CSDN 客户端 (Fragment ViewPager)(http://blog.csdn.net/xiaanming/article/details/10766053)

    • 以网易新闻、凤凰新闻以及新推出的新浪博客(阅读版)为代表,使用ViewPager+Fragment,即ViewPager里适配器里放的不是一般的View,而是Fragment。所以适配器不能继承PagerAdapter,而要继承FragmentPagerAdapter,这是在android.support.v4.app.FragmentPagerAdapter包里的。有点奇葩的是,FragmentPagerAdapter只在这个包里有,在android.app.这个包下面么有。到后面会发现,只能用android.support.v4.app.包下面的东西。两个包里的FragmentManager是不通用的,而且两个包里提供的Fragment也不大一样。如果继承android.app.*下的Fragment,则不能重新写构造函数,只能用默认的。v4的包里么有这个限制。
  3. 开源控件ViewPagerIndicator的使用

    • 第1步:import library项目
    • 第2步:导入library进我们自己新建的项目
      从Github(https://github.com/JakeWharton)(Project:ListSamples)上Download下来这个zip包之后,里面会有一个library文件,是库工程,还有一个sample,是作者提供的例子(将sample这个项目import,可以看到作者提供的各种样式的Indicator,作为参考)。如果要在作者例子的基础上自己开发样式,需要将library项目import进Eclipse(library是库工程,我们需要将其作为我们自己项目的依赖库)。然后创建一个新项目,新建的项目libs目录下面有android-support-v4.jar,这个必须删除,因为ViewPageIndicator里面有这个库,我们项目中不允许两个android-support-v4.jar,不删除我们的项目是不能编译的。右键项目—Properties—Android选项卡—Add—选择library库工程—OK,导入完毕。

20150923

  1. Fragment中获取数据

    • Bundle mBundle = getArguments();
  2. Android Theme(http://blog.csdn.net/dalancon/article/details/20359535)

    2.1 attrs.xml

    • attrs文件摘要
      attrs:这个文件里面放置自定义属性。android自带很多属性,比如我们布局的时候使用的layout_width,layout_height等等,android自带的attrs.xml文件在sdk/platforms/android-版本号/data/res/values/attrs.xml

    • attrs.xml文件格式:

      <declare-styleable name="TextAppearance">
      
      <attr name="android:fontFamily" format=”color”/>
      
      <attr name="android:textAllCaps" />
      
      <attr name="android:textColor" />
      

      每个attr代表一个属性,字段format表示这个属性代表的是哪一种资源

  3. state_pressed、state_focused、state_selected区别:

    pressed按下后还未松开,表示按下。再松开后当前控件获得了焦点,是focused,同时也有selected状态,表示选中。

    但是选中状态的控件是可以有很多个的,而focused的只有一个,即focused和selected的一个重要区别是,一个窗口只能有一个视图获得焦点focused,而一个窗口可以有很多个视图同时处于选中selected状态。

  4. 设置音乐音量为最大音量

    AudioManager mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
    int mVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC); // 获取当前音乐音量
    int maxVolume = mAudioManager
    .getStreamMaxVolume(AudioManager.STREAM_MUSIC);// 获取最大声音
    Toast.makeText(getApplicationContext(), "volume: "+mVolume+" max volume: "+maxVolume, Toast.LENGTH_LONG).show();
    mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, maxVolume, 0);

  5. android 使用MediaPlayer播放assets目录的音频文件

    播放应用的原始资源文件(assets)
    1) 通过Context.getAssets()方法获得AssetManager对象
    2) 通过AssetManager对象的openFd(String name)方法打开指定的原生资源文件夹,返回一个AssetFileDescriptor对象
    3) 通过AssetFileDescriptor的getFileDescriptor()得到一个FileDescriptor对象
    4) 通过public void setDataSource (FileDescriptor fd, long offset, long length)来创建MediaPlayer对象
    5) 调用MediaPlayer.prepare()方法准备音频
    6) 调用MediaPlayer的start()、pause()、stop()等方法控制

    AssetFileDescriptor fileDescriptor = this.getAssets()..openFd("a2.mp3");
    mediaPlayer = new MediaPlayer();
    mediaPlayer.setDataSource(fileDescriptor.getFileDescriptor(),
    fileDescriptor.getStartOffset(),
    fileDescriptor.getLength());
    mediaPlayer.prepare();
    mediaPlayer.start();

  6. mPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);//提示声音音量

  7. Android的对话框有两种:PopupWindow和AlertDialog。它们的不同点在于:(http://blog.csdn.net/tianjf0514/article/details/7570302#)Project:PopUpWindow
    AlertDialog的位置固定,而PopupWindow的位置可以随意
    AlertDialog是非阻塞线程的,而PopupWindow是阻塞线程的
    PopupWindow的位置按照有无偏移分,可以分为偏移和无偏移两种;按照参照物的不同,可以分为相对于某个控件(Anchor锚)和相对于父控件。具体如下
    showAsDropDown(View anchor):相对某个控件的位置(正左下方),无偏移
    showAsDropDown(View anchor, int xoff, int yoff):相对某个控件的位置,有偏移
    showAtLocation(View parent, int gravity, int x, int y):相对于父控件的位置(例如正中央Gravity.CENTER,下方Gravity.BOTTOM等),可以设置偏移或无偏移

  8. ButterKnife(http://jakewharton.github.io/butterknife/)

20150924

  1. 音乐分享增加Facebook

  2. Angelus下的闹钟时间应可以设置

  3. Music > Select song > Set as Ringtone > It should have an option for SIM 1 and SIM 2.

  4. 将闹钟列表用RadioGroup实现

    • @Override
      public void onCheckedChanged(RadioGroup group, int checkedId) {
      // TODO Auto-generated method stub
      if(mEnableRadioButton.getId()==checkedId){
      alarmModel.isEnabled = true;
      dbHelper.updateAlarm(alarmModel);
      AlarmManagerHelper.setAlarms(AlarmListActivity.this);
      }else if(mDisableRadioButton.getId()==checkedId){
      alarmModel.isEnabled = false;
      dbHelper.updateAlarm(alarmModel);
      AlarmManagerHelper.setAlarms(AlarmListActivity.this);
      }else{
      setAlarmTime();
      }

    }

    • switch (checkedId) {
      case mEnableRadioButton.getId():

      break;
      

      default:
      break;
      }
      采用switch来选择radioButton的Id,无法使用.getId()方法

  5. Android Studio import-summary

    * Ignored Files:

    The following files were not copied into the new Gradle project; you
    should evaluate whether these are still needed in your project and if
    so manually move them:

    • .AndroidManifest.xml.swp
    • .gitignore
    • proguard-project.txt

    * Moved Files:

    Android Gradle projects use a different directory structure than ADT
    Eclipse projects. Here's how the projects were restructured:

    • AndroidManifest.xml => app/src/main/AndroidManifest.xml
    • assets/ => app/src/main/assets/
    • res/ => app/src/main/res/
    • src/ => app/src/main/java/

20150925

  1. 修改闹铃界面的背景

20150928

  1. PINOY闹钟灭屏响起时,需要亮屏

    • android唤醒锁定屏幕:
      PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
      WakeLock mWakelock = pm.newWakeLock(PowerManager.ACQUIRE_CAUSES_WAKEUP |PowerManager.SCREEN_DIM_WAKE_LOCK, "SimpleTimer");
      mWakelock.acquire();

该方法的使用一定要伴随mWakelock.release();否则会报异常;
推荐使用方法:在唤醒屏幕显示的activity的onResume方法中唤醒,在onPause方法中release;

  1. 来电铃声响起 PINOY闹钟也响起,两个声音一块.

    • OnAudioFocusChangeListener
  2. ExifInterface.TAG_DATETIME

  3. Pinoy中图片显示顺序和系统图库显示顺序不一致

    • 系统图库根据图片日期来显示图片

    • public long getDateTime(String path) {
      try {
      ExifInterface exifInterface = new ExifInterface(path);
      String dateTimeString = exifInterface.getAttribute(ExifInterface.TAG_DATETIME);
      if (dateTimeString == null) return -1;

      ParsePosition pos = new ParsePosition(0);
      SimpleDateFormat sFormatter =  new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
      try {
          Date datetime = sFormatter.parse(dateTimeString, pos);
          if (datetime == null) return -1;
          return datetime.getTime();
      } catch (IllegalArgumentException ex) {
          Log.e(TAG, "getDateTime: IllegalArgumentException!", ex);
          return -1;
      }
      

      } catch (Exception e) {
      // TODO: handle exception
      e.printStackTrace();
      }
      return -1;
      }

  4. Android多媒体- ExifInterface读取图片相关信息

    • 图片的的Exif信息和MP3的ID3标签类似,使用了属性和值的存储方式。通过public void setAttribute (String tag, String value) 来设置,而获取可以通过 public int getAttributeInt (String tag, int defaultValue) 和 public String getAttribute (String tag) 两种方法都可以,getAttributeInt 重载方法一第二个参数为我们设置的默认值,如果成功则返回相应Tag的值;特定的整数内容为该方法直接返回值。而重载方法二该方法直接返回结果,如果失败则为null。
  5. Android Studio安装后Fetching android sdk component information超时的解决方案

    • Android Studio安装完成后,如果直接启动,Android Studio会去获取 android sdk 组件信息,这个过程相当慢,还经常加载失败,导致Android Studio启动不起开。解决办法就是不去获取android sdk 组件信息。

    • 解决方法:
      1)进入刚安装的Android Studio目录下的bin目录。找到idea.properties文件,用文本编辑器打开。

    2)在idea.properties文件末尾添加一行:disable.android.first.run=true,然后保存文件。

    3)关闭Android Studio后重新启动,便可进入界面。

  6. Android Studio常见错误之:Rendering Problems/The following classes could not be instantiated

    • 解决办法:
      打开es/values/目录下styles.xml文件。
      把:
      修改为:

20150929

  1. study Android_Universal_Image_Loader

  2. String数组转List,List转String数组

    • List 转换为 String数组

    List list = new ArrayList();
    list.add("a1");
    list.add("a2");
    String[] toBeStored = list.toArray(new String[list.size()]);
    for(String s : toBeStored) {
    System.out.println(s);
    }

    • String数组转List

    String[] arr = new String[] {"1", "2"};
    List list = Arrays.asList(arr);

  3. 使用Universal-Image-Loader框架不仅可以加载网络图片,还可以加载sd卡中的图片,Content provider等

    • //图片来源于Content provider
      String contentprividerUrl = "content://media/external/audio/albumart/13";

      //图片来源于assets
      String assetsUrl = Scheme.ASSETS.wrap("image.png");

      //图片来源于
      String drawableUrl = Scheme.DRAWABLE.wrap("R.drawable.image");

  4. AndroidStudio创建项目时一直处于building“project name”gradle project info的解决办法

    • 定位一下gradle的版本以及存放位置。

    查看gradle版本:查看目录C:\Users\用户名.gradle\wrapper\dists\gradle-1.XX-all

    存放位置:C:\Users\用户名.gradle\wrapper\dists\gradle-1.XX-all\3jdgemv0iv8uqohg3kcp2o88r1\gradle-1.XX-all.zip

    知道了版本,知道了位置,剩下的就是在网上下载离线包了,搜索gradle-1.XX-all.zip,我的版本为gradle-1.10-all下载完毕后直接把zip拷贝到C:\Users\用户名.gradle\wrapper\dists\gradle-1.XX-all\3jdgemv0iv8uqohg3kcp2o88r1\ 下即可。重启Android Studio后,打开项目即可。

  5. android studio如何导入android-support-v7-appcompat包

    • 第一步在module上右击,选择 open module settings

    • Dependencies

  6. gitHub/DynamicCardLayout

    • 类似win8贴片式显示图片,效果惊人。
  7. Android getMeasuredHeight()与getHeight()的区别

    • getMeasuredHeight()返回的是原始测量高度,与屏幕无关,getHeight()返回的是在屏幕上显示的高度。实际上在当屏幕可以包裹内容的时候,他们的值是相等的,只有当view超出屏幕后,才能看出他们的区别。当超出屏幕后,getMeasuredHeight()等于getHeight()加上屏幕之外没有显示的高度。

    • 1 mScrollView.getChildAt(0).getMeasuredHeight()表示:

      • ScrollView所占的高度.即ScrollView内容的高度.常常有一

      • 部分内容要滑动后才可见,这部分的高度也包含在了

      • mScrollView.getChildAt(0).getMeasuredHeight()中

      *
      2 view.getScrollY表示:

      • ScrollView顶端已经滑出去的高度

      *
      3 view.getHeight()表示:


      • ScrollView的可见高度

20150930

  1. Application context

    • 如想在整个应用中使用,在java中一般是使用静态变量,而在android中有个更优雅的方式是使用Application context。
    • 每个Activity 都是Context,其包含了其运行时的一些状态,android保证了其是single instance的。
    • 方法是创建一个属于你自己的android.app.Application的子类,然后在manifest中申明一下这个类,这是 android就为此建立一个全局可用的实例,你可以在其他任何地方使用Context.getApplicationContext()或Context.getApplication方法方法获取这个实例,进而获取其中的状态(变量)。

    • MyApplication mApplication = (MyApplication)getApplication();

  2. Activity context

    • 通常我们在各种类和方法间传递的是activity context
  3. Android中资源文件夹res/raw和assets的使用

*res/raw和assets的相同点:

1.两者目录下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制。

*res/raw和assets的不同点:
1.res/raw中的文件会被映射到R.java文件中,访问的时候直接使用资源ID即R.id.filename;assets文件夹下的文件不会被映射到R.java中,访问的时候需要AssetManager类。
2.res/raw不可以有目录结构,而assets则可以有目录结构,也就是assets目录下可以再建立文件夹

*读取文件资源:

1.读取res/raw下的文件资源,通过以下方式获取输入流来进行写操作

[java] view plaincopy
InputStream is = getResources().openRawResource(R.id.filename);  

2.读取assets下的文件资源,通过以下方式获取输入流来进行写操作

[java] view plaincopy
AssetManager am = null;  
am = getAssets();  
InputStream is = am.open("filename");  

20151007

  1. 修复菲律宾5460_V4客户反馈问题

    • #101 Alarm prayers should be ON by default.
  2. vi/vim使用进阶: 目录(http://blog.csdn.net/kingchan/article/details/6729800)

    • 输入命令: vimtutor 这是一个简单的入门教程
  3. 菲律宾5420_V5各自模块反馈

    • Pinoy > Wordstring > Personal Prayers > Change Choosen to Chosen

    • Pinoy > Prayer setting > Angelus > Morning, afternoon, and evening angelus, wordstring should be Angelus

    • Pinoy > Prayer setting should be enabled as default.

    • Pinoy > Intercession Prayers> Change the Holy Spirit to The Holy Spirit

    • Pinoy > my|country > Alam mo ba? > Change the wordstring from Gat. Jose Rizal to Rizal from Filipino Heros to Filipino Heroes.

    • Pinoy > my|country > Gat. Jose Rizal > Add space before the number, after the word Rizal.

    • Prayer setting> After the Prayer (Morning, Angelus, 3oclock Prayer, Evening Prayer) alarms it will alarm again. After the alarm played, it should stop not loop In playing.

    • Pinoy > Remove the Set as ringtone function when the use long press the pinoy file.

  4. 横竖屏切换不销毁activity

    • 在activity的属性中添加 android:configChanges="orientation|screenSize"

    • java代码的activity中加入配置信息改动的处理代码

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    // 检测屏幕的方向:纵向或横向
    if (this.getResources().getConfiguration().orientation
    == Configuration.ORIENTATION_LANDSCAPE) {
    //当前为横屏, 在此处添加额外的处理代码
    }
    else if (this.getResources().getConfiguration().orientation
    == Configuration.ORIENTATION_PORTRAIT) {
    //当前为竖屏, 在此处添加额外的处理代码
    }
    }

  5. gvim菜单乱码问题解决方法

    * Ubuntu 10.10 默认安装将会把中文区域设置为zh_CN.utf8,而GVim能识别的中文区域设置为zh_CN.UTF-8。因此GVim会在启动时报错,且 无法正常加载中文菜单。
    

    解决方案: Linux下编辑 ~/.vimrc,Windows下编辑安装目录下的_vimrc
    在前面加入一下代码:
    set langmenu=zh_CN.UTF-8 "设置菜单语言
    source VIMRUNTIME/delmenu.vim"sourceVIMRUNTIME/menu.vim "导入正常的菜单脚本
    language messages zh_CN.utf-8 "设置提示信息语言


20151008

  1. Android Studio 目录结构(http://ginsmile.github.io/blog/# 2015/05/23/how-to-import-opensource-project-and-solve-errors/#.VeSHPeEVi-u)

    • TestMe/build.gradle,全局gradle,在这个文件里的设置会在整个项目里通用。
      TestMe/app/build.gradle,模块的gradle,仅在app模块通用。
      TestMe/settings.gradle,用于指定哪个目录是模块model。里面的内容默认是include ':app',表示app这个文件夹是一个模块。

    • build.gradle文件第一行为:apply plugin: 'com.android.library',表示这是一个Library。

    • build.gradle文件第一行为:apply plugin: 'com.android.application',表示这是一个应用。

    • 根目录下的setting.gradle里面是include ':MaterialDesign', ':MaterialDesignDemo'。表示以上两个文件夹都是module。

  2. 重命名Project

    • 修改project目录下.project文件
  3. 如何在Android Studio项目中导入开源库?

  4. Android style中自定义属性


    • @color/colorPrimary
      @color/colorPrimaryDark
      @color/colorAccent
      @color/window_background
      @style/CardViewStyle.Light
      @color/colorAccent
      @android:color/black
      @color/window_background
      @color/state_selector_light
      @color/progressBackgroundColorLight
      @drawable/progress_drawable
      @drawable/progress_drawable_withbackground

    • 自定义的属性名是如何对应到相应的属性?


20151009

  1. Android library projects cannot be launched 问题解决方法

    • 方法: project->properties,展开android--Library,将勾选框去掉即可。
  2. eclipse DDMS always gives the error 'Can't bind to local 86XX for debugger' every time

    • 方法: If you are using Linux, I recommend you as well to run this command:

      fuser -k 8600/tcp

    With this command you will kill any process running at the 8600 TCP port (The one Android is using to debug).

  3. Error: Android开发~you need to use a theme.appcompat theme (or descendant) with this activity

    • 必須繼承 Theme.AppCompat 或屬於它的子元素,這是因為必須保持相容性。
  4. AppCompatActivity cannot be resolved to a type?

    • ActionBarActivity已被AppCompatActivity取代。导入的android-support-v7-appcompat包中必须包含AppCompatActivity.class

20151014

  1. No such property: nexusUsername for class: org.gradle.api.publication.maven.internal.ant.DefaultGroo

    • 删掉build.gradle里面的apply from:xxx一行就ok。

20151015

  1. 关机闹钟

    • 系统闹钟有关机闹钟的功能

    • mobile log tools: ##84666364##

    • catch log information:

      D/PowerOffAlarmManager( 876): LAUNCH_PWROFF_ALARM: android.intent.action.LAUNCH_POWEROFF_ALARM
      D/PowerOffAlarmManager( 876): handleMessage enter msg name=ALARM_BOOT
      D/PowerOffAlarmManager( 876): handleAlarmBoot
      D/PowerOffAlarmManager( 876): maybeShowAlarmView start to showLocked
      D/PowerOffAlarmManager( 876): handleMessage exit msg name=ALARM_BOOT
      D/PowerOffAlarmManager( 876): sendRemoveIPOWinBroadcast ...
      D/PowerOffAlarmManager( 876): NORMAL_BOOT_ACTION: android.intent.action.normal.boot
      D/PowerOffAlarmManager( 876): handleMessage enter msg name=RESHOW_KEYGUARD_LOCK
      D/PowerOffAlarmManager( 876): handleMessage exit msg name=RESHOW_KEYGUARD_LOCK

    • PowerOffAlarmManager.java

    • PowerOffAlarm.java

    • key log: D/AlarmManager( 747): set alarm to RTC 11932058

      -------> AlarmManagerService--setLocked

  2. Pinoy version

    • the version of Pinoy.apk should name after platform version and add date, e.g. 1.151015

    • when client feed back bugs about APP, first check the app version to ensure synchronization.

  3. Android源码分析-Alarm机制与Binder的交互(http://blog.csdn.net/singwhatiwanna/article/details/18448997#)

    3.1 什么是Alarm?

    • Alarm是android提供的用于完成闹钟式定时任务的类,系统通过AlarmManager来管理所有的Alarm,Alarm支持一次性定时任务和循环定时任务。

    • example:

      AlarmManager alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
      Intent intent = new Intent(getApplicationContext(), TestActivity.class);
      PendingIntent pendIntent = PendingIntent.getActivity(getApplicationContext(),
      0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
      //5秒后发送广播,只发送一次
      int triggerAtTime = SystemClock.elapsedRealtime() + 5 * 1000;
      alarmMgr.set(AlarmManager.RTC_WAKEUP, triggerAtTime, pendIntent);

    3.2 Alarm和Timer以及Handler在定时任务上的区别

    • 相同点:
      三者都可以完成定时任务,都支持一次性定时和循环定时(注:Handler可以间接支持循环定时任务)

    • 不同点:
      Handler和Timer在定时上是类似的,二者在系统休眠的情况下无法正常工作,定时任务不会按时触发。Alarm在系统休眠的情况下可以正常工作,并且还可以决定是否唤醒系统,同时Alarm在自身不启动的情况下仍能正常收到定时任务提醒,但是当系统重启或者应用被杀死的情况下,Alarm定时任务会被取消。另外,从Android4.4开始,Alarm事件默认采用非精准方式,即定时任务可能会有小范围的提前或延后,当然我们可以强制采用精准方式,而在此之前,Alarm事件都是精准方式。

    3.3 Alarm与Binder的交互

    private void setImpl(int type, long triggerAtMillis, long windowMillis, long intervalMillis,
    PendingIntent operation, WorkSource workSource) {
    if (triggerAtMillis < 0) {
    /* NOTYET
    if (mAlwaysExact) {
    // Fatal error for KLP+ apps to use negative trigger times
    throw new IllegalArgumentException("Invalid alarm trigger time "
    + triggerAtMillis);
    }
    */
    triggerAtMillis = 0;
    }

    try {
        //定时任务实际上都有mService来完成,也就是说AlarmManager只是一个空壳
        //从下面的构造方法可以看出,这个mService是IAlarmManager类型的,而IAlarmManager是一个接口
        //如果大家了解AIDL就应该知道IAlarmManager应该是一个AIDL接口
        mService.set(type, triggerAtMillis, windowMillis, intervalMillis, operation,
                workSource);
    } catch (RemoteException ex) {
    }
    

    }


20151016

  1. AIDL(Android Interface Definition Language)

    • AIDL (Android Interface Definition Language) 是一种IDL 语言,用于生成可以在Android设备上两个进程之间进行进程间通信(interprocess communication, IPC)的代码。如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参数。
      AIDL IPC机制是面向接口的,像COM或Corba一样,但是更加轻量级。它是使用代理类在客户端和实现端传递数据。

    • 选择AIDL的使用场合
      官方文档特别提醒我们何时使用AIDL是必要的:只有你允许客户端从不同的应用程序为了进程间的通信而去访问你的service,以及想在你的service处理多线程。如果不需要进行不同应用程序间的并发通信(IPC),you should create your interface by implementing a Binder;或者你想进行IPC,但不需要处理多线程的,则implement your interface using a Messenger。无论如何,在使用AIDL前,必须要理解如何绑定service——bindService。如何绑定服务,请参考我的另一篇文章:http://blog.csdn.net/singwhatiwanna/article/details/9058143

    • 远程服务的创建和调用需要使用AIDL语言,一般分为以下几个过程

      1.使用AIDL语言定义远程服务的接口
      2.通过继承Service类实现远程服务

      * IMathService.aidl是对远程服务接口的定义,自动生成的IMathService.java内部实现了远程服务数据传递的相关方法
      * 实现远程服务需要建立一个继承android.app.Service的类,并在该类中通过onBind()方法返回IBinder对象,调用者使用返回的IBinder对象访问远程服务
      

      IBinder对象的建立通过使用IMathService.java内部的Stub类实现,并逐一实现在IMathService.aidl接口文件定义的函数。

      3.绑定和使用远程服务

  2. 在什么情况下使用 startService 或 bindService 或 同时使用startService 和 bindService

    • 如果你只是想要启动一个后台服务长期进行某项任务那么使用 startService 便可以了。如果你想要与正在运行的 Service 取得联系,那么有两种方法,一种是使用 broadcast ,另外是使用 bindService ,前者的缺点是如果交流较为频繁,容易造成性能上的问题,并且 BroadcastReceiver 本身执行代码的时间是很短的(也许执行到一半,后面的代码便不会执行),而后者则没有这些问题,因此我们肯定选择使用 bindService.
  3. 在 AndroidManifest.xml 里 Service 元素的常见选项

    android:name  -------------  服务类名

    android:label  --------------  服务的名字,如果此项不设置,那么默认显示的服务名则为类名

    android:icon  --------------  服务的图标

    android:permission  -------  申明此服务的权限,这意味着只有提供了该权限的应用才能控制或连接此服务

    android:process  ----------  表示该服务是否运行在另外一个进程,如果设置了此项,那么将会在包名后面加上这段字符串表示另一进程的名字

    android:enabled  ----------  如果此项设置为 true,那么 Service 将会默认被系统启动,不设置默认此项为 false

    android:exported  ---------  表示该服务是否能够被其他应用程序所控制或连接,不设置默认此项为 false

  4. when Pinoy alarm is ringing, display "AUDIOFOCUS_LOSS_RANSIENT" after open the video interface.

  5. Android基础概念Context的作用(http://bbs.csdn.net/topics/360043738)


20151017

  1. 如何解决Android 5.0中出现的警告:Service Intent must be explicit

    • Intent mIntent = new Intent();
      mIntent.setAction("XXX.XXX.XXX");//你定义的service的action
      mIntent.setPackage(getPackageName());//这里你需要设置你应用的包名
      context.startService(mIntent);

20151019

  1. Remote Service(RemoteMathCallerDemo) error:

    • API 21: Unable to start service Intent { act=edu.hrbeu.RemoteMathServiceDemo.MathService pkg=edu.hrbeu.RemoteMathCallerDemoActivity } U=0: not found
      Service Intent must be explicit: Intent { act=edu.hrbeu.RemoteMathServiceDemo.MathService }

    • Android 5.0一出来后,其中有个特性就是Service Intent must be explitict. So change API from 21 to 19, the demo is work well. But how could we realize the remote service demo on API 21?

  2. Pinoy->MyCountry->Alammoba->History: the item icon is wrong.

  3. Parcelable对象

    • 在Android系统中,进程间传递的数据包括:
      • Java语言支持的基本数据类型
      • 用户自定义的数据类型
        为了使数据能够穿越进程边界,所有数据都必须是“可打包”的
        对于Java语言的基本数据类型,打包过程是自动完成的
        但对于自定义的数据类型,用户则需要实现Parcelable接口,使自定义的数据类型能够转换为系统级原语保存在Parcel对象中,穿越进程边界后可再转换为初始格式
  4. Looper(http://blog.csdn.net/thanksgining/article/details/43152555)

    • Looper通常是运行在一个消息的循环队列中的这个线程中,线程默认不会提供一个循环的消息去关联它们,即在一般的线程中是没有一个消息队列去关联这个消息的。那么如果线程想管理这些消息,就必须在此线程中调用Looper.prepare()使这个消息队列运行起来,并且调用Looper.loop()这个方法使它消息队列一直运行到停止。而Handler就是消息队列一个交互消息,包括从将消息发到消息队列,以及从消息队列取出消息并处理。

    • UI线程默认有个Looper对象,在Activity有一个默认的Looper的对象,来处理子线程中发送的消息。如果在一般的子线程中是不能创建handler对象的,因为自身没有带Looper对象,而主线程中是自带有这个对象的,从主线程拿出这个对象的;所以Andriod为了方便,不要开发者自己创建消息循环,所以提供了令外一个类HandlerThread。

    • Message:消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一队列,终由Handler处理
      Handler:处理者,负责Message的发送及处理。使用Handler时,需要实现handleMessage(Message msg)方法来对特定的Message进行处理,例如更新UI等
      MessageQueue:消息队列,用来存放Handler发送过来的消息,并按照FIFO规则执行。当然,存放Message并非实际意义的保存,而是将Message以链表的方式串联起来的,等待Looper的抽取
      Looper:消息泵,不断地从MessageQueue中抽取Message执行。因此,一个MessageQueue需要一个Looper,针对接收Message消息线程
      Thread:线程,负责调度整个消息循环,即消息循环的执行场所

  5. HandlerThread(http://blog.csdn.net/alex0203/article/details/7671492)

    • HandlerThread继承Thread,当线程开启时,也就是它run方法运行起来后,线程同时创建了一个含有消息队列的Looper,并对外提供自己这个Looper对象的get方法,这就是它和普通Thread唯一不同的地方。

    • HandlerThread继承与Thread,所以本身就是一个线程。他类似于创建了一个含有Looper对象的线程类,而Looper可以用于创建Handler类,这样我们就不用自己实例化Looper对象,调用preare和Loop了,而是直接调用HandlerThread。与普通的Thread相比,就是多了Looper对象。

    • 为什么要使用HandlerThread
      1、开发中如果多次使用类似new Thread(){}.start(); 这种方式开启一个子线程,会创建多个匿名线程,使得程序运行越来越慢,而HandlerThread自带Looper使他可以通过消息来多次重复使用当前线程,节省开支
      2、android系统提供的Handler类内部的Looper默认绑定的是UI线程的消息队列,对于非UI线程又想使得消息机制,那么HandlerThread内部的Looper是最合适的,它不会干扰或阻塞UI线程

    • 用法:
      1、HandlerThread继承Thread,与Thread不同就是提供自己的Looper对象,不过需要先启动这个HandlerThread线程
      2、调用handlerThread.getLooper()来获取Looper对象,则不要调用Looper.prepare()和Looper.loop()方法


20151020

  1. Android中的回调Callback(http://blog.csdn.net/shulianghan/article/details/16887509)

    • 回调就是外部设置一个方法给一个对象, 这个对象可以执行外部设置的方法, 通常这个方法是定义在接口中的抽象方法, 外部设置的时候直接设置这个接口对象即可.

    例如给安卓添加按钮点击事件, 我们创建了OnClickListener接口 实现了其中的onClick方法, 在合适的时机(按钮被点击的时候) , 就会执行我们实现的onClick()方法. 这个方法就被回调了 .

    1. 如何定义一个回调

      a. 定义接口 : 在类中定义一个Interface, 并在接口中定义一个抽象方法;
      b. 接口对象 : 在类中定义一个该接口的成员变量;
      c. 设置对象 : 在类中定义一个公共的方法, 可以设置这个接口的对象, 调用该方法给接口对象成员变量赋值;
      d. 调用方法 : 在合适的位置调用接口对象中的方法;

  2. android LocalActivityManager

    • Helper class for managing multiple running embedded activities in the same process. This class is not normally used directly, but rather created for you as part of theActivityGroup implementation.

    • LocalActivityManager内部机制的核心在于,它使用了主线程对象mActivityThread来装载指定的Activity。注意,这里是装载,而不是启动.

    • LocalActivityManager类是管理activity的,然后通过startActivity(String id,Intent intent)这个方法获取Window获取当前Window对象,再然后调用getDecorView()方法获取当前activity对应的view.

    • 在oncreate,onresume,onpause方法中分别加入如下代码:

    oncreate()--------------mLocalActivityManager.dispatchCreate(savedInstanceState);

    onpause()--------------mLocalActivityManager.dispatchPause(false);

    onresume()--------------mLocalActivityManager.dispatchResume();

  3. TabActivity,LocalActivityManager,TabHost,TabWidget深度分析(http://blog.csdn.net/fzh0803/article/details/6559081)

    • TabAcitivity继承自AcitivtyGroup,AcitivityGroup的主要作用是创建一个LocalActivityManger,然后把activity的onCreate等事件传递给LocalActivity来处理,作用仅此而已,非常简单。

    • TabActivity真正重要的包括三部分,TabHost,TabWidget,LocalActivityManager.

    • TabHost主要是面向用户的接口,它的主要作用就是添加tab,用TabSpec来完成一个完整的tab的抽象(包括标签及其内容),一个string 类型的tag,这个tag用来标识一个tab,比如在退出程序时记录当前是哪个tab以便在再次进入的时候显示退出前显示的tab,它最重要的作用在于当用intent做为一个tab,即要把一个activity作为内容(content)嵌入(即embeded activity的概念)进去,成为一个tab的内容。

    • TabActivity真正存在的原因就是为了embeded activity,即把activity做为一个view加入到另一个actvity中,而又有LocalActivityManger来控制activity的生命周期所以不必操心生命周期问题。


20151021

  1. Android点九图(.9.png)的特点和制作

    • 点九图又称九图,是一种png格式的图片,其后缀为.9.png ,其与传统png图片不同的地方是,点九图的四周边缘各有1个像素宽高的区域,而且只能填两种颜色,透明(#00000000)和黑色(#FF000000),其目的是用于对该图片的扩展区域和内容显示区域进行定义。

    • 左侧和上侧作为扩展区域,右侧和下侧则是控制文字显示的区域。(左上拉伸区域)当需要上下拉伸的时候,就从左侧的黑色区域开始复制拉伸;当需要左右拉伸的时候,就从上侧的黑色区域开始拉伸。(右下文字显示区域)当想要在显示文字时,控制其与上下或左右边缘的距离,可以设置右侧或下侧的黑色区域,右侧的黑色区域控制文字上下位置,下侧控制文字的左右位置。

  2. android xml文件名字命名

    • 规则:File-based resource names must contain only lowercase a-z, 0-9, or _. 但源码目录下面许多xml文件名中都包含大写字母。
  3. Android中的Handler, Looper, MessageQueue和Thread

    • Android 系统的消息队列和消息循环都是针对具体线程的,一个线程可以存在(当然也可以不存在)一个消息队列和一个消息循环(Looper),特定线程的消息只能分发给本线程,不能进行跨线程,跨进程通讯。但是创建的工作线程默认是没有消息循环和消息队列的,如果想让该线程具有消息队列和消息循环,需要在线程中首先调用Looper.prepare()来创建消息队列,然后调用Looper.loop()进入消息循环

    • 职责

      • Message:消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一列队,终由Handler处理。

      • Handler:处理者,负责Message的发送及处理。使用Handler时,需要实现handleMessage(Message msg)方法来对特定的Message进行处理,例如更新UI等。

      • MessageQueue:消息队列,用来存放Handler发送过来的消息,并按照FIFO规则执行。当然,存放Message并非实际意义的保存,而是将Message以链表的方式串联起来的,等待Looper的抽取。

      • Looper:消息泵,不断地从MessageQueue中抽取Message执行。因此,一个MessageQueue需要一个Looper。

      • Thread:线程,负责调度整个消息循环,即消息循环的执行场所。

  4. android:label

    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="test1"
    android:theme="@style/AppTheme" >
    android:name=".MainActivity"
    android:label="test2" >

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    

    • test1: Displayed in App info

    • test2: Displayed in App name


20151022

  1. "重载","复写"

    区别 方法重载 方法复写
    英文单词 Overloading Override
    概念 方法名称相同,参数的个数或者类型不同 方法名称相同,参数的个数和类型相同,方法的访问权限不能更严格
    使用范围 发生在同一个类中 发生在继承关系中,是由子类进行复写

  2. 判断手机是否有装载好的SDcard

    • Music->MusicUtils>hasMountedSDcard

    • static boolean hasMountedSDcard(Context context) {
      StorageManager storageManager = (StorageManager) context.getSystemService(
      Context.STORAGE_SERVICE);
      boolean hasMountedSDcard = false;
      if (storageManager != null) {
      String[] volumePath = storageManager.getVolumePaths();
      if (volumePath != null) {
      String status = null;
      int length = volumePath.length;
      for (int i = 0; i < length; i++) {
      status = storageManager.getVolumeState(volumePath[i]);
      MusicLogUtils.d(TAG, "hasMountedSDcard: path = " + volumePath[i] + ",status = "
      + status);
      if (Environment.MEDIA_MOUNTED.equals(status)) {
      hasMountedSDcard = true;
      }
      }
      }
      }
      MusicLogUtils.d(TAG, "hasMountedSDcard = " + hasMountedSDcard);
      return hasMountedSDcard;
      }


20151023

  1. URI(Uniform Resource Identifier)

    • 就Android平台而言,URI主要分三个部分:scheme, authority and path。其中authority又分为host和port。格式如下:
      scheme://host:port/path
      举个实际的例子:
      content://com.example.project:200/folder/subfolder/etc
      ---------/ ---------------------------/ ---/ --------------------------/
      scheme host port path
      --------------------------------/
      authority
  2. DCC就是通过了内部测试,符合公司正式发放流程。我们把最后一版测试叫DCC测试。客户那边确认软件后就不再给客户发软件了,只走内部测试流程,发现问题内部继续改。

  3. Android中的Shape使用总结

    • solid:填充
      android:color指定填充的颜色

    *gradient:渐变
    android:startColor和android:endColor分别为起始和结束颜色,
    android:angle是渐变角度,必须为45的整数倍。
    另外渐变默认的模式为android:type="linear",即线性渐变,
    可以指定渐变为径向渐变,android:type="radial",径向渐变需要指定半径android:gradientRadius="50"。

    *stroke:描边
    android:width="2dp" 描边的宽度,android:color 描边的颜色。
    我们还可以把描边弄成虚线的形式,设置方式为:
    android:dashWidth="5dp"
    android:dashGap="3dp"
    其中android:dashWidth表示'-'这样一个横线的宽度,android:dashGap表示之间隔开的距离

    *corners:圆角
    android:radius为角的弧度,值越大角越圆。
    我们还可以把四个角设定成不同的角度,
    同时设置五个属性,则Radius属性无效

    android:Radius="20dp" 设置四个角的半径
    android:topLeftRadius="20dp" 设置左上角的半径
    android:topRightRadius="20dp" 设置右上角的半径
    android:bottomLeftRadius="20dp" 设置右下角的半径
    android:bottomRightRadius="20dp" 设置左下角的半径

    *padding:间隔
    可以设置上下左右四个方向的间隔

  4. 查看git config信息

    • /home/.gitconfi

20151024

  1. Pinoy多个相同闹钟问题:

    • 当多个闹钟设置相同的闹铃时间或前一个闹钟响铃时后一个闹钟被启动时,因为前一个闹铃Activity A未被销毁,所以当关闭后一个闹钟Activity B之后,会跳转到Activity A,不符合设计要求。

    • 原因(猜想):闹铃界面AlarmScreen运行在主线程,设置闹钟时间时,没有特意设定毫秒,所以闹钟时间的毫秒是系统“随机“设定(0-999)。当“同时”(间隔时间非常短,在几百毫秒之内,认为是同时)调用多个AlarmScreen时,会造成线程的阻塞。所以会造成某AlarmScreen没有启动,等前面的AlarmScreen被销毁后才被启动。

    解决方案一:Activity B启动后,Activity A的将失去音频焦点,从而停止闹铃,finish()。但多个相同闹钟同时闹铃里,Activity却未被销毁???

    解决方案二:将闹钟界面Activity的launchMode设为singleTop,这样就只会启动一个Activity。但如果是两个闹钟先后响起,即前一个闹钟还未响完,后一个闹钟也被启动,则后一个闹钟会失效。也不符合设计需求。

    可行解决方案:设置闹钟时间时,设置时间间隔为100毫秒(或更长),这样启动AlarmScreen就有一个时间差,就不会造成主线程阻塞。


20151026

  1. 获取当前线程ID:Thread.currentThread().getId()

  2. ActivityThread

  3. 写Pinoy总结,主要完成了大纲。

    • Pinoy项目在5420和5460平台上,客户均已确认。从8月20日至10月24日,历时两个月,修改了几十次。在UI和测试部门同事的支持配合以及导师和SPM的指导下,从零开始逐步开发Pinoy,才有了最终的Pinoy。通过全程参与Pinoy的开发过程,不仅让我熟悉了Android常用组件的使用,还学会了如何使用Activity、Service、BroadReceiver、SQLite。因为我们小组是负责Media和Message模块,所以在Pinoy的开发过程中,我对音乐播放器和闹钟模块也有了更进一步的认识。更为重要的是,我学会了如何去查看log,并学习源码解决问题的思路和方法。
  4. RemoteControlClient的使用(http://blog.csdn.net/liu149339750/article/details/31406701)

    • RemoteControlClient是从API 14也就是android 4.0开始出现的类,用于在锁屏状态控制音乐播放。界面是系统提供的。

    • api doc文档上附了一段注册代码

      ComponentName myEventReceiver = new ComponentName(getPackageName(), MyRemoteControlEventReceiver.class.getName());
      AudioManager myAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
      myAudioManager.registerMediaButtonEventReceiver(myEventReceiver);
      // build the PendingIntent for the remote control client
      Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
      mediaButtonIntent.setComponent(myEventReceiver);
      PendingIntent mediaPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, mediaButtonIntent, 0);
      // create and register the remote control client
      RemoteControlClient myRemoteControlClient = new RemoteControlClient(mediaPendingIntent);
      myAudioManager.registerRemoteControlClient(myRemoteControlClient);


20151027

1.1 RemoteViews(http://blog.csdn.net/tx16bing/article/details/41204287)
顾名思义,它是一个远程视图。App Widget中的视图,都是通过RemoteViews表现的。
在RemoteViews的构造函数中,通过传入layout文件的id来获取 “layout文件对应的视图(RemoteViews)”;然后,调用RemoteViews中的方法能对layout中的组件进行设置(例如,可以调用setTextViewText()来设置TextView组件的文本,可以调用setOnClickPendingIntent() 来设置Button的点击响应事件)。

因此,我们可以将 “RemoteViews 看作是 layout文件中所包含的全部视图的集合”。

1.2 RemoteViewsService
RemoteViewsService,是管理RemoteViews的服务。
一般,当App Widget 中包含“GridView、ListView、StackView等”集合视图时,才需要使用RemoteViewsService来进行更新、管理。(集合视图是指GridView、ListView、StackView等包含子元素的视图)
RemoteViewsService更新“集合视图”的一般步骤是:
(01) 通过setRemoteAdapter来设置 “RemoteViews对应RemoteViewsService”。
(02) 之后在RemoteViewsService中,实现RemoteViewsFactory接口。然后,在RemoteViewsFactory接口中对“集合视图”的各个子项进行设置(“集合视图”的各个子项:例如,GridView的每一个格子都是一个子项;ListView中的每一列也是一个子项)。

因此,我们可以将 “RemoteViewsService 看作是 管理layout中集合视图的服务”。

1.3 RemoteViewsFactory
通过RemoteViewsService中的介绍,我们可以了解“RemoteViewsService是通过RemoteViewsFactory来具体管理layout中集合视图的”,即“RemoteViewsFactory管理集合视图的实施者”。
RemoteViewsFactory是RemoteViewsService中的一个接口。RemoteViewsFactory提供了一系列的方法管理“集合视图”中的每一项。例如:
(01)RemoteViews getViewAt(int position)
通过getViewAt()来获取“集合视图”中的第position项的视图,视图是以RemoteViews的对象返回的。
(02)int getCount()
通过getCount()来获取“集合视图”中所有子项的总数。

因此,我们可以将 “RemoteViewsFactory 看作是 layout中集合视图管理的具体实施者”。
  1. ActivityManager.isUserAMonkey:用来判断用户是不是在胡乱使用手机,像猴子一样。

  2. 修改提交log信息
    git commit –amend 可以修改最后一次提交的信息。

    对于历史提交,必须使用rebase。
    git rebase –i HEAD~3
    表示要修改当前版本的倒数第三次状态。执行这个命令后,会显示:
    pick:
    pick:

    pick:*
    如果你要修改哪个,就将那行的pick改成edit,然后退出。然后再使用:
    git commit –amend来对commit进行修改。
    修改完成之后,使用git rebase –continue。


20151028

1. Pinoy项目总结->音乐播放->翻译Google SDK MediaPlayer State Diagram

2. android Objects wait notify

3. sleep和wait的区别有:

4. instanceof 关键字的使用

可以用 instanceof 判断一个类是否实现了某个接口,也可以用它来判断一个实
例对象是否属于一个类。instanceof 的语法格式为:
对象 instanceof 类(或接口)
它的返回值是布尔型的,或真(true)、或假(false)。

5. 获取Text Width

mTextWidth = (int) tv.getPaint().measureText(tv.getText().toString());


20151029

  • 学习Markdown。
    • 学习Markdown画流程图。
  • 写Pinoy项目总结。
    • 第3章 音乐播放。
  • 整理笔记,将dialy_review搬到Markdown
  • 使用vim模式编辑Markdown文档
  • 5030 Music源码。

1. Microsoft Office 2007 可用密钥

W2JJW-4KYDP-2YMKW-FX36H-QYVD8

2. 利用github存储图片,在markdown引用图片链接地址步骤如下:

1 将markdown需要用的图片放到git仓库中,发布到github上
2 访问github仓库,https://github.com/guhuizaifeiyang/MarkdownPicture.git
3 访问图片
4 点击Raw按钮
5 拷贝链接地址https://github.com/guhuizaifeiyang/MarkdownPicture.git
6 在Markdown中引用图片
guhui

3. vim替换命令

替換(substitute):[range]s/pattern/string/[c,e,g,i]5.1

range   指的是範圍,1,7 指從第一行至第七行,1,$ 指從第一行至最後一行,也就是整篇文章,也可以 % 代表。還記得嗎? % 是目前編輯的文章,# 是前一次編輯的文章。
pattern 就是要被替換掉的字串,可以用 regexp 來表示。
string  將 pattern 由 string 所取代。
c   confirm,每次替換前會詢問。
e   不顯示 error。
g   globe,不詢問,整行替換。
i   ignore 不分大小寫。
  1. 示例:
  2. :s/vivian/sky/ 替换当前行第一个 vivian sky
  3. :s/vivian/sky/g 替换当前行所有 vivian sky
  4. :n,$s/vivian/sky/ 替换第 n 行开始到最后一行中每一行的第一个 vivian sky
  5. :n,$s/vivian/sky/g 替换第 n 行开始到最后一行中每一行所有 vivian sky
  6. n 为数字,若 n .,表示从当前行开始到最后一行
  7. :%s/vivian/sky/(等同于 :g/vivian/s//sky/) 替换每一行的第一个 vivian 为 sky
  8. :%s/vivian/sky/g(等同于 :g/vivian/s//sky/g) 替换每一行中所有 vivian 为 sky
  9. 可以使用 # 作为分隔符,此时中间出现的 / 不会作为分隔符
  10. :s#vivian/#sky/# 替换当前行第一个 vivian/ 为 sky/
  11. :s/vivian/sky/g 替换当前行所有 vivian sky
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注