參考資料:http://esp32-ttgo.blogspot.com/
https://www.aliexpress.com/item/TTGO-ZERO-ESP32-4-MB-PSRAM-4-MB-Flash-WiFi-Module-Bluetooth-ESP32-WROVER-Micropython/32858716536.html?spm=a2g0s.9042311.0.0.590f4c4dCZxodC

接脚描述

TTGO ZERO ESP32 PSRAM 4 MB Flash WiFi Module Bluetooth ESP32-WROVER Micropython

undefined

 

Espressif official ESP32-WROVER module

Lastest ESP32 Version: REV1

WIFI  

Bluetooth   

4MB Flash  

4MB PSRAM

Default firmware: Latest Micropython firmware

Battery Connector: PH-2 2.0mm

2A Battery Management

Power button: Click one time will start. Fast click 2 times will shut down.

Protection: Short protection. Over charging protection. Overflowing

stanley 發表在 痞客邦 留言(0) 人氣()

本來想說這不是一個大問題,但隨著APP的接近完成時,卻發現螢幕上元件的顥示值會隨著某些情境改變或亂掉,才又重新思考及研究一下這個東西,網路文章很多但解釋的不清楚,我們今天要從使用者的使用情境角度去思考生命週期的事件變化。

下圖是在網路上常見的activity 生命週期圖

undefined

下面這篇比較詳細依照情境去描述event的發生順序,所以請參考下面這篇文章

Activity的生命週期,它會自動執行那些方法? 方法如何覆寫?

上篇文章說明了(1)一般情境 (2)暫停情境 (3)切換Activity情境

我將每個情境做一些歸納並加入第4種使用情境=>(4)手機螢幕切換情境,(5)Activity 啟動另一個 Activity 情境

(1)一般情境

01-05​13:32:30.266:​DEBUG/StateInfo(5477):​onCreate
01-05​13:32:30.296:​DEBUG/StateInfo(5477):​onStart
01-05​13:32:30.296:​DEBUG/StateInfo(5477):​onResume
..........手機持續使用中.......,當使用者按下返回鍵結束Activity
01-05​13:35:20.106:​DEBUG/StateInfo(5477):​onPause
01-05​13:35:20.106:​DEBUG/StateInfo(5477):​onStop
01-05​13:35:20.106:​DEBUG/StateInfo(5477):​onDestroy

(2)暫停情境

在執行應用程式時,使用者執行 Toast、 AlertDiaog或按下手機的返回桌面後再按鈕執行撥打電話應用程式,
就會使得目前執行的 Activity 進入暫停狀態,目前執行的 Activity 會退到背景執行,但是 Activity並未結束。
此時執行過程為先執行 onPause() 接著執行 onStop()。然後將執行權交給另一個內建的 Activity。

01-05​13:32:30.266:​DEBUG/StateInfo(5477):​onCreate
01-05​13:32:30.296:​DEBUG/StateInfo(5477):​onStart
01-05​13:32:30.296:​DEBUG/StateInfo(5477):​onResume
對話框出現在Activity的前面,此時Activity是無法使用的,進入暫停狀態 
01-05​13:35:20.106:​DEBUG/StateInfo(5477):​onPause
01-05​13:32:30.296:​DEBUG/StateInfo(5477):​onStop

等接完電話回來時,原來進入暫停的 Activity又會回復執行。這個時候執行過程為先執行  onRestart()接著執行 onStart()  
和 onResume(),原來的 Activity就會取回螢幕控制權。

01-05​13:32:30.296:​DEBUG/StateInfo(5477):​onReStart
01-05​13:32:30.296:​DEBUG/StateInfo(5477):​onStart
01-05​13:32:30.296:​DEBUG/StateInfo(5477):​onResume

(3)切換Activity情境(從前景到背景)

使用者點擊另一個APP執行,讓原本在前景的Activity進入背景前,

01-05​13:35:20.106:​DEBUG/StateInfo(5477):​onPause
01-05​13:35:20.106:​DEBUG/StateInfo(5477):​onStop
會先呼叫onPause方法,再呼叫onStop方法後,此時Activity完全進入背景,不在手機畫面上。
使用者再由APP清單中點擊這個Activity後,這個Activity會被重新執行。

01-05​13:32:30.296:​DEBUG/StateInfo(5477):​onReStart
01-05​13:32:30.296:​DEBUG/StateInfo(5477):​onStart
01-05​13:32:30.296:​DEBUG/StateInfo(5477):​onResume

(4)手機螢幕切換或改變方向情境

開始使用時

01-05​13:32:30.266:​DEBUG/StateInfo(5477):​onCreate
01-05​13:32:30.296:​DEBUG/StateInfo(5477):​onStart
01-05​13:32:30.296:​DEBUG/StateInfo(5477):​onResume

