เจตนา ACTION_IMAGE_CAPTURE ของ Android


163

เรากำลังพยายามใช้แอพกล้องถ่ายรูปเพื่อให้ผู้ใช้ถ่ายภาพใหม่ มันใช้งานได้ดีถ้าเราออกไปEXTRA_OUTPUT extraและส่งกลับภาพบิตแมปขนาดเล็ก อย่างไรก็ตามหากเราputExtra(EXTRA_OUTPUT,...)ตั้งใจก่อนที่จะเริ่มทุกอย่างทำงานได้จนกว่าคุณจะพยายามกดปุ่ม "ตกลง" ในแอพกล้อง ปุ่ม "ตกลง" ไม่ทำอะไรเลย แอพกล้องเปิดอยู่และไม่มีอะไรล็อค เราสามารถยกเลิกได้ แต่ไฟล์ไม่เคยเขียน เราต้องทำอะไรเพื่อให้ได้ACTION_IMAGE_CAPTUREภาพที่เขียนไปยังไฟล์?

แก้ไข: สิ่งนี้กระทำผ่านMediaStore.ACTION_IMAGE_CAPTUREเจตนาเพื่อให้ชัดเจน

คำตอบ:


144

นี่เป็นข้อผิดพลาดที่บันทึกไว้เป็นอย่างดีใน Android บางรุ่น นั่นคือบน Google Experience สร้างของ Android การจับภาพไม่ทำงานตามที่บันทึกไว้ สิ่งที่ฉันใช้โดยทั่วไปคือสิ่งนี้ในคลาสยูทิลิตี้

public boolean hasImageCaptureBug() {

    // list of known devices that have the bug
    ArrayList<String> devices = new ArrayList<String>();
    devices.add("android-devphone1/dream_devphone/dream");
    devices.add("generic/sdk/generic");
    devices.add("vodafone/vfpioneer/sapphire");
    devices.add("tmobile/kila/dream");
    devices.add("verizon/voles/sholes");
    devices.add("google_ion/google_ion/sapphire");

    return devices.contains(android.os.Build.BRAND + "/" + android.os.Build.PRODUCT + "/"
            + android.os.Build.DEVICE);

}

จากนั้นเมื่อฉันเปิดใช้การจับภาพฉันสร้างความตั้งใจที่จะตรวจสอบข้อผิดพลาด

Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
if (hasImageCaptureBug()) {
    i.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File("/sdcard/tmp")));
} else {
    i.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
}
startActivityForResult(i, mRequestCode);

จากนั้นในกิจกรรมที่ฉันกลับไปฉันทำสิ่งต่าง ๆ ตามอุปกรณ์

protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
     switch (requestCode) {
         case GlobalConstants.IMAGE_CAPTURE:
             Uri u;
             if (hasImageCaptureBug()) {
                 File fi = new File("/sdcard/tmp");
                 try {
                     u = Uri.parse(android.provider.MediaStore.Images.Media.insertImage(getContentResolver(), fi.getAbsolutePath(), null, null));
                     if (!fi.delete()) {
                         Log.i("logMarker", "Failed to delete " + fi);
                     }
                 } catch (FileNotFoundException e) {
                     e.printStackTrace();
                 }
             } else {
                u = intent.getData();
            }
    }

สิ่งนี้ช่วยให้คุณไม่ต้องเขียนแอพกล้องใหม่ แต่รหัสนี้ก็ไม่ได้ยอดเยี่ยมเช่นกัน ปัญหาใหญ่คือ

  1. คุณไม่เคยได้รับภาพขนาดเต็มจากอุปกรณ์ที่มีบั๊ก คุณได้รับรูปภาพที่มีความกว้าง 512px ซึ่งใส่เข้าไปในผู้ให้บริการเนื้อหารูปภาพ บนอุปกรณ์ที่ไม่มีข้อผิดพลาดทุกอย่างทำงานเป็นเอกสารคุณจะได้ภาพใหญ่ปกติ

  2. คุณต้องรักษารายการไว้ ตามที่เขียนไว้มันเป็นไปได้สำหรับอุปกรณ์ที่จะกระพริบพร้อมกับรุ่นของ Android (พูดสร้างของ cyanogenmod ) ที่มีการแก้ไขข้อผิดพลาด หากเกิดขึ้นรหัสของคุณจะผิดพลาด การแก้ไขคือการใช้ลายนิ้วมือของอุปกรณ์ทั้งหมด


