68
PHÁT TRIỂN ỨNG DỤNG CHO CÁC DỊCH VỤ DI ĐỘNG Các vấn đề khác 23/06/22

Lap Trinh Di Dong Ch3.6

Embed Size (px)

DESCRIPTION

gg

Citation preview

Page 1: Lap Trinh Di Dong Ch3.6

PHÁT TRIỂN ỨNG DỤNG CHO CÁC DỊCH VỤ DI ĐỘNG

Các vấn đề khác19/04/23

Page 2: Lap Trinh Di Dong Ch3.6

Animation và graphic

19/04/23

Page 3: Lap Trinh Di Dong Ch3.6

Animation

Có 2 hệ thống animation chính trong android Property animation

Cho phép thay đổi thuộc tính của các đối tượng (cả đối tượng không xuất hiện trên màn hình)

Khá mềm dẻo và mạnh View animation

Chỉ cho phép thực hiện animation trên đối tượng view Đủ mạnh cho hầu hết các hệ thống

Ngoài ra còn có Drawable animation Là cách thực hiện animation sử dụng chuỗi các

drawable (giống chiều phim)

19/04/23

Page 4: Lap Trinh Di Dong Ch3.6

Graphic

Có nhiều lựa chọn để vẽ các đối tượng graphic Canvas và drawable

Cung cấp một số view dùng để vẽ và hiển thị các đối tượng drawable

Hardware acceleration Có thể tăng tốc sử dụng phần cứng khi xử lý các hình

vẽ trong hầu hết các trường hợp OpenGL

Có thể sử dụng OpenGL cả trong Android framework API và Native Development Kit (NDK)

19/04/23

Page 5: Lap Trinh Di Dong Ch3.6

Property animation

Cho phép định nghĩa nhưng thông số của animation sau Độ dài Mức độ thay đổi tính chất theo thời gian

Hàm thay đổi của tính chất phụ thuộc vào thời gian Số lần lập lại và hành vi của animation

Có lập lại hay không Hành vi đặc biệt (chạy ngược)

Animation theo bộ Lập các bộ animation để quản lý (chạy theo thứ tự hay

đồng thời) Tốc độ refresh của màn hình

19/04/23

Page 6: Lap Trinh Di Dong Ch3.6

Animation

19/04/23

Non-linear animation

Linear animation

Page 7: Lap Trinh Di Dong Ch3.6

Các animator

Các các lớp dùng để thực hiện các animation ValueAnimator

Chỉ thực hiện tính toán thay đổi của giá trị Để thực hiện animation cần nghe sự kiện và tự thay

đổi thuộc tính của các đối tượng ObjectAnimator

Lớp con của ValueAnimator Thực hiện thêm bước thay đổi tính chất của đối tượng

AnimatorSet Gom các animation vào nhóm Cho phép sắp xếp thứ tự các animation trong nhóm

19/04/23

Page 8: Lap Trinh Di Dong Ch3.6

View animation

Dùng để thay đổi một số thuộc tính các đối tượng view Vị trí Kích thước Chiều xoay Mức độ trong (transparency)

19/04/23

Page 9: Lap Trinh Di Dong Ch3.6

19/04/23

<set android:shareInterpolator="false">    <scale        android:interpolator="@android:anim/accelerate_decelerate_interpolator"        android:fromXScale="1.0"        android:toXScale="1.4"        android:fromYScale="1.0"        android:toYScale="0.6"        android:pivotX="50%"        android:pivotY="50%"        android:fillAfter="false"        android:duration="700" />    <set android:interpolator="@android:anim/decelerate_interpolator">        <scale           android:fromXScale="1.4"           android:toXScale="0.0"           android:fromYScale="0.6"           android:toYScale="0.0"           android:pivotX="50%"           android:pivotY="50%"           android:startOffset="700"           android:duration="400"           android:fillBefore="false" />        <rotate           android:fromDegrees="0"           android:toDegrees="-45"           android:toYScale="0.0"           android:pivotX="50%"           android:pivotY="50%"           android:startOffset="700"           android:duration="400" />    </set></set>

ImageView spaceshipImage = (ImageView) findViewById(R.id.spaceshipImage);Animation hyperspaceJumpAnimation = AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump);spaceshipImage.startAnimation(hyperspaceJumpAnimation);

Dãn hình

Co và xoay đông thời

Load và áp dụng vào một ImageView

Page 10: Lap Trinh Di Dong Ch3.6

Drawable animation

Cho phép load một chuỗi các tài nguyên drawable Định nghĩa animation như là một tài nguyên

