使用意图捕获图片后,应用程序崩溃

时间:2016-09-09 11:11:58

标签: android

使用intents.log cat捕获5到6张照片后,我的应用程序崩溃了。我无法找到崩溃的原因。请帮帮我。

    private void capturePhoto() {

        File root = new File(Environment.getExternalStorageDirectory(), "Feedback");
        if (!root.exists()) {
            root.mkdirs();
        }
        File file = new File(root, Constants.PROFILE_IMAGE_NAME + ".jpeg");
        Uri outputFileUri = Uri.fromFile(file);


        Intent photoPickerIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        photoPickerIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
        photoPickerIntent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        photoPickerIntent.putExtra("return-data", true);
        photoPickerIntent.putExtra("android.intent.extras.CAMERA_FACING", 1);
        startActivityForResult(photoPickerIntent, requestCode);


    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (this.requestCode == requestCode && resultCode == RESULT_OK) {

            File root = new File(Environment.getExternalStorageDirectory(), "Feedback");
            if (!root.exists()) {
                root.mkdirs();
            }
            File file = new File(root, Constants.PROFILE_IMAGE_NAME+".jpeg");
            checkFlowIdisPresent(file);

            displayPic();


        }
    }
  private void displayPic() {

        String filePath = Environment.getExternalStorageDirectory()
                .getAbsolutePath() + File.separator + "/Feedback/" + Constants.PROFILE_IMAGE_NAME + ".jpeg";
        //  Bitmap bmp = BitmapFactory.decodeFile(filePath);
        //Bitmap scaled = Bitmap.createScaledBitmap(bmp, 300, 300, true);


        File imgFile = new File(filePath);
        Bitmap bmp = decodeFile(imgFile);

        if (imgFile.exists()) {

            dispProfilePic.setImageBitmap(bmp);
        } else {
            dispProfilePic.setBackgroundResource(R.drawable.user_image);

        }
    }

 private Bitmap decodeFile(File f) {
        try {
            // Decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(new FileInputStream(f), null, o);

            // The new size we want to scale to
            final int REQUIRED_SIZE = 70;

            // Find the correct scale value. It should be the power of 2.
            int scale = 1;
            while (o.outWidth / scale / 2 >= REQUIRED_SIZE &&
                    o.outHeight / scale / 2 >= REQUIRED_SIZE) {
                scale *= 2;
            }

            // Decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize = scale;
            return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
        } catch (FileNotFoundException e) {
        }
        return null;
    }

以上代码用于捕获照片并在ImageView中显示捕获的图片。我正在使用MI选项卡。

编辑实际应用程序没有崩溃...它变为白色屏幕,如果我按任何按钮然后它崩溃并且onActivityResult在它变为白屏时不执行

新修改我可以复制此内容。我点击了监视器,点击了Android监视器。然后,当我与app交互时,它显示应用程序的内存利用率。现在在左侧栏我点击终止应用程序图标。现在有趣的是它会破坏当前的活动并转移到以前的活动。之前的活动变为白屏。

请帮帮我们。

9 个答案:

答案 0 :(得分:3)

试试这段代码。我在我的一些应用程序中使用它:

启动意图方法:

private void launchCamera() {
        Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);
    }

捕获结果:

@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        try {
            if (requestCode == CAMERA_PIC_REQUEST) {
                if (data != null) {
                    Bundle extras = data.getExtras();
                    if (extras != null) {
                        Bitmap thumbnail = (Bitmap) extras.get("data");
                        if (thumbnail != null)
                            displayPic(thumbnail);
                    }
                }
            }
            } catch (Exception e) {
            e.printStackTrace();
            }
    }

答案 1 :(得分:3)

你的代码很好......

我认为你保存图像或用相同名称覆盖同一路径上的图像,因此存在内存问题。因此,我建议您使用System.currentTimeMillis()或任意随机名称更改名称,而不是Constants.PROFILE_IMAGE_NAME

并检查权限

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

同时检查此权限的运行时间...对于运行时间,请按照this

private static final int REQUEST_RUNTIME_PERMISSION = 123;


    if (CheckPermission(demo.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {


        capturePhoto();

    } else {
        // you do not have permission go request runtime permissions
        RequestPermission(demo.this, Manifest.permission.WRITE_EXTERNAL_STORAGE, REQUEST_RUNTIME_PERMISSION);
    }



public void RequestPermission(Activity thisActivity, String Permission, int Code) {
        if (ContextCompat.checkSelfPermission(thisActivity,
                Permission)
                != PackageManager.PERMISSION_GRANTED) {
            if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
                    Permission)) {
                capturePhoto();

            } else {
                ActivityCompat.requestPermissions(thisActivity,
                        new String[]{Permission},
                        Code);
            }
        }
    }

    public boolean CheckPermission(Activity context, String Permission) {
        if (ContextCompat.checkSelfPermission(context,
                Permission) == PackageManager.PERMISSION_GRANTED) {
            return true;
        } else {
            return false;
        }
    }

答案 2 :(得分:3)

如果日志中没有显示任何内容,则很难推测任何内容,但请在使用模拟器时检查问题是否为,而不是在真实设备上。您还可以检查是否可以通过使仿真器容量更小(Ram和内部存储器)来重现问题。如果是这种情况,那么增加模拟器的内存或内存,它应该可以正常工作。然后,您需要为较低规格的设备优化图像处理任务。

希望这有帮助。

答案 3 :(得分:2)