21
บน Galaxy S: intent.getData () ส่งคืนค่า null และยิ่งไปกว่านั้นแอปกล้องใน Galaxy s จะแทรกรูปภาพใหม่เข้าไปในแกลเลอรี่ด้วยตัวเอง แต่ไม่มี uri ที่ส่งคืน ดังนั้นหากคุณแทรกภาพถ่ายจากไฟล์ลงในแกลเลอรี่ภาพก็จะซ้ำกัน
Arseniy

1
เฮ้อุปกรณ์ของฉันไม่อยู่ในรายการที่นี่และฉันได้ดำเนินการโดย ur.but แต่ใบสมัครของฉันยังคงเกิดปัญหาฉันไม่ทราบเหตุผลโปรดช่วยฉัน
Geetanjali

ใช้รหัสนี้บนอุปกรณ์ droid-x และ sony xpheria อุปกรณ์ทั้งสองคืนค่าเจตนาเป็นโมฆะ droidx จะส่งกลับผลลัพธ์เป็น 0 ในขณะที่ xpheria ส่งคืนผลลัพธ์เป็น -1 ทุกคนรู้ว่าทำไมจึงควรเป็นเช่นนั้น
rOrlig

5
ลิงก์ไปยัง "ข้อผิดพลาดที่บันทึกไว้อย่างดี" ซึ่งเป็นจุดเริ่มต้นของคำตอบของ yanokwa นั้นไม่ถูกต้อง ข้อผิดพลาดนั้นเกี่ยวกับการเรียกใช้แอปกล้องโดยไม่ต้องputExtra (EXTRA_OUTPUT, ... )
Frank Harper

code.google.com/p/android/issues/detail?id=1480ทีนี้คุณจะอธิบายสิ่งนี้ได้อย่างไร
Pencilcheck

50

ฉันรู้ว่าสิ่งนี้ได้รับการตอบก่อนหน้านี้ แต่ฉันรู้ว่ามีผู้คนจำนวนมากติดอยู่กับเรื่องนี้ดังนั้นฉันจะเพิ่มความคิดเห็น

ฉันมีปัญหาเดียวกันนี้เกิดขึ้นกับ Nexus One ของฉัน นี่เป็นไฟล์ที่ไม่มีอยู่ในดิสก์ก่อนที่แอพกล้องจะเริ่มขึ้น ดังนั้นฉันทำให้แน่ใจว่าไฟล์ที่มีอยู่ก่อนที่จะเริ่มแอพกล้อง นี่คือตัวอย่างรหัสที่ฉันใช้:

String storageState = Environment.getExternalStorageState();
        if(storageState.equals(Environment.MEDIA_MOUNTED)) {

            String path = Environment.getExternalStorageDirectory().getName() + File.separatorChar + "Android/data/" + MainActivity.this.getPackageName() + "/files/" + md5(upc) + ".jpg";
            _photoFile = new File(path);
            try {
                if(_photoFile.exists() == false) {
                    _photoFile.getParentFile().mkdirs();
                    _photoFile.createNewFile();
                }

            } catch (IOException e) {
                Log.e(TAG, "Could not create file.", e);
            }
            Log.i(TAG, path);

            _fileUri = Uri.fromFile(_photoFile);
            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE );
            intent.putExtra( MediaStore.EXTRA_OUTPUT, _fileUri);
            startActivityForResult(intent, TAKE_PICTURE);
        }   else {
            new AlertDialog.Builder(MainActivity.this)
            .setMessage("External Storeage (SD Card) is required.\n\nCurrent state: " + storageState)
            .setCancelable(true).create().show();
        }

