您的位置:首页 > 移动开发 > Android开发

android 7.0 调用系统相机崩溃问题

2017-10-19 16:42 483 查看
之前好好的代码6.0以前都没事,但是在7.0手机调系统相机拍照就崩溃了,查看7.0系统权限问题,网上收罗许久,

发现解决方案:

1、(推荐)7.0之后你的app就算有权限,给出一个URI之后手机也认为你没有权限。

不用修改原有代码,在Application的oncreate方法中:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
}

2、在调用相机的时候添加7.0系统的判断,
/*获取当前系统的android版本号*/
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
Log.e("currentapiVersion","currentapiVersion====>"+currentapiVersion);
if (currentapiVersion<24){
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(pathFile));
startActivityForResult(intent, TAKE_PICTURE);
}else {
ContentValues contentValues = new ContentValues(1);
contentValues.put(MediaStore.Images.Media.DATA, pathFile.getAbsolutePath());
Uri uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,contentValues);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(intent, TAKE_PICTURE);}

另外给大家推荐一个轻量级Android照片处理框架 TakePhoto-TakePhoto是一款用于在Android设备上获取照片(拍照或从相册、文件中选择)、裁剪图片、压缩图片的开源工具库,目前最新版本4.0.3。 3.0以下版本及API说明,详见TakePhoto2.0+。

导包

compile 'com.jph.takephoto:takephoto_library:4.0.3'

源码地址:https://github.com/crazycodeboy/TakePhoto

支持通过相机拍照获取图片

支持从相册选择图片

支持从文件选择图片

支持批量图片选取

支持图片压缩以及批量图片压缩

支持图片裁切以及批量图片裁切

支持照片旋转角度自动纠正

支持自动权限管理(无需关心SD卡及摄像头权限等问题)

支持对裁剪及压缩参数个性化配置

提供自带裁剪工具(可选)

支持智能选取及裁剪异常处理

支持因拍照Activity被回收后的自动恢复

支持Android7.0

+支持多种压缩工具

+支持多种图片选择工具

使用TakePhoto有以下两种方式:

方式一:通过继承的方式

继承TakePhotoActivity、TakePhotoFragmentActivity、TakePhotoFragment三者之一。

通过getTakePhoto()获取TakePhoto实例进行相关操作。

重写以下方法获取结果

void takeSuccess(TResult result);

void takeFail(TResult result,String msg);

void takeCancel();

此方式使用简单,满足的大部分的使用需求,具体使用详见simple。如果通过继承的方式无法满足实际项目的使用,可以通过下面介绍的方式。

方式二:通过组装的方式

可参照:TakePhotoActivity,以下为主要步骤:

1.实现TakePhoto.TakeResultListener,InvokeListener接口。

2.在 onCreate,onActivityResult,onSaveInstanceState方法中调用TakePhoto对用的方法。

3.重写onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults),添加如下代码。

@Override

public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {

super.onRequestPermissionsResult(requestCode, permissions, grantResults);

//以下代码为处理Android6.0、7.0动态权限所需

TPermissionType type=PermissionManager.onRequestPermissionsResult(requestCode,permissions,grantResults);

PermissionManager.handlePermissionsResult(this,type,invokeParam,this);

}

4.重写TPermissionType invoke(InvokeParam invokeParam)方法,添加如下代码:

@Override

public TPermissionType invoke(InvokeParam invokeParam) {

TPermissionType type=PermissionManager.checkPermission(TContextWrap.of(this),invokeParam.getMethod());

if(TPermissionType.WAIT.equals(type)){

this.invokeParam=invokeParam;

}

return type;

}

5.添加如下代码获取TakePhoto实例:

/**

* 获取TakePhoto实例

* @return

*/

public TakePhoto getTakePhoto(){

if (takePhoto==null){

takePhoto= (TakePhoto) TakePhotoInvocationHandler.of(this).bind(new TakePhotoImpl(this,this));

}

return takePhoto;

}

下面贴一个我使用的类,详情去源码链接

import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.annotation.RequiresApi;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.JavascriptInterface;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

import com.jph.takephoto.app.TakePhoto;
import com.jph.takephoto.app.TakePhotoImpl;
import com.jph.takephoto.compress.CompressConfig;
import com.jph.takephoto.model.InvokeParam;
import com.jph.takephoto.model.LubanOptions;
import com.jph.takephoto.model.TContextWrap;
import com.jph.takephoto.model.TResult;
import com.jph.takephoto.model.TakePhotoOptions;
import com.jph.takephoto.permission.InvokeListener;
import com.jph.takephoto.permission.PermissionManager;
import com.jph.takephoto.permission.TakePhotoInvocationHandler;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;