这可能是因为操作系统调用活动被杀死然后重新启动,因为IMAGE CAPTURE意图处理大量内存以处理通过CAMERA捕获的BITMAP。< / p>

解决方案:保存图片的文件路径,并在调用 onActivityResult 时使用它。您可以使用 onSavedInstanceState onRestoreInstanceState 方法来保存和检索 IMAGE_PATH 以及活动的其他字段。

您可以参考how to use onSavedInstanceState and onRestoreInstanceState

的此链接

答案 4 :(得分:2)

尝试在异步任务中执行此操作,因为您遇到的问题是由于在UI线程中完成的拥抱处理

请参阅here以获取有关异步任务实施的更多帮助

答案 5 :(得分:2)

这可能是您正在拍摄照片并将其存储在位图中的内存问题 检查你的Android监视器的APp内存检测 只需将此方法设为静态

即可
private static Bitmap decodeFile(File f) {
        try {
            // Decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(new FileInputStream(f), null, o);

            // The new size we want to scale to
            final int REQUIRED_SIZE = 70;

            // Find the correct scale value. It should be the power of 2.
            int scale = 1;
            while (o.outWidth / scale / 2 >= REQUIRED_SIZE &&
                    o.outHeight / scale / 2 >= REQUIRED_SIZE) {
                scale *= 2;
            }

            // Decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize = scale;
            return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
        } catch (FileNotFoundException e) {
        }
        return null;
    }

使用不同的名称保存文件,例如以时间戳名称保存

答案 6 :(得分:1)

尝试使用以下代码。它对我来说很好。

 private static final int REQUEST_CAMERA = 1;

 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (resultCode == RESULT_OK)
    {
        if (requestCode == REQUEST_CAMERA)
        {
            Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
            ByteArrayOutputStream bytes = new ByteArrayOutputStream();
            thumbnail.compress(Bitmap.CompressFormat.JPEG, 90, bytes);

            File destination = new File(Environment.getExternalStorageDirectory(), System.currentTimeMillis() + ".jpg");

            FileOutputStream fos;

            try
            {
                destination.createNewFile();
                fos = new FileOutputStream(destination);
                fos.write(bytes.toByteArray());
                fos.close();
            }
            catch (FileNotFoundException fnfe)
            {
                fnfe.printStackTrace();
            }
            catch (IOException ioe)
            {
                ioe.printStackTrace();
            }
            ivSetImage.setImageBitmap(thumbnail);

        }
   }
}

在给定的代码段中,我压缩了捕获的图像,因为解决了应用程序崩溃问题。

在您的情况下,在ImageView上设置图片时,您的应用程序崩溃时捕获的图像质量可能会很高。

尝试压缩图像。它会工作!

不要忘记在清单文件中添加权限。

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

答案 7 :(得分:1)

检查您的Manifast.xml文件权限 外部存储

<强>

和相机权限。

<uses-permission android:name="android.permission.CAMERA" />    
<uses-feature android:name="android.hardware.camera" />  <uses-feature
android:name="android.hardware.camera.autofocus" />

如果你的应用程序在Marsh enter code here锦葵花检查运行时权限

上运行

答案 8 :(得分:0)

尝试使用以下代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>

#define SIZE 512




int main(int argc, char *argv[])
{
    int portnumber;
    int sockfd; //for new client connections
    int sockfd_current; //for accepted clients
    struct sockaddr_in sockIn;
    struct sockaddr_in portIn;
    char buffert[SIZE];
    int addrlen;
    char ipAddress[INET_ADDRSTRLEN]; //incomming IP-address to server with length


    portnumber= atoi(argv[1]);  //second parameter passed from main into portnumber


    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)  //trying to create socket address-family
    {   
        perror ("socket");
        exit(1);
    }

    memset(&sockIn, 0, sizeof(sockIn)); //assign memory and set socket address structure
    sockIn.sin_family= AF_INET;
    sockIn.sin_addr.s_addr =INADDR_ANY;
    sockIn.sin_port = htons(portnumber); //assign port to network byteorder: hostToNetwork

    if(bind(sockfd, (struct sockaddr *) &sockIn, sizeof(sockIn)) == -1)//trying to assign address to socket
    {
    perror("bind");
    exit(1);
    }

    if(listen(sockfd, 10) == -1)    //trying to Listen for clients that fulfills the requirements  
    {
        perror("listen");
        exit(1);
    }
    addrlen = sizeof(portIn);
    if((sockfd_current = accept(sockfd, (struct sockaddr*) &portIn, (socklen_t*) &addrlen)) == -1)  //trying to Create a new socket for the accepted client
    {
        perror("accept");
        exit(1);
    }

//Start communication aka HEAD/GET from client...
    printf("Accepting connection...\n\n");
    if(recv(sockfd_current, buffert, sizeof(buffert), 0) == -1) //trying to recive message from client
    {
        perror("Failed to recive request from client");
        exit(1);
    }

    inet_ntop(AF_INET, &portIn.sin_addr, ipAddress, sizeof(ipAddress)); //convert binary-ip from client to "networkToPresentable" string
    printf("Request from %s:%i\n", ipAddress, ntohs(portIn.sin_port));
    printf("Message: %s\n", buffert);


//Responds to clients request
    printf("Send Response:\n\n");
    fgets(buffert, SIZE - 1, stdin);

    if(send(sockfd_current, buffert, strlen(buffert) + 1, 0) == -1) 
    {
        perror("send");
        exit(1);
    }


    close(sockfd_current);
    close(sockfd);
    return 0;
}