ฉันก่อนสร้างชื่อไฟล์ (ค่อนข้าง) ที่ไม่ซ้ำกันโดยใช้ MD5 แฮชและวางไว้ในโฟลเดอร์ที่เหมาะสม จากนั้นฉันจะตรวจสอบเพื่อดูว่ามีอยู่ (ไม่ควร แต่เป็นวิธีปฏิบัติที่ดีในการตรวจสอบอยู่แล้ว) หากไม่มีอยู่ฉันจะได้รับ dir พาเรนต์ (โฟลเดอร์) และสร้างลำดับชั้นของโฟลเดอร์ขึ้นมา (ดังนั้นหากโฟลเดอร์ที่นำไปสู่ตำแหน่งของไฟล์ไม่มีอยู่พวกเขาจะอยู่หลังบรรทัดนี้จากนั้นหลังจากนั้น ฉันสร้างไฟล์เมื่อไฟล์ถูกสร้างขึ้นฉันจะได้รับ Uri และส่งต่อไปยังจุดประสงค์จากนั้นปุ่ม OK จะทำงานตามที่คาดไว้และทั้งหมดเป็นสีทอง

ตอนนี้เมื่อกดปุ่มตกลงบนแอพกล้องไฟล์จะปรากฏในตำแหน่งที่กำหนด ในตัวอย่างนี้จะเป็น /sdcard/Android/data/com.example.myapp/files/234asdioue23498ad.jpg

ไม่จำเป็นต้องคัดลอกไฟล์ใน "onActivityResult" ตามที่โพสต์ไว้ข้างต้น


13
ตรวจสอบให้แน่ใจว่าคุณมี<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />รายการของคุณหากคุณใช้งานใหม่กว่า Android 1.5 - ใช้เวลาสองสามชั่วโมงในการดีบั๊กกล้องและสิ่งนี้ไม่ได้รวมอยู่ด้วยดังนั้นการบันทึกของฉันจะล้มเหลวเสมอ
swanson

มันใช้งานได้ดีสำหรับฉัน แต่ทุก ๆ ภาพประมาณ 10 ภาพไฟล์ว่างเปล่าไม่ถูกเขียนทับและฉันก็จบลงด้วยไฟล์ 0 ไบต์ที่ภาพควรจะเป็น มันน่ารำคาญมากและยากที่จะติดตาม
joey_g216

2
บนอุปกรณ์บางอย่างเช่น Nexus 7 ที่มี jelly bean คุณต้องเปลี่ยน Environment.getExternalStorageDirectory (). getName () เพื่อใช้. getAbsolutePath () แทน. getName ()
Keith

35

ฉันใช้กลยุทธ์การจับภาพมาหลายครั้งและดูเหมือนจะเป็นกรณีแพลตฟอร์มหรืออุปกรณ์บางอย่างซึ่งกลยุทธ์บางอย่างหรือทั้งหมดข้างต้นจะล้มเหลวในรูปแบบที่ไม่คาดคิด ฉันสามารถค้นหากลยุทธ์ที่ใช้รหัสการสร้าง URI ด้านล่างซึ่งดูเหมือนจะใช้งานได้จริงหากไม่ใช่ทุกกรณี

mPhotoUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 
            new ContentValues());
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mPhotoUri);
startActivityForResult(intent,CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE_CONTENT_RESOLVER);

เพื่อสนับสนุนการอภิปรายต่อไปและช่วยเหลือผู้มาใหม่ฉันได้สร้างแอปตัวอย่าง / ทดสอบที่แสดงกลยุทธ์ที่แตกต่างกันหลายประการสำหรับการปรับใช้การจับภาพ การมีส่วนร่วมของการใช้งานอื่น ๆ ได้รับการสนับสนุนอย่างแน่นอนเพื่อเพิ่มการสนทนา

https://github.com/deepwinter/AndroidCameraTester


