请教,手机拍照功能在MainActivity正常,独立成单独类,就会闪退

xuyang0109 2019-03-14 10:15:09
诚心请教,非常感谢!

以下代码放在 MainActivity 中,一切正常,可以拍照。 MainActivity的一个按钮的点击事件,执行 mTakePhoto();

//拍照常量
private final int REQUEST_IMAGE_CAPTURE = 1;

//方法,拍照
public void mTakePhoto()
{
Intent myIntent;
Uri myPictureUri;

//设定照相之后保存的路径和文件名。路径【kelingyi/kly/photo/】必须设定在 【provider_file_paths.xml】中,否则会出错闪退
File myPictureFile = new File(Environment.getExternalStorageDirectory() + "/kelingyi/kly/photo/",
"user_head.jpg");

// 判断当前系统,判断版本大于等于7.0
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
myIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

//添加这一句表示对目标应用临时授权该Uri所代表的文件
myIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //读取权限
myIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); //写入权限

//第二个参数,必须是 AndroidMainfest.xml中<provider>设定的【android:authorities="com.kelingyi.android_app.fileprovider"】
//在 MainActivity使用时,用 this 代替 gblContext
myPictureUri = FileProvider.getUriForFile(this,
"com.kelingyi.android_app.fileprovider",
myPictureFile);
} else {
myIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
myPictureUri = Uri.fromFile( myPictureFile );
}

//创建保存图片的路径【/kelingyi/kly/photo】(必须要事先创建好保存的路径,否则回调的 resultCode 一直是 RESULT_CANCELED)
//File myPhotoFolder = new File(Environment.getExternalStorageDirectory() + "/kelingyi/kly/photo/");
File myPhotoFolder = new File(Environment.getExternalStorageDirectory() + "/kelingyi/kly/", "photo");

//判断文件目录是否存在,不存在则创建
if (!myPhotoFolder.exists()) {
myPhotoFolder.mkdirs();
}

// 拍照。拍照的结果存到 myPictureUri 对应的路径中
myIntent.putExtra(MediaStore.EXTRA_OUTPUT,
myPictureUri);

//得到新打开Activity关闭后返回的数据。
//第二个参数为请求码,自己定义
startActivityForResult(myIntent,
REQUEST_IMAGE_CAPTURE);

}
//方法,拍照
//public void mTakePhoto()


//为了得到新打开Activity关闭后返回的数据,必须在前面的Activity中(指MainActivity类)重写onActivityResult方法
//参数:
// requestCode 请求码,即调用startActivityForResult()传递过去的值
// resultCode 结果码,结果码用于标识返回数据来自哪个新Activity
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//在 MainActivity使用时,用 this 代替 gblContext
Toast.makeText(this,
"onActivityResult 回调 requestCode:【" + requestCode + "】 resultCode:【" + resultCode + "】",
Toast.LENGTH_LONG).show();

}


但是,我想把这个功能独立出来,放在一个单独的类里面。一点击拍照按钮就出错闪退。类代码如下

public class clsTakePhotoSelectImg extends AppCompatActivity {

//上下文
private Context gblContext;

//构造函数
public clsTakePhotoSelectImg(Context praContext)
{
gblContext = praContext;
}


//说明:以下代码,与MainActivity的唯一区别是,把 this 换成了 gblContext

//拍照
private final int REQUEST_IMAGE_CAPTURE = 1;

//方法,拍照
public void mTakePhoto()
{
Intent myIntent;
Uri myPictureUri;

//设定照相之后保存的路径和文件名。路径【kelingyi/kly/photo/】必须设定在 【provider_file_paths.xml】中,否则会出错闪退
File myPictureFile = new File(Environment.getExternalStorageDirectory() + "/kelingyi/kly/photo/",
"user_head.jpg");

// 判断当前系统,判断版本大于等于7.0
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
myIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

//添加这一句表示对目标应用临时授权该Uri所代表的文件
myIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //读取权限
myIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); //写入权限

//第二个参数,必须是 AndroidMainfest.xml中<provider>设定的【android:authorities="com.kelingyi.android_app.fileprovider"】
//在 MainActivity使用时,用 this 代替 gblContext
myPictureUri = FileProvider.getUriForFile(gblContext,
"com.kelingyi.android_app.fileprovider",
myPictureFile);
} else {
myIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
myPictureUri = Uri.fromFile( myPictureFile );
}

