在 <manifest></manifest>
標籤內添加以下內容。
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
在 AndroidManifest.xml 文件中的 <application></application>
標籤內添加以下標籤。注意 android:authorities
這項屬性的 XXX.android.fileprovider
其中 XXX 是你的專案的前綴(不包含檔名)。
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.example.android.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"></meta-data>
</provider>
如果您的應用以Android 10(API級別29)為目標平台,請停用分區存儲。使更高版本 SDK 能相容。
<manifest ... >
<!-- This attribute is "false" by default on apps targeting
Android 10 or higher. -->
<application android:requestLegacyExternalStorage="true" ... >
...
</application>
</manifest>
當您將應用更新為以Android 11(API級別30)為目標平台後,如果應用在搭載Android 11的設備上運行,系統會忽略requestLegacyExternalStorage屬性,因此您的應用必須做好支持分區存儲並為這些設備上的用戶遷移應用數據的準備。
開啟 activity_main.xml 加入一個 ImageView 並將 id 命名為 displayImageView 與 Button 按鈕 id 命名 cameraBtn。
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:id="@+id/displayImageView"
android:layout_width="300dp"
android:layout_height="300dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.23000002"
app:srcCompat="@drawable/ic_launcher_background" />
<Button
android:id="@+id/cameraBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:text="Camera"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/displayImageView" />
</androidx.constraintlayout.widget.ConstraintLayout>
public class MainActivity extends AppCompatActivity {
public static final int CAMERA_PERM_CODE = 101;
public static final int CAMERA_REQUEST_CODE = 102;
ImageView selectedImage;
Button cameraBtn;
String currentPhotoPath;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
selectedImage = findViewById(R.id.displayImageView);
cameraBtn = findViewById(R.id.cameraBtn);
// Open Camera
cameraBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
verifyPermissions();
}
});
}
private void verifyPermissions(){
String[] permissions = {Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.CAMERA};
if(ContextCompat.checkSelfPermission(this.getApplicationContext(),
permissions[0]) == PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(this.getApplicationContext(),
permissions[1]) == PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(this.getApplicationContext(),
permissions[2]) == PackageManager.PERMISSION_GRANTED){
dispatchTakePictureIntent();
}else{
ActivityCompat.requestPermissions(this,
permissions,
CAMERA_PERM_CODE);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if(requestCode == CAMERA_PERM_CODE){
if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
dispatchTakePictureIntent();
}else {
Toast.makeText(this, "Camera Permission is Required to Use camera.", Toast.LENGTH_SHORT).show();
}
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == CAMERA_REQUEST_CODE){
if(resultCode == Activity.RESULT_OK){
File f = new File(currentPhotoPath);
selectedImage.setImageURI(Uri.fromFile(f));
Log.d("tag", "ABsolute Url of Image is " + Uri.fromFile(f));
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
}
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
// File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
currentPhotoPath = image.getAbsolutePath();
return image;
}
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
}
// Continue only if the File was successfully created
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(this,
"com.example.android.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, CAMERA_REQUEST_CODE);
}
}
}
}