มันเยี่ยมมาก ฉันยังไม่ได้ทดสอบสิ่งนี้กับอุปกรณ์ทั้งหมดของฉัน แต่ฉันคิดว่าคุณทำไปแล้ว มีเสียงดังมากในหัวข้อนี้และคำตอบนี้ง่ายและสะอาด ทำงานบน Nexus 5 จนถึงตอนนี้ซึ่งเป็นที่แรกที่ฉันได้รับรายงานมากมายว่า ACTION_IMAGE_CAPTURE ไม่ทำงานหากไม่มี EXTRA_OUTPUT ฉันหวังว่ามันจะใช้งานได้ทั่วกระดาน แต่จนถึงตอนนี้ก็ดีมาก ขอบคุณ
Rich

1
@deepwinter - ขอบคุณครับ ฉันดึงผมออกมา แต่ตัวแก้ไขเนื้อหาของคุณทำงานได้ดีในทุกสถานการณ์ที่ฉันมี
Billy Coover

สายไปปาร์ตี้นี้ แต่นี่เป็นทางออกเดียวสำหรับฉัน ขอบคุณมัด!
StackJP

ฉันสามารถเรียก MediaStore.EXTRA_OUTPUT ในonActivityResultหรือฉันต้องจำได้ด้วยตัวเอง ฉันจะต้องเก็บไว้อย่างถาวรเพื่อให้แอพของฉันจำได้แม้มันจะถูกทำลายในขณะที่ถ่ายภาพ ...
prom85

มันไม่ทำงานบน samsung galaxy note 3 ด้วย lolipop: ava.lang.NullPointerException: พยายามเรียกใช้วิธีเสมือน 'java.lang.String android.net.Uri.getScheme ()' ในการอ้างอิงวัตถุว่าง
Igor Janković

30

ฉันมีปัญหาเดียวกันกับที่ปุ่มตกลงในแอพกล้องไม่ได้ทำอะไรเลยทั้งในโปรแกรมจำลองและบน Nexus หนึ่ง

ปัญหาหายไปหลังจากระบุชื่อไฟล์ที่ปลอดภัยที่ไม่มีช่องว่างสีขาวไม่มีอักขระพิเศษในMediaStore.EXTRA_OUTPUT นอกจากนี้หากคุณระบุไฟล์ที่อยู่ในไดเรกทอรีที่ยังไม่ได้สร้างคุณต้องสร้างมันขึ้นมาก่อน แอปกล้องถ่ายรูปไม่ได้ทำ mkdir ให้คุณ


1
และตรวจสอบให้แน่ใจว่าคุณใช้mkdirs()แทนmkdir()ถ้าเส้นทางของคุณมีมากกว่าหนึ่งระดับไดเรกทอรีและคุณต้องการให้สร้างทั้งหมด ( mkdirสร้างเฉพาะไดเรกทอรีสุดท้าย 'ไดเรกทอรี' ใบไม้) ฉันมีปัญหากับสิ่งนั้นและคำตอบนี้ช่วยฉันได้
ไดอาน่า

เราสามารถใช้การประทับเวลาอย่างง่ายได้หรือไม่? หรือยังสามารถทำข้อผิดพลาด? pleas ทำแท็กฉันเมื่อตอบกลับ :)
Rakeeb Rajbhandari

@ user2247689 ฉันไม่แน่ใจเกี่ยวกับชื่อไฟล์ที่คุณสร้างโดย "Simple timestamps" แต่ตราบใดที่ไม่มีตัวอักษรพิเศษที่ไม่ได้รับอนุญาตจากรูปแบบ FAT ในการ์ด SD มันควรจะโอเคฉันคิดว่า
Yenchi

28

เวิร์กโฟลว์ที่คุณอธิบายควรทำงานตามที่คุณอธิบายไว้ มันอาจช่วยได้ถ้าคุณสามารถแสดงรหัสให้เราทราบเกี่ยวกับการสร้างเจตนา โดยทั่วไปรูปแบบต่อไปนี้จะช่วยให้คุณทำสิ่งที่คุณพยายาม