..........手機持續使用中.......
當使用者手機螢幕切換
時, 會先Destory 再Create 
01-05​13:35:20.106:​DEBUG/StateInfo(5477):​onPause
01-05​13:35:20.106:​DEBUG/StateInfo(5477):​onStop
01-05​13:35:20.106:​DEBUG/StateInfo(5477):​onDestroy
01-05​13:35:20.246:​DEBUG/StateInfo(5477):​onCreate
01-05​13:35:20.256:​DEBUG/StateInfo(5477):​onStart
01-05​13:35:20.256:​DEBUG/StateInfo(5477):​onResume

.........手機使用中.......
(5)一個應用程式內,Activity 啟動另一個 Activity 情境(程式開發人員參考用)

其中一個 Activity 啟動另一個 Activity 時。 Activity A 啟動 Activity B 時所發生的操作順利如下:
Activity A 的 onPause() 方法會執行。
Activity B 按順序執行 onCreate()、onStart() 以及 onResume() 方法。 (Activity B 現在擁有使用者焦點)。
然後,如果螢幕上已經看不到 Activity A,就會執行 Activity A 的 onStop() 方法。

後記

(1)對任何activity ,有二種方法將資料儲存下來要將狀態儲存在Pause() event中。
(2)儲存資料的View要在 android:id attribute 要命名,如有手機螢幕切換時會把值保存下來 。
(3)Activity 的整個生命週期是介於 onCreate() 呼叫和 onDestroy() 呼叫之間。您的 Activity 應在 onCreate() 中設定「全域」狀態 (例如定義版面配置),並且在 onDestroy() 中釋放所有剩餘的資源。 例如,如果您的 Activity 有一個執行緒在背景執行,並從網路下載資料,那麼最好可以在 onCreate() 中建立該執行緒,然後在 onDestroy() 中將它停止。
(4)Activity 的可見生命週期是介於 onStart() 呼叫和 onStop() 呼叫之間。在此期間,使用者可以在螢幕上看到該 Activity,並與之互動。 例如,啟動新的 Activity,而這個 Activity 不再看得到時,會呼叫 onStop()。 在這兩個方法之間,您可以維護需要讓使用者看到的資源。 例如,您可以在onStart() 中註冊 BroadcastReceiver,以監視影響到 UI 的變更,然後當使用者不再看到您顯示的內容時,在 onStop() 中將它取消註冊。 系統可以在 Activity 的整個生命週期時,多次呼叫 onStart()  onStop(),因為 Activity 對使用者而言會一直在顯示和隱藏之間切換。
(5)Activity 的前景生命週期是介於 onResume() 呼叫和 onPause() 呼叫之間。在此期間,Activity 會在螢幕上所有其他 Activity 的前面,而且具有使用者輸入焦點。 Activity 可以經常在前景和背景之間轉換 — 例如,裝置進入睡眠或顯示對話方塊時,會呼叫 onPause()。 由於此狀態可能會經常轉換,因此這兩個方法中的程式碼應十分精簡,這樣可以避免使用者在轉換時等待。

 

文章標籤

stanley 發表在 痞客邦 留言(0) 人氣()

參考資料:

(1)http://xjobinternship.blogspot.com/2014/07/tablelayout.html
(2)http://pianovv510.blogspot.com/2013/07/android-tablelayout.html
(3)https://kknews.cc/zh-tw/news/9jvjp65.html

本例中因為要讓TableLayout更好顯示在每一列所以在最外層用LinearLayout包起來,所以當我們在裡面寫了第二個TableLayout則會是在LinearLayout中的第二列去作顯示,透過這種方式可以很簡單得來排版我們常用的小算盤。

TableLayout是一個類似表格排列方式的layout,TableLayout使用TableRow將內容分行,TableLayout主要的功能有下面這幾個項目:

  • android:stretchColumns:將指定的欄位填滿剩餘的空間,可以用*代表是全部的欄位
  • android:shrinkColumns:將指定的欄位縮小空間,可以用*代表是全部的欄位
  • android:collapseColumns:將指定的欄位進行刪除
上面這些設定有一個地方是需要值得注意的欄位的編號是從0開始計算的,下面是TableRow中的功能:
  • android:layout_span:合併欄位的格數
  • android:layout_column:指定欄位的編號

結果參考http://xjobinternship.blogspot.com/2014/07/tablelayout.html

如何設定tablelayout cell 格數

vertical 需要注意的是TableRow不需要設置寬度layout_width和高度layoutJheight,其寬度一定是match_parent,即自動填充父容器,高度一定為wrap_content,即根據內容改變高度。

但對於TableRow中的其他控制項來說,是可以設置寬度和高度的,但必其須是 wrap_content 或者 fill_parent。

