找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
广告投放联系QQ68610888
查看: 7246|回复: 4

折腾OSCAM之三---(转帖)Oscam for Android

[复制链接]
发表于 2017-12-26 11:52 | 显示全部楼层 |阅读模式
本帖最后由 兔巴哥 于 2019-11-7 18:18 编辑

之一之二后,一直折腾怎么样将oscam打包成安卓的app,无奈功力不够,只能进行到编译出主程序一步,遂放弃.....近日发现了很有意义的博文,于是分享给大家。(内容有删减)


一、Compiling Oscam for Android
1、首先配置Linux系统
2、下载最新的Linux 64位(x86)Android NDK,可以在这里下载https://developer.android.com/ndk/downloads/index.html,在写这篇文章的时候,最新的稳定版本是r13b。
将NDK文件解压到Home,然后cd到build / tools文件夹中,以便于构建用于交叉编译的工具链。
  1. cd ~/android-ndk-r13b/build/tools
  2. export TOOLCHAIN=~/android-toolchain
  3. ./make_standalone_toolchain.py --arch arm --api 24 --install-dir $TOOLCHAIN
复制代码
这个命令在你的Home上创建一个android工具链。
3、在使用这个工具链交叉编译OScam之前,我们还需要编译OpenSSL,否则在使用cccam协议时会出现无法连接的情况。
下载,解压缩和构建OpenSSL:
  1. cd ~
  2. wget http://www.openssl.org/source/openssl-1.0.1g.tar.gz
  3. tar -xf openssl-1.0.1g.tar.gz
  4. cd openssl-1.0.1g
  5. export CC=$TOOLCHAIN/bin/arm-linux-androideabi-gcc
  6. export RANLIB=$TOOLCHAIN/bin/arm-linux-androideabi-ranlib
  7. ./Configure --prefix=$TOOLCHAIN/sysroot/usr android
  8. make
  9. make install_sw
复制代码
检查Oscam svn并编译添加openssl。
  1. cd ~
  2. svn checkout http://www.streamboard.tv/svn/oscam/trunk oscam-svn
  3. cd oscam-svn
  4. ./config.sh --enable WEBIF WITH_SSL
复制代码
4、交叉编译Android上运行的Oscam。
  1. make static EXTRA_FLAGS="-pie" LIB_RT= LIB_PTHREAD= CROSS=$TOOLCHAIN/bin/arm-linux-androideabi-
复制代码
如果一切正常,应该在oscam-svn的Distribution文件夹中生成一个在Android环境中运行的程序文件,比如oscam-1.20-unstable_svn11347-arm-linux-androideabi-ssl
当然,这不是一个APK,刚刚做的只是编译出来了本机C代码。这个在安卓设备运行比较麻烦,而且也不容易实现。
APK是一个包含字节码(编译的java代码)和资源的包,它将在android java虚拟机(可以是Dalvik或ART,取决于您的Android版本)内运行。
那么如何在安卓设备上安装并运行该程序呢?
我们基本上需要构建一个包含我们的本地二进制文件作为资源的Android应用程序(APK),将其提取到可执行的位置(不在SDCard上运行),使其可执行并运行。


二、Building an Oscam APK for Android在上一节中如果已经编译出Oscam二进制文件,那么这一步生成APK的过程无论是Linux系统还是Windows系统都是可以完成的。
1、使用Android Studio创建一个新的项目。

2、在“res”文件夹下创建一个“raw”文件夹。

3、把oscam二进制文件改名为“oscam”并放在raw文件夹下。

4、添加一些小部件到用户界面,并做一些代码。

5、布局的XML代码应该是这样的:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     xmlns:tools="http://schemas.android.com/tools"
  4.     android:id="@+id/activity_main"
  5.     android:layout_width="match_parent"
  6.     android:layout_height="match_parent"
  7.     android:paddingBottom="@dimen/activity_vertical_margin"
  8.     android:paddingLeft="@dimen/activity_horizontal_margin"
  9.     android:paddingRight="@dimen/activity_horizontal_margin"
  10.     android:paddingTop="@dimen/activity_vertical_margin"
  11.     tools:context="com.tekreaders.myoscamapk.MainActivity">

  12.     <Button
  13.         android:id="@+id/startButton"
  14.         android:layout_alignParentTop="true"
  15.         android:layout_width="wrap_content"
  16.         android:layout_height="wrap_content"
  17.         android:text="Start Oscam"
  18.         android:onClick="startOscam"
  19.         />
  20.     <Button
  21.         android:id="@+id/stopButton"
  22.         android:layout_toRightOf="@+id/startButton"
  23.         android:layout_alignParentTop="true"
  24.         android:layout_width="wrap_content"
  25.         android:layout_height="wrap_content"
  26.         android:text="Stop Oscam"
  27.         android:onClick="stopOscam"
  28.         />

  29.     <TextView
  30.         android:id="@+id/outputView"
  31.         android:layout_alignParentBottom="true"
  32.         android:layout_alignParentRight="true"
  33.         android:layout_alignParentLeft="true"
  34.         android:layout_below="@+id/startButton"
  35.         android:layout_width="match_parent"
  36.         android:layout_height="match_parent"
  37.         android:maxLines="200"
  38.         android:scrollbars="vertical"
  39.         android:text="Oscam log will be displayed here..."
  40.          />
  41. </RelativeLayout>
