不选择裁剪图像应用程序时,停止应用程序崩溃 - Android

时间:2014-11-18 01:25:03

标签: android

我有一个应用程序可以从图库或相机中裁剪图像。除了一个小功能外,它的工作原理非常好当我从图库中选择一个图像时,它会询问我想要使用哪个裁剪应用程序来裁剪我的图像,但如果我在布局框外单击或按下后退按钮我的整个应用程序崩溃。如何让应用程序不崩溃?

这是我的主要活动

package com.goboapp;

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.loopj.android.http.RequestParams;


public class Main extends ActionBarActivity {
    private Uri mImageCaptureUri;

    private static final int PICK_FROM_CAMERA = 1;
    private static final int CROP_FROM_CAMERA = 2;
    private static final int PICK_FROM_FILE = 3;

     ImageView imageView1;
     RoundImage roundedImage;
     Bitmap bitmap;
     ProgressDialog prgDialog;
     String encodedString;
     RequestParams params = new RequestParams();
     String imgPath, fileName;
     Bitmap bitmap2;
     TextView tv;
     String uploadFilePath;
     String uploadFileName;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //SET VIEWS
        imageView1 = (ImageView) findViewById(R.id.imageView1);
        tv = (TextView) findViewById(R.id.tv);


        //CAMERA STUFF

        final String [] items           = new String [] {"Take from camera", "Select from gallery"};                
        ArrayAdapter<String> adapter    = new ArrayAdapter<String> (this, android.R.layout.select_dialog_item,items);
        AlertDialog.Builder builder     = new AlertDialog.Builder(this);

        builder.setTitle("Select Image");
        builder.setAdapter( adapter, new DialogInterface.OnClickListener() {
            public void onClick( DialogInterface dialog, int item ) { //pick from camera
                if (item == 0) {
                    Intent intent    = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

                    mImageCaptureUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(),
                                       "tmp_avatar_" + String.valueOf(System.currentTimeMillis()) + ".jpg"));

                    intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mImageCaptureUri);

                    try {
                        intent.putExtra("return-data", true);

                        startActivityForResult(intent, PICK_FROM_CAMERA);
                    } catch (ActivityNotFoundException e) {
                        e.printStackTrace();
                    }
                } else { //pick from file
                    Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                    startActivityForResult(i, PICK_FROM_FILE);

                }
            }
        } );

        final AlertDialog dialog = builder.create();

        Button button   = (Button) findViewById(R.id.btn_crop);

        button.setOnClickListener(new View.OnClickListener() {  
            @Override
            public void onClick(View v) {
                dialog.show();
            }
        });

        //END END END CAMERA STUFF


         }// End OnCreate



    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }//end onCreateOptionsMenu

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }//end onOptionsItemSelected



    //CAMERA STUFF

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode != RESULT_OK) return;

        switch (requestCode) {
            case PICK_FROM_CAMERA:
                doCrop();

                break;

            case PICK_FROM_FILE: 
                mImageCaptureUri = data.getData();

                doCrop();

                break;          

            case CROP_FROM_CAMERA:          
                Bundle extras = data.getExtras();

                if (extras != null) {               
                    Bitmap photo = extras.getParcelable("data");

                   imageView1.setImageBitmap(photo);


                }

                File f = new File(mImageCaptureUri.getPath());            

                if (f.exists()) f.delete();

                break;

        }
    }



    //CROP IMAGE

      private void doCrop() {
        final ArrayList<CropOption> cropOptions = new ArrayList<CropOption>();

        Intent intent = new Intent("com.android.camera.action.CROP");
          intent.setType("image/*");

          List<ResolveInfo> list = getPackageManager().queryIntentActivities( intent, 0 );

          int size = list.size();

          if (size == 0) {          
            Toast.makeText(this, "Can not find image crop app", Toast.LENGTH_SHORT).show();

              return;
          } else {
            intent.setData(mImageCaptureUri);

              intent.putExtra("outputX", 200);
              intent.putExtra("outputY", 200);
              intent.putExtra("aspectX", 1);
              intent.putExtra("aspectY", 1);
              intent.putExtra("scale", true);
              intent.putExtra("return-data", true);

            if (size == 1) {
                Intent i        = new Intent(intent);
                ResolveInfo res = list.get(0);

                i.setComponent( new ComponentName(res.activityInfo.packageName, res.activityInfo.name));

                startActivityForResult(i, CROP_FROM_CAMERA);
            } else {
                for (ResolveInfo res : list) {
                    final CropOption co = new CropOption();

                    co.title    = getPackageManager().getApplicationLabel(res.activityInfo.applicationInfo);
                    co.icon     = getPackageManager().getApplicationIcon(res.activityInfo.applicationInfo);
                    co.appIntent= new Intent(intent);

                    co.appIntent.setComponent( new ComponentName(res.activityInfo.packageName, res.activityInfo.name));

                    cropOptions.add(co);
                }

                CropOptionAdapter adapter = new CropOptionAdapter(getApplicationContext(), cropOptions);

                AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setTitle("Choose Crop App");
                builder.setAdapter( adapter, new DialogInterface.OnClickListener() {
                    public void onClick( DialogInterface dialog, int item ) {
                        startActivityForResult( cropOptions.get(item).appIntent, CROP_FROM_CAMERA);
                    }
                });

                builder.setOnCancelListener( new DialogInterface.OnCancelListener() {
                    @Override
                    public void onCancel( DialogInterface dialog ) {

                        if (mImageCaptureUri != null ) {
                            getContentResolver().delete(mImageCaptureUri, null, null );
                            mImageCaptureUri = null;
                        }
                    }
                } );

                AlertDialog alert = builder.create();

                alert.show();
            }
          }
    }

      //END END END CROP IMAGE





}//end activity