drawable (res/drawable/) Load và sử dụng như tài nguyên drawable bình

thường Tuy nhiên có thể khởi động animation

19/04/23

Page 11: Lap Trinh Di Dong Ch3.6

Drawable animation

19/04/23

Activity.javaAnimationDrawable rocketAnimation;

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

  ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);  rocketImage.setBackgroundResource(R.drawable.rocket_thrust);  rocketAnimation = (AnimationDrawable) rocketImage.getBackground();}

public boolean onTouchEvent(MotionEvent event) {  if (event.getAction() == MotionEvent.ACTION_DOWN) {    rocketAnimation.start();    return true;  }  return super.onTouchEvent(event);}

rocket_thrust.xml<animation-list xmlns:android="http://schemas.android.com/apk/res/android"    android:oneshot="true">    <item android:drawable="@drawable/rocket_thrust1" android:duration="200" />    <item android:drawable="@drawable/rocket_thrust2" android:duration="200" />    <item android:drawable="@drawable/rocket_thrust3" android:duration="200" /></animation-list>

Page 12: Lap Trinh Di Dong Ch3.6

Canvas và drawable

Vẽ trực tiếp lên đối tượng View Dùng trong trường hợp chỉ muốn vẽ đối tượng

đơn giản Ứng dụng tương đối tĩnh

Vẽ lên Canvas và điểu khiển mọi khía cạch của hiển thị và animation

19/04/23

Page 13: Lap Trinh Di Dong Ch3.6

Vẽ sử dụng Canvas

Vẽ lên View Sử dụng đối tượng Canvas khi vẽ trong phương

thức callback onDraw() onDraw() chỉ được gọi khi cần thiết nên nếu

muốn render lại thì cần gọi invalidate() Vẽ lên SurfaceView

Là một lớp con của View Cho phép vẽ các đối tượng bằng một thread

riêng (tránh phải chờ thread hệ thống)

19/04/23

Page 14: Lap Trinh Di Dong Ch3.6

Vẽ một hình bằng ImageView

19/04/23

LinearLayout mLinearLayout;

  protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);

  // Create a LinearLayout in which to add the ImageView  mLinearLayout = new LinearLayout(this);

  // Instantiate an ImageView and define its properties  ImageView i = new ImageView(this);  i.setImageResource(R.drawable.my_image);  i.setAdjustViewBounds(true); // set the ImageView bounds to match the Drawable's dimensions  i.setLayoutParams(new Gallery.LayoutParams(LayoutParams.WRAP_CONTENT,  LayoutParams.WRAP_CONTENT));

  // Add the ImageView to the layout and set the layout as the content view  mLinearLayout.addView(i);  setContentView(mLinearLayout);  }

Page 15: Lap Trinh Di Dong Ch3.6

Nine-patch

Nine-patch là hình chia làm 9 phần cho phép co dãn

19/04/23

<Button id="@+id/tiny"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentTop="true"        android:layout_centerInParent="true"        android:text="Tiny"        android:textSize="8sp"        android:background="@drawable/my_button_background"/>

<Button id="@+id/big"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentBottom="true"        android:layout_centerInParent="true"        android:text="Biiiiiiig text!"        android:textSize="30sp"        android:background="@drawable/my_button_background"/>

Page 16: Lap Trinh Di Dong Ch3.6

Media và Camera

19/04/23

Page 17: Lap Trinh Di Dong Ch3.6

Media playback

Android hỗ trợ media playback sử dụng MediaPlayer

Trước khi sử dụng MediaPlayer cần cài đặt một số quyền Internet permission

<uses-permission android:name="android.permission.INTERNET" />

Wake lock permission <uses-permission android:name="android.permission.WAKE_LOCK" />

19/04/23

Page 18: Lap Trinh Di Dong Ch3.6

MediaPlayer

Dùng để bật audio và video từ các nguồn khác nhau Tài nguyên địa phương URI trong (từ các ứng dụng khác) URL ngoài (stream)

19/04/23

MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.sound_file_1);mediaPlayer.start(); // no need to call prepare(); create() does that for you

Uri myUri = ....; // initialize Uri hereMediaPlayer mediaPlayer = new MediaPlayer();mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);mediaPlayer.setDataSource(getApplicationContext(), myUri);mediaPlayer.prepare();mediaPlayer.start();

String url = "http://........"; // your URL hereMediaPlayer mediaPlayer = new MediaPlayer();mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);mediaPlayer.setDataSource(url);mediaPlayer.prepare(); // might take long! (for buffering, etc)mediaPlayer.start();