//创建保存图片的路径【/kelingyi/kly/photo】(必须要事先创建好保存的路径,否则回调的 resultCode 一直是 RESULT_CANCELED)
//File myPhotoFolder = new File(Environment.getExternalStorageDirectory() + "/kelingyi/kly/photo/");
File myPhotoFolder = new File(Environment.getExternalStorageDirectory() + "/kelingyi/kly/", "photo");

//判断文件目录是否存在,不存在则创建
if (!myPhotoFolder.exists()) {
myPhotoFolder.mkdirs();
}

// 拍照。拍照的结果存到 myPictureUri 对应的路径中
myIntent.putExtra(MediaStore.EXTRA_OUTPUT,
myPictureUri);

//得到新打开Activity关闭后返回的数据。
//第二个参数为请求码,自己定义
startActivityForResult(myIntent,
REQUEST_IMAGE_CAPTURE);

}
//方法,拍照
//public void mTakePhoto()


//为了得到新打开Activity关闭后返回的数据,必须在前面的Activity中(指MainActivity类)重写onActivityResult方法
//参数:
// requestCode 请求码,即调用startActivityForResult()传递过去的值
// resultCode 结果码,结果码用于标识返回数据来自哪个新Activity
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//在 MainActivity使用时,用 this 代替 gblContext
Toast.makeText(gblContext,
"onActivityResult 回调 requestCode:【" + requestCode + "】 resultCode:【" + resultCode + "】",
Toast.LENGTH_LONG).show();

}

}



MainActivity的按钮的点击事件,执行

clsTakePhotoSelectImg myTakePhotoSelectImgObj = new clsTakePhotoSelectImg(MainActivity.this);
myTakePhotoSelectImgObj.mTakePhoto();


...全文
970 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
weixin_41243960 2019-03-15
  • 打赏
  • 举报
回复
啥意思
weixin_44760703 2019-03-15
  • 打赏
  • 举报
回复
ner 或者 list 这类的东西里面...public class MainActivity extends Activity implements
xuyang0109 2019-03-15
  • 打赏
  • 举报
回复
引用 10 楼 shiyun123456 的回复:
这个是代码问题这个是代码问题这个是代码问题这个是代码问题
当然是代码的问题。难道是天气的问题?
xuyang0109 2019-03-15
  • 打赏
  • 举报
回复
非常感谢王能的提示!相比之下只是嘲笑训斥,只是浪费大家的时间。 我完全不会安卓开发,一直是一面查资料一面痛苦地研究。你提示我的这个地方我完全不知道应该怎么弄,startActivityForResult的前面不加对象,一直报错。 图片路径写死是不要紧的,回调 onActivityResult 之后,马上把照片上传到服务器。 为了让别人不会出现同样错误,贴上全部相关的代码 在 MainActivity.java 中

    protected void onCreate(Bundle savedInstanceState)
    {
            ......
            
            //activity_main 上的按钮,id是 btn_camera
            Button myBtnCamera;
            myBtnCamera = (Button) findViewById(R.id.btn_camera);

            //监听事件
            myBtnCamera.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //拍照
                    clsTakePhotoSelectImg.mTakePhoto(MainActivity.this);
                }
            });

            ......
    }

    //拍照常量
    private final int REQUEST_IMAGE_CAPTURE = 1;

    //为了得到新打开Activity关闭后返回的数据,必须在前面的Activity中(指MainActivity类)重写onActivityResult方法
    //参数:
    //      requestCode 请求码,即调用startActivityForResult()传递过去的值
    //      resultCode 结果码,结果码用于标识返回数据来自哪个新Activity
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Uri myPictureUri;

        // 回调成功
        //注意!必须要事先创建好保存的路径,否则回调的 resultCode 一直是 RESULT_CANCELED
        if (resultCode == RESULT_OK) {
            switch (requestCode) {
                // 拍照
                //private final int REQUEST_IMAGE_CAPTURE = 1;
                //此时,照片已经保存在【/coma/kly/photo】
                case REQUEST_IMAGE_CAPTURE:
                    Toast.makeText(this,
                            "onActivityResult 回调 拍照完成。requestCode:【" + requestCode + "】 resultCode:【" + resultCode + "】",
                            Toast.LENGTH_LONG).show();

                    //将照片上传到后台服务器

                    break;
            }

    }
以下是 clsTakePhotoSelectImg.java

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.content.FileProvider;
import java.io.File;

public class clsTakePhotoSelectImg{

    //拍照
    private static final int REQUEST_IMAGE_CAPTURE = 1;