相同高度的例子: https://stackoverflow.com/questions/13738630/table-layout-with-equal-rows-height

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TableLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:weightSum="4" >

            <TextView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginRight="1dp"
                android:layout_weight="1"
                android:background="#B0B0B0" />

            <TextView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginRight="1dp"
                android:layout_weight="1"
                android:background="#B0B0B0" />

            <TextView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginRight="1dp"
                android:layout_weight="1"
                android:background="#B0B0B0" />

            <TextView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="#B0B0B0" />
        </TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="1dp"
            android:orientation="vertical"
            android:weightSum="4" >

            <TextView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginRight="1dp"
                android:layout_weight="1"
                android:background="#B0B0B0" />

            <TextView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginRight="1dp"
                android:layout_weight="1"
                android:background="#B0B0B0" />

            <TextView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginRight="1dp"
                android:layout_weight="1"
                android:background="#B0B0B0" />

            <TextView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="#B0B0B0" />
        </TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="1dp"
            android:orientation="vertical"
            android:weightSum="4" >

            <TextView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginRight="1dp"
                android:layout_weight="1"
                android:background="#B0B0B0" />

            <TextView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginRight="1dp"
                android:layout_weight="1"
                android:background="#B0B0B0" />

            <TextView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginRight="1dp"
                android:layout_weight="1"
                android:background="#B0B0B0" />

            <TextView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="#B0B0B0" />
        </TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="1dp"
            android:orientation="vertical"
            android:weightSum="4" >

            <TextView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginRight="1dp"
                android:layout_weight="1"
                android:background="#B0B0B0" />

            <TextView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginRight="1dp"
                android:layout_weight="1"
                android:background="#B0B0B0" />

            <TextView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginRight="1dp"
                android:layout_weight="1"
                android:background="#B0B0B0" />

            <TextView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="#B0B0B0" />
        </TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="1dp"
            android:orientation="vertical"
            android:weightSum="4" >

            <TextView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginRight="1dp"
                android:layout_weight="1"
                android:background="#B0B0B0" />

            <TextView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginRight="1dp"
                android:layout_weight="1"
                android:background="#B0B0B0" />

            <TextView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginRight="1dp"
                android:layout_weight="1"
                android:background="#B0B0B0" />

            <TextView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="#B0B0B0" />
        </TableRow>

        <TableRow
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="1dp"
            android:orientation="vertical"
            android:weightSum="4" >

            <TextView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginRight="1dp"
                android:layout_weight="1"
                android:background="#B0B0B0" />

            <TextView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginRight="1dp"
                android:layout_weight="1"
                android:background="#B0B0B0" />

            <TextView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_marginRight="1dp"
                android:layout_weight="1"
                android:background="#B0B0B0" />

            <TextView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="#B0B0B0" />
        </TableRow>
    </TableLayout>

</LinearLayout>

undefined

另一個例子 https://stackoverflow.com/questions/5794499/tablelayout-with-different-columns-at-different-rows?rq=1

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="?android:attr/listPreferredItemHeight"
    android:padding="6dip">
    <ImageView
        android:id="@+id/color_label"
        android:layout_width="12dip"
        android:layout_height="fill_parent"
        android:layout_marginRight="6dip"
        android:background="#ffffff" />

    <TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:stretchColumns="1">
        <TableRow>
            <TextView
                android:id="@+id/toptext"
                android:gravity="left"
            />
            <TextView
                android:id="@+id/bottomtext"
                android:gravity="right"
            />       
        </TableRow>        

        <View android:layout_height="2dip"
            android:background="#FF909090" />

        <TableRow>
            <TextView
                android:id="@+id/col1"
                android:gravity="left"
                android:text="Column 1"
            />
            <TextView
                android:id="@+id/col2"
                android:gravity="right"
                android:text="Column 2"
            />
            <TextView
                android:id="@+id/col3"
                android:gravity="left"
                android:text="Column 3"
            />
            <TextView
                android:id="@+id/col4"
                android:gravity="right"
                android:text="Column 4"
            />            
        </TableRow>        


        <View android:layout_height="2dip"
            android:background="#FF909090" />

    </TableLayout>   
</LinearLayout>

undefined

Android LinearLayout with weight  

http://devdevelop.com/android-ui-design/

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context="eng.devdevelop.com.uidemostackedpercentage.MainActivity">

    <Button
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="2"
        android:textColor="@color/colorWhite"
        android:layout_marginBottom="@dimen/activity_vertical_margin"
        android:background="@color/colorGrey"
        android:text="20%" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="2"
        android:textColor="@color/colorWhite"
        android:background="@color/colorGrey"
        android:layout_marginBottom="@dimen/activity_vertical_margin"
        android:text="20%" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="6"
        android:textColor="@color/colorWhite"
        android:background="@color/colorGrey"
        android:layout_marginBottom="@dimen/activity_vertical_margin"
        android:text="60%" />
