admin 管理员组

文章数量: 887021

转自: http://www.52rd/Blog/Detail_RD.Blog_jimbo_lee_30433.html

             http://www.52rd/Blog/Detail_RD.Blog_jimbo_lee_30865.html

编译代码步骤:
一.无源代码目录时
1.登录编译服务器
  进入命令行执行 ssh release@192.168.1.30
2.从GIT服务器上下载代码
  1). curl http://192.168.1.29/repo/repo >repo      //下载repo脚本
  2). chmod +x repo                                 //修改repo的权限  
  3). ./repo init -u http://192.168.1.29/repo/hct-mtk/6513-v1.37/manifests.git/     //初始化repo
  4). ./repo sync     //同步MASTER分支到本地
3.开启release分支
  ./repo start release --all
4. 下载release分支内容到本地
  ./repo download `./repo list | awk -F: '{print $1}'` -m
5. 拷贝项目分支到根目录  
  ./distribute.sh -p ****
6. 修改版本号码
   vi mediatek/config/hct13_gb/ProjectConfig.mk
   修改MTK_BUILD_VERNO = P90.r1
7. 开始编译
  /distribute.sh -mtk new
8.编译完成打包
   ./distribute.sh -b
9.拷贝编译好的包到制定目录
   mv *** ../Public/distribute
二.存在有源代码目录时
1、./distri.sbuteh -mtk clean            先清空编译过的中间代码
2、./repo forall -c git clean -d -f        清空未受管控代码
3、./repo forall -c git checkout -f      同步本地代码跟服务器完全相同(去除本地所有修改)
4、./repo status                查看本地代码
5、./repo list | sed 's/:.*//' | xargs ./repo download -m    列出所有受管控的代码库并merge下载
6、    ./repo start release dists/    设置到release目录
    ./repo download --br develop -m dists/    合入到realease 分支
7、./distribute.sh -p projectname    把项目相关的目录覆盖到根目录下
8、vi mediatek/config/hct13_gb/ProjectConfig.mk 编辑版本号
9、./distribute.sh -mtk -o=TARGET_BUILD_VARIANT=user new  编译版本

1.壁纸
/mediatek/source/frameworks/banyan/res/res/drawable/lockscreen_default_wallpaper.png 320X480 可以自动拉伸,slide lock screen 的默认壁纸
/frameworks/base/core/res/res/drawable/default_wallpaper.jpg  640X480 ,默认墙纸
/packages/apps/Launcher2/res/drawable-hdpi/wallpapers.xml   墙纸列表
/frameworks/base/core/res/res/values/config.xml <string name="default_wallpaper_component">@null</string> 修改为:<string name="default_wallpaper_component">动态墙纸包名/.动态墙纸类名</string>    , 动态墙纸

/packages/apps/Launcher2/res/xml/default_workspace.xml  预置桌面项目

/frameworks/base/media/java/android/media/AudioManager.java DEFAULT_STREAM_VOLUME  默认的音量和来电铃声
修改 build\target\product\下的 core.mk 文件,添加 ro.config.ringtone=对应铃声文件名 即可
/frameworks/base/data/sounds/Android.mk        铃声列表   
 
/frameworks/base/core/res/assets/images/android-logo-mask.png  开机logo
这个动画是由两个图片通过 openGL 叠加出来的,文件分别为:
/frameworks/base/core/res/assets/images/android-logo-mask.png
Android 默认的前景图片,文字部分镂空,大小 256×64
/frameworks/base/core/res/assets/images/android-logo-shine.png
Android 默认的背景图片,有动感效果,大小 512×64
只要把 android-logo-mask.png 替换成想要的 png 图片就可以了。

实现开机铃声:
可以在 BootAnimation.cpp 文件的 BootAnimation::android() 中实现
在这个函数的最开始部分加入
sp<MediaPlayer> mp = new MediaPlayer();
mp->setDataSource("/system/media/audio/notifications/TaDa.ogg", NULL);
mp->prepare();
mp->start();

这里的音乐文件路径可以自己更改(注意这时候 sdcard 还没有挂上来,不要用 sdcard 中的
音乐文件)。
然后在这个函数的结束再加上
mp->stop();
mp->disconnect();
mp->setListener(NULL);
mp = NULL;

更换开机铃声:
先将要设置为铃声的音乐文件更名为 bootanimation.mp3,注意需要为 mp3 文件方能生效。
将该文件放入工程的资源目录下 frameworks\base\data\sounds\newwavelabs,修改
Android.mk 文件,将该文件打到 data\local\路径下,添加如下语句:
$(LOCAL_PATH)/newwavelabs/bootanimation.mp3:data/local/bootanimation.mp3
再次 build 工程即可

恢复出厂设置过后,开机动画和开机铃声为设置后的,非 Google 默认的开机动画和铃声
将该文件放入工程的资源目录下,如 frameworks\base\data\sounds\newwavelabs,修
改 Android.mk 文件,将该文件打到 system\media\路径下,添加如下语句:
MediaTek Confidential
© 2007 MediaTek Inc.
The information contained in this document can be modified without notice
Page: 20 of 75
FAQ
$(LOCAL_PATH)/newwavelabs/bootanimation.mp3:system/media/bootanimation.mp3
再次 build 工程即可。