private void saveFullImage() {
  Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
  File file = new File(Environment.getExternalStorageDirectory(), "test.jpg");
  outputFileUri = Uri.fromFile(file);
  intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
  startActivityForResult(intent, TAKE_PICTURE);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  if ((requestCode == TAKE_PICTURE) && (resultCode == Activity.RESULT_OK)) {
    // Check if the result includes a thumbnail Bitmap
    if (data == null) {    
      // TODO Do something with the full image stored
      // in outputFileUri. Perhaps copying it to the app folder
    }
  }
}

โปรดทราบว่ามันเป็นกิจกรรมกล้องที่จะสร้างและบันทึกไฟล์และมันไม่ได้เป็นส่วนหนึ่งของแอปพลิเคชันของคุณดังนั้นจึงไม่มีสิทธิ์เขียนไปยังโฟลเดอร์แอปพลิเคชันของคุณ หากต้องการบันทึกไฟล์ลงในโฟลเดอร์แอปของคุณให้สร้างไฟล์ชั่วคราวบนการ์ด SD และย้ายไปยังโฟลเดอร์แอปของคุณในonActivityResultตัวจัดการ


สิ่งนี้ / ควร / ทำงานได้ แต่ปุ่มตกลงของแอปกล้องไม่ทำอะไรเลย เราทำให้มันทำงานได้เขียนไปยังการ์ด SD ดังนั้นฉันสงสัยว่านี่เป็นปัญหาการอนุญาตไฟล์ (แม้ว่าฉันคิดว่าแอปพลิเคชันมีสิทธิ์ในการเขียนลงในไดเรกทอรีส่วนบุคคลโดยอัตโนมัติ) ขอบคุณสำหรับความช่วยเหลือ!
Drew

1
แอปของคุณมีสิทธิ์เขียนเป็นไดเรกทอรีส่วนบุคคล - แอปกล้องถ่ายรูป (ซึ่งกำลังถ่ายรูป) ไม่ได้ คุณสามารถย้ายไฟล์ใน theActivityResult ได้เช่นกันเพราะนั่นคือภายในแอปของคุณ หรือคุณอาจใช้กิจกรรมกล้องด้วยตัวเอง แต่ดูเหมือนจะเกินความจริง
Reto Meier

การทำซ้ำแอปกล้องดูเหมือนจะเป็นวิธีที่ธรรมดา แต่น่าเบื่อ ... เมื่อเราใช้ getDir ("images", MODE_WORLD_WRITEABLE) การอนุญาตนั้นไม่ได้ใช้กับไฟล์ใด ๆ ที่เราบอกให้สร้างในไดเรกทอรีนั้นหรือไม่?
Drew

ไม่จำเป็น. การอนุญาตสำหรับโฟลเดอร์นั้นไม่จำเป็นสำหรับไฟล์ที่อยู่ภายใน
Reto Meier

ฉันทดสอบรหัสด้วยอุปกรณ์ Android ที่ใช้ Android 2.2 ขึ้นไปและทั้งหมดนั้นบันทึกภาพไว้ในเส้นทางที่ให้มา ดังนั้นฉันเดาว่านี่ควรเป็นพฤติกรรมมาตรฐานในการรับภาพ
Janusz

7

หากต้องการติดตามความคิดเห็นของ Yenchi ด้านบนปุ่ม OK จะไม่ทำอะไรเลยหากแอปกล้องไม่สามารถเขียนไปยังไดเรกทอรีที่เป็นปัญหาได้

ซึ่งหมายความว่าคุณไม่สามารถสร้างไฟล์ในสถานที่ที่แอปพลิเคชันของคุณสามารถเขียนได้เท่านั้น (ตัวอย่างเช่นบางสิ่งภายใต้บางสิ่งภายใต้getCacheDir())สิ่งที่getExternalFilesDir()ควรใช้งานได้

มันจะดีถ้าแอพกล้องพิมพ์ข้อความแสดงข้อผิดพลาดไปยังบันทึกถ้ามันไม่สามารถเขียนไปยังEXTRA_OUTPUTเส้นทางที่ระบุแต่ฉันไม่พบมัน


4

