- Hands-On Android UI Development
- Jason Morris
- 1014字
- 2021-07-02 23:26:09
Handling events from other activities
On Android, you'll often find that you want to send your user to another Activity to do something, and then return them to your current Activity with the result of that action. Good examples are having the user pick a contact, or take a photo with the camera app. In these cases, Android uses a system of special events that are built into the Activity class. For capturing travel expense claims, your user needs to be able to go select a file to attach things such as photos or email attachments to their claim.
In order to present them with a familiar file chooser (and avoid writing a file chooser ourselves), you'll need to use this mechanism. However, to read files from outside of your application's private space, you'll need it to ask the user for permissions. Anytime an application needs access to potentially sensitive data (public directories, the device's camera or microphones, contact list, and so on), you need permission from the user. In versions of Android prior to 6.0, this was done during installation; the application declared what permissions it needed, and the user could choose to not install it. However, this mechanism isn't very flexible to users, and was changed in 6.0 so that applications must now ask for permission at runtime.
In order to access the user's files, the application will both declare that it requires the permission, and will also include the code to ask for permission while it's running (covering both cases):
- Open the CaptureClaimActivity class, and make the class implement the View.OnClickListener interface:
public class CaptureClaimActivity extends AppCompatActivity
implements View.OnClickListener {
- Create two new constants to hold the request codes. Anytime your user leaves your current Activity, and you are expecting a result, you need a request code:
private static final int REQUEST_ATTACH_FILE = 1;
private static final int REQUEST_ATTACH_PERMISSION = 1001;
- In the onCreate method, find the line where the Android Studio template captures the FloatingActionButton:
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
- Rename the button to attach, as follows (use the Android Studio refactoring to change the ID, and the ID in the layout file will be changed as well):
FloatingActionButton attach = (FloatingActionButton) findViewById(R.id.attach);
- Now, set OnClickListener for the FloatingActionButton to Activity:
attach.setOnClickListener(this);
- Now, at the end of the CaptureClaimActivity, implement the onClick method, and delegate the click from the FloatingActionButton:
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.attach:
onAttachClick();
break;
}
}
- Your application will need permission to read the content from outside its own private space. Open the manifests folder in the file browser, and open the AndroidManifest.xml file:

- At the top of the file within the manifest element, but before the application element, add the following permission declaration:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.packtpub.claim">
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="23" />
<application
android:name=".ClaimApplication"
- The preceding permission only works for versions of Android where permissions were requested during installation; on Android 6.0 and newer, you need to check and request permissions at runtime. Doing this when the user taps on the FloatingActionButton to attach a file is the best time, as this is just before they actually choose a file that you will need permission to read. Implement the onAttachClick method, starting with a check for the permission, and request the permission if it's not already granted:
public void onAttachClick() {
final int permissionStatus = ContextCompat.checkSelfPermission(
this,
Manifest.permission.READ_EXTERNAL_STORAGE);
if (permissionStatus != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_ATTACH_PERMISSION);
return;
}
- Now the app can request that the system start an Activity, allowing the user to choose any openable file. This is where the REQUEST_ATTACH_FILE constant you defined earlier starts getting used:
final Intent attach = new Intent(Intent.ACTION_GET_CONTENT)
.addCategory(Intent.CATEGORY_OPENABLE)
.setType("*/*");
startActivityForResult(attach, REQUEST_ATTACH_FILE);
}
- If we failed the preceding permission check, the system will have launched a dialog asking whether the user would grant permission to access external files. When the user returns from this dialog, a method named onRequestPermissionsResult will be invoked. Here, you need to check whether they granted your request, and if so, you can simply trigger the onAttachClick() method to continue the process smoothly:
@Override
public void onRequestPermissionsResult(
final int requestCode,
final String[] permissions,
final int[] grantResults) {
switch (requestCode) {
case REQUEST_ATTACH_PERMISSION:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
onAttachClick();
}
break;
}
}
- Now when the system returns from the file chooser Activity, it will invoke a method called onActivityResult, which is very similar in structure to the onRequestPermissionResult method:
@Override
protected void onActivityResult(
final int requestCode,
final int resultCode,
final Intent data) {
switch (requestCode) {
case REQUEST_ATTACH_FILE:
onAttachFileResult(resultCode, data);
break;
}
}
- In the preceding onActivityResult, you simply check whether it's responding to your request to attach a file, and then delegate the rest to a method that will need to handle the resulting data:
public void onAttachFileResult(
final int resultCode, final Intent data) {
- Verify that the resultCode was okay and that the data is valid:
if (resultCode != RESULT_OK
|| data == null
|| data.getData() == null) {
return;
}
- For now, you'll just want a Toast to pop up showing that this code has run; later, you can build the complete logic to attach the selected file. A Toast is a small message that appears and then disappears with no user interaction, perfect for temporary messages or debugging:
Toast.makeText(this, data.getDataString(), Toast.LENGTH_SHORT).show();
Now, if you run the application and tap on the floating action attach button, you'll be rewarded with a permission request (if you're running Android 6 or higher, on earlier versions the permission is granted as part of the installation), and then the option to select a file with whatever file selection systems you might have available on your emulator or device. Once you have chosen a file, you'll be returned to the CaptureClaimActivity and the selected Uri will be displayed in a Toast message on the screen:

This might not look like much, but it's all you need to access the file later on and attach it to the claim that the user is capturing. When you need to send your user to another Activity, you're hooking into Android's Activity to Activity messaging systems through methods such as onActivityResult and onRequestPermissionsResult.
- Java程序設計實戰教程
- Visual FoxPro程序設計教程
- Spring技術內幕:深入解析Spring架構與設計
- Web Development with Django Cookbook
- 深入淺出Android Jetpack
- Unity Shader入門精要
- Building a Quadcopter with Arduino
- VMware虛擬化技術
- 前端HTML+CSS修煉之道(視頻同步+直播)
- Python3.5從零開始學
- Arduino電子設計實戰指南:零基礎篇
- Clojure編程樂趣
- JSP應用與開發技術(第3版)
- OpenStack Sahara Essentials
- Mastering VMware Horizon 6