jjzjj

android - 适用于 Jelly Bean 但不适用于 Kitkat 的相机 API

coder 2023-12-01 原文

我有一个非常奇怪的问题。我的以下代码用于在单击按钮时拍照。它适用于 Jelly Bean 手机,但不适用于 Kitkat:

MainActivity.java:

package com.example.takepic;

import android.app.Activity;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;


public class MainActivity extends Activity {
  private final static String DEBUG_TAG = "MakePhotoActivity";
  private Camera camera;
  private Button capture = null;
  private int cameraId = 0;

  @Override
  public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  capture = (Button)findViewById(R.id.captureBack);
  capture.setOnClickListener(new View.OnClickListener() {

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
         camera.startPreview(); //After this, nothing gets printed, and picture does not get taken
        System.out.println("Camera preview has started.");
            camera.takePicture(null, null, new PhotoHandler(getApplicationContext()));
    }
});
// do we have a camera?
if (!getPackageManager()
    .hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
  Toast.makeText(this, "No camera on this device", Toast.LENGTH_LONG)
      .show();
} else {
  cameraId = findBackFacingCamera();
  if (cameraId < 0) {
    Toast.makeText(this, "No back facing camera found.",
        Toast.LENGTH_LONG).show();
  } else {
    camera = Camera.open(cameraId);
  }
}
  }



 private int findBackFacingCamera() {
int cameraId = -1;
// Search for the front facing camera
int numberOfCameras = Camera.getNumberOfCameras();
for (int i = 0; i < numberOfCameras; i++) {
  CameraInfo info = new CameraInfo();
  Camera.getCameraInfo(i, info);
  if (info.facing == CameraInfo.CAMERA_FACING_BACK) {
    Log.d(DEBUG_TAG, "Camera found");
    cameraId = i;
    break;
  }
}
return cameraId;
}

  @Override
  protected void onPause() {
if (camera != null) {
  camera.release();
  camera = null;
}
super.onPause();
 }

} 

PhotoHandler.java:

package com.example.takepic;



import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;

public class PhotoHandler implements PictureCallback {

  private final Context context;

  public PhotoHandler(Context context) {
    this.context = context;
  }

  @Override
 public void onPictureTaken(byte[] data, Camera camera) {

   File pictureFileDir = getDir();
  Toast.makeText(context, "Entered onPictureTaken", Toast.LENGTH_LONG).show();
   if (!pictureFileDir.exists() && !pictureFileDir.mkdirs()) {

  Log.d("Directory error", "Can't create directory to save image.");
  Toast.makeText(context, "Can't create directory to save image.",
      Toast.LENGTH_LONG).show();
  return;

 }

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyymmddhhmmss");
String date = dateFormat.format(new Date());
String photoFile = "Picture_" + date + ".jpg";

String filename = pictureFileDir.getPath() + File.separator + photoFile;

File pictureFile = new File(filename);

try {
  FileOutputStream fos = new FileOutputStream(pictureFile);
  fos.write(data);
  fos.close();
  Toast.makeText(context, "New Image saved:" + photoFile,
      Toast.LENGTH_LONG).show();
} catch (Exception error) {
  Log.d("File saving error", "File" + filename + "not saved: "
      + error.getMessage());
  Toast.makeText(context, "Image could not be saved.",
      Toast.LENGTH_LONG).show();
  }
}

  private File getDir() {
  //  File sdDir =    Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
 File sdDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
 Toast.makeText(context, ("Path : "+sdDir.getAbsolutePath()), Toast.LENGTH_LONG).show();
  return sdDir;
 }
} 

list 文件:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.takepic"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="15" />
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
    <activity
        android:name="com.example.takepic.MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

为了调试目的,我已经放置了很多 toast 消息和打印语句。我没有在这里发布 logcat,因为当我在 KitKat 手机上运行它时,我在 logcat 上什么也得不到。没有异常或警告。

当我在 jellybean 手机上运行它时,它运行正常,显示所有 toasts 并打印并拍照。

当我在 Kitkat 上运行它时,在

之后我没有收到任何调试消息
camera.startPreview();
System.out.println("Camera preview has started.");

我怀疑问题出在 takePicture API 上,但我无法对其进行调试。

编辑

经过进一步分析,我找到了问题的原因。 PhotoHandler 对象被成功调用,但是 onPictureTaken 方法没有被调用,可能是因为它没有得到相机点击图片的信息。我不知道为什么。

最佳答案

