2011年12月31日

Android:下载与线程控制



最近在写的一个APP涉及到下载。
目前想到有两种设计方法。
方法一:建一个下载线程,与主线程保持同步。
1、启动下载线程。
2、在主线程利用synchronized锁定下载线程,前用wait()方法让主线程等待。// wait() = sleep() until notify();
3、下载线程利用synchronized加锁,操作完成后用notify()方法通知主线程释放。
这种方法的优点是可以保持2个线程的同步,缺点是下载线程未完成时主线程的界面冻结。

方法二:下载线程与主线程异步操作,利用Handler向Activity传递消息。
1、创建一个Handler类,重写handleMessage方法。
2、启动下载线程。
3、下载线程利用sendMessage(message)方法向Activity发送消息。
4、Handler.handleMessage()在处理下载完成的消息时,继续后续的动作。
这种方法的优点是方便在主界面显示进度条,也可以利用按钮中止下载。
缺点是主界面的一些业务逻辑要根据下载的状态进行一些判断。

2011年12月29日

Android MediaPlayer:进度条、静音



进度条:
    Runnable start = new Runnable()
    {      
@Override
public void run() 
{
// TODO Auto-generated method stub
mp.start(); // start mediaplayer
handler.post(updatesb);
//use a handler to update SeekBar
}
    };
    
    Runnable updatesb = new Runnable()
    {
@Override
public void run() 
{
// TODO Auto-generated method stub
SeekBar1.setProgress(mp.getCurrentPosition());
handler.postDelayed(updatesb, 100);
}
    };
然后用handler.post(start)启动播放器。

静音:
btnMute.setOnClickListener(new Button.OnClickListener()
    {
      @Override
      public void onClick(View v)
      {  
     //System.out.println("Button Mute");
          if (SoundEnabled) 
          {
              audioManager.setStreamMute(AudioManager.STREAM_MUSIC , true);
              btnMute.setText(" Unmute ");
          } 
          else 
          {
              audioManager.setStreamMute(AudioManager.STREAM_MUSIC , false);
              btnMute.setText("  Mute  ");
          }
          SoundEnabled = !SoundEnabled;                      
      }
    }); // btnMute onClick ends

2011年12月26日

Android BroadcastReceiver

1. 在AndroidManifest.xml定义相关权限:
<uses-permission android:name="android.permission.WAKE_LOCK" />
2. 在Main Activity中建立AlarmManager:
Intent  intent = new Intent(MainActivity.this, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, Schedule_Time, pendingIntent);
3. 在Receiver中建立响应:
public class AlarmReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
Intent i = new Intent(context, ActionActivity.class);
Bundle bundleRet = new Bundle();
bundleRet.putString("STR_CALLER", "");
i.putExtras(bundleRet);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}

关于MapReduce

这两天在读More Joel on Software,其中有一节讲到MapReduce的原理,于是查了WIKI,读了一些博客,大致了解了其原理。
考虑到我准备写一个翻译MES系统界面的程序,可以借鉴MapReduce的方法。
大致地说,Map是将一个大的作业转化为若干个小的、可分发、可并行的作业。
Reduce是一个逻辑独立的作业,每次作业都能减少总体的运算量。
举例来说,这个翻译是将一个XML文件中对应位置的英语文本翻译为中文。
按照MapReduce的方法,大致分为以下4个步骤:
1、Map,将所有要翻译的句子提取出来,存入数组。
2、Sort,将数组里的数据排序。
3、Reduce,这里有2个函数:
第1个函数取字符串中匹配起始字符,字典中可查到的最长单词,如查Work Station而不是Work。
第2个函数将最小单位字符串查询字典进行翻译。
4、Union,按既定的顺序拼接翻译好的数组。

Select From Amazon SimpleDB

//1. Creating a SimpleDB Client

AWSCredentials credentials = new BasicAWSCredentials( ACCESS_KEY, SECRET_KEY );

AmazonSimpleDBClient sdbClient = new AmazonSimpleDBClient( credentials);

sdbClient.setEndpoint("sdb.us-west-1.amazonaws.com"); // to define Data Center Region

 

//2. Select

String nextToken = null;

SelectRequest selectRequest = new SelectRequest( "select * from myDomain" ).withConsistentRead( true );

selectRequest.setNextToken( nextToken );

SelectResult response = sdbClient.select( selectRequest );

nextToken = response.getNextToken();

Android连接Amazon SimpleDB

1. 安装AWS Toolkit for Eclipse:http://aws.amazon.com/eclipse/

安装完成以后在Eclipse中增加了一个Database Development perspective视图,可以对SimpleDB进行一些简单的维护操作,通过SQL Scrapbook进行SQL查询。

2. 安装AWS SDK for Android:http://aws.amazon.com/sdkforandroid/

此SDK包含了所有的库和部分示例代码及文档,注意使用前需注册外部类库。

这样就可以象操作本地数据库一样进行SimpleDB的读写了。

Android时间同步

1. 系统函数SystemClock.setCurrentTimeMillis()用于设置系统时间,需要<uses-permission android:name="android.permission.APPROPRIATE" />权限,但是出于安全考虑,已被GOOGLE禁用。

2. 对于ROOT手机,可以用<uses-permission android:name="android.permission.WRITE_SETTINGS" />打开权限。

3. 另一个变通的方法是,先查询本地时间,再查询NTP服务器的UTC,从而得到两个时间的差值。

在多台手机之间,通过补偿差值,从而实现多台手机之间的事件同步。

Android通过NTP服务器取得UTC标准时间

1. http://hi-android.info/src/android/net/SntpClient.java.html

利用这个类调用NTP函数。

 

2. 通过函数client.requestTime("1.us.pool.ntp.org", 10000)获取本地时间戳。

 

3. 减去时区偏离值:

Calendar c = Calendar.getInstance();

int zoneOffset = c.get(java.util.Calendar.ZONE_OFFSET);

Local Time & UTC Time in Android

SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

Calendar c = Calendar.getInstance();

Date date1 = c.getTime();

Dtime = fmt.format(date1);

mTextView1.setText(Dtime); // display local time

 

int zoneOffset = c.get(java.util.Calendar.ZONE_OFFSET);

int dstOffset = c.get(java.util.Calendar.DST_OFFSET);

c.add(java.util.Calendar.MILLISECOND, -(zoneOffset + dstOffset));

Date date2 = c.getTime();

Dtime = fmt.format(date2);

mTextView2.setText(Dtime); // display utc time