顯示具有 Android apk 標籤的文章。 顯示所有文章
顯示具有 Android apk 標籤的文章。 顯示所有文章

2021年8月11日 星期三

basic CMakeLists.txt for hello_world

$ tree
cmake-hello-world/
├── CMakeLists.txt
├── linux-android.toolchain.cmake
└── src
    ├── main.cpp
    └── TestHello
        ├── test.cpp
        └── test.h

CMakeLists.txt (下面還有一個,比較好用, Cross compile for Android)
cmake_minimum_required (VERSION 3.10)
project (CMakeHelloWorld)

#version number
set (CMakeHelloWorld_VERSION_MAJOR 1)
set (CMakeHelloWorld_VERSION_MINOR 0)

message (STATUS "CXX is $ENV{CXX}")

set(argument_list)

option(USE_ANDROID "" OFF) #OFF by default
if (USE_ANDROID)
    set (CMAKE_ANDROID_ARCH_ABI arm64-v8a)
    set (ANDROID_STL "c++_static")
    set (CMAKE_CXX_COMPILER $ENV{CXX})
    set (CMAKE_AR $ENV{AR})
    set (CMAKE_RANLIB $ENV{RANLIB})
    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
endif()


include_directories(src/TestHello)         # 指定 include header path        
set(HELLO_SOURCES src/TestHello/test.cpp)    # 設定變數, 將第二個所給予的內容指定到第一個變數名稱當中
#set(HELLO_SOURCES src/HelloWorld.cpp)
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)   # PROJECT....是CMAKE寫好的變數
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

#add_library(test_hello SHARED src/main.cpp src/TestHello/test.cpp src/TestHello/test.h)

add_library(hello ${HELLO_SOURCES})
#add_library(hello2 ${HELLO_SOURCES2})
add_executable(main src/main.cpp ${HELLO_SOURCES})    #  產生可執行檔
if (USE_ANDROID)
    #target_link_libraries需寫在add_executable的下方
    target_link_libraries(main hello -latomic -lc++_static -lc++abi)
else()
    target_link_libraries(main hello)
endif()
APP_STL := c++_shared or c++_static
不要在ndk中使用系统预编译好的C++库

main.cpp
#include <test.h>

using namespace std;

int main(void)
{
    Test t;
    t.Hello();
}

test.cpp
#include "test.h"

using namespace std;

void Test::Hello(void)
{
    cout << "Hello, world!\n" << endl;
}

test.h
#include <stdio.h>
#include <iostream>

using namespace std;

class Test{
    public:
        void Hello (void);
};

compile
$ mkdir build; cd build
$ cmake ..
or
$ cmake -D USE_ANDROID=ON ..
沒有問題後
$ cd build
$ make


ref:
1. cmake
2. How to cross-compile for embedded with CMake like a champ
3. 不要在ndk中使用系统预编译好的C++库
4. CMake 入門/運算子
5. 关于安卓的交叉编译

CMakeLists.txt
cmake_minimum_required (VERSION 3.10)
project (CMakeHelloWorld)

#version number
set (CMakeHelloWorld_VERSION_MAJOR 1)
set (CMakeHelloWorld_VERSION_MINOR 0)

message (STATUS "CXX is $ENV{CXX}")

set(argument_list)

option(USE_ANDROID "" OFF) #OFF by default
if (USE_ANDROID)
    set (CMAKE_ANDROID_ARCH_ABI arm64-v8a)
    set (ANDROID_STL "c++_static")
    set (CMAKE_CXX_COMPILER $ENV{CXX})
    set (CMAKE_AR $ENV{AR})
    set (CMAKE_RANLIB $ENV{RANLIB})
    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
endif()
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()
    message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")

endif()