这是 CropOptionAdapter.java

package com.goboapp;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import android.content.Context;

import java.util.ArrayList;

public class CropOptionAdapter extends ArrayAdapter<CropOption> {
    private ArrayList<CropOption> mOptions;
    private LayoutInflater mInflater;

    public CropOptionAdapter(Context context, ArrayList<CropOption> options) {
        super(context, R.layout.crop_selector, options);

        mOptions    = options;

        mInflater   = LayoutInflater.from(context);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup group) {
        if (convertView == null)
            convertView = mInflater.inflate(R.layout.crop_selector, null);

        CropOption item = mOptions.get(position);

        if (item != null) {
            ((ImageView) convertView.findViewById(R.id.iv_icon)).setImageDrawable(item.icon);
            ((TextView) convertView.findViewById(R.id.tv_name)).setText(item.title);

            return convertView;
        }

        return null;
    }
}

这是 CropOption.java

package com.goboapp;

import android.content.Intent;
import android.graphics.drawable.Drawable;

public class CropOption {
    public CharSequence title;
    public Drawable icon;
    public Intent appIntent;
}

这是 crop_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="10dp"
    android:gravity="center_vertical">

    <ImageView
        android:id="@+id/iv_icon"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/tv_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text=""/>
</LinearLayout>

这是 LogCat

11-17 20:17:15.708: E/AndroidRuntime(23829): FATAL EXCEPTION: main
11-17 20:17:15.708: E/AndroidRuntime(23829): Process: com.goboapp, PID: 23829
11-17 20:17:15.708: E/AndroidRuntime(23829): java.lang.SecurityException: Permission Denial: writing com.android.providers.media.MediaProvider uri content://media/external/images/media/1448 from pid=23829, uid=10168 requires android.permission.WRITE_EXTERNAL_STORAGE, or grantUriPermission()
11-17 20:17:15.708: E/AndroidRuntime(23829):    at android.os.Parcel.readException(Parcel.java:1471)
11-17 20:17:15.708: E/AndroidRuntime(23829):    at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:185)
11-17 20:17:15.708: E/AndroidRuntime(23829):    at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:137)
11-17 20:17:15.708: E/AndroidRuntime(23829):    at android.content.ContentProviderProxy.delete(ContentProviderNative.java:536)
11-17 20:17:15.708: E/AndroidRuntime(23829):    at android.content.ContentResolver.delete(ContentResolver.java:1282)
11-17 20:17:15.708: E/AndroidRuntime(23829):    at com.goboapp.Main$5.onCancel(Main.java:340)
11-17 20:17:15.708: E/AndroidRuntime(23829):    at android.app.Dialog$ListenersHandler.handleMessage(Dialog.java:1241)
11-17 20:17:15.708: E/AndroidRuntime(23829):    at android.os.Handler.dispatchMessage(Handler.java:102)
11-17 20:17:15.708: E/AndroidRuntime(23829):    at android.os.Looper.loop(Looper.java:136)
11-17 20:17:15.708: E/AndroidRuntime(23829):    at android.app.ActivityThread.main(ActivityThread.java:5097)
11-17 20:17:15.708: E/AndroidRuntime(23829):    at java.lang.reflect.Method.invokeNative(Native Method)
11-17 20:17:15.708: E/AndroidRuntime(23829):    at java.lang.reflect.Method.invoke(Method.java:515)
11-17 20:17:15.708: E/AndroidRuntime(23829):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
11-17 20:17:15.708: E/AndroidRuntime(23829):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
11-17 20:17:15.708: E/AndroidRuntime(23829):    at dalvik.system.NativeStart.main(Native Method)

我省略了与主要活动无关的一些功能。我也想知道是否可以强制用户使用默认裁剪应用程序而不是让他们选择。我按照教程获取此代码,这就是为什么我不知道该怎么做。

1 个答案:

答案 0 :(得分:0)

您的应用程序缺少权限android.permission.WRITE_EXTERNAL_STORAGE

我认为无论裁剪什么照片都需要能够写入磁盘,因为它正在使用MediaProvider内容提供商。