bootanimation.zip 的制作方法举例如下:
分别创建名为“part0”和“part1”的文件夹以及一个名为“desc.txt”文件。“part0”
中存储动画的第一阶段的资源图片,“part1”存储第二阶段的资源图片,注意图片为
png 格式。
播放控制由“desc.txt”指定,内容如下:
320 480 30
p 1 0 part0
p 0 0 part1
各参数功能如下:
320 480 30
宽 高 帧率(每秒播放多少帧图片)
p   1  0      part0
标志符 循环次数 阶段切换间隔时间 对应目录名
p           0              0                                part1
标志符 循环次数 阶段切换间隔时间 对应目录名
最后,将这三个组件通过存储压缩的方式压缩为 bootanimation.zip 文件即制作完成。


预制开机动画的过程如下:
将 制 作 完 成 的 bootanimation.zip 文 件 放 在 工 程 的 资 源 目 录 下 , 如
frameworks\base\data\sounds 目录下,修改 Android.mk 文件,通过以下语句将该压缩
包打到 system\medial\路径下:
$(LOCAL_PATH)/bootanimation.zip:system/media/bootanimation.zip
再次 build 工程即可。

举例:

480 320 15

p 2 30 folder0 //将folder0里的图片,播放2遍,播放完一遍后停顿30帧,因为我们之前设置了帧率是15帧每秒,那么这里就等于停顿2秒。
p 0 0 folder1 //将folder1里的图片无限循环播放,每次播放不停顿


如何获取当前的情景模式 和设置不同的情景模式?
 首 先 通 过 getSystemService(Context.AUDIO_SERVICE) 获 取 AudioManager 的 实 例 audioManager 。然后调用set/get方法
铃声和震动:
audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
audioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,
AudioManager.VIBRATE_SETTING_ON);
audioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION,
AudioManager.VIBRATE_SETTING_ON);
铃声:
audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
audioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,
AudioManager.VIBRATE_SETTING_OFF);
audioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION,
AudioManager.VIBRATE_SETTING_OFF);
Cen
震动:
audioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
audioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,
AudioManager.VIBRATE_SETTING_ON);
audioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION,
AudioManager.VIBRATE_SETTING_ON);
静音:
audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
audioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,
AudioManager.VIBRATE_SETTING_OFF);
audioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION,
AudioManager.VIBRATE_SETTING_OFF);

在一个Activity去除Statusbar和Titlebar
修改对应的 Activity,添加以下代码:
final Window win = getWindow();
win.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);//remove statusbar
requestWindowFeature(Window.FEATURE_NO_TITLE);
requestWindowFeature(Window.FEATURE_PROGRESS);//remove titlebar
注意:必须添加在 setContentView()方法之前,否则将提示错误。

如何拦截来电,即在电话 ring 之前就有机会检查来电号码?
packages\apps\Phone\src\com\android\phone\CallNotifier.java onNewRingingConnection
根据需要从Connection c = (Connection) r.result; 中来电连接中分析来电数据,从而判定是否要拦截。

何拦截短信? 即新短信来时,能否在提示给用户之前检查短信来源和内容。
可以在 SmsReceiverService.java 的 insertMessage 方法里拦截。短信的来源和内容都可以通过 class SmsMessage 提供的方法获取。
如可以通过 getOriginatingAddress 方法获取,内容则可以通过 getMessageBody 方法获取。如果满足拦截的条件,就不做 storeMessage 的动作。

修改默认时间:
\alps\mtk\src\custom\[project]\preloader\custom\custom\inc\cust_rtc.h
\alps\mtk\src\custom\[project]\kernel\rtc\rtc\rtc-mt6516.h
#define RTC_DEFAULT_YEA
#define RTC_DEFAULT_MTH
#define RTC_DEFAULT_DOM

1. 修改文件 alps\frameworks\base\packages\SettingsProvider\res\values\defaults.xml
增加代码<string name="time_12_24" translatable="false">24</string>
红色标记表示 24 小时制,也可以改为 12(12 小时制)
2. 修改文件
alps\frameworks\base\packages\SettingsProvider\src\com\android\providers\settings\Databas
eHelper.java
找到函数 loadSystemSettings (),在函数中增加以下语句:
loadStringSetting(stmt, Settings.System.TIME_12_24, R.string.time_12_24);

修改蓝牙设备的默认名称
修改 frameworks\base\core\jni\Android_bluetooth_common.h
将 BTMTK_ANDROID_DEFAULT_LOCAL_NAME 值改掉,注意此处有引号。
#define BTMTK_ANDROID_DEFAULT_LOCAL_NAME "ANDROID BT"


Call requires API level 5 (current min is 1)

解决措施:

    <use-sdk android:minSdkVersion="10"
        android:targetSdkVersion="10" >
    </use-sdk>

1、ImageView使用:
(1)、加载资源中的图片:
image1.setImageResource(R.drawable.f2);
(2)、加载本地图片:
ImageView image1 = (ImageView) findViewById(R.id.iv1);  //获得ImageView对象
Bitmap bitmap = getLoacalBitmap("/sdcard/tubiao.jpg"); //从本地取图片(在cdcard中获取)  //
image1 .setImageBitmap(bitmap); //设置Bitmap

