抱歉,当时写完这边博客,手机号就没用了,就没登陆过,后续我会整理完,放到github上的,有问题可以在github上交流.
参考文章
1)从Arduino IDE转到文件 > 首选项
2)在“其他Board Manager URL”字段中输入 https://www.arduino.cn/package_esp32_index.json,如下图所示。然后,单击“好”按钮。
3)工具->开发板->开发板管理器
4)搜索esp32并安装
5)安装完成后
在工具->开发板 菜单中选择板子 在这选择了 ESP32 Wrover Module
未修改之前
//#define CAMERA_MODEL_AI_THINKER
修改后,去掉注释
#define CAMERA_MODEL_AI_THINKER
配置要连接的wifi
const char* ssid = “NETGEAR50”;
const char* password = “whua9307”;
下载代码时注意将esp32的IO0与GND相连
出现这个说明下载成功
1.在layout层需要添加两个元件控件
一个imageview 命名为img
一个button 命名为downloadFile
2.Acticity的代码
package xyz.pengzhihui.esp32ipcam;
import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
public class MainActivity extends Activity implements View.OnClickListener
{
private static final String TAG = "MainActivity::";
private HandlerThread handlerThread;
private Handler handler;
private ImageView imageView;
private final int DOWNDLOAD = 1;
private final int REGISTER = 2;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.downloadFile).setOnClickListener(this);
imageView = findViewById(R.id.img);
handlerThread = new HandlerThread("http");
handlerThread.start();
handler = new HttpHandler(handlerThread.getLooper());
}
@Override
public void onClick(View v)
{
switch (v.getId())
{
case R.id.downloadFile:
handler.sendEmptyMessage(DOWNDLOAD);
break;
default:
break;
}
}
//动态申请权限
public static boolean isGrantExternalRW(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && activity.checkSelfPermission(
Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
activity.requestPermissions(new String[]{
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
}, 1);
return false;
}
return true;
}
private class HttpHandler extends Handler
{
public HttpHandler(Looper looper)
{
super(looper);
}
@Override
public void handleMessage(Message msg)
{
switch (msg.what)
{
case DOWNDLOAD:
downloadFile();
break;
default:
break;
}
}
}
private void downloadFile()
{
String downloadUrl = "http://192.168.50.26:80/stream";
String savePath = "/sdcard/pic.jpg";
File file = new File(savePath);
if (file.exists())
{
file.delete();
}
if(!isGrantExternalRW(this)){
return;
}
BufferedInputStream bufferedInputStream = null;
FileOutputStream outputStream = null;
try
{
URL url = new URL(downloadUrl);
try
{
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("GET");
httpURLConnection.setConnectTimeout(1000 * 5);
httpURLConnection.setReadTimeout(1000 * 5);
httpURLConnection.setDoInput(true);
httpURLConnection.connect();
if (httpURLConnection.getResponseCode() == 200)
{
InputStream in = httpURLConnection.getInputStream();
InputStreamReader isr = new InputStreamReader(in);
BufferedReader bufferedReader = new BufferedReader(isr);
String line;
StringBuffer stringBuffer = new StringBuffer();
int i = 0;
int len;
byte[] buffer;
while ((line = bufferedReader.readLine()) != null)
{
if (line.contains("Content-Type:"))
{
line = bufferedReader.readLine();
len = Integer.parseInt(line.split(":")[1].trim());
bufferedInputStream = new BufferedInputStream(in);
buffer = new byte[len];
int t = 0;
while (t < len)
{
t += bufferedInputStream.read(buffer, t, len - t);
}
bytesToImageFile(buffer, "0A.jpg");
final Bitmap bitmap = BitmapFactory.decodeFile("sdcard/0A.jpg");
runOnUiThread(new Runnable()
{
@Override
public void run()
{
imageView.setImageBitmap(bitmap);
}
});
}
}
}
} catch (IOException e)
{
e.printStackTrace();
}
} catch (MalformedURLException e)
{
e.printStackTrace();
} finally
{
try
{
if (bufferedInputStream != null)
{
bufferedInputStream.close();
}
if (outputStream != null)
{
outputStream.close();
}
} catch (IOException e)
{
e.printStackTrace();
}
}
}
private void bytesToImageFile(byte[] bytes, String fileName)
{
try
{
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + fileName);
FileOutputStream fos = new FileOutputStream(file);
fos.write(bytes, 0, bytes.length);
fos.flush();
fos.close();
} catch (Exception e)
{
e.printStackTrace();
}
}
}
3.需要烧录进Esp32Cam的代码
自己修改其中的局域网名和局域网密码,其他还有类似pins.h文件,需要从我开头所给的参考文章中获取。
#include
// #include
#include
#include
// #include
#include "Pins.h"
#include "Camera.h"
#include "Motor.h"
const char* ssid = ""; //填你自己的局域网名
const char* password = ""; //局域网密码
WiFiServer server(81);
// OV2640 camera
Camera ov2640;
void setup()
{
Serial.begin(115200);
Wire.begin(I2C0_SDA, I2C0_SCL);
Wire.setClock(400000);
// while (!mpu6050.testConnection());
// mpu6050.initialize();
ov2640.initialize();
int n = WiFi.scanNetworks();
Serial.println("scan done");
if (n == 0)
{
Serial.println("no networks found");
}
else
{
Serial.print(n);
Serial.println(" networks found");
for (int i = 0; i < n; ++i)
{
// Print SSID and RSSI for each network found
Serial.print(i + 1);
Serial.print(": ");
Serial.print(WiFi.SSID(i));
Serial.print(" (");
Serial.print(WiFi.RSSI(i));
Serial.print(")");
Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN) ? " " : "*");
delay(10);
}
}
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
ov2640.startCameraServer();
Serial.print("Camera Ready! Use 'http://");
Serial.print(WiFi.localIP());
Serial.println("' to connect");
server.begin();
}
float i = -1;
long heart_beat = 0;
void loop()
{
Serial.println(analogRead(38));
WiFiClient client = server.available(); // listen for incoming clients
if (client)
{
// if you get a client,
Serial.println("New Client."); // print a message out the serial port
String currentLine = ""; // make a String to hold incoming data from the client
while (client.connected())
{ // loop while the client's connected
if (client.available())
{ // if there's bytes to read from the client,
}
}
}
delay(50);
}
String getValue(String data, char separator, int index)
{
int found = 0;
int strIndex[] = { 0, -1 };
int maxIndex = data.length() - 1;
for (int i = 0; i <= maxIndex && found <= index; i++)
{
if (data.charAt(i) == separator || i == maxIndex)
{
found++;
strIndex[0] = strIndex[1] + 1;
strIndex[1] = (i == maxIndex) ? i + 1 : i;
}
}
return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
}
4.注意事项
1.关于I2Cdev.h文件可能在烧录的时候没有这个库,这个需要自行去github上下载对应的库,并导入就能正常编译了
icdev库下载
2.如果要在手机APP模拟器上连上网就需要在文件AndroidManifest.xml 加上
android:supportsRtl=“true”
3.需要在文件AndroidManifest.xml 加上android:requestLegacyExternalStorage = “true” 这个属性
android 10 系统获取图片权限问题