我发现您没有为相机分配任何表面支架。为相机提供预览表面很重要。

根据这里的文档:

http://developer.android.com/guide/topics/media/camera.html

遵循文档建议的代码。在没有预览的情况下拍照是一个很大的安全问题。 Android 人员可能已经在 kitkat 中解决了这个问题。

您可能在粘贴此处时错过了那部分代码,因此请注意,还要检查您是否在 SurfaceHolder 的回调方法“onSurfaceCreated”中执行代码“camera.takePicture(null,null,callback)”。

您可以在上述链接中获取所有相关代码。

关于android - 适用于 Jelly Bean 但不适用于 Kitkat 的相机 API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22625904/

有关android - 适用于 Jelly Bean 但不适用于 Kitkat 的相机 API的更多相关文章

  1. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  2. Ruby Sinatra 配置用于生产和开发 - 2

    我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm

  3. ruby-on-rails - ActionController::RoutingError: 未初始化常量 Api::V1::ApiController - 2

    我有用于控制用户任务的Rails5API项目,我有以下错误,但并非总是针对相同的Controller和路由。ActionController::RoutingError:uninitializedconstantApi::V1::ApiController我向您描述了一些我的项目,以更详细地解释错误。应用结构路线scopemodule:'api'donamespace:v1do#=>Loginroutesscopemodule:'login'domatch'login',to:'sessions#login',as:'login',via::postend#=>Teamroutessc

  4. ruby - inverse_of 是否适用于 has_many? - 2

    当我使用has_one时,它​​工作得很好,但在has_many上却不行。在这里您可以看到object_id不同,因为它运行了另一个SQL来再次获取它。ruby-1.9.2-p290:001>e=Employee.create(name:'rafael',active:false)ruby-1.9.2-p290:002>b=Badge.create(number:1,employee:e)ruby-1.9.2-p290:003>a=Address.create(street:"123MarketSt",city:"SanDiego",employee:e)ruby-1.9.2-p290

  5. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  6. ruby-on-rails - Mandrill API 模板 - 2

    我正在使用Mandrill的RubyAPIGem并使用以下简单的测试模板:testastic按照Heroku指南中的示例,我有以下Ruby代码:require'mandrill'm=Mandrill::API.newrendered=m.templates.render'test-template',[{:header=>'someheadertext',:main_section=>'Themaincontentblock',:footer=>'asdf'}]mail(:to=>"JaysonLane",:subject=>"TestEmail")do|format|format.h

  7. ruby-on-rails - 在 Ruby (on Rails) 中使用 imgur API 获取图像 - 2

    我正在尝试使用Ruby2.0.0和Rails4.0.0提供的API从imgur中提取图像。我已尝试按照Ruby2.0.0文档中列出的各种方式构建http请求,但均无济于事。代码如下:require'net/http'require'net/https'defimgurheaders={"Authorization"=>"Client-ID"+my_client_id}path="/3/gallery/image/#{img_id}.json"uri=URI("https://api.imgur.com"+path)request,data=Net::HTTP::Get.new(path

  8. [工业相机] 分辨率、精度和公差之间的关系 - 2

    📢博客主页:https://blog.csdn.net/weixin_43197380📢欢迎点赞👍收藏⭐留言📝如有错误敬请指正!📢本文由Loewen丶原创,首发于CSDN,转载注明出处🙉📢现在的付出,都会是一种沉淀,只为让你成为更好的人✨文章预览:一.分辨率(Resolution)1、工业相机的分辨率是如何定义的?2、工业相机的分辨率是如何选择的?二.精度(Accuracy)1、像素精度(PixelAccuracy)2、定位精度和重复定位精度(RepeatPrecision)三.公差(Tolerance)四.课后作业(Post-ClassExercises)视觉行业的初学者,甚至是做了1~2年

  9. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  10. ruby-on-rails - 使用 HTTParty 的非常基本的 Rails 4.1 API 调用 - 2

    Rails相对较新。我正在尝试调用一个API,它应该向我返回一个唯一的URL。我的应用程序中捆绑了HTTParty。我已经创建了一个UniqueNumberController,并且我已经阅读了几个HTTParty指南,直到我想要什么,但也许我只是有点迷路,真的不知道该怎么做。基本上,我需要做的就是调用API,获取它返回的URL,然后将该URL插入到用户的数据库中。谁能给我指出正确的方向或与我分享一些代码? 最佳答案 假设API为JSON格式并返回如下数据:{"url":"http://example.com/unique-url"

随机推荐