如何从呼叫意图返回

发布于 2024-12-17 03:56:02 字数 1009 浏览 0 评论 0原文

我打电话给相机拍照。但拍完照片后我就无法再回到原来的活动了。有什么问题吗?谢谢。

    public void addEntry(View view)
{
              String EntryName=RegisterName.toString();
              Toast.makeText(this, EntryName, Toast.LENGTH_LONG);
              Intent addEntryintent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
              File file = new File(getFilesDir(),EntryName);
              registeryFileUri = Uri.fromFile(file);
              addEntryintent.putExtra(MediaStore.EXTRA_OUTPUT, registeryFileUri);
              startActivityForResult(addEntryintent,TAKE_PICTURE);         

}


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
      if (requestCode == TAKE_PICTURE) 
      {
          if (data != null)
          {   
         Toast.makeText(this, "Successfully Registered!", Toast.LENGTH_LONG);
         ImageView Registerimage= (ImageView)findViewById(R.id.RegisterPicture);
         Registerimage.setImageURI(registeryFileUri);
         }

    }
  }

I call camera to take a picture. But I cannot go back to my own original activity after taking the picture. What's the problem? Thank you.

    public void addEntry(View view)
{
              String EntryName=RegisterName.toString();
              Toast.makeText(this, EntryName, Toast.LENGTH_LONG);
              Intent addEntryintent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
              File file = new File(getFilesDir(),EntryName);
              registeryFileUri = Uri.fromFile(file);
              addEntryintent.putExtra(MediaStore.EXTRA_OUTPUT, registeryFileUri);
              startActivityForResult(addEntryintent,TAKE_PICTURE);         

}


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
      if (requestCode == TAKE_PICTURE) 
      {
          if (data != null)
          {   
         Toast.makeText(this, "Successfully Registered!", Toast.LENGTH_LONG);
         ImageView Registerimage= (ImageView)findViewById(R.id.RegisterPicture);
         Registerimage.setImageURI(registeryFileUri);
         }

    }
  }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

清风疏影 2024-12-24 03:56:02

我花了一段时间才让它发挥作用,我做了几件事,终于它起作用了。我无法确定我所做的哪些事情是问题的解决方案,但它们一起构成了可行的解决方案。

相机活动不返回的原因有多种。两个主要问题是:

  1. 新图片的路径无效,或不存在,或无法创建

  2. 应用程序被暂停,保存的路径丢失。

所以这是我的代码解决所有这些问题,所有这些问题一起工作。

首先,我创建了辅助类 ImageServices

class ImageServices {

  private static String getTempDirectoryPath(Context ctx) {
    File cache;

    // SD Card Mounted
    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
      cache = new File(Environment.getExternalStorageDirectory().getAbsolutePath() +
              "/Android/data/" + ctx.getPackageName() + "/cache/");
    }
    // Use internal storage
    else {
      cache = ctx.getCacheDir();
    }

    // Create the cache directory if it doesn't exist
    if (!cache.exists()) {
      cache.mkdirs();
    }

    return cache.getAbsolutePath(); 
  }

  public static Uri getOutputImageFileUri(Context ctx) {
    // TODO: check the presence of SDCard

    String tstamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    File file = new File(getTempDirectoryPath(ctx), "IMG_" + tstamp + ".jpg");

    return Uri.fromFile(file);

  }
}

该代码部分受到 developer.android.com 部分由 CameraLauncher 类阿帕奇科尔多瓦项目。

在我的活动中,拍照按钮的事件处理程序如下所示:

private Uri imageFileUri;

private static final int MAKE_PHOTO_RESULT_CODE = 100;
private static final int PICK_PHOTO_RESULT_CODE = 101;

public void onMakePhoto(View v) {
  Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
  imageFileUri = ImageServices.getOutputImageFileUri(this);
  intent.putExtra(MediaStore.EXTRA_OUTPUT, imageFileUri);
  Log.i("babies", "Taking picture: requested " + imageFileUri);
  startActivityForResult(intent, MAKE_PHOTO_RESULT_CODE);
}

方法onActivityResult实际上并不包含太多内容,因为imageFileUri已经指向现有文件,并且必要的渲染是在onResume<中完成的/code> 方法,当 Activity 返回前台时调用该方法:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  if (resultCode == RESULT_OK) {
    switch(requestCode) {
      case MAKE_PHOTO_RESULT_CODE:
        assert imageFileUri != null;
        break;
      case ...
        ...other cases...
        break;
    }
  }
}

但这仍然不够,因为当您的应用程序暂停时 imageFileUri 会丢失。在普通设备上,这种可能性接近 100%。因此,接下来您需要将 imageFileUri 的值存储到实例状态:

@Override
protected void onSaveInstanceState(Bundle outState) {
  super.onSaveInstanceState(outState);
  if (imageFileUri == null) {
    outState.putString("file-uri", "");
  }
  else {
    outState.putString("file-uri", imageFileUri.toString());
  }
};

并再次加载它 - 最简单的是直接在 onCreate 中:

public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  if (savedInstanceState != null) {
    String fileUri = savedInstanceState.getString("file-uri");
    if (!fileUri.equals("")) imageFileUri = Uri.parse(fileUri);
  }
}

因此,同样,在许多其他解决方案之上在本网站以及其他地方呈现的内容中,有两个主要区别:

  1. 受 Apache Cordova 启发的更智能的 getTempDirectoryPath
  2. 允许 imageFileUri 在挂起的应用程序中幸存下来

现在 - 至少对我来说 - 一切工作正常。

It took me a while to get it working and I have made several things and finally it works. I can't tell certainly which of the things I did is the solution to the problem, but they all together form the working solution.