include_directories(src/TestHello)         # 指定 include header path        
#set(HELLO_SOURCES src/TestHello/test.cpp)    # 設定變數, 將第二個所給予的內容指定到第一個變數名稱當中
file(GLOB SOURCES src/TestHello/*.cpp src/TestHello/*.h)
#set(HELLO_SOURCES src/HelloWorld.cpp)
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)   # PROJECT....是CMAKE寫好的變數
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

#add_library(test_hello SHARED src/main.cpp src/TestHello/test.cpp src/TestHello/test.h)

#add_library(hello ${HELLO_SOURCES})
#add_library(hello2 ${HELLO_SOURCES2})
add_executable(main src/main.cpp ${SOURCES})    #  產生可執行檔
if (USE_ANDROID)
    target_link_libraries(main  -latomic -lc++_static -lc++abi)
else()
    target_link_libraries(main)
endif()

linux-android.toolchain.cmake
if (USE_ANDROID)
    if (NOT NDKDIR)
        message(FATAL_ERROR "Set NDK_DIR, Recommended version 22.1.7171670")
    endif()

#set (NDK "/opt/android_studio/sdk/ndk/22.1.7171670")
set (TOOLCHAIN "${NDKDIR}/toolchains/llvm/prebuilt/linux-x86_64")

#set (CMAKE_ANDROID_API 29)
set (ANDROID_STL "c++_static")

if (${CMAKE_ANDROID_ARCH_ABI} STREQUAL "arm64-v8a")
    set (TARGET "aarch64-linux-android")
elseif (${CMAKE_ANDROID_ARCH_ABI} STREQUAL "armeabi-v7a")
    set (TARGET "armv7a-linux-androideabi")
else()
    set (TARGET "x86_64-linux-android")
endif()

set (CMAKE_C_COMPILER ${TOOLCHAIN}/bin/${TARGET}${CMAKE_ANDROID_API}-clang)
message (STATUS "1111111111 is ${CMAKE_C_COMPILER}")
set (CMAKE_CXX_COMPILER ${TOOLCHAIN}/bin/${TARGET}${CMAKE_ANDROID_API}-clang++)
set (CMAKE_AR     ${TOOLCHAIN}/bin/${TARGET}$-ar)
set (CMAKE_RANLIB ${TOOLCHAIN}/bin/${TARGET}$-ranlib)

# set searching rules for cross-compiler
SET (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
endif()

compile
$ mkdir build; cd build
$ cmake -D USE_ANDROID=ON -D CMAKE_TOOLCHAIN_FILE=../linux-android.toolchain.cmake  -D NDKDIR=/opt/android_studio/sdk/ndk/22.1.7171670 -D CMAKE_ANDROID_ARCH_ABI=arm64-v8a -D CMAKE_ANDROID_API=29 ..
沒有問題後
$ make

2021年7月5日 星期一

FaceDetector_Android_Studio

Tengine 人脸检测 Android Camera版
裡面使用的是 opencv-3.4.11-android-sdk.zip (其它版本下載)
在用Android studio build時一直有問題,(當時環境是 ndk 20.x版的,連結文章是用ndk 16.x的)
...
...
...
system.cpp:(.text.unlikely._ZSt8_DestroyIPSsSsEvT_S1_RSaIT0_E.isra.88+0x18): undefined reference to `std::string::_Rep::_S_empty_rep_storage'
system.cpp:(.text.unlikely._ZSt8_DestroyIPSsSsEvT_S1_RSaIT0_E.isra.88+0x2c): undefined reference to `std::string::_Rep::_S_empty_rep_storage'
system.cpp:(.text.unlikely._ZSt8_DestroyIPSsSsEvT_S1_RSaIT0_E.isra.88+0x5c): undefined reference to `std::string::_Rep::_M_destroy(std::allocator)'
...
...

查了一陣子,應該是libc++ 或 libstdc++ 使用陣營不同的問題
NDK switched to libc++ as default STL, but OpenCV is built with gnustl.
看起來ndk 20.x版的STL是libc++, ndk 16.x版的應該是使用gnustl…吧
所以用 ndk 16.x 版的,build的過程就沒什麼問題了
(在Android 9, API_Level 28上,是跑不起來,只好用OpenCV-android-sdk_4.0.1+ndk 20.x就行了)

Tengine 人脸检测 Android版的Android/app/build.gradle
ndk {
            ldLibs "log"

            //声明创建指定cpu架构的so库
            //如果想在模拟器运行 加上 "x86"
            abiFilters 'armeabi-v7a', 'arm64-v8a'

            stl "gnustl_static"
        }



OpenCV-android-sdk_4.0.1+ndk 20.x

Andorid/app/build.gradle
  android {
  ...
  ...
  ndk {
            //abiFilters 'armeabi-v7a','arm64-v8a'
            abiFilters 'arm64-v8a'
            stl "gunstl_static"
  }
  ...
  ...
  ndkVersion '20.1.5948944'
}


Andorid/app/src/main/cpp/CMakeLists.txt
  ...
  ...
  ...
set(OpenCV_DIR "/home/ubuntu/object_recognition/OpenCV-android-sdk_4.0.1//sdk/native/jni")
find_package(OpenCV 4.0 REQUIRED)

if(OpenCV_FOUND) (輸出 debug message :.cxx/cmake/debug/arm64-v8a/build_output.txt)
    include_directories(${OpenCV_INCLUDE_DIRS})
    message(STATUS "OpenCV library status:")
    message(STATUS "    version: ${OpenCV_VERSION}")
    message(STATUS "    libraries: ${OpenCV_LIBS}")
    message(STATUS "    include path: ${OpenCV_INCLUDE_DIRS}")
    message(STATUS "    distribution dir: ${distribution_DIR}")
else(OpenCV_FOUND)
    message(FATAL_ERROR "OpenCV library not found")
endif(OpenCV_FOUND)


include_directories(tengine/include/)
include_directories(/home/ubuntu/object_recognition/OpenCV-android-sdk_4.0.1//sdk/native/jni/include/)

add_library(tengine SHARED IMPORTED)
set_target_properties(tengine PROPERTIES IMPORTED_LOCATION ${distribution_DIR}/libtengine-lite.so)
   ...
   ...

其中libtengine-lite.so一定要用ndk build,不要從target device摳,不然 libdl.so.2 會找不到
  $ cd Tengine
  $ mkdir build_android_64
  $ cd build_android_64
  $ cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake \
  -DANDROID_ABI="arm64-v8a"\
  -DANDROID_PLATFORM=android-28\ 
  -DANDROID_STL=c++_shared
  -DANDROID_ARM_NEON=ON\
  -DCONFIG_ARCH_ARM64=ON\
  -DANDROID_ALLOW_UNDEFINED_SYMBOLS=TRUE ..

CV_RGBA2RGB
error: use of undeclared identifier 'CV_RGBA2RGB'
改成
cv::COLOR_RGBA2RGB

ref:
1. How can I integrate OpenCV 4.0 into a pure C++ Android NDK project
2. Linking errors on Android with OpenCV 3.4.0 and NDK
3. clang: error: linker command failed with exit code 1

2021年2月19日 星期五

hello_jni

環境: android_studio 4.1.2

Tree結構:
project_name(testJni)/app/src/main
$ tree
.
├── AndroidManifest.xml
├── java
│   └── com
│       └── example
│           └── testjni
│               ├── FirstFragment.java
│               ├── MainActivity.java
│               ├── SecondFragment.java
│               └── TestJni.java
├── jni (必要,自行產生)
│   ├── Android.mk
│   ├── Application.mk
│   ├── hello_jni.c
│   └── hello_jni.h
├── jniLibs (必要, 從 libs拷貝資料夾過來)
│   ├── x86
│   │   └── libhello_jni.so
│   └── x86_64
│       └── libhello_jni.so
├── libs (ndk-build產生)
│   ├── arm64-v8a
│   │   └── libhello_jni.so
│   ├── x86
│   │   ├── gdbserver
│   │   ├── gdb.setup
│   │   └── libhello_jni.so
│   └── x86_64
│       ├── gdbserver
│       ├── gdb.setup
│       └── libhello_jni.so
...
...
...
...


project_name(testJni)/
$ tree
├── gradle.properties
├── local.properties


local.properties
sdk.dir=/opt/android_studio/sdk
ndk.dir=/opt/android_studio/sdk/ndk/20.1.5948944/ (官方建議寫在 build.gradle)


build.gradle
android {
    compileSdkVersion 28
    buildToolsVersion '28.0.3'
    ...
    ...
    ndkVersion "20.1.5948944"
}


app/src/main/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.testjni"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="16"
        android:targetSdkVersion="26" />


app/src/main/jni/hello_jni.c

#include <jni.h>
#include <stdio.h>
#include <android/log.h>
#include "hello_jni.h"

#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, "TAG", __VA_ARGS__);
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, "TAG", __VA_ARGS__);
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, "TAG", __VA_ARGS__);
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, "TAG", __VA_ARGS__);
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, "TAG", __VA_ARGS__);

//                        Java_pacakgeName_className_functionName
JNIEXPORT jstring JNICALL Java_com_example_testjni_TestJni_getString(JNIEnv * env, jobject obj, jstring s)
{
    char * st = (char *) (*env)->GetStringUTFChars(env, s, 0);
    LOGI("\n c-string:  %s", st);

    char * str = "hello_world";
    jstring rtn;
    rtn = (*env)->NewStringUTF(env, str);
    return rtn;
}


app/src/main/jni/hello_jni.h
#ifndef TESTJNI_HELLO_JNI_H
#define TESTJNI_HELLO_JNI_H
JNIEXPORT jstring JNICALL Java_com_example_testjni_TestJni_getString(JNIEnv * env, jobject obj, jstring s);
#endif //TESTJNI_HELLO_JNI_H


app/src/main/jni/Android.mk
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := hello_jni

LOCAL_SRC_FILES := hello_jni.c

LOCAL_LDLIBS :=  -L$(SYSROOT)/usr/lib -llog

include $(BUILD_SHARED_LIBRARY)



app/src/main/jni/Application.mk.mk
APP_ABI := x86 (x86電腦的emulator用。本來用x86_64,但編譯時說找不到@@)
APP_PLATFORM := android-16
APP_STL := c++_shared
app_abi

Compiler:
$ cd path/testJni/app/src/main/jni
$ ndk-build

在/usr/local/bin產生個ndk-build的script
#!/bin/sh
#DIR="$(cd "$(dirname "$0")" && pwd)"
DIR="/opt/android_studio/sdk/ndk/20.1.5948944/"
$DIR/build/ndk-build "$@"


成功後,會產生libs和obj資料夾
將 libs/abi 資料夾拷貝到 jniLibs


app/src/main/TestJni.java
package com.example.testjni;

public class TestJni {
    public native String getString(String str);

    static {
        System.loadLibrary("hello_jni");
    }
}

app/src/main/MainActivity.java
package com.example.testjni;

import android.os.Bundle;

import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

import android.util.Log;
import android.view.View;

import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends AppCompatActivity {

    TestJni tj = new TestJni();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        Log.i("test_hello", "Start jni");
        Log.i("test_nello", "jni="+tj.getString("hello_jni"));
        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();

            }
        });
    }
...
...
...


這樣應該可以在emulator上執行了,開啟logcat應該看得到jni的輸出


bsp code (system/core/rootdir/etc/public.libraries.android.txt)
...
...
libstdc++.so 
libsync.so 
libvulkan.so 
libwebviewchromium_plat_support.so 
libz.so
libhello_jni.so 添加


ref:
內置應用so庫無法打開問題解決
AndroidStudio NDK開發【dlopen failed: library "libc++_shared.so" not found】報錯解決

安裝android_studio

環境: android_studio 4.1.2

  • jre 和 jdk (應該是用apt)
$ dpkg -l | grep -e jdk -e jre
ii  openjdk-8-jdk:amd64                        8u282-b08-0ubuntu1~18.04                         amd64        OpenJDK Development Kit (JDK)
ii  openjdk-8-jdk-headless:amd64               8u282-b08-0ubuntu1~18.04                         amd64        OpenJDK Development Kit (JDK) (headless)
ii  openjdk-8-jre:amd64                        8u282-b08-0ubuntu1~18.04                         amd64        OpenJDK Java runtime, using Hotspot JIT
ii  openjdk-8-jre-headless:amd64               8u282-b08-0ubuntu1~18.04                         amd64        OpenJDK Java runtime, using Hotspot JIT (headless)
  • 自已的/opt設定
4.1.2
jre -> /usr/lib/jvm/java-8-openjdk-amd64/
jre8 -> /usr/lib/jvm/java-8-openjdk-amd64/jre
sdk (裝android_studio時,會把相關需要的東西裝在這)
  •  自已的.bashrc設定
...
export PATH=/opt/java/jdk-11.0.8/bin:$PATH
export JAVA_HOME=/opt/java/jdk-11.0.8
export JRE_HOME=$JAVA_HOME
...
export GRAALVM_HOME=/opt/graalVM/graalvm-ce-java11-21.0.0



2016年9月20日 星期二

Create XML by XmlSerializer

public class newXML {
    public void XmlFileCreator(){
        File newxmlfile = new File(Environment.getExternalStorageDirectory()+"/new.xml");
        try{
            if(!newxmlfile.exists())
                newxmlfile.createNewFile();
        }catch(IOException e){
            Log.e("IOException", "exception in createNewFile() method");
        }       
        FileOutputStream fileos = null;
        try{
            fileos = new FileOutputStream(newxmlfile);
        }catch(FileNotFoundException e){
            Log.e("FileNotFoundException", "can't create FileOutputStream");
        }
        
        XmlSerializer serializer = Xml.newSerializer();
        try {           
            serializer.setOutput(fileos, "UTF-8");           
            serializer.startDocument(null, Boolean.valueOf(true));          
            serializer.startTag(null, "ENVELOPE");
                serializer.startTag(null, "IDCARD");
                    serializer.startTag(null, "IMGSTR");
                    serializer.text("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
                    serializer.endTag(null, "IMGSTR");
                serializer.endTag(null, "IDCARD");

            serializer.startTag(null, "INFO");
                serializer.startTag(null, "BRANCH");
                serializer.text("999");
                serializer.endTag(null, "BRANCH");

                serializer.startTag(null, "CH_TYPE");
                serializer.text("R");
                serializer.endTag(null, "CH_TYPE");

                serializer.startTag(null, "ROB_NO");
                serializer.text("M01-0001");
                serializer.endTag(null, "ROB_NO");

                serializer.startTag(null, "DATE");
                serializer.text(getDate());
                serializer.endTag(null, "DATE");

                serializer.startTag(null, "TIME");
                serializer.text(getTime());
                serializer.endTag(null, "TIME");

                serializer.startTag(null, "DATA_A");
                serializer.text("AAA");
                serializer.endTag(null, "DATA_A");
                serializer.startTag(null, "DATA_B");
                serializer.text("BBB");
                serializer.endTag(null, "DATA_B");
                serializer.startTag(null, "DATA_C");
                serializer.text("CCC");
                serializer.endTag(null, "DATA_C");

                serializer.startTag(null, "RESULT");
                serializer.text("000");
                serializer.endTag(null, "RESULT");
            serializer.endTag(null, "INFO");
            serializer.endTag(null, "ENVELOPE");
            serializer.endDocument();            
            serializer.flush();           
            fileos.close();
        } catch (Exception e) {
            Log.e("Exception","error occurred while creating xml file");
        }
    }

    private String getDate()
    {
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        Log.i("nice", sdf.format(cal.getTime()));

        return sdf.format(cal.getTime());
    }

    private String getTime()
    {
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("HHmmss");
        Log.i("nice", sdf.format(cal.getTime()));

        return sdf.format(cal.getTime());
    }
}
ref : Here

2016年9月1日 星期四

Parser XML on Android

XML file
<Response>
    <Type>1</Type>
    <Content>
        想睡覺
    </Content>
    <NodeId>00147070853775200944005056ba786b</NodeId>
    <ModuleId>core</ModuleId>
    <Similarity>1.0</Similarity>
    <Commands>
    <Command name="weather" state="1">
    <Arg>北京</Arg>
    <Arg/>
    <Arg/>
    </Command>
    </Commands>
    <RelatedQuestions>
        <Question>123</Question>
        <Question>456</Question>
    </RelatedQuestions>
</Response>

public class MainActivity extends AppCompatActivity {
    private Handler mHandler = new MainActivityHandler(this);
    public static Button btnDomstic, btnForegin;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        GetData getMegaNumber = new GetData();
        getMegaNumber.getData();
    }
}

public class httpGetXML {
    public String getHtmlByGet(String _url) {
        String result = "";
        HttpClient client = new DefaultHttpClient();
        try {
            HttpGet get = new HttpGet(_url);
            HttpResponse response = client.execute(get);
            HttpEntity resEntity = response.getEntity();
            if (resEntity != null)
            {
                //result = EntityUtils.toString(resEntity);
                result = EntityUtils.toString(response.getEntity(),"UTF-8");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            client.getConnectionManager().shutdown();
        }
        return result;
    }
}

public class GetData {
    String TAG="GetData";
    String retstrXML;
    String retstr;
    ExecutorService executor = Executors.newFixedThreadPool(1);
    runGetXml gXML = new runGetXml();
    Future<String> future = executor.submit(gXML);
    Document doc;
    public void getData ()
    {
        try {
            retstrXML = future.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        doc=getDomElement(retstrXML);
        NodeList nl = doc.getElementsByTagName("Content");
        // looping through all item nodes <item>
        for (int i = 0; i < nl.getLength(); i++) {
            Element e = (Element) nl.item(i);
            // adding each child node to HashMap key => value
            retstr = nl.item(i).getTextContent();
            Log.i(TAG, "aaaaaaaaaa2="+retstr);
        }
    }

    private class runGetXml implements Callable<String>
    {
        String ret;
        @Override
        public String call() throws Exception {
            httpGetXML hGet = new httpGetXML();
            ret=hGet.getHtmlByGet("http://Html Address to link a XML data by html-get);
            Log.i(TAG, "ret="+ret);
        return ret;
        }
    }

    public Document getDomElement(String xml){
        Document doc = null;
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        try {
            DocumentBuilder db = dbf.newDocumentBuilder();
            InputSource is = new InputSource();
            is.setCharacterStream(new StringReader(xml));
            doc = db.parse(is);
        } catch (ParserConfigurationException e) {
            Log.e("Error: ", e.getMessage());
            return null;
        } catch (SAXException e) {
            Log.e("Error: ", e.getMessage());
            return null;
        } catch (IOException e) {
            Log.e("Error: ", e.getMessage());
            return null;
        }
        Log.i(TAG, "doccccccc="+doc);
        // return DOM
        return doc;
    }

    public String getValue(Element item, String str) {
        NodeList n = item.getElementsByTagName(str);
        return this.getElementValue(n.item(0));
    }

    public final String getElementValue( Node elem ) {
        Node child;
        if( elem != null){
            if (elem.hasChildNodes()){
                for( child = elem.getFirstChild(); child != null; child = child.getNextSibling() ){
                    if( child.getNodeType() == Node.TEXT_NODE  ){
                        return child.getNodeValue();
                    }
                }
            }
        }
        return "";
    }
}
ref : android-xml-parsing-tutorial

2016年7月21日 星期四

Dual Screen on Android 6.0

環境: Intel Celeron N3050 ( Braswell ) + Android 6.01 + kernel 3.14.55-x86 

實作之前,先在setting 裡打開雙螢幕功能

FisrtScreen.java
import android.hardware.display.DisplayManager;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Display;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends ActionBarActivity {

    private String TAG = "MainActivity";
    private SecondScreen_Main mPresentation = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        GetMultiScreenInit();
    }

    private void GetMultiScreenInit()
    {
        DisplayManager dm = (DisplayManager) getSystemService(DISPLAY_SERVICE);
        if (dm != null)
        {
            Display[] displays =
                    dm.getDisplays(
                            DisplayManager.DISPLAY_CATEGORY_PRESENTATION);

            for (Display display : displays)
            {
                mPresentation = new SecondScreen_Main(this, display);
                mPresentation.show();
            }
        }
        else
            Log.i(TAG, "Can't find second screen");
    }
}
SecondScreen_Main.java
import android.app.Presentation;
import android.content.Context;
import android.os.Bundle;
import android.view.Display;

public class SecondScreen_Main extends Presentation {
    public SecondScreen_Main(Context outerContext, Display display)
    {
        super(outerContext, display);
    }
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.second_screen_main);
    }
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <TextView 
        android:text="@string/hello_world" 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>
second_screen_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"
    android:clickable="false">

    <TextView
        android:text="hello_world_222"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/textView" />
</RelativeLayout>
AndroidManifest.xml
<permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
ref :
Multiple Displays – Part 2
Android實現雙屏顯示
/*nice*/