public static Bitmap getLoacalBitmap(String url) {
 try {
      FileInputStream fis = new FileInputStream(url);
      return BitmapFactory.decodeStream(fis);  ///把流转化为Bitmap图片       

   } catch (FileNotFoundException e) {
      e.printStackTrace();
      return null;
 }
}
扩展学习
BitmapFactory(android.graphics.BitmapFactory)是Android API提供的对象,可以将图片文件转换成Bitmap(android.graphics.Bitmap)对象,范例中使用的decodeFile()可以将手机文件系统中的图片文件转换成Bitmap对象。另外,BitmapFactory也提供了其他的方法,如decodeResource()可以将 /res/drawable/内预先存入的图片文件转换成Bitmap对象,decodeStream()方法则可将InputStream转换成Bitmap对象。
(3)、加载网络图片:
3、获取网络上的图片
ImageView image1 = (ImageView) findViewById(R.id.iv1);
Bitmap bitmap =getHttpBitmap("http://images.missyuan/attachments/day_071123/20071123_b2bfefe1ec56e2df6582vCGIZG81gbyM.png");  //从网上取图片
image1 .setImageBitmap(bitmap); //设置Bitmap

 从服务器取图片
public static Bitmap getHttpBitmap(String url) {
 URL myFileUrl = null;
 Bitmap bitmap = null;
 try {
      myFileUrl = new URL(url);
 } catch (MalformedURLException e) {
      e.printStackTrace();
 }
 try {
      HttpURLConnection conn = (HttpURLConnection) myFileUrl.openConnection();
      conn.setConnectTimeout(0);
      conn.setDoInput(true);
      conn.connect();
      InputStream is = conn.getInputStream();
      bitmap = BitmapFactory.decodeStream(is);
      is.close();
 } catch (IOException e) {
      e.printStackTrace();
 }
 return bitmap;
}

注意:由于需要使用网络,所以 AndroidManfest.xml 文件需要添加使用网络权限!!!
    <uses-permission android:name="android.permission.INTERNET" />
这也是我为什么一直错,而且一直找不到原因,它就是不显示图片,什么错误都没有,坑爹啊!!
 
并可用Activity中的getText(R.string.hello)直接转成字符串

调用拨号界面拨打电话:
Uri telUri = Uri.parse("tel:1008611");
Intent intent= new Intent(Intent.ACTION_DIAL, telUri);
//intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

<uses-permission android:name="android.permission.CALL_PHONE"></uses-permission>   拨号权限

android 如何实现跳转到发短信界面,并指定短信内容:
Uri smsToUri = Uri.parse("smsto://10086");
Intent mIntent = new Intent( android.content.Intent.ACTION_SENDTO, smsToUri );
mIntent.putExtra("sms_body", "this is content");
startActivity( mIntent );

启动activity:
//Intent launchAppIntent = new Intent(context, WidgetSetting.class);
Intent launchAppIntent = new Intent();
launchAppIntent.setClass(context, WidgetSetting.class); 从context activity 跳到 WidgetSetting activity
launchAppIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 不同进程间跳转

context.startActivity(launchAppIntent);

android:process=":lee.study.widget.main"  在新进程中启动activity

widget中的按键处理:
在onUpdate函数中添加代码
  Intent intent=new Intent(ACT_SETTING);
  PendingIntent myPendingIntent= PendingIntent.getBroadcast(context, 0, intent, 0);
//  PendingIntent myPendingIntent= PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);// 如果Intent不带数据,则最后一个参数设为0
 
  remoteViews.setOnClickPendingIntent(R.id.button_setting, myPendingIntent);
  
  ComponentName cmp = new ComponentName(context, WidgetDemo.class);    
  AppWidgetManager myAppWidgetManager = AppWidgetManager.getInstance(context);     
  myAppWidgetManager.updateAppWidget(cmp, remoteViews);
在onReceive函数中添加处理的代码:
  if(intent.getAction().equals(ACT_SETTING))  {
   // 收到并处理自定义的消息
   // Intent launchAppIntent = new Intent(context, WidgetSetting.class);
   Intent launchAppIntent = new Intent();
   launchAppIntent.setClass(context, WidgetSetting.class);
   launchAppIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

   context.startActivity(launchAppIntent);

   
   AppWidgetManager appWidgetManger = AppWidgetManager.getInstance(context);          
   int[] appIds = appWidgetManger.getAppWidgetIds(new ComponentName(context, WidgetDemo.class));    
   appWidgetManger.updateAppWidget(appIds, remoteViews); 
   
  }else{
   super.onReceive(context, intent);
  }
在AndroidManifest.xml要增加  
  <receiver android:name=".WidgetDemo" >
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
                <action android:name="lee.study.widget.SETTING"></action>
            </intent-filter>

            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/widget_provider" />
        </receiver>
 其中 lee.study.widget.SETTING 就是 代码中ACT_SETTING的字串
 

在程序中访问SDCard,你需要申请访问SDCard的权限.
在AndroidManifest.xml中加入访问SDCard的权限如下:
<!-- 在SDCard中创建与删除文件权限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- 往SDCard写入数据权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

   Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)
Environment.getExternalStorageState()方法用于获取SDCard的状态,如果手机装有SDCard,并且可以进行读写,那么方法返回的状态等于Environment.MEDIA_MOUNTED.

