Dana
2025-11-30 c73a0d8e4cac688bea44da00e349fe4e726d8a54
1.加远程服务,客户端以bindservice的形式调用
2个文件已修改
10个文件已添加
510 ■■■■■ 已修改文件
app/build.gradle 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/AndroidManifest.xml 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/aidl/com/anyun/h264/IH264EncodeService.aidl 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/aidl/com/anyun/h264/model/ResourceInfo.aidl 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/anyun/h264/H264EncodeService.java 421 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
key/Verify.txt 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
key/bjkey.jks 补丁 | 查看 | 原始文档 | blame | 历史
key/key.jks 补丁 | 查看 | 原始文档 | blame | 历史
key/key.jks.ori 补丁 | 查看 | 原始文档 | blame | 历史
key/keyrk3288.jks 补丁 | 查看 | 原始文档 | blame | 历史
key/keysc200.jks 补丁 | 查看 | 原始文档 | blame | 历史
key/keysc626.jks 补丁 | 查看 | 原始文档 | blame | 历史
app/build.gradle
@@ -19,6 +19,9 @@
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildFeatures{
        aidl true
    }
    signingConfigs{
app/src/main/AndroidManifest.xml
@@ -31,6 +31,16 @@
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <!-- H264编码服务 -->
        <service
            android:name=".h264.H264EncodeService"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.anyun.h264.H264EncodeService" />
            </intent-filter>
        </service>
    </application>
</manifest>
app/src/main/aidl/com/anyun/h264/IH264EncodeService.aidl
New file
@@ -0,0 +1,28 @@
package com.anyun.h264;
import com.anyun.h264.model.ResourceInfo;
import java.util.List;
/**
 * H264编码服务AIDL接口
 */
interface IH264EncodeService {
    /**
     * 控制H264编码
     * @param action 操作类型:0-开启h264文件写入,1-停止h264编码并停止写入文件,2-开启网络推送h264(不写入文件),3-停止h264编码并停止网络推送
     * @param jsonConfig JSON格式的配置参数,包含:ip(服务器IP)、port(服务器端口)、width(视频宽度)、height(视频高度)、framerate(帧率)
     *                  示例:{"ip":"192.168.1.100","port":8888,"width":640,"height":480,"framerate":25}
     *                  如果action为1或3(停止操作),此参数可为空或null
     * @return 0-成功,1-失败
     */
    int controlEncode(int action, String jsonConfig);
    /**
     * 获取资源列表
     * @param startTime 开始时间(格式:YYMMDDHHmmss,BCD编码的6字节字符串)
     * @param endTime 结束时间(格式:YYMMDDHHmmss,BCD编码的6字节字符串)
     * @return 资源列表(根据JT/T 1076-2016表23定义)
     */
    List<ResourceInfo> getResourceList(String startTime, String endTime);
}
app/src/main/aidl/com/anyun/h264/model/ResourceInfo.aidl
New file
@@ -0,0 +1,7 @@
package com.anyun.h264.model;
/**
 * 音视频资源信息(根据JT/T 1076-2016表23定义)
 */
parcelable ResourceInfo;
app/src/main/java/com/anyun/h264/H264EncodeService.java
New file
@@ -0,0 +1,421 @@
package com.anyun.h264;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import com.anyun.h264.model.ResourceInfo;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
/**
 * H264编码服务
 * 提供AIDL接口供客户端调用,用于控制H264编码和查询资源列表
 */
public class H264EncodeService extends Service {
    private static final String TAG = "H264EncodeService";
    private H264Encoder h264Encoder;
    private String outputFileDirectory; // H264文件输出目录
    // 默认编码参数
    private static final int DEFAULT_WIDTH = 640;
    private static final int DEFAULT_HEIGHT = 480;
    private static final int DEFAULT_FRAME_RATE = 25;
    private static final int DEFAULT_BITRATE = 2000000; // 2Mbps
    // 默认摄像头参数
    private static final int[] DEFAULT_CAMERA_ID_RANGE = {1, 2};
    private static final int[] DEFAULT_RESOLUTION = {640, 480};
    // AIDL接口实现
    private final IH264EncodeService.Stub binder = new IH264EncodeService.Stub() {
        @Override
        public int controlEncode(int action, String jsonConfig) throws RemoteException {
            return H264EncodeService.this.controlEncode(action, jsonConfig);
        }
        @Override
        public List<ResourceInfo> getResourceList(String startTime, String endTime) throws RemoteException {
            return H264EncodeService.this.getResourceList(startTime, endTime);
        }
    };
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "H264EncodeService created");
        // 初始化输出文件目录(使用应用外部存储目录)
        outputFileDirectory = getExternalFilesDir(null).getAbsolutePath();
        Log.d(TAG, "Output file directory: " + outputFileDirectory);
    }
    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "Service bound");
        return binder;
    }
    @Override
    public boolean onUnbind(Intent intent) {
        Log.d(TAG, "Service unbound");
        // 不自动停止编码器,让它在服务中保持运行
        return super.onUnbind(intent);
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "Service destroyed");
        // 停止并释放编码器
        stopEncoder();
    }
    /**
     * 编码配置类
     */
    private static class EncodeConfig {
        String ip;
        int port;
        int width;
        int height;
        int framerate;
        // 从JSON解析配置
        static EncodeConfig fromJson(String jsonConfig) throws JSONException {
            EncodeConfig config = new EncodeConfig();
            if (jsonConfig == null || jsonConfig.trim().isEmpty()) {
                // 使用默认值
                config.width = DEFAULT_WIDTH;
                config.height = DEFAULT_HEIGHT;
                config.framerate = DEFAULT_FRAME_RATE;
                config.ip = null;
                config.port = 0;
                return config;
            }
            JSONObject json = new JSONObject(jsonConfig);
            config.width = json.optInt("width", DEFAULT_WIDTH);
            config.height = json.optInt("height", DEFAULT_HEIGHT);
            config.framerate = json.optInt("framerate", DEFAULT_FRAME_RATE);
            config.ip = json.optString("ip", null);
            config.port = json.optInt("port", 0);
            return config;
        }
    }
    /**
     * 控制H264编码
     * @param action 操作类型:0-开启h264文件写入,1-停止h264编码并停止写入文件,2-开启网络推送h264(不写入文件),3-停止h264编码并停止网络推送
     * @param jsonConfig JSON格式的配置参数,包含:ip、port、width、height、framerate
     * @return 0-成功,1-失败
     */
    private synchronized int controlEncode(int action, String jsonConfig) {
        Log.d(TAG, "controlEncode called with action: " + action + ", jsonConfig: " + jsonConfig);
        try {
            EncodeConfig config = null;
            // 对于停止操作,不需要解析配置
            if (action != 1 && action != 3) {
                try {
                    config = EncodeConfig.fromJson(jsonConfig);
                    Log.d(TAG, "Parsed config - width: " + config.width + ", height: " + config.height +
                            ", framerate: " + config.framerate + ", ip: " + config.ip + ", port: " + config.port);
                } catch (JSONException e) {
                    Log.e(TAG, "Failed to parse JSON config: " + jsonConfig, e);
                    return 1; // 失败
                }
            }
            switch (action) {
                case 0: // 开启h264文件写入
                    return startFileEncode(config);
                case 1: // 停止h264编码并停止写入文件
                    return stopEncoder();
                case 2: // 开启网络推送h264(不写入文件)
                    return startNetworkEncode(config);
                case 3: // 停止h264编码并停止网络推送
                    return stopEncoder();
                default:
                    Log.e(TAG, "Unknown action: " + action);
                    return 1; // 失败
            }
        } catch (Exception e) {
            Log.e(TAG, "Error in controlEncode", e);
            return 1; // 失败
        }
    }
    /**
     * 启动文件编码模式(只写入文件,不进行网络推送)
     */
    private int startFileEncode(EncodeConfig config) {
        Log.d(TAG, "Starting file encode mode");
        // 如果编码器已经在运行,先停止
        if (h264Encoder != null) {
            Log.w(TAG, "Encoder is already running, stopping it first");
            stopEncoder();
        }
        try {
            // 创建编码器
            h264Encoder = new H264Encoder();
            // 设置编码参数(使用配置中的参数)
            int width = config != null ? config.width : DEFAULT_WIDTH;
            int height = config != null ? config.height : DEFAULT_HEIGHT;
            int framerate = config != null ? config.framerate : DEFAULT_FRAME_RATE;
            h264Encoder.setEncoderParams(width, height, framerate, DEFAULT_BITRATE);
            // 设置输出文件
            String fileName = "h264_" + System.currentTimeMillis() + ".h264";
            File outputFile = new File(outputFileDirectory, fileName);
            h264Encoder.setOutputFile(outputFile.getAbsolutePath());
            h264Encoder.setEnableFileOutput(true); // 启用文件输出
            // 禁用网络传输
            h264Encoder.setEnableNetworkTransmission(false);
            // 初始化并启动(使用配置中的分辨率)
            int[] resolution = {width, height};
            if (h264Encoder.initialize(DEFAULT_CAMERA_ID_RANGE, null, resolution, false)) {
                h264Encoder.start();
                Log.d(TAG, "File encode started successfully, output file: " + outputFile.getAbsolutePath() +
                        ", resolution: " + width + "x" + height + ", framerate: " + framerate);
                return 0; // 成功
            } else {
                Log.e(TAG, "Failed to initialize encoder");
                h264Encoder = null;
                return 1; // 失败
            }
        } catch (Exception e) {
            Log.e(TAG, "Failed to start file encode", e);
            h264Encoder = null;
            return 1; // 失败
        }
    }
    /**
     * 启动网络推送模式(只进行网络推送,不写入文件)
     */
    private int startNetworkEncode(EncodeConfig config) {
        Log.d(TAG, "Starting network encode mode");
        // 如果编码器已经在运行,先停止
        if (h264Encoder != null) {
            Log.w(TAG, "Encoder is already running, stopping it first");
            stopEncoder();
        }
        // 检查必需的配置参数
        if (config == null || config.ip == null || config.ip.trim().isEmpty() || config.port <= 0) {
            Log.e(TAG, "Network encode requires valid ip and port in config");
            return 1; // 失败
        }
        try {
            // 创建编码器
            h264Encoder = new H264Encoder();
            // 设置编码参数(使用配置中的参数)
            int width = config.width;
            int height = config.height;
            int framerate = config.framerate;
            h264Encoder.setEncoderParams(width, height, framerate, DEFAULT_BITRATE);
            // 禁用文件输出
            h264Encoder.setEnableFileOutput(false);
            // 启用网络传输并设置服务器地址
            h264Encoder.setEnableNetworkTransmission(true);
            h264Encoder.setServerAddress(config.ip, config.port);
            // 设置协议参数(使用默认值,可根据需要从配置中添加)
            // TODO: 如果需要在JSON配置中添加simCardNumber和logicalChannelNumber,可以在这里解析
            h264Encoder.setProtocolParams("123456789012", (byte)1);
            // 初始化并启动(使用配置中的分辨率)
            int[] resolution = {width, height};
            if (h264Encoder.initialize(DEFAULT_CAMERA_ID_RANGE, null, resolution, false)) {
                h264Encoder.start();
                Log.d(TAG, "Network encode started successfully, server: " + config.ip + ":" + config.port +
                        ", resolution: " + width + "x" + height + ", framerate: " + framerate);
                return 0; // 成功
            } else {
                Log.e(TAG, "Failed to initialize encoder");
                h264Encoder = null;
                return 1; // 失败
            }
        } catch (Exception e) {
            Log.e(TAG, "Failed to start network encode", e);
            h264Encoder = null;
            return 1; // 失败
        }
    }
    /**
     * 停止编码器
     */
    private int stopEncoder() {
        Log.d(TAG, "Stopping encoder");
        if (h264Encoder != null) {
            try {
                h264Encoder.stop();
                h264Encoder.release();
                h264Encoder = null;
                Log.d(TAG, "Encoder stopped successfully");
                return 0; // 成功
            } catch (Exception e) {
                Log.e(TAG, "Error stopping encoder", e);
                h264Encoder = null;
                return 1; // 失败
            }
        } else {
            Log.w(TAG, "Encoder is not running");
            return 0; // 成功(没有运行的编码器,视为成功)
        }
    }
    /**
     * 获取资源列表(根据JT/T 1076-2016表23定义)
     * @param startTime 开始时间(格式:YYMMDDHHmmss)
     * @param endTime 结束时间(格式:YYMMDDHHmmss)
     * @return 资源列表
     */
    private List<ResourceInfo> getResourceList(String startTime, String endTime) {
        Log.d(TAG, "getResourceList called, startTime: " + startTime + ", endTime: " + endTime);
        List<ResourceInfo> resourceList = new ArrayList<>();
        try {
            // 扫描输出目录中的H264文件
            File dir = new File(outputFileDirectory);
            if (!dir.exists() || !dir.isDirectory()) {
                Log.w(TAG, "Output directory does not exist: " + outputFileDirectory);
                return resourceList;
            }
            File[] files = dir.listFiles((dir1, name) -> name.toLowerCase().endsWith(".h264"));
            if (files == null || files.length == 0) {
                Log.d(TAG, "No H264 files found in directory");
                return resourceList;
            }
            // 解析时间范围
            Date startDate = parseTime(startTime);
            Date endDate = parseTime(endTime);
            if (startDate == null || endDate == null) {
                Log.e(TAG, "Invalid time format, startTime: " + startTime + ", endTime: " + endTime);
                return resourceList;
            }
            // 遍历文件,查找在时间范围内的文件
            for (File file : files) {
                ResourceInfo resourceInfo = createResourceInfoFromFile(file, startDate, endDate);
                if (resourceInfo != null) {
                    resourceList.add(resourceInfo);
                }
            }
            Log.d(TAG, "Found " + resourceList.size() + " resources in time range");
            return resourceList;
        } catch (Exception e) {
            Log.e(TAG, "Error getting resource list", e);
            return resourceList;
        }
    }
    /**
     * 从文件创建资源信息(如果文件在时间范围内)
     */
    private ResourceInfo createResourceInfoFromFile(File file, Date startDate, Date endDate) {
        try {
            // 从文件名或文件修改时间获取文件时间
            // 这里假设文件名包含时间戳,或者使用文件修改时间
            Date fileDate = new Date(file.lastModified());
            // 检查文件时间是否在指定范围内
            if (fileDate.before(startDate) || fileDate.after(endDate)) {
                return null; // 不在时间范围内
            }
            // 创建资源信息对象
            ResourceInfo resourceInfo = new ResourceInfo();
            // 逻辑通道号(默认值,实际应从配置获取)
            resourceInfo.setLogicalChannelNumber((byte) 1);
            // 开始时间和结束时间(使用文件修改时间)
            SimpleDateFormat bcdFormat = new SimpleDateFormat("yyMMddHHmmss", Locale.US);
            resourceInfo.setStartTime(bcdFormat.format(fileDate));
            // 结束时间可以使用文件修改时间加上一个默认时长(例如1分钟)
            long fileDuration = 60000; // 默认1分钟,实际应该根据文件内容计算
            Date endTime = new Date(fileDate.getTime() + fileDuration);
            resourceInfo.setEndTime(bcdFormat.format(endTime));
            // 报警标志(默认值,实际应从文件元数据获取)
            resourceInfo.setAlarmFlag(0L);
            // 音视频资源类型:2-视频
            resourceInfo.setResourceType((byte) 2);
            // 码流类型:1-主码流
            resourceInfo.setStreamType((byte) 1);
            // 存储器类型:1-主存储器
            resourceInfo.setStorageType((byte) 1);
            // 文件大小
            resourceInfo.setFileSize(file.length());
            return resourceInfo;
        } catch (Exception e) {
            Log.e(TAG, "Error creating resource info from file: " + file.getName(), e);
            return null;
        }
    }
    /**
     * 解析BCD时间字符串
     * @param timeStr 时间字符串(格式:YYMMDDHHmmss)
     * @return Date对象,如果解析失败返回null
     */
    private Date parseTime(String timeStr) {
        if (timeStr == null || timeStr.length() != 12) {
            return null;
        }
        try {
            SimpleDateFormat format = new SimpleDateFormat("yyMMddHHmmss", Locale.US);
            return format.parse(timeStr);
        } catch (ParseException e) {
            Log.e(TAG, "Failed to parse time: " + timeStr, e);
            return null;
        }
    }
}
key/Verify.txt
New file
@@ -0,0 +1,41 @@
    private static PrivateKey getKey(String key, char[] password) throws Exception {
        byte[] cabuf = new BASE64Decoder().decodeBuffer(key);
        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        keyStore.load(new ByteArrayInputStream(cabuf), password);
        Enumeration<String> aliases = keyStore.aliases();
        if (!aliases.hasMoreElements()) {
            throw new RuntimeException("no alias found");
        }
        String alias = aliases.nextElement();
        PrivateKey privateKey = (RSAPrivateCrtKeyImpl) keyStore.getKey(alias, password);
        return privateKey;
    }
    public static String sign(String data, PrivateKey key) throws Exception {
//        MessageDigest md = MessageDigest.getInstance("SHA-256");
        MessageDigest md = MessageDigest.getInstance("SHA-1");
        md.update(data.getBytes("utf-8"));
        byte[] hash = md.digest();
//        Cipher cipher = Cipher.getInstance("RSA");
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] encrypted = cipher.doFinal(hash);
        return HexBin.encode(encrypted);
    }
    public static String sign(String data, String keyString ,String pwd ) throws Exception {
        char[] password = pwd.toCharArray();
        return sign(data,getKey(keyString,password));
    }
    public static void main(String[] args) {
        try{
            String sign = sign("xuanborobot123456nullnullnull","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","27U777");
            System.out.println(sign);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
key/bjkey.jks
Binary files differ
key/key.jks
Binary files differ
key/key.jks.ori
Binary files differ
key/keyrk3288.jks
Binary files differ
key/keysc200.jks
Binary files differ
key/keysc626.jks
Binary files differ