复制代码
6、整个MainActivity的代码:
  1. public class MainActivity extends AppCompatActivity {
  2.     TextView outputView;
  3.     Button startButton;
  4.     Button stopButton;

  5.     private String confDir = Environment.getExternalStorageDirectory().getPath() + "/oscam";
  6.     private String tmpDir = Environment.getExternalStorageDirectory().getPath() + "/oscam/tmp";
  7.     private String oscamFilename = "";
  8.     private Process oscamProcess;

  9.     @Override
  10.     protected void onCreate(Bundle savedInstanceState) {
  11.         super.onCreate(savedInstanceState);
  12.         setContentView(R.layout.activity_main);
  13.         outputView = (TextView)findViewById(R.id.outputView);
  14.         startButton = (Button)findViewById(R.id.startButton);
  15.         stopButton = (Button)findViewById(R.id.stopButton);
  16.         outputView.setMovementMethod(new ScrollingMovementMethod());
  17.         requestPermissions();
  18.     }

  19.     //request the runtime permissions, this required since Marshmallow
  20.     public void requestPermissions() {
  21.         if (Build.VERSION.SDK_INT >= 23) {
  22.             ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
  23.         }
  24.     }

  25.     //output logs and enable/disable buttons according to the running state
  26.     public void setStatus(final boolean running, final String message){
  27.         runOnUiThread(new Runnable() {
  28.             @Override
  29.             public void run() {
  30.                 if (message!=null) {
  31.                     outputView.setText(outputView.getText()+"\n"+message);
  32.                     if (outputView.getVisibility() == View.VISIBLE) {
  33.                         final int scrollAmount = outputView.getLayout().getLineTop(outputView.getLineCount()) - outputView.getHeight();
  34.                         if (scrollAmount > 0)
  35.                             outputView.scrollTo(0, scrollAmount);
  36.                         else
  37.                             outputView.scrollTo(0, 0);
  38.                     }
  39.                 }
  40.                 startButton.setEnabled(!running);
  41.                 stopButton.setEnabled(running);
  42.             }
  43.         });
  44.     }

  45.     public void startOscam(View view){
  46.         if (oscamProcess == null) {
  47.             //run this process on a new thread to avoid UI blocking
  48.             new Thread(new Runnable() {
  49.                 @Override
  50.                 public void run() {
  51.                     try {
  52.                         setStatus(true, "Initializing...");
  53.                         //check the config and tmp folders
  54.                         File cdir = new File(confDir);
  55.                         File tdir = new File(tmpDir);
  56.                         boolean confDirExists = cdir.exists();
  57.                         boolean tmpDirExists = tdir.exists();
  58.                         if (!confDirExists)
  59.                             confDirExists = cdir.mkdir();
  60.                         if (!tmpDirExists)
  61.                             tmpDirExists = tdir.mkdir();
  62.                         if (confDirExists && tmpDirExists) {
  63.                             //check the stat file to sanitize the default errors
  64.                             File stat = new File(tmpDir + "/stat");
  65.                             if (!stat.exists()) {
  66.                                 FileWriter statfile = new FileWriter(stat);
  67.                                 statfile.write("");
  68.                                 statfile.close();
  69.                             }
  70.                             //extract the resource in the raw folder into the App private space and overwrite if it already exists
  71.                             String appFileDirectory = getFilesDir().getParent();
  72.                             oscamFilename = appFileDirectory + "/oscam";
  73.                             InputStream ins = getResources().openRawResource(R.raw.oscam);
  74.                             final byte[] buffer = new byte[ins.available()];
  75.                             ins.read(buffer);
  76.                             ins.close();
  77.                             File destination = new File(oscamFilename);
  78.                             if (destination.exists())
  79.                                 destination.delete();
  80.                             FileOutputStream fos = new FileOutputStream(destination);
  81.                             fos.write(buffer);
  82.                             fos.close();
  83.                             if (destination.exists()) {
  84.                                 //set executable rights on the file (chmod)
  85.                                 boolean isExecutable = destination.setExecutable(true);
  86.                                 if (isExecutable) {
  87.                                     setStatus(true, "Launching oscam with confDir='" + confDir + "' and tmpDir='" + tmpDir + "'...");
  88.                                     //start the Oscam process
  89.                                     oscamProcess = new ProcessBuilder().command(oscamFilename, "--config-dir", confDir, "--temp-dir", tmpDir).redirectErrorStream(true).start();
  90.                                     //start a thread to read Oscam logs and print them on our textview
  91.                                     Thread readThread = new Thread(new Runnable() {
  92.                                         @Override
  93.                                         public void run() {
  94.                                             try {
  95.                                                 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(oscamProcess.getInputStream()));
  96.                                                 while (!Thread.currentThread().isInterrupted()) {
  97.                                                     if (bufferedReader.ready()) {
  98.                                                         String line = bufferedReader.readLine();
  99.                                                         setStatus(true, line);
  100.                                                     }
  101.                                                 }
  102.                                                 bufferedReader.close();
  103.                                             } catch (Exception e) {
  104.                                                 e.printStackTrace();
  105.                                             }
  106.                                         }
  107.                                     });
  108.                                     readThread.start();
  109.                                     //wait for the process to terminate
  110.                                     oscamProcess.waitFor();
  111.                                     //when we get here, the process is already dead, we should cleanup
  112.                                     readThread.interrupt();
  113.                                     oscamProcess = null;
  114.                                     setStatus(false, "Oscam stopped!");
  115.                                 } else
  116.                                     setStatus(false, "Oscam is not executable!");
  117.                             } else
  118.                                 setStatus(false, "Oscam binary not found!");
  119.                         } else
  120.                             setStatus(false, "Unable to read/write configuration and tmp folder!");
  121.                     } catch (Exception e) {
  122.                         e.printStackTrace();
  123.                     }
  124.                 }
  125.             }).start();
  126.         }
  127.     }

  128.     public void stopOscam(View view){
  129.         if (oscamProcess != null) {
  130.             try {
  131.                 //get the Oscam process PID by using reflection
  132.                 long pid = -1;
  133.                 try {
  134.                     Field f = oscamProcess.getClass().getDeclaredField("pid");
  135.                     f.setAccessible(true);
  136.                     pid = f.getLong(oscamProcess);
  137.                     f.setAccessible(false);
  138.                 } catch (Exception e) {
  139.                     pid = -1;
  140.                 }
  141.                 //send a SIGTERM to the oscam process
  142.                 Runtime.getRuntime().exec("kill -15 " + pid);
  143.             } catch (IOException e) {
  144.                 e.printStackTrace();
  145.             }
  146.         }else
  147.             setStatus(false, "Oscam stopped!");
  148.     }


  149. }