</LinearLayout>

The total number of weights is
2 + 2 + 6 = 10.
So the first button view occupies 2/10 or 20% of the screen vertically.
In turn the second button view occupies 20% (vertically)of the space allocated for all the buttons and the last button occupies 60 % (vertically)of the screen space.


原文網址:https://kknews.cc/zh-tw/news/9jvjp65.html

 

stanley 發表在 痞客邦 留言(0) 人氣()

參考資料:https://medium.com/@authmane512/how-to-build-an-apk-from-command-line-without-ide-7260e1e22676

最基本程式HelloWorld

(1) AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.helloworld"
    android:versionCode="1"
    android:versionName="1.0" >
    <application        
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

(2) MainActivity.java 

package com.helloworld;

import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

(3) res/layout/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">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />
</RelativeLayout>

 

(4)res/values/strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Hello World</string>
    <string name="hello_world">Hello world!</string>
</resources>

 

 

Download Jar of Beans 4.8 - Giả lập Android trên PC -taimienphi.vn

Andy 47.0.1091 Download for Windows / FileHorse.com

 

 

 

 

 

 

stanley 發表在 痞客邦 留言(0) 人氣()

參考資料:http://adbshell.com/

完整說明請參上面網址
adb install [-l] [-r] [-s] [--algo <algorithm name> --key <hex-encoded key> --iv <hex-encoded iv>] <file> - push this package file to the device and install it ('-l' means forward-lock the app) 1 ('-r' means reinstall the app, keeping its data) 2 ('-s' means install on SD card instead of internal storage) ('--algo', '--key', and '--iv' mean the file is encrypted already)

(1) adb logcat 除錯用(ref http://imsardine.simplbug.com/note/android/adb/commands/logcat.html
(2)列出現在正在運行的虛擬機。
    android-sdk-windows\toos> adb devices
(3)進入現在正在運行的虛擬機中,可下命令的環境。 
    android-sdk-windows\toos> adb shell
(4)查看整體目錄結構# ls -l
(5)查看可操作的命令集 # ls /system/bin
(6)查看設備安裝的package 列表#ls data/data

 
ADB 系統除錯與連結工具指令
$adb devices (顯示目前有多少個模擬器正在執行) 
$adb -s (指定模擬器來操作)  Ex:adb -s emulator-5554 install email.apk
$adb install apkfile (安裝 APK 應用程式套件)  Ex:adb install email.apk
$adb uninstall package (移除 APK 應用程式套件)  Ex:adb uninstall com.android.email
$adb shell (進入 Android 系統指令列模式)
$dmesg (查看 Android Linux Kernel 運作訊息)
ls - 顯示檔案目錄
cd - 進入目錄
rm - 刪除檔案
mv - 移動檔案
mkdir - 產生目錄
rmdir - 刪除目錄

$adb push (複製檔案到 SD 卡)  Ex:adb push mp3 /sdcard
$adb pull . (從 Android 系統下載檔案)  Ex:adb pull /data/app/com.android.email
$adb logcat (監控模擬器運作紀錄,以Ctrl + c 離開監控模式)
$adb bugreport (產生 adb 除錯報告)
$adb get-state (獲得 adb 伺服器運作狀態)
$adb start-server (啟動 adb 伺服器)
$adb kill-server (關掉 adb 伺服器)
$adb forward tcp:6100 tcp:7100 (更改模擬器網路 TCP 通訊埠)
$adb shell ps -x (顯示 Android 上所有正在執行的行程)
$adb version (顯示 adb 版本)
$adb help (顯示 adb 指令參數)
 

stanley 發表在 痞客邦 留言(0) 人氣()

參考資料:
(1)https://medium.com/@dalenguyen/working-with-android-emulator-through-command-line-b3a96965566f
(1)http://fecbob.pixnet.net/blog/post/38633853-android-sdk%E9%9B%A2%E7%B7%9A%E5%AE%89%E8%A3%9D%E6%96%B9%E6%B3%95%E8%A9%B3%E8%A7%A3%28%E5%8A%A0%E9%80%9F%E5%AE%89%E8%A3%9D%29
(2)https://www.tech-recipes.com/rx/6588/how-to-install-android-sdk-without-internet-connection/
(3)https://androidsdkoffline.blogspot.com/p/android-sdk-41-api-16-jelly-bean-direct.html (4.1 all version-good)
(4)https://androidsdkoffline.blogspot.com/2016/06/how-to-install-android-sdk-offline.html(good)
(5)https://www.developer.com/ws/android/exploring-the-android-sdk-and-avd-managers.html(good)
(6)http://www.mkyong.com/tutorials/android-tutorial/
(7)http://codeingaddiction.blogspot.com/2014/12/building-signed-android-apk-through.html

(1)android-sdk_r24.4.1-windows.zip

sdkmanager --list

avdmanager list avd

emulator -list-avds

emulator -avd moii_E996_API_16

 

stanley 發表在 痞客邦 留言(0) 人氣()

 

(1)Android App Development Tutorial: Beginners Guide With Examples, Code And Tutorials 

(2)Android TutorialsPoint

(3)Android Tutorial (mkyong)

(4)

(5)Android Example Projects 

(6)Android Example

 

 

 

stanley 發表在 痞客邦 留言(0) 人氣()

 

(1)Calling one Activity from another in Android
用法:

Intent launchActivity2 = new Intent(Activity1.this, Activity2.class);

 you can simply launch the activity by running:
startActivity(launchActivity2 );

utton next = (Button) findViewById(R.id.TEST);
next.setOnClickListener(new View.OnClickListener() {
    public void onClick(View view) {
        Intent myIntent = new Intent( view.getContext(), MyActivity.class);
        startActivity(myIntent);
    }
});

參考資料:http://hmkcode.com/android-start-another-activity-within-the-same-application/

(2)Android – Passing Data to Another Activities

(1)MainActivity.java
package com.hmkcode.android;
 
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
 
public class MainActivity extends Activity implements OnClickListener {
 
    Button btnStartAnotherActivity;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        btnStartAnotherActivity = (Button) findViewById(R.id.btnPassData);
 
        btnStartAnotherActivity.setOnClickListener(this);
    }
 
    @Override
    public void onClick(View view) {
 
        // 1. create an intent pass class name or intnet action name
        Intent intent = new Intent("com.hmkcode.android.ANOTHER_ACTIVITY");
 
        // 2. put key/value data
        intent.putExtra("message", "Hello From MainActivity");
 
        // 3. or you can add data to a bundle
        Bundle extras = new Bundle();
        extras.putString("status", "Data Received!");
 
        // 4. add bundle to intent
        intent.putExtras(extras);
 
        // 5. start the activity
        startActivity(intent);
    }
 
}
 