如何将一个Activity设置成窗口的样式:
在AndroidManifest.xml 中定义Activity的地方一句话android:theme="@android:style/Theme.Dialog" 或 android:theme="@android:style/Theme.Translucent"就变成半透明的

数据存储:
1.文件、
在Android中通常使用File存储方式是用 Context.openFileOutput(String fileName, int mode)和Context.openFileInput(String fileName)。
Context.openFileOutput(String fileName, int mode)生成的文件自动存储在/data/data/Package Name/files目录下,其全路径是/data/data/Package Name/files/fileName 。注意下,这里的参数fileName不可以包含路径分割符(如"/")。
通常来说,这种方式生成的文件只能在这个apk内访问。但这个结论是指使用Context.openFileInput(String fileName)的方式。使用这种方式,每个apk只可以访问自己的/data/data/Package Name/files目录下的文件,原因很简单,参数fileName中不可以包含路径分割符,Android会自动在/data/data /Package Name/files目录下寻找文件名为fileName的文件。
String fn = “moandroid.log”;
FileInputStream fis = openFileInput(fn);
FileOutputStream fos = openFileOutput(fn,Context.MODE_PRIVATE);
除此之外,Android还提供了其他函数来操作文件,详细说明请阅读Android SDK。
2、SharedcPreferences、
首先说明SharedPreferences存储方式,它是 Android提供的用来存储一些简单配置信息的一种机制,例如:登录用户的用户名与密码。其采用了Map数据结构来存储数据,以键值的方式存储,可以简单的读取与写入,具体实例如下:
void ReadSharedPreferences(){
String strName,strPassword;
SharedPreferences   user = getSharedPreferences(“user_info”,0);
strName = user.getString(“NAME”,””);
strPassword = user getString(“PASSWORD”,””);
}
void WriteSharedPreferences(String strName,String strPassword){
SharedPreferences   user = getSharedPreferences(“user_info”,0);
uer.edit();
user.putString(“NAME”, strName);
user.putString(“PASSWORD” ,strPassword);
usermit();
}
3、ContentProvider:
如果要把一个字符串转换成Uri,可以使用Uri类中的parse()方法,如下:
Uri uri = Uri.parse("content://com.changcheng.provider.contactprovider/contact")

ContentResolver:当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用 ContentResolver 类来完成,要获取ContentResolver 对象,可以使用Activity提供的getContentResolver()方法。 ContentResolver使用insert、delete、update、query方法,来操作数据。
4、SQLite数据库存储数据:
5、网络存储:

service使用:
第一步:继承Service类
public class SMSService extends Service {
}
第二步:在AndroidManifest.xml文件中的<application>节点里对服务进行配置:
<service android:name=".SMSService" />

服务不能自己运行,需要通过调用Context.startService()或Context.bindService()方法启动服务。这两个方法都可以启动Service,但是它们的使用场合有所不同。使用startService()方法启用服务,调用者与服务之间没有关连,即使调用者退出了,服务仍然运行。使用bindService()方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的特点。

如果打算采用Context.startService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onStart()方法。如果调用startService()方法前服务已经被创建,多次调用startService()方法并不会导致多次创建服务,但会导致多次调用onStart()方法。采用startService()方法启动的服务,只能调用Context.stopService()方法结束服务,服务结束时会调用onDestroy()方法。
如果打算采用Context.bindService()方法启动服务,在服务未被创建时,系统会先调用服务的onCreate()方法,接着调用onBind()方法。这个时候调用者和服务绑定在一起,调用者退出了,系统就会先调用服务的onUnbind()方法,接着调用onDestroy()方法。如果调用bindService()方法前服务已经被绑定,多次调用bindService()方法并不会导致多次创建服务及绑定(也就是说onCreate()和onBind()方法并不会被多次调用)。如果调用者希望与正在绑定的服务解除绑定,可以调用unbindService()方法,调用该方法也会导致系统调用服务的onUnbind()-->onDestroy()方法。

服务常用生命周期回调方法如下:
onCreate() 该方法在服务被创建时调用,该方法只会被调用一次,无论调用多少次startService()或bindService()方法,服务也只被创建一次。
onDestroy()该方法在服务被终止时调用。
与采用Context.startService()方法启动服务有关的生命周期方法
onStart() 只有采用Context.startService()方法启动服务时才会回调该方法。该方法在服务开始运行时被调用。多次调用startService()方法尽管不会多次创建服务,但onStart() 方法会被多次调用。

与采用Context.bindService()方法启动服务有关的生命周期方法
onBind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务绑定时被调用,当调用者与服务已经绑定,多次调用Context.bindService()方法并不会导致该方法被多次调用。
onUnbind()只有采用Context.bindService()方法启动服务时才会回调该方法。该方法在调用者与服务解除绑定时被调用

采用Context.startService()方法启动服务的代码如下:
public class HelloActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        ......
        Button button =(Button) this.findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener(){
       public void onClick(View v) {
              Intent intent = new Intent(HelloActivity.this, SMSService.class);
              startService(intent);
       }});      
   }
}
 
采用Context. bindService()方法启动服务的代码如下:
public class HelloActivity extends Activity {
     ServiceConnection conn = new ServiceConnection() {
              public void onServiceConnected(ComponentName name, IBinder service) {
           }
           public void onServiceDisconnected(ComponentName name) {
           }
     };