Page 19: Lap Trinh Di Dong Ch3.6

prepare()

Hàm prepare() có thể mất nhiều thời gian Load dữ liệu trên mạng Nên gọi prepare từ một thread không phải là UI

thread Dùng prepareAsync() thay vì prepare()

onPrepared() của OnPreparedListener sẽ được gọi khi việc chuẩn bị được hoàn tất

19/04/23

Page 20: Lap Trinh Di Dong Ch3.6

Quản lý trạng thái của MediaPlayer

Cần hiểu trạng thái của MediaPlayer Mỗi hành động chỉ hợp lệ khi MediaPlayer ở một

trạng thái nhất định nào đó Nếu thực hiện hành động không hợp lệ,

exception sẽ xảy ra

19/04/23

Page 21: Lap Trinh Di Dong Ch3.6

19/04/23

Page 22: Lap Trinh Di Dong Ch3.6

Trả lại tài nguyên

MediaPlayer có thể sử dụng nhiều tài nguyên Cần phải trả lại tài nguyên khi không sử dụng Gọi release() khi không sử dụng Giải phóng biến trỏ đến MediaPlayer để Java có

thể xóa đối tượng

19/04/23

Page 23: Lap Trinh Di Dong Ch3.6

Sử dụng Service với MediaPlayer

Khi sử dụng MediaPlayer với Service ta nên Thực hiện các công việc nặng trên thread riêng Sử dụng prepareAsync

19/04/23

public class MyService extends Service implements MediaPlayer.OnPreparedListener {    private static final String ACTION_PLAY = "com.example.action.PLAY";    MediaPlayer mMediaPlayer = null;

    public int onStartCommand(Intent intent, int flags, int startId) {        ...        if (intent.getAction().equals(ACTION_PLAY)) {            mMediaPlayer = ... // initialize it here            mMediaPlayer.setOnPreparedListener(this);            mMediaPlayer.prepareAsync(); // prepare async to not block main thread        }    }

    /** Called when MediaPlayer is ready */    public void onPrepared(MediaPlayer player) {        player.start();    }}

Page 24: Lap Trinh Di Dong Ch3.6

Chạy service nổi

Sử dụng service nổi để bật media

19/04/23

String songName;// assign the song name to songNamePendingIntent pi = PendingIntent.getActivity(getApplicationContext(), 0,                new Intent(getApplicationContext(), MainActivity.class),                PendingIntent.FLAG_UPDATE_CURRENT);Notification notification = new Notification();notification.tickerText = text;notification.icon = R.drawable.play0;notification.flags |= Notification.FLAG_ONGOING_EVENT;notification.setLatestEventInfo(getApplicationContext(), "MusicPlayerSample",                "Playing: " + songName, pi);startForeground(NOTIFICATION_ID, notification);

Page 25: Lap Trinh Di Dong Ch3.6

Kiểu media hỗ trợ

Hỗ trợ hầu hết các định dạng Audio

AAC, FLAC, MP3, MIDI, WAVE … Image

JPEG, GIF, PNG, BMP… Video

H.263, MPEG-4 …

Xem thêm: http://developer.android.com/guide/appendix/media-formats.html

19/04/23

Page 26: Lap Trinh Di Dong Ch3.6

Ghi âm

Để ghi âm cần thực hiện các bước Tạo MediaRecorder Khai báo nguồn setAudioSource()

(MediaRecorder.AudioSource.MIC) Khai báo format setOutputFormat Khai báo tên file setOutputFile() Khai báo hệ mã hóa setAudioEncoder() Gọi prepare() Ghi âm start() Ngừng stop() Giải phóng MediaRecorder release()

19/04/23

Page 27: Lap Trinh Di Dong Ch3.6

19/04/23

public class AudioRecordTest extends Activity{    private static final String LOG_TAG = "AudioRecordTest";    private static String mFileName = null;

    private RecordButton mRecordButton = null;    private MediaRecorder mRecorder = null;

    private PlayButton   mPlayButton = null;    private MediaPlayer   mPlayer = null;

    private void onRecord(boolean start) {        if (start) {startRecording();} else {stopRecording();}    }

private void onPlay(boolean start) {        if (start) {startPlaying();} else {stopPlaying();}    }

    private void startPlaying() {        mPlayer = new MediaPlayer();        try {            mPlayer.setDataSource(mFileName);            mPlayer.prepare();            mPlayer.start();        } catch (IOException e) {            Log.e(LOG_TAG, "prepare() failed");        }    }

    private void stopPlaying() {        mPlayer.release();        mPlayer = null;    }

private void startRecording() {        mRecorder = new MediaRecorder();        mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);        mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);        mRecorder.setOutputFile(mFileName);        mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

        try {            mRecorder.prepare();        } catch (IOException e) {            Log.e(LOG_TAG, "prepare() failed");        }

        mRecorder.start();    } private void stopRecording() {        mRecorder.stop();        mRecorder.release();        mRecorder = null;    }

Page 28: Lap Trinh Di Dong Ch3.6

19/04/23

class RecordButton extends Button {        boolean mStartRecording = true;