    //方法,拍照
    public static void mTakePhoto(Activity praActivity)
    {
        Intent myIntent;
        Uri myPictureUri;

        //设定照相之后保存的路径和文件名。路径【coma/kly/photo/】必须设定在 【provider_file_paths.xml】中,否则会出错闪退
        File myPictureFile = new File(Environment.getExternalStorageDirectory() + "/coma/kly/photo/",
                "take_photo_by_kly.jpg");

        // 判断当前系统,判断版本大于等于7.0
        if (Build.VERSION.SDK_INT  >= Build.VERSION_CODES.N) {
            myIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

            //添加这一句表示对目标应用临时授权该Uri所代表的文件
            myIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);		//读取权限
            myIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);		//写入权限

            //第二个参数,必须是 AndroidMainfest.xml中<provider>设定的【android:authorities="com.coma.android_app.fileprovider"】
            //在 MainActivity使用时,用 this 代替 gblContext
            myPictureUri = FileProvider.getUriForFile(praActivity,
                    "com.coma.android_app.fileprovider",
                    myPictureFile);
        } else {
            myIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            myPictureUri = Uri.fromFile( myPictureFile );
        }

        //创建保存图片的路径【/coma/kly/photo】(必须要事先创建好保存的路径,否则回调的 resultCode 一直是 RESULT_CANCELED)
        File myPhotoFolder = new File(Environment.getExternalStorageDirectory() + "/coma/kly/",  "photo");

        //判断文件目录是否存在,不存在则创建
        if (!myPhotoFolder.exists()) {
            myPhotoFolder.mkdirs();
        }

        // 拍照。拍照的结果存到 myPictureUri 对应的路径中
        myIntent.putExtra(MediaStore.EXTRA_OUTPUT,
                myPictureUri);

        //得到新打开Activity关闭后返回的数据。
        //第二个参数为请求码,自己定义
        praActivity.startActivityForResult(myIntent,
                REQUEST_IMAGE_CAPTURE);

    }
    //方法,拍照
    //public void mTakePhoto(...)

}

  • 打赏
  • 举报
回复
这个有关UI,拍照也是在UI上操作,最好在主线程上处理。类里面,只是调用主线程的一部分过程方法为佳。
shiyun123456 2019-03-15
  • 打赏
  • 举报
回复
这个是代码问题这个是代码问题这个是代码问题这个是代码问题
haihaidemiziyou 2019-03-15
  • 打赏
  • 举报
回复
学习学些学习
王能 2019-03-15
  • 打赏
  • 举报
回复
onActivityResult也不能在工具类里面写,应该在对应的Activity里面 还有你这写工具类没啥用啊,图片路径都被你写死了,难不成每次都覆盖原图?
王能 2019-03-15
  • 打赏
  • 举报
回复
大神Activity new出来是没有任何意义的。要不然天天startActivity干嘛? 你把你的clsTakePhotoSelectImg不要继承任何东西,也不需要构造
public static void mTakePhoto(Activity activity){
...
activity.startActivity...
}
xuyang0109 2019-03-15
  • 打赏
  • 举报
回复
可能是在单独类的这里出错的

        //得到新打开Activity关闭后返回的数据。
        //第二个参数为请求码,自己定义
        startActivityForResult(myIntent,
                REQUEST_IMAGE_CAPTURE);
我不知道怎么查详细的错误信息,在变量窗口里,ex=java.lang.NullPointerException
LYจุ๊บ 2019-03-15
  • 打赏
  • 举报
回复
很不错 值得学习
hackingtruth 2019-03-15
  • 打赏
  • 举报
回复
logcat 贴上来
雕·不懒惰 2019-03-14
  • 打赏
  • 举报
回复
再还有,闪退没有报错信息吗?根据日志排查,不会就把报错的日志贴出来
雕·不懒惰 2019-03-14
  • 打赏
  • 举报
回复
你自己封装的工具类,继承Activity干什么,
还有 clsTakePhotoSelectImg myTakePhotoSelectImgObj = new clsTakePhotoSelectImg(MainActivity.this);
myTakePhotoSelectImgObj.mTakePhoto();
new一个Activity?
雕·不懒惰 2019-03-14
  • 打赏
  • 举报
回复
public class clsTakePhotoSelectImg extends AppCompatActivity
这里是重点,圈起来要考的
xuyang0109 2019-03-14
  • 打赏
  • 举报
回复
感谢关注!我不是很懂java,请问我怎样才能把拍照功能从 MainActivity 里分离出来?我问题描述的,在 MainActivity 里可以正常拍照

80,351

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