复制代码
7、运行应用程序并单击开始按钮后,你应该看到这样的界面。

就是这样。 你刚做了一个可以启动和停止的Oscam APK。 请记住将您的配置文件放在/ sdcard / oscam /文件夹中,然后就可以开始了。
以上所有代码的示例项目也可以在GitHub上获得。
显然你可以对这个应用程序做更多的改进。 例如,这应该是一个服务,并在启动时运行,不会被系统杀死。
但是,这超出了本教程的范围,您应该查看Android文档以了解更多信息。





本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
我的恩山、我的无线 The best wifi forum is right here.
发表于 2017-12-26 13:38 | 显示全部楼层
技,技,,,,,,,,技术帖。。
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

发表于 2017-12-27 05:23 | 显示全部楼层
感觉很牛的样子
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

发表于 2018-5-5 17:41 | 显示全部楼层
二、Building an Oscam APK for Android在上一节中如果已经编译出Oscam二进制文件,那么这一步生成apk的过程无论是Linux系统还是Windows系统都可以完成。
1、使用空白活动创建一个新的Android项目。

应该为:
二、Building an Oscam APK for Android在上一节中如果已经编译出Oscam二进制文件,那么这一步生成apk的过程无论是Linux系统还是Windows系统都可以完成。
1、使用 Android Studio 创建一个新的Android项目。



.

点评

谢谢指正!  详情 回复 发表于 2019-11-7 18:21
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

 楼主| 发表于 2019-11-7 18:21 | 显示全部楼层
高级菜鸟 发表于 2018-5-5 17:41
二、Building an Oscam APK for Android在上一节中如果已经编译出Oscam二进制文件,那么这一步生成apk的过 ...

谢谢指正!
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

有疑问请添加管理员QQ86788181|手机版|小黑屋|Archiver|恩山无线论坛(常州市恩山计算机开发有限公司版权所有) ( 苏ICP备05084872号 )

GMT+8, 2024-3-29 20:06

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

| 江苏省互联网有害信息举报中心 举报信箱:js12377 | @jischina.com.cn 举报电话:025-88802724 本站不良内容举报信箱:68610888@qq.com 举报电话:0519-86695797

快速回复 返回顶部 返回列表