(2)AnotherActivity.java
 
package com.hmkcode.android;
 
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;
 
public class AnotherActivity extends Activity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_another);
 
        // 1. get passed intent
        Intent intent = getIntent();
 
        // 2. get message value from intent
        String message = intent.getStringExtra("message");
 
        // 3. show message on textView
        ((TextView)findViewById(R.id.tvMessage)).setText(message);
 
        // 4. get bundle from intent
        Bundle bundle = intent.getExtras();
 
        // 5. get status value from bundle
        String status = bundle.getString("status");
 
        // 6. show status on Toast
        Toast toast = Toast.makeText(this, status, Toast.LENGTH_LONG);
        toast.show();
    }
}

(3) Define All Activities in the Manifest XML File

<?xml version="1.0" encoding="utf-8"?>
    package="com.hmkcode.android"
    android:versionCode="1"
    android:versionName="1.0" >
 
    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />
 
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
 
        <activity
            android:name="com.hmkcode.android.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
 
        <activity
            android:name="com.hmkcode.android.AnotherActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="com.hmkcode.android.ANOTHER_ACTIVITY" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>
 
</manifest>

參考資料:http://hmkcode.com/android-passing-data-to-another-activities/

(3)Android – Passing Java Object to Another Activity

(3.1) MainActivity.java

package com.hmkcode.android;
 
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
 
public class MainActivity extends Activity implements OnClickListener {
 
    Button btnPassObject;
    EditText etName, etAge;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        btnPassObject = (Button) findViewById(R.id.btnPassObject);
        etName = (EditText) findViewById(R.id.etName);
        etAge = (EditText) findViewById(R.id.etAge);
 
        btnPassObject.setOnClickListener(this);
    }
 
    @Override
    public void onClick(View view) {
 
        // 1. create an intent pass class name or intnet action name
        Intent intent = new Intent("com.hmkcode.android.ANOTHER_ACTIVITY");
 
        // 2. create person object
        Person person = new Person();
        person.setName(etName.getText().toString());
        person.setAge(Integer.parseInt(etAge.getText().toString()));
 
        // 3. put person in intent data
        intent.putExtra("person", person);

        // 4. start the activity
        startActivity(intent);
    }
 
}
 

(3.2) AnotherActivity.java

package com.hmkcode.android;
 
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
 
public class AnotherActivity extends Activity {
 
    TextView tvPerson;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_another);
 
        // 1. get passed intent
        Intent intent = getIntent();
 
        // 2. get person object from intent
 
        Person person = (Person) intent.getSerializableExtra("person");
 
        // 3. get reference to person textView
        tvPerson = (TextView) findViewById(R.id.tvPerson);
 
        // 4. display name & age on textView
        tvPerson.setText(person.toString());
 
    }
}
 
