Boş niyet probleminden kaçınan basit çalışan kamera uygulaması
- bu yanıta dahil edilen tüm değiştirilmiş kodlar; android eğiticisine yakın
Bu konuya çok zaman harcadığım için bir hesap oluşturmaya ve sonuçlarımı sizinle paylaşmaya karar verdim.
Resmi android öğreticisi "Sadece Fotoğraf Çekmek" söz verdiği şeyi pek tutmadı. Orada sağlanan kod cihazımda çalışmadı: Android 4.4.2 / KitKat / API Seviye 19 sürümünü çalıştıran bir Samsung Galaxy S4 Mini GT-I9195.
Ana sorunun, fotoğrafı çekerken kullanılan yöntemdeki aşağıdaki satır olduğunu anladım ( dispatchTakePictureIntent
eğitimde):
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
onActivityResult
Null olarak sonradan yakalanan niyet ile sonuçlandı .
Bu sorunu çözmek için, burada daha önce yanıtlar ve github ilgili bazı yararlı mesajların (çoğunlukla dışarı çok ilham çekti deepwinter tarafından bu bir - onun için büyük teşekkür, siz bir yakından ilişkili onun cevap kontrol etmek isteyebilirsiniz yazı sıra).
Bu hoş tavsiyelerin ardından, söz konusu putExtra
satırı silme ve bunun yerine onActivityResult () yöntemi ile çekilen fotoğrafı kameradan geri alma stratejisini seçtim . Resimle ilişkili bitmap'i geri almak için belirleyici kod satırları şunlardır:
Uri uri = intent.getData();
Bitmap bitmap = null;
try {
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);
} catch (IOException e) {
e.printStackTrace();
}
Sadece resim çekme, SD karta kaydetme ve görüntüleme becerisine sahip örnek bir uygulama yarattım. Bu konuda tökezlediğimde benimle aynı durumdaki insanlara yardımcı olabileceğini düşünüyorum, çünkü mevcut yardım önerileri çoğunlukla söz konusu şeyi yapan ancak yeni başlayanlar için denetlenmesi çok kolay olmayan oldukça kapsamlı github gönderilerine atıfta bulunuyor. ben mi. Yeni bir proje oluştururken Android Studio'nun varsayılan olarak oluşturduğu dosya sistemi ile ilgili olarak, amacım için sadece üç dosyayı değiştirmek zorunda kaldım:
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical"
tools:context="com.example.android.simpleworkingcameraapp.MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="takePicAndDisplayIt"
android:text="Take a pic and display it." />
<ImageView
android:id="@+id/image1"
android:layout_width="match_parent"
android:layout_height="200dp" />
</LinearLayout>
MainActivity.java:
package com.example.android.simpleworkingcameraapp;
import android.content.Intent;
import android.graphics.Bitmap;
import android.media.Image;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MainActivity extends AppCompatActivity {
private ImageView image;
static final int REQUEST_TAKE_PHOTO = 1;
String mCurrentPhotoPath;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
image = (ImageView) findViewById(R.id.image1);
}
// copied from the android development pages; just added a Toast to show the storage location
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmm").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
Toast.makeText(this, mCurrentPhotoPath, Toast.LENGTH_LONG).show();
return image;
}
public void takePicAndDisplayIt(View view) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (intent.resolveActivity(getPackageManager()) != null) {
File file = null;
try {
file = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
}
startActivityForResult(intent, REQUEST_TAKE_PHOTO);
}
}
@Override
protected void onActivityResult(int requestCode, int resultcode, Intent intent) {
if (requestCode == REQUEST_TAKE_PHOTO && resultcode == RESULT_OK) {
Uri uri = intent.getData();
Bitmap bitmap = null;
try {
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);
} catch (IOException e) {
e.printStackTrace();
}
image.setImageBitmap(bitmap);
}
}
}
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.simpleworkingcameraapp">
<!--only added paragraph-->
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- only crucial line to add; for me it still worked without the other lines in this paragraph -->
<uses-permission android:name="android.permission.CAMERA" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Sorun için bulduğum çözümün aynı zamanda android manifest dosyasının basitleştirilmesine de yol açtığını unutmayın: Android öğreticisi tarafından bir sağlayıcı ekleme açısından önerilen değişikliklere artık java kodumda herhangi birini kullanmadığım için gerekli değildir. Bu nedenle, bildirim dosyasına yalnızca birkaç standart satır - çoğunlukla izinlerle ilgili - eklenmesi gerekiyordu.
Ayrıca, Android Studio'nun otomatik içe aktarmasının java.text.SimpleDateFormat
ve java.util.Date
. Her ikisini de manuel olarak içe aktarmak zorunda kaldım.