(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 += "
";
            text += query.getString(query
                    .getColumnIndex(Browser.BookmarkColumns.URL));
            text += "

";

        }

        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(10, AudioManager.STREAM_MUSIC, 0);

        // TODO - set a SoundPool OnLoadCompletedListener that calls setupGestureDetector()
        mSoundPool.setOnLoadCompleteListener(new OnLoadCompleteListener(){

            @Override
            public void onLoadComplete(SoundPool soundPool, int sampleId,
                    int status) {
                if (0 == status) {
                    setupGestureDetector();
                }
            }
            
        });
        
        // TODO - load the sound from res/raw/bubble_pop.wav
        mSoundID = mSoundPool.load(this, R.raw.bubble_pop, 1);
mSoundPool.play(mSoundID, mStreamVolume, mStreamVolume, 1, 0, 1.0f);
原文地址:https://www.cnblogs.com/manhua/p/3538717.html