(3.3)Define Activities in the Manifest XML File
 
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.hmkcode.android"
    android:versionCode="1"
    android:versionName="1.0" >
 
    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />
 
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
 
        <activity
            android:name="com.hmkcode.android.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
 
        <activity
            android:name="com.hmkcode.android.AnotherActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="com.hmkcode.android.ANOTHER_ACTIVITY" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>
 
</manifest>
 
參考資料:http://hmkcode.com/android-passing-java-object-another-activity/

(4)Android ImageButton Example Code

  1) XML File: activity_main

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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="com.example.faraz.imagebutton_example.MainActivity">

    <ImageButton
        android:id="@+id/imageButton1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/finger"
        tools:layout_editor_absoluteX="130dp"
        tools:layout_editor_absoluteY="155dp" />
</android.support.constraint.ConstraintLayout>

2) File: MainActivity.java

package com.example.faraz.imagebutton_example;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ImageButton;
import android.widget.Toast;
import android.view.View;
import android.view.View.OnClickListener;

public class MainActivity extends Activity {

    ImageButton imageButton;

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

        addListenerOnButton();

    }

    public void addListenerOnButton() {

        imageButton = (ImageButton) findViewById(R.id.imageButton1);

        imageButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {

                Toast.makeText(MainActivity.this, "You Clicked Image Button!", Toast.LENGTH_LONG).show();

            }

        });

    }

}

參考資料:https://www.includehelp.com/android/ImageButton-Example-Code.aspx

 

(4)

android 的view類的setVisibility();值的意思

android view setVisibility():
有三個參數:Parameters: visibility One of VISIBLE , INVISIBLE , or GONE,想對應的三個常量值:0、4、8
VISIBLE:0 意思是可見的
INVISIBILITY:4 意思是不可見的,但還佔著原來的空間
GONE:8 意思是不可見的,不佔用原來的佈局空間
 
View Code 
 LinearLayout num_Layout = (LinearLayout) findViewById(R.id.num_layout);
  if (numberOfRecord > 0){ 
              TextView num = (TextView) findViewById(R.id.num);
              num.setText(numberOfRecord.toString() );
              num_Layout.setVisibility(0); 
         } 
else {
              num_Layout.setVisibility(8);
         }
 
 

stanley 發表在 痞客邦 留言(0) 人氣()

MainActivity這是最基本的網路連線操作,包括了wifi 的scan,連線,開啟,關閉。
本以為這是一個最基本且簡單的需求,没想到也是花費了一段時間研究程式
Wifi scan 程式流程要解決下面的需求

資料來源:
https://www.includehelp.com/code-snippets/android-application-to-display-available-wifi-network-and-connect-with-specific-network.aspx
https://www.nplix.com/scan-list-wifi-network-android/
https://www.nplix.com/scan-wifi-network-connect-android/
http://cooking-java.blogspot.com/2010/07/android-wifi.html
https://bryceknowhow.blogspot.com/2014/02/android-wifimanagerget-wifissid-power.html
http://fecbob.pixnet.net/blog/post/39322597-android-%3E-wifi-%3E-%E6%8E%83%E6%8F%8F%E9%99%84%E8%BF%91wifi-
https://www.tutorialspoint.com/android/android_wi_fi.htm
https://codertw.com/android-%E9%96%8B%E7%99%BC/339828/ (自動連線)
https://codertw.com/android-%E9%96%8B%E7%99%BC/330593/ (自動連線)
http://king39461.pixnet.net/blog/post/349470859-android-wifi-connection(連線)
http://fecbob.pixnet.net/blog/post/39248623-android-wifi%E9%80%A3%E6%8E%A5%E9%96%8B%E7%99%BC
http://fecbob.pixnet.net/blog/post/39278785-android-%E8%87%AA%E5%8B%95%E9%80%A3%E6%8E%A5%E6%8C%87%E5%AE%9Assid%E7%9A%84wifi%E7%86%B1%E9%BB%9E%EF%BC%88%E4%B8%8D%E5%8A%A0%E5%AF%86-%E5%8A%A0
https://stackoverflow.com/questions/15225232/programmatically-connect-to-an-android-device-in-portable-hotspot
https://www.nplix.com/scan-wifi-network-connect-android/ (good)
https://forums.xamarin.com/discussion/5402/connect-to-wifi-networks-programmatically
https://stackoverflow.com/questions/8818290/how-do-i-connect-to-a-specific-wi-fi-network-in-android-programmatically(good)