    @Override public void onCreate(Bundle savedInstanceState) {
        Button button =(Button) this.findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener(){
               public void onClick(View v) {
                  Intent intent = new Intent(HelloActivity.this, SMSService.class);
                  bindService(intent, conn, Context.BIND_AUTO_CREATE);
                  //unbindService(conn);//解除绑定
          }});      
    }
}

Activity生命周期:
横竖屏切换时候 activity 的生命周期
1. 不设置 Activity 的 android:configChanges 时 , 切屏会重新调用各个生命周期 , 切横屏时会执行一次 , 切竖屏时会执行两次 .
2. 设置 Activity 的 android:configChanges=”orientation” 时 , 切屏还是会重新调用各个生命周期 , 切横、竖屏时只会执行一次 .
3. 设置 Activity 的 android:configChanges=”orientation|keyboardHidden” 时 , 切屏不会重新调用各个生命周期 , 只会执行 onConfigurationChanged 方法 .

{
 // 推荐的定时器的使用方法:
 Timer timer2 = new Timer();
 Handler handler = new Handler(){
  public void handleMessage(Message msg){
   switch (msg.what) {
   case 1:
    // 自己的操作
    break;

   default:
    super.handleMessage(msg);
    break;
   }
  }
 };  
 TimerTask task = new TimerTask() {
  
  @Override
  public void run() {
   Message message = new Message();
   message.what = 1;
   handler.sendMessage(message);    
  }
 };
 timer.schedule(task, 1000);

// 本身的定时功能
 private Handler handler = new Handler();
 private Runnable myRunnable = new Runnable() {
  @Override
  public void run() {
   handler.postDelayed(this, 1000);
   
   //自己的定时处理   
  }
 };
 // 然后在其他地方调用 handler.post(myRunnable); 或  handler.postDelayed(myRunnable, delayMillis);

view的刷新函数:
  View.postInvalidate();
  View.postInvalidate(left, top, right, bottom);
  View.postInvalidateDelayed(delayMilliseconds);
  View.postInvalidateDelayed(delayMilliseconds, left, top, right, bottom);
 推荐使用handler处理:


App widget 定时刷新操作:
public void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds) {
 Timer timer = new Timer();
 timer.scheduleAtFixedRate(new MyTime(context, appWidgetManager), 1, 2000);
 super.onUpdate(context, appWidgetManager, appWidgetIds);
}
private class MyTime extends TimerTask {
 RemoteViews remoteViews;
 AppWidgetManager appWidgetManager;
 ComponentName thisWidget;
 
 public MyTime(Context context, AppWidgetManager appWidgetManager) {
  this.appWidgetManager = appWidgetManager;
  remoteViews = new RemoteViews(context.getPackageName(), R.layout.main);
  thisWidget = new ComponentName(context, WidgetDemo.class);
 }
 
