Professional Documents
Culture Documents
https://developer.android.com/docs/ (Sensors)
1
Internal Services
2
Sending Email: Java
public void sendScoresViaEmail() {
Intent emailIntent =
new Intent(android.content.Intent.ACTION_SEND);
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,
"Look at my AWESOME TicTacToe Score!");
// Can also fill To: using putExtra(..., EXTRA_EMAIL)
emailIntent.setType("plain/text");
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT,
firstPlayerName + " score is " + scorePlayerOne +
" and " + secondPlayerName + " score is " +
scorePlayerTwo);
startActivity(emailIntent);
}
4
SMS: Java
public void sendScoresViaSMS() {
Intent SMSIntent = new Intent(Intent.ACTION_VIEW);
SMSIntent.putExtra("sms_body",
"Look at my AWESOME TicTacToe Score!" +
firstPlayerName + " score is " + scorePlayerOne +
" and " + secondPlayerName + " score is " +
scorePlayerTwo);
SMSIntent.setType("vnd.android-dir/mms-sms");
startActivity(SMSIntent);
}
6
Telephony: Java
public void callTicTacToeHelp() {
Intent phoneIntent = new Intent(Intent.ACTION_DIAL);
String phoneNumber = "842-822-4357"; // TIC TAC HELP
String uri = "tel:" + phoneNumber.trim();
phoneIntent.setData(Uri.parse(uri));
startActivity(phoneIntent);
}
Needs:
<uses-permission
android:name="android.permission.CALL_PHONE"/>
7
Telephony: Kotlin
fun callTicTacToeHelp() {
val phoneIntent = Intent(Intent.ACTION_DIAL)
val phoneNumber = "842-822-4357" // TIC TAC HELP
val uri = "tel:" + phoneNumber.trim { it <= ' ' }
phoneIntent.data = Uri.parse(uri)
startActivity(phoneIntent)
}
8
Playing Audio Example: Setup
1. <?xml version="1.0" encoding="utf-8"?>
<LinearLayout ... >
<Button ... android:text="Start Audio"/>
<Button ... android:text="Stop Audio”/>
<Button ... android:text="Record Audio"/>
<Button ... android:text="Exit" />
</LinearLayout>
2.
12
Source: https://developer.android.com/reference/android/media/MediaPlayer.html
Playing Audio: Service: Java
<service android:enabled="true” android:name=".MediaPlaybackService”/>
// MediaPlayerService.java
public class MediaPlaybackService extends Service {
MediaPlayer player;
@Override
public IBinder onBind(Intent intent) { return null;}
@Override
public void onCreate() {
player = MediaPlayer.create(this, R.raw.sample_audio); player.setLooping(true); }
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
Bundle extras = intent.getExtras();
if (extras != null) {
String audioFileURIString = extras.getString("URIString");
Uri audioFileURI = Uri.parse(audioFileURIString);
try {
player.reset(); player.setDataSource(this.getApplicationContext(), audioFileURI);
player.prepare(); player.start();
} catch (Exception e) { e.printStackTrace(); }
}
return START_STICKY; }
@Override
13
public void onDestroy() { player.stop(); }
}
Playing Audio: Service: Kotlin
<service android:enabled="true” android:name=".MediaPlaybackService”/>
// MediaPlayerService.kt
class MediaPlaybackService : Service() {
internal lateinit var player: MediaPlayer
override fun onBind(intent: Intent): IBinder? { return null}
return Service.START_STICKY
}
15
// VideoFragment.java Handling Video:
Java (1)
public class VideoFragment extends Fragment
implements View.OnClickListener {
private Button mButtonStart, mButtonStop, mButtonRecord;
private VideoView mVideoView = null;
private Uri mVideoFileUri = null;
private Intent mRecordVideoIntent =
new Intent(android.provider.MediaStore.ACTION_VIDEO_CAPTURE);
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Activity activity = getActivity();
View v = inflater.inflate(R.layout.fragment_video, container, false);
mVideoView = v.findViewById(R.id.videoView);
// Get references to Buttons and for each Button, setOnClickListener(this);
String path =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES).getPath()
+ File.separator + "sample_video.mp4";
File videoFile = new File(path);
if (videoFile.exists()) { mVideoFileUri = Uri.fromFile(videoFile); }
else { // Video file doesn't exist, so load sample video from resources.
if (activity != null) {
String videoResourceName = "android.resource://" + activity.getPackageName() +
File.separator + R.raw.sample_video;
mVideoFileUri = Uri.parse(videoResourceName); } }
// Guard against no video recorder app (disable the "record" button).
return v; 16
}
}
Handling Video: Java (2)
// VideoFragment.java (continued)
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.buttonVideoStart:
// Load and start the movie
mVideoView.setVideoURI(mVideoFileUri);
mVideoView.start();
break;
case R.id.buttonVideoRecord:
startActivityForResult(mRecordVideoIntent, VIDEO_CAPTURED);
break;
case R.id.buttonVideoStop:
mVideoView.stopPlayback();
break;
case R.id.buttonVideoExit:
Activity activity = getActivity();
if (activity != null) { activity.finish(); }
break;
}
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK && requestCode == VIDEO_CAPTURED) {
mVideoFileUri = data.getData();
}
} 17
}
// AudioFragment.kt
class VideoFragment : Fragment(),
View.OnClickListener {
private lateinit var mButtonStart: Button
Handling Video:
private lateinit var mButtonStop: Button
private lateinit var mButtonRecord: Button
private lateinit var mVideoView: VideoView
Kotlin (1)
private var mVideoFileUri: Uri? = null
private val mRecordVideoIntent = Intent(android.provider.MediaStore.ACTION_VIDEO_CAPTURE)
20
Handling Images: Java (1)
// ImageFragment.java
public class ImagesFragment extends Fragment implements View.OnClickListener {
private ImageView imageView = null;
private static Uri imageFileURI;
private String imageFilePath = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES).getPath() + File.separator + "other_image.png";
private Bitmap imageBitmap = null;
private Intent mCaptureImageIntent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_images, container, false);
return v; 21
}
Handling Images: Java (2)
// ImageFragment.java (continued)
@Override
public void onClick(View view) {
switch(view.getId()) {
case R.id.buttonImageShow:
File imageFile = new File(imageFilePath);
if (imageFile.exists()) {
imageBitmap = BitmapFactory.decodeFile(imageFilePath);
imageView.setImageBitmap(imageBitmap);
} else {
// File doesn't exist, so load a sample SVG image.
imageView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
imageView.setImageResource(R.drawable.ic_scoreboard); }
break;
case R.id.buttonImageCapture:
startActivityForResult(mCaptureImageIntent, IMAGE_CAPTURED);
break;
case R.id.buttonImageExit:
// Finish Activity; call break
} 22
}
Handling Images: Java (3)
// ImageFragment.java (continued)
public void onActivityResult(int requestCode, int resultCode, Intent
cameraIntent) {
if (resultCode == RESULT_OK && requestCode == IMAGE_CAPTURED) {
Bundle extras = cameraIntent.getExtras();
if (extras != null) {
imageBitmap = (Bitmap) extras.get("data");
imageView.setImageBitmap(imageBitmap);
}
}
}
imageView = v.findViewById(R.id.imageView)
val buttonShow = v.findViewById(R.id.buttonImageShow)
val buttonCapture = v.findViewById(R.id.buttonImageCapture)
// Set onClickListener(this) for each Button
return v
} /* . . . */ 24
Handling Images: Kotlin (2)
// ImagesFragment.kt (continued)
override fun onClick(view: View) {
when (view.id) {
R.id.buttonImageShow -> {
val imageFile = File(imageFilePath)
if (imageFile.exists()) {
imageBitmap = BitmapFactory.decodeFile(imageFilePath)
imageView.setImageBitmap(imageBitmap)
} else {
// File doesn't exist, so load a sample SVG image.
// Disable hardware acceleration for SVGs
imageView.setLayerType(View.LAYER_TYPE_SOFTWARE, null)
imageView.setImageResource(R.drawable.ic_scoreboard)
}
}
R.id.buttonImageCapture -> startActivityForResult(mCaptureImageIntent,
IMAGE_CAPTURED)
}
}
25
Handling Images: Kotlin (3)
// ImagesFragment.kt (continued)
override fun onActivityResult(requestCode: Int, resultCode: Int,
cameraIntent: Intent?) {
if (resultCode == RESULT_OK && requestCode == IMAGE_CAPTURED) {
val extras = cameraIntent?.extras
if (extras != null) {
imageBitmap = extras.get("data") as Bitmap
imageView.setImageBitmap(imageBitmap)
}
}
}
26
Sensors
Uses:
Provide contextual and environmental data to app
Tailor app to environment, how people are using devices
Example Tic-Tac-Toe files:
SensorsFragment class
fragment_sensors.xml, list_item_sensor.xml
Issues:
Noisy sensor data on real-world devices
Best tested on real devices. To simulate sensors on the emulator see:
https://github.com/openintents/sensorsimulator
Inexpensive devices: Moto E (4th gen.), Moto G (5th gen.). See:
http://thewirecutter.com/reviews/best-budget-android-phone, Amazon, eBay
Type Examples
Motion Accelerometer, gyroscope
Environmental Light, temperature, humidity, barometric pressure
Miscellaneous Camera, microphone,
27 fingerprint, infrared
Displaying Sensors
Display all device sensors (and their Views
info) in a RecyclerView
RecyclerView: displays (possibly
large) dynamic list/grid of “items”
with limited memory footprint
More info:
https://developer.android.com/
guide/topics/ui/layout/recyclerview.
html
28
RecyclerView Workflow
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_sensor_list, container, false);
Activity activity = getActivity();
RecyclerView sensorRecyclerView = v.findViewById(R.id.sensor_recycler_view);
if (activity != null) {
sensorRecyclerView.setLayoutManager(new LinearLayoutManager(activity));
mSensorManager = (SensorManager) activity.getSystemService(SENSOR_SERVICE);
if (mSensorManager != null) {
mSensorList = mSensorManager.getSensorList(Sensor.TYPE_ALL);
SensorAdapter adapter = new SensorAdapter(mSensorList);
sensorRecyclerView.setAdapter(adapter);
sensorRecyclerView.setItemAnimator(new DefaultItemAnimator()); } }
return v; 30
}
Listing Available Sensors: Kotlin
private lateinit var mSensorRecyclerView: RecyclerView
private lateinit var mAdapter: SensorAdapter
private lateinit var mSensorManager: SensorManager
private lateinit var mSensorList: List<Sensor>
private var lastSensorValues = Hashtable<String, FloatArray>()
}
Registering Sensor Updates
36
References
Chapter 8 from Android Programming: The Big Nerd Ranch Guide, 3rd ed. (RecyclerView)
Services: http://developer.android.com/guide/topics/fundamentals/services.html
SMS: http://developer.android.com/reference/android/telephony/SmsManager.html
SIP (internet telephony): http://developer.android.com/reference/android/net/sip/package-
summary.html
MediaPlayer: http://developer.android.com/reference/android/media/MediaPlayer.html
MediaRecorder: http://developer.android.com/reference/android/media/MediaRecorder.html
MediaStore class (extract media metadata):
http://developer.android.com/reference/android/provider/MediaStore.html
Camera: http://developer.android.com/reference/android/hardware/Camera.html
BitmapFactory: http://developer.android.com/reference/android/graphics/BitmapFactory.html
Bitmap: http://developer.android.com/reference/android/graphics/Bitmap.html
Sensor: http://developer.android.com/reference/android/hardware/Sensor.html
SensorEvent:
http://developer.android.com/reference/android/hardware/SensorEventListener.html
37
Thank You
38