public class StartScanActivity extends BaseActivity implements TakePhoto.TakeResultListener, InvokeListener {
@ViewInject(id = R.id.webView)
TinyWebView webView;
@ViewInject(id = R.id.rl_content)
RelativeLayout rl_content;
@ViewInject(id = R.id.progress)
LinearLayout progress;
@ViewInject(id = R.id.top_layout)
RelativeLayout top_layout;
@ViewInject(id = R.id.top_left)
LinearLayout top_left;
private int index = -1;
private String url = "", titled = "";
private MyHandler handler;
private static final int MSG_AUTH_SHOW = 1;
//---------------------------------------
private TakePhoto takePhoto;
private InvokeParam invokeParam;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start_scan);
initViewd();
getTakePhoto().onCreate(savedInstanceState);
handler = new MyHandler();
}

@OnClick(R.id.top_left)
void onlick(View v) {
switch (v.getId()) {
case R.id.top_left:
StartScanActivity.this.finish();
break;
}
}

public void initViewd() {
Bundle bd = getIntent().getExtras();
if (bd != null) {
url = bd.getString("url");
titled = bd.getString("title");
}
// getWindow().setFlags(
// WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
// WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
//---------------
WebSettings settings = webView.getSettings();
settings.setAppCacheEnabled(true);
settings.setAppCacheMaxSize(1024 * 1024 * 8);
String appCachePath = this.getCacheDir().getAbsolutePath();
settings.setAppCachePath(appCachePath);
settings.setJavaScriptEnabled(true);
settings.setUseWideViewPort(true);
settings.setLoadWithOverviewMode(true);
settings.setAppCacheEnabled(true);
settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
settings.setSupportZoom(false);
if (Build.VERSION.SDK_INT >=Build.VERSION_CODES.KITKAT){
WebView.setWebContentsDebuggingEnabled(true);
}
settings.setAllowFileAccess(true);
settings.setDomStorageEnabled(true);
// settings.setDefaultTextEncodingName("utf-8");
// settings.setRenderPriority(WebSettings.RenderPriority.HIGH);
webView.addJavascriptInterface(new CourseList(), "NativeBridge");
// webView.setWebChromeClient(new ChromeClient());
webView.loadUrl("file:///android_asset/index.html");
webView.setWebViewClient(new PicClient());
}

public final class CourseList {
@JavascriptInterface
public void scancode(String s) {
if (StartScanActivity.this instanceof org.aisen.android.ui.activity.basic.BaseActivity) {
org.aisen.android.ui.activity.basic.BaseActivity aisenBaseActivity = (org.aisen.android.ui.activity.basic.BaseActivity) StartScanActivity.this;
new IAction(aisenBaseActivity, new CameraPermissionAction(aisenBaseActivity, null)) {
@Override
public void doAction() {
Intent intent = new Intent(StartScanActivity.this, CaptureActivity.class);
startActivityForResult(intent, 12);
}
}.run();
}
}

@JavascriptInterface
public void imagePicker(String s) {
String type = "";
try {
JSONObject obj = new JSONObject(s);
type = obj.getString("type");

} catch (JSONException e) {
e.printStackTrace();
}

File file = new File(Environment.getExternalStorageDirectory(), "/temp/" + System.currentTimeMillis() + ".jpg");
if (!file.getParentFile().exists()) file.getParentFile().mkdirs();
CompressConfig config;
LubanOptions option = new LubanOptions.Builder()
.setMaxHeight(1000)
.setMaxWidth(1000)
.setMaxSize(512)
.create();
config = CompressConfig.ofLuban(option);
config.enableReserveRaw(false);
takePhoto.onEnableCompress(config, false);
TakePhotoOptions.Builder builder = new TakePhotoOptions.Builder();
builder.setWithOwnGaller
aab9
y(true);
builder.setCorrectImage(true);//纠正角度
takePhoto.setTakePhotoOptions(builder.create());

if (type.equals("takePhoto")) {
takePhoto.onPickFromCapture(FileUtil.geturi());//相机不裁剪
} else {
takePhoto.onPickFromGallery();//不裁剪
}
}

@JavascriptInterface
public void colseDlb(String s) {
Intent intent = new Intent(StartScanActivity.this, MainActivity.class);
startActivity(intent);
}

@JavascriptInterface
public void renderFinish(String s) {
Message msg = new Message();
msg.what = MSG_AUTH_SHOW;
handler.sendMessage(msg);
}

//分享
@JavascriptInterface
public void shareToWechat(String s) {
String title = "", image = "", url = "", scene = "";
try {
JSONObject obj = new JSONObject(s);
title = obj.getString("title");
image = obj.getString("image");
url = obj.getString("url");
scene = obj.getString("scene");

} catch (JSONException e) {
e.printStackTrace();
}
if (scene.equals("SESSION")) {//好有
ShareUtil.showShare(StartScanActivity.this, Wechat.NAME, title, "", url, image);
} else {//朋友圈
ShareUtil.showShare(StartScanActivity.this, WechatMoments.NAME, title, "", url, image);
}
}

@JavascriptInterface
public void nextPageDlb(String s) {
String title = "", image = "", url = "";
try {
JSONObject obj = new JSONObject(s);
title = obj.getString("title");
url = obj.getString("url");
} catch (JSONException e) {
e.printStackTrace();
}
if(url.endsWith("pdf")){
Intent intent = new Intent(StartScanActivity.this, ReadPdfActivity.class);
intent.putExtra("title", title);
intent.putExtra("url", url);
startActivity(intent);
}else {
Intent intent = new Intent(StartScanActivity.this, ShopWebActivity.class);
intent.putExtra("title", title);
intent.putExtra("url", url);
startActivity(intent);
}
}
}