เพื่อให้กล้องเขียนไปยัง sdcard แต่เก็บไว้ในอัลบั้มใหม่ในแอพแกลเลอรี่ฉันใช้สิ่งนี้:

 File imageDirectory = new File("/sdcard/signifio");
          String path = imageDirectory.toString().toLowerCase();
           String name = imageDirectory.getName().toLowerCase();


            ContentValues values = new ContentValues(); 
            values.put(Media.TITLE, "Image"); 
            values.put(Images.Media.BUCKET_ID, path.hashCode());
            values.put(Images.Media.BUCKET_DISPLAY_NAME,name);

            values.put(Images.Media.MIME_TYPE, "image/jpeg");
            values.put(Media.DESCRIPTION, "Image capture by camera");
           values.put("_data", "/sdcard/signifio/1111.jpg");
         uri = getContentResolver().insert( Media.EXTERNAL_CONTENT_URI , values);
            Intent i = new Intent("android.media.action.IMAGE_CAPTURE"); 

            i.putExtra(MediaStore.EXTRA_OUTPUT, uri);

            startActivityForResult(i, 0); 

โปรดทราบว่าคุณจะต้องสร้างชื่อไฟล์ที่ไม่ซ้ำกันทุกครั้งและแทนที่ teh 1111.jpg ที่ฉันเขียน นี่คือการทดสอบกับ Nexus หนึ่ง uri ถูกประกาศในคลาสส่วนตัวดังนั้นจากผลของกิจกรรมฉันสามารถโหลดรูปภาพจาก uri ไปยัง imageView เพื่อดูตัวอย่างถ้าต้องการ


คอลัมน์ "_data" มาจากไหน ไม่มีค่าคงที่หรือไม่
แมทเทียส

3
อามันเป็นdeveloper.android.com/reference/android/provider/ ......คุณไม่ควรใช้สายเวทย์ในรหัส
Matthias

1

ฉันมีปัญหาเดียวกันและฉันแก้ไขด้วยต่อไปนี้:

ปัญหาคือเมื่อคุณระบุไฟล์ที่มีเฉพาะแอปของคุณเท่านั้นที่สามารถเข้าถึง (เช่นโดยการโทรgetFileStreamPath("file");)

นั่นคือเหตุผลที่ฉันเพิ่งตรวจสอบให้แน่ใจว่าไฟล์ที่กำหนดมีอยู่จริงและทุกคนมีสิทธิ์ในการเขียน

Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
File outFile = getFileStreamPath(Config.IMAGE_FILENAME);
outFile.createNewFile();
outFile.setWritable(true, false);
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT,Uri.fromFile(outFile));
startActivityForResult(intent, 2);

ด้วยวิธีนี้แอปกล้องมีสิทธิ์เขียน Uri ที่กำหนดและปุ่ม OK ทำงานได้ดี :)


AndroidRuntime (2.1 อีมูเลเตอร์) พ่น NoSuchMethodError: java.io.File.setWritable
jwadsack

1

ฉันแนะนำให้คุณติดตามโพสต์อบรมสำหรับ Android เพื่อถ่ายภาพ พวกเขาแสดงในตัวอย่างวิธีการถ่ายภาพขนาดเล็กและใหญ่ คุณสามารถดาวน์โหลดซอร์สโค้ดได้จากที่นี่


0

ฉันสร้างห้องสมุดง่าย ๆ ซึ่งจะจัดการการเลือกภาพจากแหล่งต่าง ๆ (คลังภาพ, กล้อง), อาจบันทึกไว้ในบางตำแหน่ง (การ์ด SD หรือหน่วยความจำภายใน) และส่งคืนรูปภาพกลับคืนดังนั้นโปรดใช้ฟรีและปรับปรุง - Android-ImageChooser .