這是網路程式,但是有問題,僅供參考: 
(1)MainActivity.java 
package tw.nicky.WifiManagerExample;
import android.app.Activity;
import android.content.Context;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends Activity {
 private WifiManager wiFiManager;
 ListView lv;
 TextView textStatus;
 Button buttonScan;
 int size = 0;
 List results;
 ArrayList> arraylist = new ArrayList>();
 SimpleAdapter adapter;
 private Button turnOnWifiButn;
 private Button turnOffWifiButn;
 
private static final Map wifichannel = new HashMap();
  static{
   wifichannel.put("2412", "2.4G Ch01");wifichannel.put("2417", "2.4G Ch02");
   wifichannel.put("2422", "2.4G Ch03");wifichannel.put("2427", "2.4G Ch04");
   wifichannel.put("2432", "2.4G Ch05");wifichannel.put("2437", "2.4G Ch06");
   wifichannel.put("2442", "2.4G Ch07");wifichannel.put("2447", "2.4G Ch08");
   wifichannel.put("2452", "2.4G Ch09");wifichannel.put("2457", "2.4G Ch10");
   wifichannel.put("2462", "2.4G Ch11");wifichannel.put("2467", "2.4G Ch12");
   wifichannel.put("2472", "2.4G Ch13");wifichannel.put("2484", "2.4G Ch14");
  }

 @Override
 public void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
   textStatus = (TextView) findViewById(R.id.textView2);
  buttonScan = (Button) findViewById(R.id.button1);
  lv = (ListView) findViewById(R.id.listView1);

 // 取得WifiManager
 wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE); 
// 一個 dialog 判別是否有連線,否則顯示出連線dialog
 if(wifi.isWifiEnabled()==false) 
 { 
   AlertDialog.Builder dialog = new AlertDialog.Builder(this); 
   dialog.setTitle("Remind"); 
   dialog.setMessage("Your Wi-Fi is not enabled, enable?"); 
   dialog.setIcon(android.R.drawable.ic_dialog_info); 
   dialog.setCancelable(false); 
   dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() { 
       @Override public void onClick(DialogInterface dialog, int which) { 
        // TODO Auto-generated method stub 
          wifi.setWifiEnabled(true); 
          Toast.makeText(getApplicationContext(), "wifi is disabled..making it enabled", Toast.LENGTH_LONG).show(); 
      } }); 
    dialog.show();
 }
 //然後按下Start Scan的按鈕開始搜尋附近的Wi-Fi網路 
  this.adapter = new SimpleAdapter(MainActivity.this, arraylist, R.layout.list, new String[] {"ssid","power","freq"}, new int[] {R.id.ssid, R.id.power, R.id.freq}); 
  lv.setAdapter(adapter); 
 registerReceiver(new BroadcastReceiver() { 
      @Override public void onReceive(Context context, Intent intent) { 
         // TODO Auto-generated method stub results = wifi.getScanResults(); size = results.size(); 
      }
 }, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)); 
 buttonScan.setOnClickListener(new OnClickListener() {}
    @Override
    public void onClick(View v) {
      // TODO Auto-generated method stub
        arraylist.clear();
        wifi.startScan();
                
        Toast.makeText(MainActivity.this, "Scanning..."+size, Toast.LENGTH_LONG).show();
        try {
          size = size -1;
          while(size >= 0)
          {
            HashMap item = new HashMap();
            item.put("ssid", results.get(size).SSID);
            item.put("power", new String(results.get(size).level+" dBm"));
            String wifichn = wifichannel.containsKey(new String(""+results.get(size).frequency))? wifichannel.get(new String(""+results.get(size).frequency)):"5G";
            item.put("freq", wifichn);
            arraylist.add(item);
            size--;
            adapter.notifyDataSetChanged();
          }
          Collections.sort(arraylist, new Comparator>() {

           @Override
           public int compare(HashMap lhs, HashMap rhs) {
              // TODO Auto-generated method stub
              return ((String) lhs.get("power")).compareTo((String) rhs.get("power"));
           }
          });
          textStatus.setText(arraylist.get(0).get("ssid"));
        } catch (Exception e) {
          // TODO: handle exception
        }
      }
    });
   }

  

 // 兩個button 
  
  turnOnWifiButn = (Button) findViewById(R.id.turnOnWifiButn);
  turnOffWifiButn = (Button) findViewById(R.id.turnOffWifiButn);

  // 開啟wifi
  turnOnWifiButn.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
    //若wifi狀態為關閉則將它開啟
    if (!wiFiManager.isWifiEnabled()) {
     wiFiManager.setWifiEnabled(true);
    }
   }
  });

  // 關閉wifi
  turnOffWifiButn.setOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
    //若wifi狀態為開啟則將它關閉
    if (wiFiManager.isWifiEnabled()) {
     wiFiManager.setWifiEnabled(false);
    }
   }
  });
 }
}


3. activity_main.xml (Layout)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<Button 
android:text="開啟Wifi" 
android:id="@+id/turnOnWifiButn" 
android:layout_width="wrap_content" 
android:layout_height="wrap_content">
</Button>

