我既没有在清单中也没有以编程方式包含相机权限,但仍然我的应用程序打开相机。直到现在我才想到的是相机许可用于打开相机,但这里完全不同。所以需要一些帮助才能知道,为什么相机在没有授予权限的情感谢每一位帮助。这是我的代码
MainActivity.java
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_CAMERA = 1;
private static final int SELECT_FILE = 2;
String userChoosenTask;
ImageView ivImage;
Button btselect;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ivImage = (ImageView) findViewById(R.id.ivImage);
btselect = (Button) findViewById(R.id.btnSelectPhoto);
btselect.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
selectImage();
}
});
}
private void selectImage() {
final CharSequence[] items = {"Take Photo", "Choose from Library", "Cancel"};
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("Add Photo!");
builder.setItems(items, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int item) {
boolean result = Utility.checkPermission(MainActivity.this);
if (items[item].equals("Take Photo")) {
userChoosenTask = "Take Photo";
if (result)
cameraIntent();
} else if (items[item].equals("Choose from Library")) {
userChoosenTask = "Choose from Library";
if (result)
galleryIntent();
} else if (items[item].equals("Cancel")) {
dialog.dismiss();
}
}
});
builder.show();
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case Utility.MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (userChoosenTask.equals("Take Photo"))
cameraIntent();
else if (userChoosenTask.equals("Choose from Library"))
galleryIntent();
} else {
//code for deny
}
break;
}
}
private void cameraIntent() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, REQUEST_CAMERA);
}
private void galleryIntent() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select File"), SELECT_FILE);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (SELECT_FILE == requestCode)
onSelectFromGalleryResult(data);
else if (requestCode == REQUEST_CAMERA)
onCaptureImageResult(data);
}
}
@SuppressWarnings("deprecation")
private void onSelectFromGalleryResult(Intent data) {
Bitmap bm = null;
if (data != null) {
try {
bm = MediaStore.Images.Media.getBitmap(getApplicationContext().getContentResolver(), data.getData());
} catch (IOException e) {
e.printStackTrace();
}
}
ivImage.setImageBitmap(bm);
}
private void onCaptureImageResult(Intent data) {
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
// CALL THIS METHOD TO GET THE URI FROM THE BITMAP
Uri tempUri = getImageUri(getApplicationContext(), thumbnail);
// CALL THIS METHOD TO GET THE ACTUAL PATH
File finalFile = new File(getRealPathFromURI(tempUri));
Bitmap finalimg = ExifUtil.rotateBitmap(finalFile.toString(), thumbnail);
ivImage.setImageBitmap(thumbnail);
}
public Uri getImageUri(Context inContext, Bitmap inImage) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
return Uri.parse(path);
}
public String getRealPathFromURI(Uri uri) {
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
return cursor.getString(idx);
}
}
ExifUtil.java
public class ExifUtil {
public static Bitmap rotateBitmap(String src, Bitmap bitmap) {
try {
int orientation = getExifOrientation(src);
if (orientation == 1) {
return bitmap;
}
Matrix matrix = new Matrix();
switch (orientation) {
case 2:
matrix.setScale(-1, 1);
break;
case 3:
matrix.setRotate(180);
break;
case 4:
matrix.setRotate(180);
matrix.postScale(-1, 1);
break;
case 5:
matrix.setRotate(90);
matrix.postScale(-1, 1);
break;
case 6:
matrix.setRotate(90);
break;
case 7:
matrix.setRotate(-90);
matrix.postScale(-1, 1);
break;
case 8:
matrix.setRotate(-90);
break;
default:
return bitmap;
}
try {
Bitmap oriented = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
bitmap.recycle();
return oriented;
} catch (OutOfMemoryError e) {
e.printStackTrace();
return bitmap;
}
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
private static int getExifOrientation(String src) throws IOException {
int orientation = 1;
try {
/**
* if your are targeting only api level >= 5
* ExifInterface exif = new ExifInterface(src);
* orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
*/
if (Build.VERSION.SDK_INT >= 5) {
Class<?> exifClass = Class.forName("android.media.ExifInterface");
Constructor<?> exifConstructor = exifClass.getConstructor(new Class[] { String.class });
Object exifInstance = exifConstructor.newInstance(new Object[] { src });
Method getAttributeInt = exifClass.getMethod("getAttributeInt", new Class[] { String.class, int.class });
Field tagOrientationField = exifClass.getField("TAG_ORIENTATION");
String tagOrientation = (String) tagOrientationField.get(null);
orientation = (Integer) getAttributeInt.invoke(exifInstance, new Object[] { tagOrientation, 1});
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
return orientation;
}
}
Utility.java
public class Utility {
public static final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 123;
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public static boolean checkPermission(final Context context)
{
int currentAPIVersion = Build.VERSION.SDK_INT;
if(currentAPIVersion>=android.os.Build.VERSION_CODES.M)
{
if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.READ_EXTERNAL_STORAGE)) {
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context);
alertBuilder.setCancelable(true);
alertBuilder.setTitle("Permission necessary");
alertBuilder.setMessage("External storage permission is necessary");
alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
}
});
AlertDialog alert = alertBuilder.create();
alert.show();
} else {
ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
}
return false;
} else {
return true;
}
} else {
return true;
}
}
}
的AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.takeimagedemo">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
答案 0 :(得分:3)
如果您只是通过Intent启动相机应用程序,则不需要相机许可。要启动任何您不需要任何权限的应用程序。 当您直接访问相机资源或使用相机apis时,您需要相机权限。
android.permission.READ_EXTERNAL_STORAGE &
android.permission.WRITE_EXTERNAL_STORAGE
这些上述许可仅仅是因为您将捕获的图像存储在SD卡或手机内存中。
我希望这些可以帮到你。
答案 1 :(得分:1)
在这example中,有两件事要注意:
第一:关于权限的说明:
虽然您的应用程序正在利用相机,但不需要android.permission.CAMERA
权限,因为它不直接访问相机。相反,它只是通过Intent启动Camera应用程序。
您似乎只需要获得直接访问相机基元的权限,而不是通过Intent。
注意上述相同的网址还指出您应该声明该功能,以防止没有相机的用户在市场上看到您的应用。