There are multiple reasons why the camera activity does not return back. Two major ones are:

  1. path for the new picture is invalid, or non-existing, or it can't be created

  2. application got suspended and saved path get lost.

So here is my code solving all these problems, all together working.

First I created helper class ImageServices:

class ImageServices {

  private static String getTempDirectoryPath(Context ctx) {
    File cache;

    // SD Card Mounted
    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
      cache = new File(Environment.getExternalStorageDirectory().getAbsolutePath() +
              "/Android/data/" + ctx.getPackageName() + "/cache/");
    }
    // Use internal storage
    else {
      cache = ctx.getCacheDir();
    }

    // Create the cache directory if it doesn't exist
    if (!cache.exists()) {
      cache.mkdirs();
    }

    return cache.getAbsolutePath(); 
  }

  public static Uri getOutputImageFileUri(Context ctx) {
    // TODO: check the presence of SDCard

    String tstamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    File file = new File(getTempDirectoryPath(ctx), "IMG_" + tstamp + ".jpg");

    return Uri.fromFile(file);

  }
}

The code is partially inspired by developer.android.com and partially by CameraLauncher class of Apache Cordova project.

In my activity the event handler for button to take a picture looks like this:

private Uri imageFileUri;

private static final int MAKE_PHOTO_RESULT_CODE = 100;
private static final int PICK_PHOTO_RESULT_CODE = 101;

public void onMakePhoto(View v) {
  Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
  imageFileUri = ImageServices.getOutputImageFileUri(this);
  intent.putExtra(MediaStore.EXTRA_OUTPUT, imageFileUri);
  Log.i("babies", "Taking picture: requested " + imageFileUri);
  startActivityForResult(intent, MAKE_PHOTO_RESULT_CODE);
}

Method onActivityResult does not really contain much, as imageFileUri already points to the existing file and necessary rendering is done in onResume method, which is called when the activity gets back into foreground:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  if (resultCode == RESULT_OK) {
    switch(requestCode) {
      case MAKE_PHOTO_RESULT_CODE:
        assert imageFileUri != null;
        break;
      case ...
        ...other cases...
        break;
    }
  }
}

But this is still not sufficient, as imageFileUri gets lost as your app gets suspended. And on regular device the chances are close to 100%. So next you need to store the value of imageFileUri to instance state:

@Override
protected void onSaveInstanceState(Bundle outState) {
  super.onSaveInstanceState(outState);
  if (imageFileUri == null) {
    outState.putString("file-uri", "");
  }
  else {
    outState.putString("file-uri", imageFileUri.toString());
  }
};

and load it again in - easiest is directly in onCreate:

public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  if (savedInstanceState != null) {
    String fileUri = savedInstanceState.getString("file-uri");
    if (!fileUri.equals("")) imageFileUri = Uri.parse(fileUri);
  }
}

So, again, on top of many other solutions presented on this site as well as elsewhere, there are two major differences:

  1. smarter getTempDirectoryPath inspired by Apache Cordova
  2. allowing imageFileUri to survive suspended application

And now - at least for me - everything works fine.

那些过往 2024-12-24 03:56:02

回答

使用appContext.getExternalCacheDir()并且不要忘记提及权限。

    @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
              if (requestCode == TAKE_PICTURE) 
              {
                      if(resultCode==Activity.RESULT_OK)
                  { //if (data != null)
                    //{   
                    Toast.makeText(this, "Successfully Registered!", Toast.LENGTH_LONG);
                    ImageView Registerimage= (ImageView)findViewById(R.id.RegisterPicture);
                    Registerimage.setImageURI(registeryFileUri);
                    //}
                       }
                      else
                         Toast.makeText(this, "Not Registered!", Toast.LENGTH_LONG);
             }  
**"android.permission.CAMERA"**     

Check whether the above permission is specified in your manifest or not

Note: It's better to use getExternalCacheDir() than getFilesDir() if you still dont get the 
      image then use that. Dont forgot to specify the permission "android.permission.WRITE_EXTERNAL_STORAGE" if you use the getExternalCacheDir().

Answer

Use appContext.getExternalCacheDir() and don't forget to mention permissons.

    @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
              if (requestCode == TAKE_PICTURE) 
              {
                      if(resultCode==Activity.RESULT_OK)
                  { //if (data != null)
                    //{   
                    Toast.makeText(this, "Successfully Registered!", Toast.LENGTH_LONG);
                    ImageView Registerimage= (ImageView)findViewById(R.id.RegisterPicture);
                    Registerimage.setImageURI(registeryFileUri);
                    //}
                       }
                      else
                         Toast.makeText(this, "Not Registered!", Toast.LENGTH_LONG);
             }  
**"android.permission.CAMERA"**     

Check whether the above permission is specified in your manifest or not

Note: It's better to use getExternalCacheDir() than getFilesDir() if you still dont get the 
      image then use that. Dont forgot to specify the permission "android.permission.WRITE_EXTERNAL_STORAGE" if you use the getExternalCacheDir().
绝對不後悔。 2024-12-24 03:56:02

不幸的是,在某些设备上,调用相机 Activity 后,onActivityResult 中的 data 将为 null。因此,您可能需要将状态保存在 Activity 的变量中,然后它们在 onActivityResult 中读取它们。请务必在 onSaveInstanceState 中保存这些变量,并在 onCreate 中恢复它们。

On some devices data will unfortunately be null in onActivityResult after calling the camera activity. So you may need to save your state in your activity's variables, and them read them in onActivityResult. Be sure to save these variables in onSaveInstanceState and restore them in onCreate.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文