<Button 
android:text="關閉Wifi" 
android:id="@+id/turnOffWifiButn" 
android:layout_width="wrap_content" 
android:layout_height="wrap_content">
</Button>
</LinearLayout>

<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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/textView1"
        android:layout_below="@+id/button1"
        android:layout_marginTop="46dp"
        android:background="#ff8" >
    </ListView>

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:text="@string/wifi_ssid" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/listView1"
        android:layout_below="@+id/button1"
        android:text="@string/wifi_analysis" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignTop="@+id/textView1"
        android:text="@string/start_scan" />

</RelativeLayout>

list.xml 

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:id="@+id/ssid"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="16dp"
        android:text="TextView" />

    <TextView
        android:id="@+id/power"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/ssid"
        android:layout_below="@+id/ssid"
        android:text="TextView" />

    <TextView
        android:id="@+id/freq"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/power"
        android:layout_alignBottom="@+id/power"
        android:layout_centerHorizontal="true"
        android:text="TextView" />

</RelativeLayout>

4. AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="tw.nicky.WifiManagerExample"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".WifiManagerExample"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
    <uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
</manifest> 

以上程式焆未完成測試,所以還没貼上畫面,僅先記錄別人的寫法。

 

stanley 發表在 痞客邦 留言(0) 人氣()

參考網站 https://steelkiwi.com/blog/working-tcp-sockets/

(1)第一步驟: 建立SOCKET, 而可用參數包括family, type family可輸入 socket.AF_INET or socket.AF_INET6 , 而 type 包括了socket.SOCK_STREAM 

import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

它返回一個socket 物件,而該件有下面的method

  • bind()
    listen()
    accept()
    connect()
    send()
    recv()

bind(), listen() and accept() 是特定為server 使用, 而 connect() 是特定為client 使用, send() and recv() 是兩者皆可使用。

簡單的圖示如下

undefined

(資料來源:http://www.keil.com/pack/doc/mw6/Network/html/NW_Diagrams.png)

Server 例子
import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('localhost', 50000))
 
s.listen(1)
conn, addr = s.accept()
while 1: data = conn.recv(1024)
  if not data:
  break
conn.sendall(data)
conn.close()

client 例子
import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('localhost', 50000))
s.sendall('Hello, world')
data = s.recv(1024)
s.close()
print 'Received', repr(data)

所有的method都是 blocking. 意指socket在讀寫資料時程能等待不能做任何事,可能旳解決方案是使用threads, 但使用threads 程式會較長。所以一個解決方式是使用非同步的方式去處理這問題。最主要概念就是讓OS知道現在socket狀態,socket 是在可讀或可寫狀態。所以下面例子在server 上多一個select method

import select, socket, sys, Queue
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setblocking(0)
server.bind(('localhost', 50000))
server.listen(5)
inputs = [server]
outputs = []
message_queues = {}

while inputs:
    readable, writable, exceptional = select.select(
        inputs, outputs, inputs)
    for s in readable:
        if s is server:
            connection, client_address = s.accept()
            connection.setblocking(0)
            inputs.append(connection)
            message_queues[connection] = Queue.Queue()
        else:
            data = s.recv(1024)
            if data:
                message_queues[s].put(data)
                if s not in outputs:
                    outputs.append(s)
            else:
                if s in outputs:
                    outputs.remove(s)
                inputs.remove(s)
                s.close()
                del message_queues[s]

    for s in writable:
        try:
            next_msg = message_queues[s].get_nowait()
        except Queue.Empty:
            outputs.remove(s)
        else:
            s.send(next_msg)

    for s in exceptional:
        inputs.remove(s)
        if s in outputs:
            outputs.remove(s)
        s.close()
        del message_queues[s]

server.setblocking(0). 設定socket 為nonblocking readable, writable, exceptional = select.select(inputs, outputs, inputs)
blocking and non-blocking socket最主要的不同是sendrecvconnect and accept能夠不做任何事而返回主程式

select.select 要OS求去檢查socekt 是準備去寫或讀或是有例外錯誤,所以需要三個lists去區分那一個socket是預計可讀,可寫,或錯誤。這個method將block程式(除非有設定timeout)直到有一些socket是準備好的,在此時,這個呼叫將返回三個list,說明socket的狀態。

 

stanley 發表在 痞客邦 留言(0) 人氣()

Close

您尚未登入,將以訪客身份留言。亦可以上方服務帳號登入留言

請輸入暱稱 ( 最多顯示 6 個中文字元 )

請輸入標題 ( 最多顯示 9 個中文字元 )

請輸入內容 ( 最多 140 個中文字元 )

reload

請輸入左方認證碼:

看不懂,換張圖

請輸入驗證碼