 public void run() {
  Date date = new Date();
  Calendar calendar = new GregorianCalendar(2014, 06, 11);
  //   long days = (((calendar.getTimeInMillis() - date.getTime()) / 1000)) / 86400;
  long seconds = (calendar.getTimeInMillis() - date.getTime()) / 1000;
  
  //   remoteViews.setTextViewText(R.id.wordcup, "距离南非世界杯还有" + days + "天");
  remoteViews.setTextViewText(R.id.wordcup, "距离南非世界杯还有" + seconds+ "秒");
  appWidgetManager.updateAppWidget(thisWidget, remoteViews);
 }

//隐藏状态栏 
Object service = getSystemService("statusbar");
Class<?> statusBarManager = Class.forName("android.app.StatusBarManager");
Method expand = statusBarManager.getMethod("disable", int.class);
expand.invoke(service, 0x00000000);
权限:
<uses-permission android:name="android.permission.STATUS_BAR"/>
<uses-permission android:name="android.permission.DISABLE_STATUS_BAR"/>
并使用系统签名


Sim卡联系人的增删改查:
TelephonyManager.getSimState() 取得sim卡状态
Uri:    content://icc/adn/
操作跟其他的contenProvider一样  参考文件:/frameworks/base/telephony/java/com/android/internal/telephony/IccProvider.java

Android 权限:
    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
    <uses-permission android:name="android.permission.CALL_PHONE" />  <!-- 拨号权限 -->
    <uses-permission android:name="android.permission.CALL_PRIVILEGED" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW" />
    <uses-permission android:name="android.permission.ADD_SYSTEM_SERVICE" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.REORDER_TASKS" />
    <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
    <uses-permission android:name="android.permission.STATUS_BAR" />
    <uses-permission android:name="android.permission.READ_SMS" />
    <uses-permission android:name="android.permission.WRITE_SMS" />
    <uses-permission android:name="android.permission.SET_TIME_ZONE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />  TelephonyManager.getSimState() 取得sim卡状态
    <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
    <uses-permission android:name="android.permission.DEVICE_POWER" />
    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.WRITE_APN_SETTINGS" />
    <uses-permission android:name="android.permission.BROADCAST_SMS"/>
    <uses-permission android:name="android.permission.BROADCAST_WAP_PUSH"/>
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.SHUTDOWN" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.BACKUP" />
    <uses-permission android:name="android.permission.USE_SIP" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <!-- 在SDCard中创建与删除文件权限 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>  <!-- 往SDCard写入数据权限 -->
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.STOP_APP_SWITCHES" />
    <uses-permission android:name="android.permission.SEND_SMS" />

把自己的程序导入到手机验证:
adb remount system/framework
adb push out/target/product/hct13_gb/system/framework/hctlockscreen.jar system/framework

 

查看相关的log:
adb logcat | grep "widget"


数据库调试:
adb devices
adb -s emulator-5554 shell
sqlite3 /data/data/lee.app.widget/databases/imageWidget.db3
INSERT INTO widget_info (widget_id, is_recycle, is_show_frame, time_interval, time_weight, widger_size, image1_path) VALUES  (999, 0, 0, 50, 0, 0, 'image1_path');
select * from widget_info;

  

Android Widget中AppWidget按钮事件: 转:http://mobile.51cto/widget-289939.htm

Android WidgetappWidget按钮事件是本文要介绍的内容,主要是了解并学习Android Widget应用中appWidget事件,具体内容的实现来看本文详解。

在appWidget中,ImageButton和Button都是被支持的控件,其事件可分成三种类型:

一、开启Activity

1、首先先定义个开启Activity的intent

eg:  Intent fullIntent=new Intent(this ,FullScreen.class); 

若要传递数据,则使用intent.putExtra()方法

eg:  fullIntent.putExtra("isCircle", isCircle); 

2、用intent实例化一个PendingIntent,调用pendingIntent的getActicity方法来启动另一个Activity

(1)若该Intent带有数据,则需要将最后一个参数的值设为:FLAG_CANCEL_CURRENT

eg:  PendingIntent Pfullintent= PendingIntent.getActivity(this, 0, fullIntent, PendingIntent.FLAG_CANCEL_CURRENT); 

(2)若该Intent不带数据,则最后一个参数设为0

eg:  PendingIntent Pfullintent= PendingIntent.getActivity(this, 0, fullIntent, 0); 

3、实例化RemoteView,其对应相应的Widget布局

eg:  RemoteViews views= new RemoteViews(getPackageName(), R.layout.widget); 

4、给RemoteView上的Button或ImageButton设置按钮事件

eg:  views.setOnClickPendingIntent(R.id.IBfullscreen, Pfullintent); 

5、更新AppWidget界面

(1)如果是在onUpdate()方法内更新AppWidget界面

eg:  appWidgetManager.updateAppWidget(appWidgetIds, ActivityView);

(2)如果是在onUpdate()方法外(一般为Service内)更新AppWidget界面,则需要定义几个变量

eg:  public RemoteViews views; //RemoteView对象 

public ComponentName thisWidget; //组件名  
public AppWidgetManager manager; // AppWidget管理器  
thisWidget = new ComponentName(this, PictureAppWidgetProvider.class);  
manager = AppWidgetManager.getInstance(this);  
manager.updateAppWidget(thisWidget, views); 

二、开启Service

1、定义一个intent来开启Service

eg:  Intent startServiceInten=new Intent("zyf.temp.Service.START"); 

注:参数为开启Service的动作

2、用Intent实例化一个PendingIntent,利用PendingIntent的getService方法来启动一个服务

eg:  PendingIntent Pintent= PendingIntent.getService(context, 0, startServiceInten, 0); 

3、实例化RemoteView,其对应相应的Widget布局

eg:  RemoteViews views= new RemoteViews(getPackageName(), R.layout.widget); 

4、给RemoteView上的Button或ImageButton设置按钮事件

eg:  views.setOnClickPendingIntent(R.id.IBfullscreen, Pfullintent); 

5、更新AppWidget界面

(1)如果是在onUpdate()方法内更新AppWidget界面

eg:  appWidgetManager.updateAppWidget(appWidgetIds, ActivityView); 

(2)如果是在onUpdate()方法外(一般为Service内)更新AppWidget界面,则需要定义几个变量

eg:  public RemoteViews views; //RemoteView对象  

 
 
  1.      public ComponentName thisWidget; //组件名  
  2.      public AppWidgetManager manager; // AppWidget管理器  
  3.      thisWidget = new ComponentName(this, PictureAppWidgetProvider.class);  
  4.      manager = AppWidgetManager.getInstance(this);  
  5.      manager.updateAppWidget(thisWidget, views); 

三、发送按钮Action

1、定义一个Intent来发送按钮Action

eg:  Intent prevInten=new Intent("PREV"); 

2、用Intent实例化一个PendingIntent,利用PendingIntent的getBroadcast方法来发送广播

eg:  PendingIntent Pprevintent= PendingIntent.getBroadcast(this, 0, prevInten, 0); 

3、实例化RemoteView,其对应相应的Widget布局

eg:  RemoteViews views= new RemoteViews(getPackageName(), R.layout.widget); 

4、给RemoteView上的Button或ImageButton设置按钮事件

eg:  views.setOnClickPendingIntent(R.id.IBprev, Pprevintent); 

5、更新AppWidget界面

(1)如果是在onUpdate()方法内更新AppWidget界面

eg: appWidgetManager.updateAppWidget(appWidgetIds, ActivityView); 

(2)如果是在onUpdate()方法外(一般为Service内)更新AppWidget界面,则需要定义几个变量

eg: public RemoteViews views; //RemoteView对象  
public ComponentName thisWidget; //组件名  
public AppWidgetManager manager; // AppWidget管理器  


thisWidget = new ComponentName(this, PictureAppWidgetProvider.class);  
manager = AppWidgetManager.getInstance(this);  
manager.updateAppWidget(thisWidget, views); 

6、接收该Action

1、在AppWidget自己的onReceive方法内接收

(1)在Action,要在Manifest.xml中加入Action

eg:        <intent-filter> 

 
 
