(updated on Mar 1th)Programming Mobile Applications for Android Handheld Systems by Dr. Adam Porter
Lab - Intents
启动程序
private void startExplicitActivation() {
Log.i(TAG,"Entered startExplicitActivation()");
// TODO - Create a new intent to launch the ExplicitlyLoadedActivity class
Intent intent=new Intent(ActivityLoaderActivity.this, ExplicitlyLoadedActivity.class);
startActivityForResult(intent, 0);
// TODO - Start an Activity using that intent and the request code defined above
}
private void startImplicitActivation() {
Log.i(TAG, "Entered startImplicitActivation()");
// TODO - Create a base intent for viewing a URL
// (HINT: second parameter uses parse() from the Uri class)
Uri webpage = Uri.parse("http://www.google.com");
Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);
// TODO - Create a chooser intent, for choosing which Activity
// will carry out the baseIntent. Store the Intent in the
// chooserIntent variable below. HINT: using the Intent class'
// createChooser
Intent chooserIntent = Intent.createChooser(webIntent, "CHOOSER");
Log.i(TAG,"Chooser Intent Action:" + chooserIntent.getAction());
// TODO - Start the chooser Activity, using the chooser intent
startActivity(chooserIntent);
}
关联程序
<activity
android:name=".MyBrowserActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" />
</intent-filter> <!-- TODO - Add necessary intent filter information so that this
Activity will accept Intents with the
action "android.intent.action.VIEW" and with an "http"
schemed URL -->
</activity>
Lab - Permissions
读取书签--使用权限
<uses-permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS"/>
private void loadBookmarks() {
Log.i(TAG, "Entered loadBookmarks()");
String text = "";
Cursor query = getContentResolver().query(Browser.BOOKMARKS_URI,
projection, null, null, null);
query.moveToFirst();
while (query.moveToNext()) {
text += query.getString(query
.getColumnIndex(Browser.BookmarkColumns.TITLE));
text += "\n";
text += query.getString(query
.getColumnIndex(Browser.BookmarkColumns.URL));
text += "\n\n";
}
TextView box = (TextView) findViewById(R.id.text);
box.setText(text);
Log.i(TAG, "Bookmarks loaded");
}
自定义权限
<permission android:name="course.labs.permissions.DANGEROUS_ACTIVITY_PERM" android:protectionLevel="dangerous"></permission>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<!-- TODO - enforce the custom permission on this Activity -->
<activity
android:name=".DangerousActivity"
android:label="@string/app_name" >
<!--
TODO - add additional intent filter info so that this Activity
will respond to an Implicit Intent with the action
"course.labs.permissions.DANGEROUS_ACTIVITY"
-->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="course.labs.permissions.DANGEROUS_ACTIVITY"/>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Lab - The Fragment Class
主activity定义layout
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
添加fragment
mFriendsFragment = new FriendsFragment();
//TODO 1 - add the FriendsFragment to the fragment_container
FragmentTransaction a=getFragmentManager().beginTransaction();
a.add(R.id.fragment_container,mFriendsFragment);
a.commit();
替换fragment
//TODO 2 - replace the fragment_container with the FeedFragment
getFragmentManager().beginTransaction().replace(
R.id.fragment_container, mFeedFragment).commit();
// execute transaction now
getFragmentManager().executePendingTransactions();
// Update Twitter feed display on FriendFragment
mFeedFragment.updateFeedDisplay(position);
判断fragment状态
// If there is no fragment_container ID, then the application is in
// two-pane mode private boolean isInTwoPaneMode() { return findViewById(R.id.fragment_container) == null; }
Lab - User Interface Classes
用户设定日期
public static class DatePickerFragment extends DialogFragment implements
DatePickerDialog.OnDateSetListener { @Override
public Dialog onCreateDialog(Bundle savedInstanceState) { // Use the current date as the default date in the picker final Calendar c = Calendar.getInstance();
int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH);
int day = c.get(Calendar.DAY_OF_MONTH); // Create a new instance of DatePickerDialog and return it
return new DatePickerDialog(getActivity(), this, year, month, day);
} @Override
public void onDateSet(DatePicker view, int year, int monthOfYear,
int dayOfMonth) {
setDateString(year, monthOfYear, dayOfMonth); dateView.setText(dateString);
} } private void showDatePickerDialog() {
DialogFragment newFragment = new DatePickerFragment();
newFragment.show(getFragmentManager(), "datePicker");
} private static void setDateString(int year, int monthOfYear, int dayOfMonth) { // Increment monthOfYear for Calendar/Date -> Time Format setting
monthOfYear++;
String mon = "" + monthOfYear;
String day = "" + dayOfMonth; if (monthOfYear < 10)
mon = "0" + monthOfYear;
if (dayOfMonth < 10)
day = "0" + dayOfMonth; dateString = year + "-" + mon + "-" + day;
}
用户设定时间
// DialogFragment used to pick a ToDoItem deadline time
public static class TimePickerFragment extends DialogFragment implements
TimePickerDialog.OnTimeSetListener {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the current time as the default values for the picker
final Calendar c = Calendar.getInstance();
int hour = c.get(Calendar.HOUR_OF_DAY);
int minute = c.get(Calendar.MINUTE);
// Create a new instance of TimePickerDialog and return
return new TimePickerDialog(getActivity(), this, hour, minute,
true);
}
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
setTimeString(hourOfDay, minute, 0);
timeView.setText(timeString);
}
}
private void showTimePickerDialog() {
DialogFragment newFragment = new TimePickerFragment();
newFragment.show(getFragmentManager(), "timePicker");
}
private static void setTimeString(int hourOfDay, int minute, int mili) {
String hour = "" + hourOfDay;
String min = "" + minute;
if (hourOfDay < 10)
hour = "0" + hourOfDay;
if (minute < 10)
min = "0" + minute;
timeString = hour + ":" + min + ":00";
}
设定默认日期时间
// Use this method to set the default date and time
private void setDefaultDateTime() {
mDate = new Date();
mDate = new Date(mDate.getTime());
Calendar c = Calendar.getInstance();
c.setTime(mDate);
setDateString(c.get(Calendar.YEAR), c.get(Calendar.MONTH),
c.get(Calendar.DAY_OF_MONTH));
dateView.setText(dateString);
setTimeString(c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE),
c.get(Calendar.MILLISECOND));
timeView.setText(timeString);
}
使用BaseAdapter实现复杂的ListView(转)原文链接
package com.app.weixin; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import com.app.wexin.R; import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView; public class WeixinActivity extends Activity {
private ImageView img;
private List<HashMap<String, Object>> mData;
private ListView listView; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.friend_list);
mData = getData();//为刚才的变量赋值
MyAdapter adapter = new MyAdapter(this);//创建一个适配器 listView = (ListView) findViewById(R.id.listView1);//实例化ListView
listView.setAdapter(adapter);//为ListView控件绑定适配器
} /** 自定义适配器 */
public class MyAdapter extends BaseAdapter {
private LayoutInflater mInflater;// 动态布局映射 public MyAdapter(Context context) {
this.mInflater = LayoutInflater.from(context);
} // 决定ListView有几行可见
@Override
public int getCount() {
return mData.size();// ListView的条目数
} @Override
public Object getItem(int arg0) {
return null;
} @Override
public long getItemId(int arg0) {
return 0;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
convertView = mInflater.inflate(R.layout.friend_list_item, null);//根据布局文件实例化view
TextView title = (TextView) convertView.findViewById(R.id.title);//找某个控件
title.setText(mData.get(position).get("title").toString());//给该控件设置数据(数据从集合类中来)
TextView time = (TextView) convertView.findViewById(R.id.time);//找某个控件
time.setText(mData.get(position).get("time").toString());//给该控件设置数据(数据从集合类中来)
TextView info = (TextView) convertView.findViewById(R.id.info);
info.setText(mData.get(position).get("info").toString());
img = (ImageView) convertView.findViewById(R.id.img);
img.setBackgroundResource((Integer) mData.get(position).get("img"));
return convertView;
}
}
// 初始化一个List
private List<HashMap<String, Object>> getData() {
// 新建一个集合类,用于存放多条数据
ArrayList<HashMap<String, Object>> list = new ArrayList<HashMap<String, Object>>();
HashMap<String, Object> map = null;
for (int i = 1; i <= 40; i++) {
map = new HashMap<String, Object>();
map.put("title", "人物" + i);
map.put("time", "9月20日");
map.put("info", "我通过了你的好友验证请求");
map.put("img", R.drawable.pic_person);
list.add(map);
} return list;
}
public void showInfo(int position){
getData();
}
}
Lab - Notifications
注册broadcast receiver
public static final String DATA_REFRESHED_ACTION = "course.labs.notificationslab.DATA_REFRESHED"; private BroadcastReceiver mRefreshReceiver; registerReceiver(mRefreshReceiver, new IntentFilter(DATA_REFRESHED_ACTION)); unregisterReceiver(mRefreshReceiver);
final PendingIntent pendingIntent = PendingIntent.getActivity(mParentActivity, 0, restartMainActivtyIntent, PendingIntent.FLAG_UPDATE_CURRENT); // Uses R.layout.custom_notification for the
// layout of the notification View. The xml
// file is in res/layout/custom_notification.xml RemoteViews mContentView = new RemoteViews(
mApplicationContext.getPackageName(),
R.layout.custom_notification); // TODO: Set the notification View's text to
// reflect whether or the download completed
// successfully
mContentView.setTextViewText(R.id.text, successMsg); // TODO: Use the Notification.Builder class to
// create the Notification. You will have to set
// several pieces of information. You can use
// android.R.drawable.stat_sys_warning
// for the small icon. You should also setAutoCancel(true). Notification.Builder notificationBuilder = new Notification.Builder(
mParentActivity)
.setSmallIcon(android.R.drawable.stat_sys_warning)
.setAutoCancel(true)
.setContent(mContentView)
.setContentIntent(pendingIntent); // TODO: Send the notification
// Pass the Notification to the NotificationManager:
NotificationManager mNotificationManager = (NotificationManager) mParentActivity.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(MY_NOTIFICATION_ID,
notificationBuilder.build());
Lab - Graphics(Gesture)
mGestureDetector = new GestureDetector(this,
new GestureDetector.SimpleOnGestureListener() {
// If a fling gesture starts on a BubbleView then change the
// BubbleView's velocity
@Override
public boolean onFling(MotionEvent event1, MotionEvent event2,
float velocityX, float velocityY) {
// TODO - Implement onFling actions.
// You can get all Views in mFrame using the
// ViewGroup.getChildCount() method
for(int i=0;i<mFrame.getChildCount();i++){
BubbleView bubbleNew= (BubbleView) mFrame.getChildAt(i);
if (bubbleNew.intersects(event1.getX(),event1.getY())){
bubbleNew.deflect(velocityX, velocityY);
return true;
}
}
return false;
}
// If a single tap intersects a BubbleView, then pop the BubbleView
// Otherwise, create a new BubbleView at the tap's location and add
// it to mFrame. You can get all views from mFrame with ViewGroup.getChildAt()
@Override
public boolean onSingleTapConfirmed(MotionEvent event) {
// TODO - Implement onSingleTapConfirmed actions.
// You can get all Views in mFrame using the
// ViewGroup.getChildCount() method
for(int i=0;i<mFrame.getChildCount();i++){
BubbleView bubbleNew= (BubbleView) mFrame.getChildAt(i);
if (bubbleNew.intersects(event.getX(),event.getY())){
//sound now
return true;
}
}
BubbleView bubbleView = new BubbleView(getApplicationContext(), event.getX(), event.getY());
mFrame.addView(bubbleView);
bubbleView.start();
return true;
}
});
@Override
public boolean onTouchEvent(MotionEvent event) { // TODO - delegate the touch to the gestureDetector return mGestureDetector.onTouchEvent(event); }
定时任务
// Start moving the BubbleView & updating the display
private void start() { // Creates a WorkerThread
ScheduledExecutorService executor = Executors
.newScheduledThreadPool(1); // Execute the run() in Worker Thread every REFRESH_RATE
// milliseconds
// Save reference to this job in mMoverFuture
mMoverFuture = executor.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
// TODO - implement movement logic.
// Each time this method is run the BubbleView should
// move one step. If the BubbleView exits the display,
// stop the BubbleView's Worker Thread.
// Otherwise, request that the BubbleView be redrawn.
if(moveWhileOnScreen()){
stop(false);
}else{
postInvalidate(); }
}
}, 0, REFRESH_RATE, TimeUnit.MILLISECONDS);
}
// Draw the Bubble at its current location
@Override
protected synchronized void onDraw(Canvas canvas) {
super.onDraw(canvas);
// TODO - save the canvas
canvas.save(); // TODO - increase the rotation of the original image by mDRotate
mRotate += mDRotate;
// TODO Rotate the canvas by current rotation
canvas.rotate(mRotate, mXPos + mScaledBitmapWidth/2, mYPos + mScaledBitmapWidth/2); // TODO - draw the bitmap at it's new location
canvas.drawBitmap(mScaledBitmap, mXPos, mYPos, mPainter); // TODO - restore the canvas
canvas.restore();
}
注意canvas中画的图坐标不是在中心,而是左上角
// Sound variables
// AudioManager
private AudioManager mAudioManager;
// SoundPool
private SoundPool mSoundPool;
// ID for the bubble popping sound
private int mSoundID;
// Audio volume
private float mStreamVolume;
// Manage bubble popping sound
// Use AudioManager.STREAM_MUSIC as stream type
mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
mStreamVolume = (float) mAudioManager
.getStreamVolume(AudioManager.STREAM_MUSIC)
/ mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
// TODO - make a new SoundPool, allowing up to 10 streams
mSoundPool = new SoundPool(, AudioManager.STREAM_MUSIC, );
// TODO - set a SoundPool OnLoadCompletedListener that calls setupGestureDetector()
mSoundPool.setOnLoadCompleteListener(new OnLoadCompleteListener(){
@Override
public void onLoadComplete(SoundPool soundPool, int sampleId,
int status) {
if ( == status) {
setupGestureDetector();
}
}
});
// TODO - load the sound from res/raw/bubble_pop.wav
mSoundID = mSoundPool.load(this, R.raw.bubble_pop, );
mSoundPool.play(mSoundID, mStreamVolume, mStreamVolume, , , 1.0f);
(updated on Mar 1th)Programming Mobile Applications for Android Handheld Systems by Dr. Adam Porter的更多相关文章
- Programming Impala Applications
Programming Impala Applications The core development language with Impala is SQL. You can also use J ...
- PhoneGap与Jquery Mobile组合开发android应用的配置
PhoneGap与Jquery Mobile结合开发android应用的配置 由于工作需要,用到phonegap与jquery moblie搭配,开发android应用程序. 这些技术自己之前也都没接 ...
- 使用jQuery Mobile + PhoneGap 开发Android应用程序(转)
使用jQuery Mobile + PhoneGap 开发Android应用程序(转) 一.简介 jQuery Mobile是jQuery在手机上和平板设备上的版本.jQuery Mobile 不仅给 ...
- PhoneGap与Jquery Mobile结合开发android应用配置
由于工作需要,用到phonegap与jquery moblie搭配,开发android应用程序. 这些技术自己之前也都没接触过,可以说是压根没听说过,真是感慨,在开发领域,技术日新月异,知识真是永远学 ...
- javascript判断设备类型-手机(mobile)、安卓(android)、电脑(pc)、其他(ipad/iPod/Windows)等
使用device.js检测设备并实现不同设备展示不同网页 html代码: <!doctype html> <html> <head> <meta charse ...
- Signing Your Applications(Android签名相关)
In this document Signing Overview Signing in Debug Mode Signing in Release Mode Signing Android Wear ...
- scaleform mobile sdk for android 多点触摸 修正
修正 scaleform 的多点触控 (随手一记 给后来的人做个参考) scaleform 版本号 4.2.24 (估计这就是最后一个 移动版的版本了,万年没有更新了) 开始 一直以为 scalefo ...
- 无责任共享 Coursera、Udacity 等课程视频
本文转载自网络,原作者不详. (本文是用 markdown 写的,访问 https://www.zybuluo.com/illuz/note/71868 获得更佳体验) 程序语言 interactiv ...
- [转]Android 学习资料分享(2015 版)
转 Android 学习资料分享(2015 版) 原文地址:http://www.jianshu.com/p/874ff12a4c01 目录[-] 我是如何自学Android,资料分享(2015 版) ...
随机推荐
- rsync配置和同步数据
rsync的搭建配置1.环境和配置文件 rsyncd.conf(主配置文件) rsyncd.secrets(密码文件) pc1:192.168.0.1,rsync的服务器,配置rsyncd.conf文 ...
- Linux rpm 命令参数使用
RPM是RedHat Package Manager(RedHat软件包管理工具)类似Windows里面的“添加/删除程序” rpm 执行安装包二进制包(Binary)以及源代码包(Source)两种 ...
- HTTP DNS
试用地址 https://www.dnspod.cn/httpdns/demo 哪些人适合使用HTTP DNS 1.希望降低访问延迟.减少跨网访问的资讯.游戏类APP: 2.希望降低连接失败率,提升业 ...
- 线段树懒标记好题 HDU4578
(1)"1 x y c",代表 把区间 [x,y] 上的值全部加c (2)"2 x y c",代表 把区间 [x,y] 上的值全部乘以c (3)"3 ...
- poj 4438 Hunters
Hunters Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- cogs2060 除法表达式
http://blog.csdn.net/sdfzyhx/article/details/52254071 作为分母的数当然是越少越好.将x2作为分母,其他作为分子,不断约分,最后判断. /*by S ...
- 应用express mockjs模拟前端json数据接口
一.首先需要在项目安装express 1.cnpm install express --save-dev 2.cnpm install mockjs --save-dev 二.在项目根目录下新建pr ...
- Linux 之 文件压缩解压
文件压缩解压 参考教程:[千峰教育] 命令: gzip: 作用:压缩文件,只能是单个文件,不能是多个,也不能是目录. 格式:gzip file 说明:执行命令会生成file.gz,删除原来的file ...
- HRBUST 2064:萌萌哒十五酱的宠物~(最近公共祖先LCA)
题意:一个n个点的树,询问某两点之间的简单路径,问路径上任选三边能否组成一个三角形. N<100000,权值<109 思路: 这里最神奇的思路过于以下这个: n个数,任意三个都不能组成三角 ...
- SQL Server 触发器 详细讲解
最近在做微信活动,需要用到存储过程,在网上找了下感觉使用触发器更好些,和大家分享下 希望对你有用. 触发器是一种特殊类型的存储过程,它不同于之前的我们介绍的存储过程.触发器主要是通过事件进行触发被自动 ...