        OnClickListener clicker = new OnClickListener() {            public void onClick(View v) {                onRecord(mStartRecording);                if (mStartRecording) {                    setText("Stop recording");                } else {                    setText("Start recording");                }                mStartRecording = !mStartRecording;            }        };

        public RecordButton(Context ctx) {            super(ctx);            setText("Start recording");            setOnClickListener(clicker);        }    }

class PlayButton extends Button {        boolean mStartPlaying = true;

        OnClickListener clicker = new OnClickListener() {            public void onClick(View v) {                onPlay(mStartPlaying);                if (mStartPlaying) {                    setText("Stop playing");                } else {                    setText("Start playing");                }                mStartPlaying = !mStartPlaying;            }        };

        public PlayButton(Context ctx) {            super(ctx);            setText("Start playing");            setOnClickListener(clicker);        }    }

Page 29: Lap Trinh Di Dong Ch3.6

19/04/23

@Override    public void onCreate(Bundle icicle) {        super.onCreate(icicle);

        LinearLayout ll = new LinearLayout(this);        mRecordButton = new RecordButton(this);        ll.addView(mRecordButton,            new LinearLayout.LayoutParams(                ViewGroup.LayoutParams.WRAP_CONTENT,                ViewGroup.LayoutParams.WRAP_CONTENT,                0));        mPlayButton = new PlayButton(this);        ll.addView(mPlayButton,            new LinearLayout.LayoutParams(                ViewGroup.LayoutParams.WRAP_CONTENT,                ViewGroup.LayoutParams.WRAP_CONTENT,                0));        setContentView(ll);    }

@Override    public void onPause() {        super.onPause();        if (mRecorder != null) {            mRecorder.release();            mRecorder = null;        }

        if (mPlayer != null) {            mPlayer.release();            mPlayer = null;        }    }}

public AudioRecordTest() {        mFileName = Environment.getExternalStorageDirectory().getAbsolutePath();        mFileName += "/audiorecordtest.3gp";    }

Page 30: Lap Trinh Di Dong Ch3.6

Camera

Định hướng ứng dụng Ứng dụng có nhất thiết phải cần camera không

Nếu có thì cần yêu cầu trong manifest Cách dùng camera

Sử dụng có thể sử dụng ảnh chụp từ ứng dụng khác Cung cấp một cách dùng camera mới

Lưu trữ Lưu trữ trong ứng dụng Lưu trữ trong Gallery cho ứng dụng khác sử dụng

19/04/23

Page 31: Lap Trinh Di Dong Ch3.6

Permission

Yêu cầu sử dụng Camera <uses-permission android:name="android.permission.CAMERA" /> Chú ý:Khi sử dụng ứng dụng chụp ảnh ngoài thì không cần permission này

Yêu cầu chỉ cài trên thiết bị có Camera <uses-feature android:name="android.hardware.camera" />

Yêu cầu sử dụng lưu trữ ngoài <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Yêu cầu được ghi âm <uses-permission android:name="android.permission.RECORD_AUDIO" />

Yêu cầu sử dụng thông tin định vị <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

19/04/23

Page 32: Lap Trinh Di Dong Ch3.6

Chụp ảnh sử dụng ứng dụng có sẵn

19/04/23

private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;private Uri fileUri;

@Overridepublic void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.main);

    // create Intent to take a picture and return control to the calling application    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

    fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image    intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name

    // start the image capture Intent    startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);}

Page 33: Lap Trinh Di Dong Ch3.6

Quay phim sử dụng ứng dụng có sẵn

19/04/23

private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;private Uri fileUri;

@Overridepublic void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.main);

    //create new Intent    Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);

    fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO);  // create a file to save the video    intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);  // set the image file name

    intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // set the video image quality to high

    // start the Video Capture Intent    startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);}

Page 34: Lap Trinh Di Dong Ch3.6

Nhận ảnh và phim kết quả

19/04/23