  1.      <action android:name="android.appwidget.action.APPWIDGET_UPDATE"> </action>
  2.      <action android:name="PREV"></action>
  3.    </intent-filter>

(2)在onReceive()方法内编写要实现的动作

 
 
  1. eg:  if(intent.getAction().equals("PREV"))  
  2. {  
  3.    //在这编写接收到该Action后要实现的动作  
  4. }

2、在Service内接收

(1)注册一个BroadcastReceive,声明接收器
eg: 

        IntentFilter filter=new IntentFilter();  

 
 
  1.  filter.addAction("PREV");  
  2. registerReceiver(doCommand, filter);

(2)在BroadcastReceive类的onReceive方法内编写要实现的动作

  1. eg:  if(intent.getAction().equals("PREV"))  
  2. {  
  3.    //在这编写接收到该Action后要实现的动作  
 
序列化Serializable总结  

1、序列化是干什么的?        简单说就是为了保存在内存中的各种对象的状态(也就是实例变量,不是方法),并且可以把保存的对象状态再读出来。虽然你可以用你自己的各种各样的方法来保存object states,但是Java给你提供一种应该比你自己好的保存对象状态的机制,那就是序列化。

2、什么情况下需要序列化       a)当你想把的内存中的对象状态保存到一个文件中或者数据库中时候;     b)当你想用套接字在网络上传送对象的时候;     c)当你想通过RMI传输对象的时候; 3、当对一个对象实现序列化时,究竟发生了什么?     在没有序列化前,每个保存在堆(Heap)中的对象都有相应的状态(state),即实例变量(instance ariable)比如:     java 代码 Foo  myFoo = new Foo();  myFoo.setWidth(37);  myFoo.setHeight(70);             当通过下面的代码序列化之后,MyFoo对象中的width和Height实例变量的值(37,70)都被保存到foo.ser文件中,这样以后又可以把它 从文件中读出来,重新在堆中创建原来的对象。当然保存时候不仅仅是保存对象的实例变量的值,JVM还要保存一些小量信息,比如类的类型等以便恢复原来的对 象。 java 代码 FileOutputStream fs = new FileOutputStream("foo.ser");  ObjectOutputStream os = new ObjectOutputStream(fs);  os.writeObject(myFoo);    4、实现序列化(保存到一个文件)的步骤        a)Make a FileOutputStream         java 代码 FileOutputStream fs = new FileOutputStream("foo.ser");           b)Make a ObjectOutputStream            java 代码 ObjectOutputStream os =  new ObjectOutputStream(fs);   c)write the object java 代码 os.writeObject(myObject1);  os.writeObject(myObject2);  os.writeObject(myObject3);       d) close the ObjectOutputStream java 代码  os.close();  5、举例说明 java 代码 import java.io.*;   public class  Box implements Serializable  {      private int width;      private int height;        public void setWidth(int width){          this.width  = width;      }      public void setHeight(int height){          this.height = height;      }        public static void main(String[] args){          Box myBox = new Box();          myBox.setWidth(50);          myBox.setHeight(30);            try{              FileOutputStream fs = new FileOutputStream("foo.ser");              ObjectOutputStream os =  new ObjectOutputStream(fs);              os.writeObject(myBox);              os.close();          }catch(Exception ex){              ex.printStackTrace();          }      }        }    6、相关注意事项     a)序列化时,只对对象的状态进行保存,而不管对象的方法;     b)当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口;     c)当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化;     d)并非所有的对象都可以序列化,,至于为什么不可以,有很多原因了,比如:        1.安全方面的原因,比如一个对象拥有private,public等field,对于一个要传输的对象,比如写到文件,或者进行rmi传输  等等,在序列化进行传输的过程中,这个对象的private等域是不受保护的。        2. 资源分配方面的原因,比如socket,thread类,如果可以序列化,进行传输或者保存,也无法对他们进行重新的资源分  配,而且,也是没有必要这样实现。 平衡二叉树(解惑) 平衡二叉树定义(AVL):它或者是一颗空树,或者具有以下性质的二叉树:它的左子树和右子树的深度之差的绝对值不超过1,且它的左子树和右子树都是一颗平衡二叉树。 如何判断little-endian big-endian bool IsBig_Endian() //如果字节序为big-endian,返回true; //反之为   little-endian,返回false {     unsigned short test = 0x1122;     if(*( (unsigned char*) &test ) == 0x11)        return TRUE; else     return FALSE; }//IsBig_Endian() 如何判断操作系统是32位还是16位 VC编程的话直接判断有没有定义_WIN32宏就可以了 bool bWin32; #ifdef _WIN32 bWin32=true; #else bWin32=false; #endif 1.操作系统是16位还是32位是跟它的地址寻址方式相关的(需要CPU支持,但与CPU字长没有必然联系),因此可以直接通过指针(地址)的长度来判断: cout << (sizeof(int *)==4 ? "32 bit" : "16 bit") << endl; 2.如果不允许用sizeof,则通过整数的表示范围来判断,16位系统中整数最大为65535: unsigned int a = ~0; cout << (a>65535 ? "32 bit" : "16 bit") << endl; ArrayList和Vector的区别 Vector和ArrayList Vector和ArrayList在使用上非常相似,都可用来表示一组数量可变的对象应用的集合,并且可以随机地访问其中的元素。   Vector的方法都是同步的(Synchronized),是线程安全的(thread-safe),而ArrayList的方法不是,由于线程的同步必然要影响性能,因此,ArrayList的性能比Vector好。 当Vector或ArrayList中的元素超过它的初始大小时,Vector会将它的容量翻倍,而ArrayList只增加50%的大小,这样,ArrayList就有利于节约内存空间 ArrayList和Vector功能类似。 整体上ArrayList是Vector的“裸奔新版” Vector从Java 1.0起就存在,ArrayList从Java 1.2起才存在,较新。 所以Vector在JavaME、Card等各种微小版本都可以使用,而ArrayList不能 ArrayList不具备线程同步的安全性,但速度较快,所以叫裸奔。 Vector具备线程安全。 HashMap和Hashtable的区别 from: http://wwwblogs/taotaoblog/archive/2009/09/19/1569958.html 1 HashMap不是线程安全的

