实现拍照和短视频功能

main
Matthew 12 months ago
parent 8d4c34d322
commit 8599a3aa78

@ -9,6 +9,8 @@
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<application <application
android:allowBackup="true" android:allowBackup="true"
@ -22,8 +24,12 @@
android:theme="@style/Theme.MpRemote" android:theme="@style/Theme.MpRemote"
android:usesCleartextTraffic="true" android:usesCleartextTraffic="true"
tools:targetApi="31"> tools:targetApi="31">
<activity
android:name=".DeviceActivity"
android:exported="false" />
<activity <activity
android:name=".VideoActivity" android:name=".VideoActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:exported="false" /> android:exported="false" />
<activity <activity
android:name=".WifiScanActivity" android:name=".WifiScanActivity"
@ -42,7 +48,7 @@
android:configChanges="orientation|keyboardHidden|screenSize" android:configChanges="orientation|keyboardHidden|screenSize"
android:exported="false" android:exported="false"
android:label="@string/title_activity_image" android:label="@string/title_activity_image"
android:screenOrientation="landscape" /> />
</application> </application>
</manifest> </manifest>

@ -0,0 +1,516 @@
package com.xypower.mpremote;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.text.Html;
import android.text.TextUtils;
import android.text.format.Formatter;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import com.xypower.common.FileUtils;
import com.xypower.common.MicroPhotoContext;
import com.xypower.mpremote.databinding.ActivityDeviceBinding;
import com.xypower.mpremote.databinding.ActivityMainBinding;
import java.io.File;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import dadb.AdbKeyPair;
import dadb.AdbShellResponse;
import dadb.Dadb;
public class DeviceActivity extends AppCompatActivity {
private static final String TAG = "ADB";
private static final boolean DEBUG = false;
private static final String PACKAGE_NAME_MP = "com.xypower.mpapp";
private static final String REMOTE_PATH_ROOT = "/sdcard/" + PACKAGE_NAME_MP + "/";
private static final String REMOTE_PATH_DATA = REMOTE_PATH_ROOT + "data/";
private static final String REMOTE_PATH_PHOTOS = REMOTE_PATH_ROOT + "photos/";
private static final String REMOTE_PATH_TMP = REMOTE_PATH_ROOT + "tmp/";
private static final String KEY_APP_BV = "app.bv";
private static final String KEY_APP_BCV = "app.bcv";
private static final String KEY_RO_SERIALNO = "ro.serialno";
private static final String KEY_APP_MP_VERSION = "mpapp.version";
private static final int ADB_SERVER_PORT = 5555;
private static final String WIFI_IP_PREFIX = "192.168.";
// private static final String WIFI_IP_DEVIDE = "192.168.50.1";
private static final String WIFI_IP_DEVICE = "192.168.50.92";
// [vendor.ril.nw.signalstrength.lte.1]: [-85,27]
//[vendor.ril.nw.signalstrength.lte.2]: [-86,27]
private ActivityDeviceBinding binding;
private Handler mHandler;
private Dadb mAdb;
private Map<String, String> mProps = new HashMap<>();
private MicroPhotoContext.AppConfig mAppConfig;
private int mBatteryVoltage = -1;
private int mBatteryChargingVoltage = -1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityDeviceBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
mHandler = new Handler();
File file = new File(getFilesDir(), ".keypair");
if (!file.exists()) {
file.mkdirs();
}
final File pubKeyFile = new File(file, "pub.key");
final File priKeyFile = new File(file, "pri.key");
if (!priKeyFile.exists() || !pubKeyFile.exists()) {
AdbKeyPair.generate(priKeyFile, pubKeyFile);
}
final File fileTmp = new File(getFilesDir(), "tmp");
if (!fileTmp.exists()) {
fileTmp.mkdirs();
}
final AdbKeyPair adbKeyPair = AdbKeyPair.read(priKeyFile, pubKeyFile);
final Context context = getApplicationContext();
(new Thread(new Runnable() {
@Override
public void run() {
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
String ipAddressByWifi = null;
if (wifiManager != null) {
ipAddressByWifi = Formatter.formatIpAddress(wifiManager.getDhcpInfo().ipAddress);
}
if (ipAddressByWifi.contains(WIFI_IP_PREFIX)) {
String deviceIP = Formatter.formatIpAddress(wifiManager.getDhcpInfo().gateway);
if (DEBUG) {
deviceIP = WIFI_IP_DEVICE;
}
Socket mSocket = null;
try {
mSocket = new Socket(deviceIP, ADB_SERVER_PORT);
if (mSocket.isConnected()) {
mSocket.close();
}
} catch (Exception ex) {
ex.printStackTrace();
}
Dadb adb = Dadb.discover(deviceIP, adbKeyPair);
if (adb != null) {
mAdb = adb;
AdbShellResponse adbShellResponse = null;
try {
adbShellResponse = mAdb.shell("getprop");
} catch (Exception ex) {
ex.printStackTrace();
}
if (adbShellResponse.getExitCode() == 0) {
String[] lines = FileUtils.splitLines(adbShellResponse.getAllOutput());
for (String line : lines) {
int pos = line.indexOf("]: [");
if (pos != -1) {
String key = line.substring(1, pos);
String val = line.substring(pos + 4, line.length() - 1);
mProps.put(key, val);
}
}
}
// adb shell pm dump com.xypower.mpremote | grep "versionName"
adbShellResponse = null;
try {
adbShellResponse = mAdb.shell("pm dump " + PACKAGE_NAME_MP + " | grep \"versionName\"");
} catch (Exception ex) {
ex.printStackTrace();
}
if (adbShellResponse.getExitCode() == 0) {
String[] lines = FileUtils.splitLines(adbShellResponse.getAllOutput());
for (String line : lines) {
int pos = line.indexOf("versionName=");
if (pos != -1) {
String val = line.substring(pos + 12);
mProps.put(KEY_APP_MP_VERSION, val);
}
}
}
String remoteFilePath = REMOTE_PATH_TMP + "bv.txt";
String cmd = "am start -n " + PACKAGE_NAME_MP + "/" + PACKAGE_NAME_MP + ".BridgeActivity --es action \"query_bv\" --es path \"" + remoteFilePath + "\"";
adbShellResponse = null;
try {
adbShellResponse = mAdb.shell(cmd);
} catch (Exception ex) {
ex.printStackTrace();
}
if (adbShellResponse.getExitCode() == 0) {
File localFilePath = new File(fileTmp, "bv.txt");
if (localFilePath.exists()) {
localFilePath.delete();
}
for (int idx = 0; idx < 10; idx++) {
boolean res = pullFile(mAdb, remoteFilePath, localFilePath);
if (res) {
String content = FileUtils.readTextFile(localFilePath.getAbsolutePath());
if (!TextUtils.isEmpty(content)) {
int pos = content.indexOf(" ");
if (pos != -1) {
String bv = content.substring(0, pos);
String bcv = content.substring(pos + 1);
if (!TextUtils.isEmpty(bv)) {
mBatteryVoltage = Integer.parseInt(bv);
}
if (!TextUtils.isEmpty(bcv)) {
mBatteryChargingVoltage = Integer.parseInt(bcv);
}
}
}
localFilePath.delete();
break;
}
try {
Thread.sleep(1000);
} catch (Exception ex) {
ex.printStackTrace();
}
}
try {
mAdb.shell("rm " + remoteFilePath);
} catch (Exception ex) {
ex.printStackTrace();
}
}
File appConfigFile = new File(fileTmp, "App.json");
boolean res = pullFile(adb, REMOTE_PATH_DATA + "App.json", appConfigFile);
if (res) {
final MicroPhotoContext.AppConfig appConfig = MicroPhotoContext.getMpAppConfig(context, appConfigFile.getAbsolutePath());
mAppConfig = appConfig;
DeviceActivity.this.mHandler.post(new Runnable() {
@Override
public void run() {
DeviceActivity.this.showAppInfo();
}
});
}
} else {
mHandler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(DeviceActivity.this, R.string.err_dev_not_found, Toast.LENGTH_LONG).show();
}
});
}
}
// Dadb dadb = Dadb.create("localhost", 5555, adbKeyPair);
// Dadb.discover();
}
})).start();
binding.takePhoto1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
takePhoto(1, 255, true);
}
});
binding.takeVideo1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
takeVideo(1, 255, false);
}
});
}
protected boolean pullFile(Dadb adb, String remoteFilePath, File localFilePath) {
if (localFilePath.exists()) {
localFilePath.delete();
}
Log.i(TAG, "PULL: " + remoteFilePath);
boolean res = false;
try {
adb.pull(localFilePath, remoteFilePath);
res = true;
} catch (Exception ex) {
ex.printStackTrace();
}
return res && localFilePath.exists();
}
protected void takePhotoImpl(final String cmd, final int channel, final int preset, final String localFileName, final String remoteFilePath, final boolean photoOrVideo, long sleepTime) {
Thread th = new Thread(new Runnable() {
@Override
public void run() {
if (sleepTime > 0) {
try {
Thread.sleep(sleepTime);
} catch (Exception ex) {
}
}
AdbShellResponse adbShellResponse = null;
try {
adbShellResponse = mAdb.shell(cmd);
} catch (Exception ex) {
ex.printStackTrace();
}
if (adbShellResponse != null) {
if (adbShellResponse.getExitCode() == 0) {
File localFilePath = new File(getFilesDir(), localFileName);
for (int idx = 0; idx < 10; idx++) {
boolean res = pullFile(mAdb, remoteFilePath, localFilePath);
if (res) {
mHandler.post(new Runnable() {
@Override
public void run() {
if (photoOrVideo) {
showPhoto(localFilePath.getAbsolutePath());
} else {
showVideo(localFilePath.getAbsolutePath());
}
}
});
break;
}
try {
Thread.sleep(1000);
} catch (Exception ex) {
ex.printStackTrace();
}
}
try {
// mAdb.shell("rm " + remoteFilePath);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
});
th.start();
}
protected long takePhoto(int channel, int preset, final boolean photoOrVideo) {
if (mAdb == null) {
return 0;
}
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddhhmmss");
Date dt = new Date();
int cameraId = channel - 1;
final String fileName = "IMG-" + Integer.toString(channel) + "-" + simpleDateFormat.format(dt) + (photoOrVideo ? ".jpg" : ".mp4");
final String remoteFilePath = REMOTE_PATH_TMP + fileName;
String leftTopOsd = "";
if (mAppConfig != null) {
leftTopOsd += mAppConfig.cmdid + " ";
}
SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
leftTopOsd += simpleDateFormat2.format(dt) + " ";
leftTopOsd += "CH:" + Integer.toString(channel) + " ";
String usb = (channel == 4) ? "true" : "false";
final String cmd = "am start -n " + PACKAGE_NAME_MP + "/" + PACKAGE_NAME_MP + ".BridgeActivity --es action \"take_photo\" --es path \""
+ remoteFilePath + "\" --ez usb " + usb + " --ei cameraId " + Integer.toString(cameraId) + " --ei channel "
+ Integer.toString(channel) + " --ei preset " + Integer.toString(preset) + " --es leftTopOsd \"" + leftTopOsd + "\"";
// adbShellResponse = null;
takePhotoImpl(cmd, channel, preset, fileName, remoteFilePath, photoOrVideo, 0);
return 0;
}
protected long takeVideo(int channel, int preset, final boolean photoOrVideo) {
if (mAdb == null) {
return 0;
}
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddhhmmss");
Date dt = new Date();
int cameraId = channel - 1;
int duration = 5;
String leftTopOsd = "";
if (mAppConfig != null) {
leftTopOsd += mAppConfig.cmdid + " ";
}
SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
leftTopOsd += simpleDateFormat2.format(dt) + " ";
leftTopOsd += "CH:" + Integer.toString(channel) + " ";
final String fileName = "IMG-" + Integer.toString(channel) + "-" + simpleDateFormat.format(dt) + (photoOrVideo ? ".jpg" : ".mp4");
final String remoteFilePath = REMOTE_PATH_TMP + fileName;
// int quality = intent.getIntExtra("quality", 0);
// int width = intent.getIntExtra("width", 1280);
// int height = intent.getIntExtra("height", 720);
// int duration = intent.getIntExtra("duration", 15);
// int orientation = intent.getIntExtra("orientation", 0);
// long videoId = System.currentTimeMillis() / 1000;
//
// String leftTopOsd = intent.getStringExtra("leftTopOsd");
// String rightTopOsd = intent.getStringExtra("rightTopOsd");
// String rightBottomOsd = intent.getStringExtra("rightBottomOsd");
// String leftBottomOsd = intent.getStringExtra("leftBottomOsd");
String usb = (channel == 4) ? "true" : "false";
final String cmd = "am start -n " + PACKAGE_NAME_MP + "/" + PACKAGE_NAME_MP + ".BridgeActivity --es action \"recording\" --es path \""
+ remoteFilePath + "\" --ez usb " + usb + " --ei cameraId " + Integer.toString(cameraId) + " --ei channel "
+ Integer.toString(channel) + " --ei preset " + Integer.toString(preset) + " --ei duration " + Integer.toString(duration)
+ " --el videoId " + Long.toString(dt.getTime() / 1000) + " --es leftTopOsd \"" + leftTopOsd + "\"";
// adbShellResponse = null;
Log.d(TAG, cmd);
takePhotoImpl(cmd, channel, preset, fileName, remoteFilePath, photoOrVideo, duration * 1000);
return 0;
}
private void showPhoto(final String filePath) {
Intent intent = new Intent(DeviceActivity.this, ImageActivity.class);
intent.putExtra("path", filePath);
// intent.putExtra("info", info);
startActivity(intent);
}
private void showVideo(final String filePath) {
Intent intent = new Intent(DeviceActivity.this, VideoActivity.class);
intent.putExtra("path", filePath);
// intent.putExtra("info", info);
startActivity(intent);
}
private void showAppInfo() {
ActionBar actionBar = getSupportActionBar();
// 视频浏览,拍照,设备信息及状态查询(编号版本双SIM卡状态电池及太阳能电压等),可以参考东视
Resources resources = getResources();
// String buildTime = BuildConfig.BUILD_
// Date date = new Date(BuildConfig.BUILD_TIMESTAMP);
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
String title = resources.getString(R.string.app_name);
if (!TextUtils.isEmpty(mAppConfig.cmdid)) {
title = mAppConfig.cmdid;
}
actionBar.setTitle(title);
StringBuilder stringBuilder = new StringBuilder();
if (mProps.containsKey(KEY_RO_SERIALNO)) {
String val = (String)mProps.get(KEY_RO_SERIALNO);
appendKeyValue(stringBuilder, "序列号", val);
}
appendKeyValue(stringBuilder, "CMDID", mAppConfig.cmdid);
appendKeyValue(stringBuilder, "主站", mAppConfig.server + ":" + Integer.toString(mAppConfig.port));
appendKeyValue(stringBuilder, "通道数", Integer.toString(mAppConfig.channels));
if (mProps.containsKey(KEY_APP_MP_VERSION)) {
String val = (String)mProps.get(KEY_APP_MP_VERSION);
appendKeyValue(stringBuilder, "APP版本", val);
}
if (mBatteryVoltage != -1) {
appendKeyValue(stringBuilder, "电池电压", Integer.toString(mBatteryVoltage / 1000) + "." + Integer.toString((mBatteryVoltage % 1000) / 100));
}
if (mBatteryChargingVoltage != -1) {
appendKeyValue(stringBuilder, "充电电压", Integer.toString(mBatteryChargingVoltage / 1000) + "." + Integer.toString((mBatteryChargingVoltage % 1000) / 100));
}
binding.deviceInfo.setText(Html.fromHtml(stringBuilder.toString()));
}
private void appendKeyValue(StringBuilder stringBuilder, String key, String val) {
stringBuilder.append(key + "<font color=\"red\"><b>" + val + "</b></font>");
stringBuilder.append("<br>");
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return false;
default:
return super.onOptionsItemSelected(item);
}
}
}

@ -6,6 +6,7 @@ import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent; import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.BitmapDrawable;
@ -80,22 +81,12 @@ public class ImageActivity extends AppCompatActivity {
binding = ActivityImageBinding.inflate(getLayoutInflater()); binding = ActivityImageBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot()); setContentView(binding.getRoot());
binding.imageViewOpt.setImageDrawable(null); binding.imageView.setImageDrawable(null);
binding.imageViewAE.setImageDrawable(null);
binding.imageViewOpt.setVisibility(View.GONE); binding.imageView.setClickable(true);
binding.imageView.setOnTouchListener(mDelayHideTouchListener);
binding.imageViewAE.setClickable(true); binding.imageView.setOnClickListener(new View.OnClickListener() {
binding.imageViewAE.setOnTouchListener(mDelayHideTouchListener);
binding.imageViewAE.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ImageActivity.this.finish();
}
});
binding.imageViewOpt.setOnClickListener(new View.OnClickListener() {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
ImageActivity.this.finish(); ImageActivity.this.finish();
@ -110,6 +101,13 @@ public class ImageActivity extends AppCompatActivity {
} }
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
binding.imageView.requestLayout();
}
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
@ -123,32 +121,18 @@ public class ImageActivity extends AppCompatActivity {
private boolean loadImage(String path) { private boolean loadImage(String path) {
binding.imageViewOpt.setVisibility(View.GONE); binding.imageView.setImageDrawable(null);
binding.imageViewAE.setVisibility(View.GONE);
File file = new File(path); File file = new File(path);
if (!file.exists()) { if (!file.exists()) {
return false; return false;
} }
Drawable drawable = loadDrawable(path); Drawable drawable = loadDrawable(path);
Drawable drawableAE = loadDrawable(path + ".ae.jpg"); if (drawable != null) {
if (drawableAE == null && drawable == null) { binding.imageView.setImageDrawable(drawable);
return false;
}
if (drawableAE != null && drawable != null) {
binding.imageViewOpt.setImageDrawable(drawable);
binding.imageViewAE.setImageDrawable(drawableAE);
binding.imageViewOpt.setVisibility(View.VISIBLE);
binding.imageViewAE.setVisibility(View.VISIBLE);
}
else if (drawable != null) {
binding.imageViewOpt.setImageDrawable(drawable);
binding.imageViewAE.setImageDrawable(null);
binding.imageViewOpt.setVisibility(View.VISIBLE);
// binding.imageViewAE.setVisibility(View.VISIBLE);
} }
return true; return drawable != null;
} }
private Drawable loadDrawable(String file) { private Drawable loadDrawable(String file) {

@ -13,6 +13,7 @@ import android.text.Html;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.format.Formatter; import android.text.format.Formatter;
import android.util.Log; import android.util.Log;
import android.view.Menu;
import android.view.View; import android.view.View;
import android.widget.Toast; import android.widget.Toast;
@ -279,6 +280,14 @@ public class MainActivity extends AppCompatActivity {
} }
@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_activity_actions, menu);
return true;
}
protected boolean pullFile(Dadb adb, String remoteFilePath, File localFilePath) { protected boolean pullFile(Dadb adb, String remoteFilePath, File localFilePath) {
if (localFilePath.exists()) { if (localFilePath.exists()) {
localFilePath.delete(); localFilePath.delete();

@ -4,6 +4,7 @@ import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent; import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle; import android.os.Bundle;
import android.view.MenuItem; import android.view.MenuItem;
import android.widget.MediaController; import android.widget.MediaController;
@ -26,7 +27,6 @@ public class VideoActivity extends AppCompatActivity {
if (path != null) { if (path != null) {
VideoView videoView = (VideoView)findViewById(R.id.videoView); VideoView videoView = (VideoView)findViewById(R.id.videoView);
videoView.setVideoPath(path); videoView.setVideoPath(path);
//创建MediaController对象 //创建MediaController对象
@ -42,6 +42,13 @@ public class VideoActivity extends AppCompatActivity {
} }
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
VideoView videoView = (VideoView)findViewById(R.id.videoView);
videoView.requestLayout();
}
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M17.65,6.35C16.2,4.9 14.21,4 12,4c-4.42,0 -7.99,3.58 -7.99,8s3.57,8 7.99,8c3.73,0 6.84,-2.55 7.73,-6h-2.08c-0.82,2.33 -3.04,4 -5.65,4 -3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6c1.66,0 3.14,0.69 4.22,1.78L13,11h7V4l-2.35,2.35z"/>
</vector>

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".DeviceActivity">
<TextView
android:id="@+id/deviceInfo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="24dp"
android:singleLine="false"
android:lineSpacingMultiplier="1.25"
android:textSize="16sp"
android:text=""
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/takePhoto1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginBottom="8dp"
android:text="通道1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="@+id/takeVideo1" />
<Button
android:id="@+id/takeVideo1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginBottom="24dp"
android:text="视频1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -8,22 +8,10 @@
tools:context=".ImageActivity"> tools:context=".ImageActivity">
<ImageView <ImageView
android:id="@+id/imageViewAE" android:id="@+id/imageView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:scaleType="fitXY" android:scaleType="fitCenter"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@android:drawable/screen_background_light_transparent" />
<ImageView
android:id="@+id/imageViewOpt"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/action_search"
android:icon="@drawable/ic_action_refresh"
android:title="@string/action_refresh"
app:showAsAction="always" />
<!-- Settings, should always be in the overflow -->
<item android:id="@+id/action_settings"
android:title="@string/action_settings"
app:showAsAction="never" />
</menu>

@ -1,5 +1,7 @@
<resources> <resources>
<string name="app_name">欣影微拍遥控</string> <string name="app_name">欣影微拍遥控</string>
<string name="err_dev_not_found">未发现微拍设备</string> <string name="err_dev_not_found">未发现微拍设备</string>
<string name="title_activity_image"></string>> <string name="title_activity_image"></string>
<string name="action_refresh">刷新</string>
<string name="action_settings">设置</string>
</resources> </resources>
Loading…
Cancel
Save