@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {    if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {        if (resultCode == RESULT_OK) {            // Image captured and saved to fileUri specified in the Intent            Toast.makeText(this, "Image saved to:\n" +                     data.getData(), Toast.LENGTH_LONG).show();        } else if (resultCode == RESULT_CANCELED) {            // User cancelled the image capture        } else {            // Image capture failed, advise user        }    }

    if (requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE) {        if (resultCode == RESULT_OK) {            // Video captured and saved to fileUri specified in the Intent            Toast.makeText(this, "Video saved to:\n" +                     data.getData(), Toast.LENGTH_LONG).show();        } else if (resultCode == RESULT_CANCELED) {            // User cancelled the video capture        } else {            // Video capture failed, advise user        }    }}

Page 35: Lap Trinh Di Dong Ch3.6

Viêt ứng dụng sử dụng Camera

Cần thực hiện các bước Phát hiện và truy cập Camera Tạo lớp xem trước Xây dựng layout để xem trước Cài đặt listener để thu ảnh Thu và lưu ảnh Giải phóng Camera

Xem thêm: http://developer.android.com/guide/topics/media/camera.html

#custom-camera

19/04/23

Page 36: Lap Trinh Di Dong Ch3.6

Xác định vị trí và cảm biến

19/04/23

Page 37: Lap Trinh Di Dong Ch3.6

Cảm biến trong thiết bị Android

Hầu hết các thiết bị Android đều có các cảm biến sau Cảm biến vị trí (GPS, A-GPS) Cảm biến gia tốc (accelerometer) Cảm biến con quay hồi chuyển (gyroscope) Cảm biến khoảng cách vật thể với màn hình

Có thể có Cảm biến ánh sáng Cảm biến áp suất (barometer) Cảm biến nhiệt độ (có thể) …

19/04/23

Page 38: Lap Trinh Di Dong Ch3.6

Vấn đề

Thông tin cảm biến môi trường là nhiều Sử dụng thông tin như thế nào?

Nhận dạng trạng thái của điện thoại Nhận dạng tình huống sử dụng Nhận dạng hành động của người dùng

Từ đó Cung cấp dịch vụ tiện lợi Cung cấp các tương tác trực quan Cung cấp các tương tác thông minh

19/04/23

Page 39: Lap Trinh Di Dong Ch3.6

Xác định vị trí

Android cung cấp dịch vụ xác định vị trí thông qua Google Location Service API Sử dụng LocationManager Lấy sử dụng

getSystemService(Context.LOCATION_SERVICE)

Có thể: Truy cập các vị trí người dùng đã từng qua Đăng ký hoặc bỏ cập nhật về vị trí Đăng ký hoặc bỏ việc kích hoạt một Intent nào đó khi

đến gần một vị trí xác định trước

19/04/23

Page 40: Lap Trinh Di Dong Ch3.6

Xác định vị trí đúng

Vấn đề của xác định vị trí chính xác Nhiều nguồn

GPS, Cell-ID và WIFI Sử dụng như thế nào còn phụ thuộc vào mức độ

chinh xác, tốc độ và tiết kiệm pin mong muốn Người dùng di chuyển

Phải cập nhật vị trí thường xuyên Mức độ chính xác thay đổi

Cùng một thiết bị có thể cho vị trí với độ chính xác khác nhau tại các thời điểm khác nhau

19/04/23

Page 41: Lap Trinh Di Dong Ch3.6

Yêu cầu cập nhật vị trí

19/04/23

// Acquire a reference to the system Location ManagerLocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);

// Define a listener that responds to location updatesLocationListener locationListener = new LocationListener() {    public void onLocationChanged(Location location) {      // Called when a new location is found by the network location provider.      makeUseOfNewLocation(location);    }

    public void onStatusChanged(String provider, int status, Bundle extras) {}

    public void onProviderEnabled(String provider) {}

    public void onProviderDisabled(String provider) {}  };

// Register the listener with the Location Manager to receive location updateslocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);

Cell và wifi

Điều khiển tần xuất cập nhật.•Thời gian giữa 2 cập nhật•Mức độ thay đổi tối thiểu giữa cập nhật

Page 42: Lap Trinh Di Dong Ch3.6

Permission

Để yêu cầu cập nhật vị trí sử dụng NETWORK_PROVIDER

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

GPS_PROVIDER <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

19/04/23

Page 43: Lap Trinh Di Dong Ch3.6

Mô hình nên sử dụng

Các bước nên dùng để xác định vị trí người dùng Khởi động ứng dụng Sau đó một thời gian, bắt đầu lắng nghe cập nhật vị

trí Giữ một giá trị vị trí tốt nhất, loại bỏ các vị trí mới

không chính xác Ngừng nghe cập nhật Sử dụng vị trí chính xác nhất đã ghi lại

19/04/23

Page 44: Lap Trinh Di Dong Ch3.6

Bắt đầu và dừng nghe cập nhật

Có thể bắt đầu nghe cập nhật ngay nhưng Nên đợi đến khi cần thiết

Nếu nghe quá lâu thì tốn pin Nêu nghe quá ngắn thì kết quả không chính xác

Nên trước khi sử dụng thông tin một khoảng thời gian và dừng ngay khi có đủ thông tin

19/04/23

//Start listeningString locationProvider = LocationManager.NETWORK_PROVIDER;// Or, use GPS location data:// String locationProvider = LocationManager.GPS_PROVIDER;

locationManager.requestLocationUpdates(locationProvider, 0, 0, locationListener);

//Stop listening// Remove the listener you previously addedlocationManager.removeUpdates(locationListener);

Page 45: Lap Trinh Di Dong Ch3.6

Xác định vị trí cuối cùng

Để đợi cập nhật vị trí đầu tiên có thể hơi lâu Nên sử dụng vị trí cuối cùng để cung cấp

thông tin cho người dùng

19/04/23

String locationProvider = LocationManager.NETWORK_PROVIDER;// Or use LocationManager.GPS_PROVIDER

Location lastKnownLocation = locationManager.getLastKnownLocation(locationProvider);

Page 46: Lap Trinh Di Dong Ch3.6

Duy trì vị trí chính xác nhất

Vị trí mới nhất chưa chắc đã là tốt nhất Do độ chính xác thay đổi

Để xác định độ chính xác cần làm Kiểm tra xem vị trí mới có mới hơn nhiều so với

cũ không Kiểm tra độ chính xác thiết bị vừa đưa ra vị trị

mới có tốt hơn thiêt bị đưa ra vị trí cũ không Kiểm tra loại thiết bị đo đạc và xác định độ tin cậy

19/04/23

Page 47: Lap Trinh Di Dong Ch3.6

19/04/23

private static final int TWO_MINUTES = 1000 * 60 * 2;

/** Determines whether one Location reading is better than the current Location fix  * @param location  The new Location that you want to evaluate  * @param currentBestLocation  The current Location fix, to which you want to compare the new one  */protected boolean isBetterLocation(Location location, Location currentBestLocation) {    if (currentBestLocation == null) {        // A new location is always better than no location        return true;    }

    // Check whether the new location fix is newer or older    long timeDelta = location.getTime() - currentBestLocation.getTime();    boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;    boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;    boolean isNewer = timeDelta > 0;

    // If it's been more than two minutes since the current location, use the new location    // because the user has likely moved    if (isSignificantlyNewer) {        return true;    // If the new location is more than two minutes older, it must be worse    } else if (isSignificantlyOlder) {        return false;    }

Page 48: Lap Trinh Di Dong Ch3.6

19/04/23

// Check whether the new location fix is more or less accurate    int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());    boolean isLessAccurate = accuracyDelta > 0;    boolean isMoreAccurate = accuracyDelta < 0;    boolean isSignificantlyLessAccurate = accuracyDelta > 200;

// Check if the old and new location are from the same provider    boolean isFromSameProvider = isSameProvider(location.getProvider(),            currentBestLocation.getProvider());

// Determine location quality using a combination of timeliness and accuracy    if (isMoreAccurate) {        return true;    } else if (isNewer && !isLessAccurate) {        return true;    } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {        return true;    }    return false;}

/** Checks whether two providers are the same */private boolean isSameProvider(String provider1, String provider2) {    if (provider1 == null) {      return provider2 == null;    }    return provider1.equals(provider2);}

Page 49: Lap Trinh Di Dong Ch3.6

Tiết kiêm pin

Để tiết kiệm pin cần chỉnh những thông số sau Giảm độ dài của đoạn lắng nghe cập nhật Giảm tần suất cập nhật Giảm số thiết bị cung cấp vị trí

19/04/23

Page 50: Lap Trinh Di Dong Ch3.6

Test ứng dụng

Có thể test ứng dụng chạy trên emulator bằng cách sử dụng Window > Show View > Other > Emulator

Contron

19/04/23

Page 51: Lap Trinh Di Dong Ch3.6

Bản đồ

Android cung cấp dịch vụ bản đồ thông qua Google Maps Android API Sử dụng MapView

Hiển thị bản đồ Lắng nghe sự kiện tương tác khi có focus Có thể vẽ nhiều lớp lên bản đồ

Xem thêm: https://developers.google.com/maps/documentation/android/start#getting_the_google_maps_android_api_v2

19/04/23

Page 52: Lap Trinh Di Dong Ch3.6

Sử dụng cảm biến

Có ba loại cảm biến chính Cảm biến chuyển động

Gia tốc, lực hút, con quay hồi chuyển, Cảm biến môi trường

Nhiệt độ, áp suất, ánh sáng, độ ẩm Cảm biến vị trí

Hướng quay, từ tính

Truy cập vào các cảm biến sử dụng Android Sensor Framework

19/04/23

Page 53: Lap Trinh Di Dong Ch3.6

Android Sensor Framework

Dùng để Xác định cảm biến nào có trên thiết bị Xác định khả năng của từng cảm biến

Phạm vi đo đạc Mức độ chính xác (resolution) Nhà sản xuất, mức độ sử dụng năng lượng

Thu thập dữ liệu thô và xác định tần suất thu nhận

Đăng ký và bỏ lắng nghe sự kiện thay đổi giá trị đo mới

19/04/23

Page 54: Lap Trinh Di Dong Ch3.6

Các loại cảm biến

19/04/23

Cảm biến Loại Mô tả Sử dụng

TYPE_ACCELEROMETER Phần cứngĐo gia tốc theo 3 chiều, cả lực hút trái đất (m/s2)

Xác định chuyển động

TYPE_AMBIENT_TEMPERATURE Phần cứng Đo nhiệt độ môi trường (độ C) Theo dõi nhiệt độ

TYPE_GRAVITYPhần cứng, phần mềm

Đo lực hút của trái đất theo 3 chiều (m/s2)

Xác định chuyền động

TYPE_GYROSCOPE Phần cứng Xác định tốc độ xoay theo 3 chiều (rad/s) Xác định độ xoay

TYPE_LIGHT Phần cứng Xác định độ sáng của môi trường (lx)Điều khiển độ sáng màn hình

TYPE_LINEAR_ACCELERATIONPhần cứng,phần mềm

Xác định gia tốc theo 3 chiều không bao gồm lực hút trái đất (m/s2)

Xác định gia tốc theo một hướng nhất định

TYPE_MAGNETIC_FIELD Phần cứngXác định từ tính của môi trường theo 3 chiều (μT)

Xác định hướng compass

Page 55: Lap Trinh Di Dong Ch3.6

Các loại cảm biến (tt)

19/04/23

Cảm biến Loại Mô tả Sử dụng

TYPE_ORIENTATION Phần mềmXác định hương xoay của thiết bị theo 3 chiều

Xác định vị trí của thiết bị

TYPE_PRESSURE Phần cứngXác định áp suất không khí (hPa hoặc mbar)

Theo dõi thay đổi áp suất, xác định độ cao so với mặt nước biển

TYPE_PROXIMITY Phần cứngXác định khoảng cách của vật thê so với mặt của màn hình

Xác định xem thiết bị đang được đặt gần tai người dùng

TYPE_RELATIVE_HUMIDITY Phần cứng Xác định độ ẩm không khí (%)Xác đinh độ ngưng tụ, độ ẩm

TYPE_ROTATION_VECTORPhần cứng,phần mềm

Xác định hướng xoay của thiết bị theo 3 thành phần của vector hướng

Xác định hướng xoay của thiết bị

TYPE_TEMPERATURE Phần cứng Xác định nhiệt độ của thiết bị (độ C) Theo dõ nhiệt độ thiết bị

Page 56: Lap Trinh Di Dong Ch3.6

Sensor framework

SensorManager Truy cập danh sách cảm biến Đăng ký và bỏ lắng nghe sự kiện cập nhật Hằng số của cảm biến Cài tần suất cảm biến Hiệu chuẩn cảm biến

Sensor Xác định khả năng của cảm biến

SensorEvent Sự kiện thông báo thông số đo của cảm biến

SensorEventListener Xử lý thông báo cập nhật độ đo của cảm biến

19/04/23

Page 57: Lap Trinh Di Dong Ch3.6

Xác định cảm biến và khả năng

Nên xác định các cảm biến có trên thiết bị Sử dụng các cảm biến khác nhau để thực hiện công việc

Sử dụng cảm biến lực hút hoặc gia tốc để điều khiển game đua xe

19/04/23

//Lấy SensorManagerprivate SensorManager mSensorManager;...mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);

//Lấy danh sách cảm biếnList<Sensor> deviceSensors = mSensorManager.getSensorList(Sensor.TYPE_ALL);

//Kiểm tra loại cảm biến cụ thểprivate SensorManager mSensorManager;...mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);if (mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) != null){  // Success! There's a magnetometer.  }else {  // Failure! No magnetometer.  }

Page 58: Lap Trinh Di Dong Ch3.6

Lắng nghe sự kiện cảm biến

Sử dụng SensorEventListener Cài onAccuracyChanged()

Cung cấp đối tượng Sensor Cung cấp độ chính xác của cảm biến

SENSOR_STATUS_ACCURACY_LOW SENSOR_STATUS_ACCURACY_MEDIUM SENSOR_STATUS_ACCURACY_HIGH SENSOR_STATUS_UNRELIABLE.

Cài onSensorChanged() Thông báo giá trị mới thông qua đối tượng

SensorEvent

19/04/23

Page 59: Lap Trinh Di Dong Ch3.6

19/04/23

public class SensorActivity extends Activity implements SensorEventListener {  private SensorManager mSensorManager;  private Sensor mLight;

  @Override  public final void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.main);    mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);    mLight = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);  }

  @Override  public final void onAccuracyChanged(Sensor sensor, int accuracy) {    // Do something here if sensor accuracy changes.  }

  @Override  public final void onSensorChanged(SensorEvent event) {    // The light sensor returns a single value.    // Many sensors return 3 values, one for each axis.    float lux = event.values[0];    // Do something with this sensor value.  }

  @Override  protected void onResume() {    super.onResume();    mSensorManager.registerListener(this, mLight, SensorManager.SENSOR_DELAY_NORMAL);  }

  @Override  protected void onPause() {    super.onPause();    mSensorManager.unregisterListener(this);  }}

Page 60: Lap Trinh Di Dong Ch3.6

Hệ tọa độ của cảm biến

Một số cảm biển chỉ đo một giá trị

Nhưng số khác đo giá trị trong một hệ tọa độ 3 chiều Hệ tọa độ này không đổi khi sử

dụng thiết bị Hệ tọa độ được xác định dựa

vào vị trí tự nhiên của thiết bị Điện thoại dùng dọc Tablet dùng ngang

19/04/23

Page 61: Lap Trinh Di Dong Ch3.6

Lưu ý khi sử dụng cảm biến

Bỏ đăng khi khi không cần sử dụng Không test code trên emulator

Có thể dùng giả lập Không nên xử lý nhiều trong onSensorChanged() Tránh sử dụng hàm và loại cảm biến đã bị loại

(deprecated) Luôn kiểm tra sự tồn tại của cảm biến trước khi

sử dụng Xác định tần suất đo đạc hợp lý, tránh lãng phí

năng lượng

19/04/23

Page 62: Lap Trinh Di Dong Ch3.6

Chi tiết các cảm biến

Cảm biến chuyển động: http://developer.android.com/guide/topics/sensors/sensors_motion.html

Cảm biến vị trí: http://developer.android.com/guide/topics/sensors/sensors_position.html

Cảm biến môi trường: http://developer.android.com/guide/topics/sensors/sensors_environment.html

19/04/23

Page 63: Lap Trinh Di Dong Ch3.6

Kết nối

19/04/23

Page 64: Lap Trinh Di Dong Ch3.6

Kết nối trong Android

Thiết bị di động có rất nhiều loại kết nối để tương tác với các thiết bị khác Bluetooth NFC Wifi P2P USB

Xem thêm: http://developer.android.com/guide/topics/connectivity/index.html

19/04/23

Page 65: Lap Trinh Di Dong Ch3.6

Lưu trữ

19/04/23

Page 66: Lap Trinh Di Dong Ch3.6

Các lựa chọn lưu trữ

Có nhiều lựa chọn Nội bộ Trên thiết bị Trên thẻ nhớ Trên cơ sở dữ liệu (SQLite) Trên mạng

Xem thêm: http://developer.android.com/guide/topics/data/index.html

19/04/23

Page 67: Lap Trinh Di Dong Ch3.6

Các lưu ý khác

19/04/23

Page 68: Lap Trinh Di Dong Ch3.6

Các lưu ý khác

Hỗ trợ nhiều kích thước màn hình Kích thước Mật độ Hướng xoay Xem thêm:

http://developer.android.com/guide/practices/screens_support.html

Hỗ trợ cả điện thoại và tablet Sử dụng Fragment Sử dụng Action bar Sử dụng layout mềm dẻo Xem thêm:

http://developer.android.com/guide/practices/tablets-and-handsets.html

19/04/23