ลิงค์ของคุณไม่ทำงานอีกต่อไป !! ทำไมฉันเห็นมันเมื่อ 2 สัปดาห์ก่อนและฉันต้องการใช้มัน :(
Mohammad Ersan

0

กล้องจำเป็นต้องเขียนไฟล์ได้ดังที่Praveenชี้ให้เห็น

ในการใช้งานของฉันฉันต้องการเก็บไฟล์ไว้ในที่จัดเก็บข้อมูลภายใน ฉันทำสิ่งนี้กับ:

Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (i.resolveActivity(getPackageManager()!=null)){
    try{
        cacheFile = createTempFile("img",".jpg",getCacheDir());
        cacheFile.setWritavle(true,false);
    }catch(IOException e){}
    if(cacheFile != null){
        i.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(cacheFile));
        startActivityForResult(i,REQUEST_IMAGE_CAPTURE);
    }
}

นี่cacheFileคือไฟล์ทั่วโลกที่ใช้ในการอ้างถึงไฟล์ที่เขียน จากนั้นในวิธีการผลลัพธ์เจตนาที่ส่งคืนจะเป็นโมฆะ จากนั้นวิธีการประมวลผลเจตนาจะมีลักษณะดังนี้:

protected void onActivityResult(int requestCode,int resultCode,Intent data){
    if(requestCode != RESULT_OK){
        return;
    }
    if(requestCode == REQUEST_IMAGE_CAPTURE){
        try{
            File output = getImageFile();
            if(output != null && cacheFile != null){
                copyFile(cacheFile,output);

                //Process image file stored at output

                cacheFile.delete();
                cacheFile=null;
            }
        }catch(IOException e){}
    }
}

นี่getImageFile()คือวิธีการยูทิลิตี้เพื่อตั้งชื่อและสร้างไฟล์ที่ควรเก็บอิมเมจและcopyFile()เป็นวิธีการคัดลอกไฟล์


0

คุณสามารถใช้รหัสนี้

private Intent getCameraIntent() {

    PackageManager packageManager = mContext.getPackageManager();
    List<ApplicationInfo> list = packageManager.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);
    Intent main = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
    List<ResolveInfo> launchables = packageManager.queryIntentActivities(main, 0);
    if (launchables.size() == 1)
        return packageManager.getLaunchIntentForPackage(launchables.get(0).activityInfo.packageName);
    else
        for (int n = 0; n < list.size(); n++) {
            if ((list.get(n).flags & ApplicationInfo.FLAG_SYSTEM) == 1) {
                Log.d("TAG", "Installed Applications  : " + list.get(n).loadLabel(packageManager).toString());
                Log.d("TAG", "package name  : " + list.get(n).packageName);
                String defaultCameraPackage = list.get(n).packageName;


                if (launchables.size() > 1)
                    for (int i = 0; i < launchables.size(); i++) {
                        if (defaultCameraPackage.equals(launchables.get(i).activityInfo.packageName)) {
                            return packageManager.getLaunchIntentForPackage(defaultCameraPackage);
                        }
                    }
            }
        }
    return null;
}

0

มันง่ายมากที่จะแก้ปัญหานี้ด้วยรหัสกิจกรรมผลลัพธ์ลองวิธีนี้อย่างง่าย

if (reqCode == RECORD_VIDEO) {
   if(resCode == RESULT_OK) {
       if (uri != null) {
           compress();
       }
    } else if(resCode == RESULT_CANCELED && data!=null){
       Toast.makeText(MainActivity.this,"No Video Recorded",Toast.LENGTH_SHORT).show();
   }
}

ตัวอย่างที่ไม่สมบูรณ์ข้างต้นไม่ได้รับความเรียบง่ายที่อ้างสิทธิ์ แน่นอนว่ามีความซับซ้อนซ่อนเร้นสำหรับนักเดินทางที่ไม่คุ้นเคย เช่นการสแกนการมีหรือไม่มีไฟล์ เช่นเหี่ยวเฉามันเป็นแบบสาธารณะหรือส่วนตัวกับแอพ เช่นต้องมีผู้ให้บริการหรือรับรูปขนาดย่อเท่านั้น นี่เป็นช่องว่างของข้อมูลสำหรับนักเดินทางที่ไม่ระวังที่ต้องระวัง
trueadjustr

0
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_CANCELED)
    {
        //do not process data, I use return; to resume activity calling camera intent
        enter code here
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.