hastmap是一个接口 是map接口的子接口,是将键映射到值的对象,其中键和值都是对象,并且不能包含重复键,但可以包含重复值。HashMap允许null key和null value,而hashtable不允许。

2 HashTable是线程安全的一个Collection。 HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因为contains方法容易让人引起误解。Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现。最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap 就必须为之提供外同步。 Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。 volatile 和 synchronized关键字的区别 一个变量声明为volatile,就意味着这个变量是随时会被其他线程修改的,因此不能将它cache在线程memory中.  volatile是变量修饰符,而synchronized则作用于一段代码或方法 volatile关键字用于声明简单类型变量,如int、float、 boolean等数据类型。如果这些简单数据类型声明为volatile,对它们的操作就会变成原子级别的. 声明为volatile的简单变量如果当前值由该变量以前的值相关,那么volatile关键字不起作用,也就是说如下的表达式都不是原子操作: n = n + 1 ; n ++ ; 如果要想使这种情况变成原子操作,需要使用synchronized关键字. 既然volatile关键字已经实现了线程间数据同步,又要 synchronized干什么呢?呵呵,它们之间有两点不同。首先,synchronized获得并释放监视器——如果两个线程使用了同一个对象锁,监视器能强制保证代码块同时只被一个线程所执行——这是众所周知的事实。但是,synchronized也同步内存:事实上,synchronized在“ 主”内存区域同步整个线程的内存。因此,执行geti3()方法做了如下几步: 1. 线程请求获得监视this对象的对象锁(假设未被锁,否则线程等待直到锁释放) 2. 线程内存的数据被消除,从“主”内存区域中读入(Java虚拟机能优化此步。。。[后面的不知道怎么表达,汗])
        3. 代码块被执行 
        4. 对于变量的任何改变现在可以安全地写到“主”内存区域中(不过geti3()方法不会改变变量值) 
        5. 线程释放监视this对象的对象锁 
      因此volatile只是在线程内存和“主”内存间同步某个变量的值,而synchronized通过锁定和解锁某个监视器同步所有变量的值。显然synchronized要比volatile消耗更多资源。 

	 原子操作 
	 "原子操作(atomic operation)是不需要synchronized"。所谓原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行倒结束,中间不会有任何 context switch (切换到另一个线程)。
	常见情况 
如果问题中的变量除了long or double 以后的基本类型,对这些类型进行简单的赋值或者返回操作时是原子操作。为类型long and double 加上volatile修饰符,对这两个基本类型的操作也是原子的。 
JVM中自增或减并不是原子操作,i++ or i-- 因为其中涉及一次读和写,在执行过程中可能被修改。
TCP/IP建立连接的步骤
在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。 
第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认; 
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态; 
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。 
完成三次握手,客户端与服务器开始传送数据,在上述过程中,还有一些重要的概念: 
未连接队列:在三次握手协议中,服务器维护一个未连接队列,该队列为每个客户端的SYN包(syn=j)开设一个条目,该条目表明服务器已收到SYN包,并向客户发出确认,正在等待客户的确认包。这些条目所标识的连接在服务器处于Syn_RECV状态,当服务器收到客户的确认包时,删除该条目,服务器进入ESTABLISHED状态。 
Backlog参数:表示未连接队列的最大容纳数目。 
SYN-ACK 重传次数 服务器发送完SYN-ACK包,如果未收到客户确认包,服务器进行首次重传,等待一段时间仍未收到客户确认包,进行第二次重传,如果重传次数超过系统规定的最大重传次数,系统将该连接信息从半连接队列中删除。注意,每次重传等待的时间不一定相同。 
半连接存活时间:是指半连接队列的条目存活的最长时间,也即服务从收到SYN包到确认这个报文无效的最长时间,该时间值是所有重传请求包的最长等待时间总和。有时我们也称半连接存活时间为Timeout时间、SYN_RECV存活时间。

本文标签: 笔记 Android MTK