@Override
public void onPause() {
super.onPause();
// 加载空白页
}

@Override
public void onResume() {
// initViewd();
super.onResume();
}

@Override
public void onDestroy() {
super.onDestroy();
if (webView != null) {
rl_content.removeView(webView);
webView.clearCache(true);
webView.removeAllViews();
webView.destroy();
webView = null;
}
}

private class PicClient extends WebViewClient {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
progress.setVisibility(View.VISIBLE);
}

@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url != null) view.loadUrl(url);
return true;
}

@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent keyEvent) {
if (keyCode == keyEvent.KEYCODE_BACK) {
if (webView.canGoBack()) {
webView.goBack();
return true;
} else {
Intent intent = new Intent(StartScanActivity.this, MainActivity.class);
startActivity(intent);
}
}
return super.onKeyDown(keyCode, keyEvent);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
getTakePhoto().onActivityResult(requestCode, resultCode, data);
//--------------
if (requestCode == 12) {
if (data == null) {
return;
}
String result = data.getExtras().getString("result");//得到新Activity关闭后返回的数据
String url = "javascript:$app.$store.dispatch('nativeCallJs',{fnname:'scancode',param:" + "'" + result + "'" + "})";
webView.loadUrl(url);
}
super.onActivityResult(requestCode, resultCode, data);
}

@Override
public void finish() {
// TODO Auto-generated method stub
moveTaskToBack(true);
Intent intent = new Intent(StartScanActivity.this, MainActivity.class);
startActivity(intent);
}

class MyHandler extends Handler {
public MyHandler() {
}

public MyHandler(Looper L) {
super(L);
}

// 子类必须重写此方法,接受数据
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_AUTH_SHOW: {
progress.setVisibility(View.GONE);
top_layout.setVisibility(View.GONE);
}
break;
}
}
}

//---------------------
@Override
protected void onSaveInstanceState(Bundle outState) {
getTakePhoto().onSaveInstanceState(outState);
super.onSaveInstanceState(outState);
}

@Override
public void takeSuccess(TResult result) {
Bitmap bitmap = FileUtil.getbtm(result.getImage().getCompressPath());
if (bitmap != null) {
final String url = "javascript:$app.$store.dispatch('nativeCallJs',{fnname:'pictureBase64',param:" + "'" + "data:image/jpg;base64," + Base64Utils.bitmapToBase64(bitmap) + "'" + "})";
StartScanActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
webView.loadUrl(url);
}
});
}
}

@Override
public void takeFail(TResult result, String msg) {

}

@Override
public void takeCancel() {

}

@Override
public PermissionManager.TPermissionType invoke(InvokeParam invokeParam) {
PermissionManager.TPermissionType type = PermissionManager.checkPermission(TContextWrap.of(this), invokeParam.getMethod());
if (PermissionManager.TPermissionType.WAIT.equals(type)) {
this.invokeParam = invokeParam;
}
return type;
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
PermissionManager.TPermissionType type = PermissionManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
PermissionManager.handlePermissionsResult(this, type, invokeParam, this);
}

/**
* 获取TakePhoto实例
*
* @return
*/
public TakePhoto getTakePhoto() {
if (takePhoto == null) {
takePhoto = (TakePhoto) TakePhotoInvocationHandler.of(this).bind(new TakePhotoImpl(this, this));

}
return takePhoto;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: