diff --git a/app/src/main/java/com/xypower/mpremote/Constants.java b/app/src/main/java/com/xypower/mpremote/Constants.java index 3a34705..d5f9846 100644 --- a/app/src/main/java/com/xypower/mpremote/Constants.java +++ b/app/src/main/java/com/xypower/mpremote/Constants.java @@ -4,11 +4,16 @@ public class Constants { public static final String PACKAGE_NAME_MP = "com.xypower.mpapp"; public static final String PACKAGE_NAME_MPMASTER = "com.xypower.mpmaster"; + public static final String PACKAGE_NAME_MPREMOTE = "com.xypower.mpremote"; public static final String REMOTE_PATH_ROOT = "/sdcard/" + PACKAGE_NAME_MP + "/"; public static final String REMOTE_PATH_DATA = REMOTE_PATH_ROOT + "data/"; public static final String REMOTE_PATH_DATA_CHANNELS = REMOTE_PATH_ROOT + "data/channels/"; public static final String REMOTE_PATH_PHOTOS = REMOTE_PATH_ROOT + "photos/"; public static final String REMOTE_PATH_TMP = REMOTE_PATH_ROOT + "tmp/"; + public static final String REMOTE_PATH_APP = REMOTE_PATH_ROOT + "data/App.json"; + + + public static final String LOCAL_PATH_REMOTE = "/sdcard/" + PACKAGE_NAME_MPREMOTE + "/" + "tmp/App.json"; public static final String KEY_APP_BV = "app.bv"; public static final String KEY_APP_BCV = "app.bcv"; diff --git a/app/src/main/java/com/xypower/mpremote/DeviceActivity.java b/app/src/main/java/com/xypower/mpremote/DeviceActivity.java index cdf08b9..5521a0b 100644 --- a/app/src/main/java/com/xypower/mpremote/DeviceActivity.java +++ b/app/src/main/java/com/xypower/mpremote/DeviceActivity.java @@ -7,9 +7,7 @@ import androidx.recyclerview.widget.GridLayoutManager; import android.annotation.SuppressLint; import android.app.AlertDialog; import android.content.Intent; -import android.content.res.Resources; import android.database.Cursor; -import android.net.ConnectivityManager; import android.os.Bundle; import android.os.Handler; import android.os.Looper; @@ -62,14 +60,16 @@ public class DeviceActivity extends AppCompatActivity implements View.OnClickLis private int mBatteryChargingVoltage = -1; private String mDeviceIp; private String localIp; - private String configPath;//存放App配置文件 - private String tmp;//存放配置文件的目录 + private String localtmpfilePath;//存放临时配置文件的目录 + private String localphotofilePath;//存放照片配置文件的目录 private AlertDialog alertDialog; private ItemAdapter photoitemAdapter; private ArrayList channelList = new ArrayList<>();//用于存放通道信息 private ItemAdapter videoitemAdapter; private static final int photoAdapter = 1; private static final int videoAdapter = 2; + private AlertDialog photoDialog; + private String localAppPath; @Override protected void onCreate(Bundle savedInstanceState) { @@ -97,6 +97,9 @@ public class DeviceActivity extends AppCompatActivity implements View.OnClickLis case 3: updateRecycleView(channelList); break; + case 4: + AlertDialogUtils.dismiss(photoDialog); + break; } } }; @@ -135,11 +138,11 @@ public class DeviceActivity extends AppCompatActivity implements View.OnClickLis Intent intent = getIntent(); mDeviceIp = intent.getStringExtra("deviceIp");// localIp = intent.getStringExtra("localIp");// - //获取配置文件在本机的存储路径 - tmp = FileUtils.join(getFilesDir(), "tmp"); - configPath = FileUtils.join(tmp, "App.json"); - + localtmpfilePath = getFilesDir() + "/tmp/"; + localphotofilePath = getFilesDir() + "/Photos/"; + localAppPath = localtmpfilePath + "App.json"; + FileUtils.createDir(localtmpfilePath); } @@ -173,12 +176,13 @@ public class DeviceActivity extends AppCompatActivity implements View.OnClickLis return; } boolean res = false; - File file = FileUtils.getFile(configPath); + File file = FileUtils.getFile(localAppPath); if (file != null) { - res = pullFile(adb, Constants.REMOTE_PATH_DATA + "App.json", file); + //将远程文件/sdcard/com.xypower.mpapp/data/App.json下载到本地 + res = pullFile(adb, Constants.REMOTE_PATH_APP, file); } if (res) { - final MicroPhotoContext.AppConfig appConfig = MicroPhotoContext.getMpAppConfig(getApplicationContext(), configPath); + final MicroPhotoContext.AppConfig appConfig = MicroPhotoContext.getMpAppConfig(getApplicationContext(), localAppPath); if (appConfig != null) { mAppConfig = appConfig; } @@ -190,8 +194,7 @@ public class DeviceActivity extends AppCompatActivity implements View.OnClickLis channelBean.setChannel(channel); channelBean.setChannelname("通道" + channel); String remoteFilePath = Constants.REMOTE_PATH_DATA_CHANNELS + Integer.toString(channel) + ".json"; - String join = FileUtils.join(tmp, Integer.toString(channel) + ".json"); - File channelfile = FileUtils.getFile(join); + File channelfile = FileUtils.getFile(localtmpfilePath + Integer.toString(channel) + ".json"); res = pullFile(adb, remoteFilePath, channelfile); if (res) { JSONObject channelJson = JSONUtils.loadJson(channelfile.getAbsolutePath()); @@ -355,6 +358,7 @@ public class DeviceActivity extends AppCompatActivity implements View.OnClickLis for (int idx = 0; idx < 10; idx++) { boolean res = pullFile(adb, remoteFilePath, localFilePath); if (res) { + mHandler.sendMessage(mHandler.obtainMessage(4)); mHandler.post(new Runnable() { @Override public void run() { @@ -417,11 +421,10 @@ public class DeviceActivity extends AppCompatActivity implements View.OnClickLis cameraId = channelJson.optInt("cameraId", cameraId); } // content update --uri content://com.xypower.mpapp.provider/importPriKey - final String cmd = "content update --uri content://" + Constants.PACKAGE_NAME_MP + ".provider/takePhoto --bind path:s:\"" - + remoteFilePath + "\" --bind usb:b:" + usb + " --bind cameraId:i:" + Integer.toString(cameraId) + " --bind channel:i:" - + Integer.toString(channel) + " --bind preset:i:" + Integer.toString(preset) + " --bind leftTopOsd:s:" + Base64.encodeToString(leftTopOsdBytes, Base64.DEFAULT | Base64.NO_WRAP) + ""; + final String cmd = "content update --uri content://" + Constants.PACKAGE_NAME_MP + ".provider/takePhoto --bind path:s:\"" + remoteFilePath + "\" --bind usb:b:" + usb + " --bind cameraId:i:" + Integer.toString(cameraId) + " --bind channel:i:" + Integer.toString(channel) + " --bind preset:i:" + Integer.toString(preset) + " --bind leftTopOsd:s:" + Base64.encodeToString(leftTopOsdBytes, Base64.DEFAULT | Base64.NO_WRAP) + ""; // adbShellResponse = null; + photoDialog = AlertDialogUtils.show(this, "照片或视频获取中"); takePhotoImpl(cmd, fileName, remoteFilePath, photoOrVideo, 0); return 0; diff --git a/app/src/main/java/com/xypower/mpremote/ImageActivity.java b/app/src/main/java/com/xypower/mpremote/ImageActivity.java index 8e63243..fe05169 100644 --- a/app/src/main/java/com/xypower/mpremote/ImageActivity.java +++ b/app/src/main/java/com/xypower/mpremote/ImageActivity.java @@ -4,24 +4,32 @@ import android.annotation.SuppressLint; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AppCompatActivity; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.LinearLayoutManager; +import android.content.ContentUris; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; +import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; import android.graphics.Typeface; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; +import android.net.Uri; import android.net.wifi.ScanResult; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.Build; import android.os.Bundle; +import android.os.Environment; import android.os.Handler; import android.os.Looper; +import android.provider.MediaStore; import android.text.TextUtils; +import android.util.Log; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; @@ -30,6 +38,8 @@ import android.view.WindowInsets; import android.widget.SimpleAdapter; import android.widget.TextView; +import com.xypower.mpremote.adapter.ImageItemAdapter; +import com.xypower.mpremote.adapter.ItemAdapter; import com.xypower.mpremote.databinding.ActivityImageBinding; import java.io.File; @@ -38,86 +48,98 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -/** - * An example full-screen activity that shows and hides the system UI (i.e. - * status bar and navigation/system bar) with user interaction. - */ -public class ImageActivity extends AppCompatActivity { - /** - * Whether or not the system UI should be auto-hidden after - * {@link #AUTO_HIDE_DELAY_MILLIS} milliseconds. - */ +public class ImageActivity extends AppCompatActivity implements View.OnClickListener { private static final boolean AUTO_HIDE = true; - /** - * If {@link #AUTO_HIDE} is set, the number of milliseconds to wait after - * user interaction before hiding the system UI. - */ private static final int AUTO_HIDE_DELAY_MILLIS = 3000; - /** - * Some older devices needs a small delay between UI widget updates - * and a change of the status and navigation bar. - */ private static final int UI_ANIMATION_DELAY = 300; private final Handler mHideHandler = new Handler(Looper.myLooper()); private String mSerialNo = ""; private List mImageFiles = new ArrayList<>(); - private ImagesAdaper mAdapter; + private ImageItemAdapter mAdapter; private List> mItems = new ArrayList>(); - /** - * Touch listener to use for in-layout UI controls to delay hiding the - * system UI. This is to prevent the jarring behavior of controls going away - * while interacting with activity UI. - */ - private final View.OnTouchListener mDelayHideTouchListener = new View.OnTouchListener() { - @Override - public boolean onTouch(View view, MotionEvent motionEvent) { - switch (motionEvent.getAction()) { - case MotionEvent.ACTION_DOWN: - - break; - case MotionEvent.ACTION_UP: - ImageActivity.this.finish(); - break; - default: - break; - } - return false; - } - }; private ActivityImageBinding binding; private String path;//图片地址 + private String cmdid; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - binding = ActivityImageBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); - initIntent(); + initView(); + initData(); + } + + + private void initIntent() { + Intent intent = getIntent(); + path = intent.getStringExtra("path"); + cmdid = intent.getStringExtra("cmdid"); + } + + private void initView() { binding.imageView.setImageDrawable(null); binding.imageView.setClickable(true); - binding.imageView.setOnTouchListener(mDelayHideTouchListener); - binding.imageView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - ImageActivity.this.finish(); - } - }); + binding.imageView.setOnClickListener(this); if (path != null) { loadImage(path); } + mAdapter = new ImageItemAdapter(); +// mAdapter.setOnClickListener(this); + binding.recyclerView.setAdapter(mAdapter); + binding.recyclerView.setLayoutManager(new LinearLayoutManager(this)); + } + + private void initData() { +// 在Activity或Fragment中 + getPicList(); } - private void initIntent() { - Intent intent = getIntent(); - path = intent.getStringExtra("path"); + //获取文件夹下所有的照片 + private void getPicList() { + // 获取应用专属目录的相对路径 + String relativePath = Environment.DIRECTORY_PICTURES + "/" + Constants.PACKAGE_NAME_MPREMOTE + "/"; + + String[] projection = { + MediaStore.Images.Media._ID, + MediaStore.Images.Media.DISPLAY_NAME + }; + + String selection = MediaStore.Images.Media.RELATIVE_PATH + " = ?"; + String[] selectionArgs = new String[]{relativePath}; + + Cursor cursor = getContentResolver().query( + MediaStore.Images.Media.EXTERNAL_CONTENT_URI, + projection, + selection, + selectionArgs, + null + ); + + List imageList = new ArrayList<>(); + if (cursor != null) { + int idColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID); + int nameColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME); + + while (cursor.moveToNext()) { + long id = cursor.getLong(idColumn); + String name = cursor.getString(nameColumn); + Uri contentUri = ContentUris.withAppendedId( + MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id); + + imageList.add(name); + } + cursor.close(); + } + + Log.e("dfsdaf", imageList.toString()); } @Override @@ -126,11 +148,8 @@ public class ImageActivity extends AppCompatActivity { binding.imageView.requestLayout(); } - private boolean loadImage(String path) { - binding.imageView.setImageDrawable(null); - File file = new File(path); if (!file.exists()) { return false; @@ -139,7 +158,6 @@ public class ImageActivity extends AppCompatActivity { if (drawable != null) { binding.imageView.setImageDrawable(drawable); } - return drawable != null; } @@ -166,65 +184,15 @@ public class ImageActivity extends AppCompatActivity { } } - private List> getData() { - mItems.clear(); - - WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE); - WifiInfo wifiInfo = wifiManager.getConnectionInfo(); - - String ssid = ""; - if (wifiInfo != null) { - ssid = wifiInfo.getSSID(); - if (!TextUtils.isEmpty(ssid)) { - if (ssid.startsWith("\"") && ssid.endsWith("\"")) { - ssid = ssid.substring(1, ssid.length() - 1); - } - } + @Override + public void onClick(View v) { + switch (v.getId()) { + case R.id.imageView: + finish(); + break; } - for (File file : mImageFiles) { - Map map = new HashMap(); - - - // Bitmap bm = - map.put("img", null); - // if (scanR) - map.put("text", file.getName()); - mItems.add(map); - } - return mItems; } -// private void refreshListView() { -// mAdapter = new ImagesAdaper(this, getData(), R.layout.list_item, new String[] { "img", "text" }, -// new int[] { R.id.id_img, R.id.id_text }); -// -// binding.imagesView.setAdapter(mAdapter); -// } - - public class ImagesAdaper extends SimpleAdapter { - public ImagesAdaper(Context context, List> items, int resource, String[] from, int[] to) { - super(context, items, resource, from, to); - - } - - public View getView(int position, View convertView, ViewGroup parent){ - convertView = super.getView(position, convertView, parent); - TextView textView = (TextView)convertView.findViewById(R.id.id_channel); - - File file = mImageFiles.get(position); - // if (scanResult.) - String text = (String)mItems.get(position).get("text"); - if (text.startsWith("XY") || text.startsWith("xy")) { - textView.setTextColor(Color.RED); - textView.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD)); - } else { - textView.setTextColor(Color.BLACK); - textView.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL)); - } - - return convertView; - } - } } \ No newline at end of file diff --git a/app/src/main/java/com/xypower/mpremote/adapter/ImageItemAdapter.java b/app/src/main/java/com/xypower/mpremote/adapter/ImageItemAdapter.java new file mode 100644 index 0000000..e4e7e5e --- /dev/null +++ b/app/src/main/java/com/xypower/mpremote/adapter/ImageItemAdapter.java @@ -0,0 +1,69 @@ +package com.xypower.mpremote.adapter; + +import android.annotation.SuppressLint; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.xypower.mpremote.R; +import com.xypower.mpremote.interfaces.OnImageItemClickListener; +import com.xypower.mpremote.utils.ImageUtils; + +import java.util.ArrayList; +import java.util.List; + +public class ImageItemAdapter extends RecyclerView.Adapter { + public int adapterType; + public OnImageItemClickListener listener; + + private List itemList = new ArrayList<>(); + + public class MyViewHolder extends RecyclerView.ViewHolder { + private ImageView imageView; + + public MyViewHolder(View view, OnImageItemClickListener listener) { + super(view); + imageView = view.findViewById(R.id.id_imageview); + } + + public ImageView getImage() { + return imageView; + } + } + + public void setOnClickListener(OnImageItemClickListener listener) { + this.listener = listener; + } + + public void setItemList(List list) { + this.itemList = list; + notifyDataSetChanged(); + } + + @NonNull + @Override + public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_img_item, parent, false); + return new MyViewHolder(view, listener); + } + + @Override + public void onBindViewHolder(@NonNull MyViewHolder holder, @SuppressLint("RecyclerView") int position) { + String s = itemList.get(position); + holder.getImage().setImageDrawable(ImageUtils.loadDrawable(s)); + holder.itemView.setOnClickListener(v -> { + if (listener != null) { + listener.onItemClick(v, position); + } + }); + } + + @Override + public int getItemCount() { + return itemList.size(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/xypower/mpremote/interfaces/OnImageItemClickListener.java b/app/src/main/java/com/xypower/mpremote/interfaces/OnImageItemClickListener.java new file mode 100644 index 0000000..175bb68 --- /dev/null +++ b/app/src/main/java/com/xypower/mpremote/interfaces/OnImageItemClickListener.java @@ -0,0 +1,10 @@ +package com.xypower.mpremote.interfaces; + +import android.view.View; + +import com.xypower.mpremote.bean.ChannelBean; + +public interface OnImageItemClickListener { + void onItemClick(View v, int position); +} + diff --git a/app/src/main/java/com/xypower/mpremote/utils/FileUtils.java b/app/src/main/java/com/xypower/mpremote/utils/FileUtils.java index 4acc055..36a2e03 100644 --- a/app/src/main/java/com/xypower/mpremote/utils/FileUtils.java +++ b/app/src/main/java/com/xypower/mpremote/utils/FileUtils.java @@ -15,21 +15,22 @@ public class FileUtils { private static final String TAG = "FileUtils"; - /** - * 拼接路径(使用 File 类) - * - * @param basePath 基础路径 - * @param subPath 子路径 - * @return 拼接后的路径 - */ - public static String join(String basePath, String subPath) { - File file = new File(basePath, subPath); - return file.getAbsolutePath(); - } - public static String join(File basePath, String subPath) { - File file = new File(basePath, subPath); - return file.getAbsolutePath(); - } +// /** +// * 拼接路径(使用 File 类) +// * +// * @param basePath 基础路径 +// * @param subPath 子路径 +// * @return 拼接后的路径 +// */ +// public static String join(String basePath, String subPath) { +// File file = new File(basePath, subPath); +// return file.getAbsolutePath(); +// } +// public static String join(File basePath, String subPath) { +// File file = new File(basePath, subPath); +// return file.getAbsolutePath(); +// } + /** * 检查外部存储是否可用 */ @@ -92,6 +93,14 @@ public class FileUtils { */ public static File getFile(String filePath) { File file = new File(filePath); + File parentDir = file.getParentFile(); + if (parentDir != null && !parentDir.exists()) { + boolean dirsCreated = parentDir.mkdirs(); // 递归创建所有父目录 + if (!dirsCreated) { + Log.e("Error", "无法创建父目录: " + parentDir.getAbsolutePath()); + return file; + } + } if (!file.exists()) { try { boolean newFile = file.createNewFile(); diff --git a/app/src/main/java/com/xypower/mpremote/utils/ImageUtils.java b/app/src/main/java/com/xypower/mpremote/utils/ImageUtils.java new file mode 100644 index 0000000..e8a44cc --- /dev/null +++ b/app/src/main/java/com/xypower/mpremote/utils/ImageUtils.java @@ -0,0 +1,26 @@ +package com.xypower.mpremote.utils; + + +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; + +public class ImageUtils { + + public static Drawable loadDrawable(String file) { + if (file == null || file.isEmpty()) { + return null; + } + + Drawable drawable = null; + try { + Bitmap bitmap = BitmapFactory.decodeFile(file); + drawable = new BitmapDrawable(bitmap); + } catch (Exception e) { + e.printStackTrace(); + } + + return drawable; + } +} diff --git a/app/src/main/res/layout/activity_image.xml b/app/src/main/res/layout/activity_image.xml index 3d30528..17f1656 100644 --- a/app/src/main/res/layout/activity_image.xml +++ b/app/src/main/res/layout/activity_image.xml @@ -12,20 +12,17 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:scaleType="fitStart" - 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" /> - + app:layout_constraintTop_toBottomOf="@+id/imageView" /> \ No newline at end of file diff --git a/app/src/main/res/layout/img_list_item.xml b/app/src/main/res/layout/img_list_item.xml deleted file mode 100644 index 4816aa4..0000000 --- a/app/src/main/res/layout/img_list_item.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/list_img_item.xml b/app/src/main/res/layout/list_img_item.xml new file mode 100644 index 0000000..deadfd5 --- /dev/null +++ b/app/src/main/res/layout/list_img_item.xml @@ -0,0 +1,19 @@ + + + + + + + \ No newline at end of file