show code block

顯示具有 權限permission 標籤的文章。 顯示所有文章
顯示具有 權限permission 標籤的文章。 顯示所有文章

2017年4月19日 星期三

Android元件 ─ 要求權限 Permission 封裝(二)

前言:

前一篇在這裡:
http://nikeru8.blogspot.tw/2017/04/android-permission.html

這篇只是把Permission和Intent做個封裝。

大致上長這樣。

讓我們開始吧。



重點程式碼:

//設定Activity頁面參數
private Class<?> mClss;

 public void launchActivity(Class<?> clss) {
        //如果沒有權限
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
                != PackageManager.PERMISSION_GRANTED) {
            mClss = clss;
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.CAMERA}, 
                    CUSTOM_NUMBER);
        } else {
            Intent intent = new Intent(this, clss);
            startActivity(intent);
        }
    }

一言蔽之,就是如果你要使用相機功能,沒有權限的話幫你導到權限畫面,如果之前已經取過權限,則直接進入。




實作:

先來看看我們今天會動到的地方。


先創一個Activity,我這邊命名為 activity_part_two.xml和PartTwoActivity

先給予這App權限吧。

STEP 1:給予相機權限


AndroidManifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.spinner.a015865.permission">

   <uses-permission android:name="android.permission.CAMERA"/>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".PartTwoActivity"/>
    </application>

</manifest>

STEP 2:創建第二個Activity並畫XML

activity_main.xml

activity_main.xml
<?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.spinner.a015865.permission.MainActivity">

   <Button
       android:text="要權限+切到畫面B"
       android:onClick="Button_to_next"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content" />

</android.support.constraint.ConstraintLayout>


activity_part_two.xml

activity_part_two.xml
<?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.spinner.a015865.permission.PartTwoActivity">

    <TextView
        android:textSize="50dp"
        android:text="BBBBBBBBB"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</android.support.constraint.ConstraintLayout>


STEP 3:實作JAVA部分

第一個Activity才是重點。

第二個新創的Activity是空的,示意一下而已,在這邊把所有的程式碼都貼上以示完整。

MainActivity.java
public class MainActivity extends AppCompatActivity {
    private Class<?> mClss;
    private static final int CUSTOM_NUMBER = 1;

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

    public void Button_to_next(View view) {
        launchActivity(PartTwoActivity.class);
    }

    public void launchActivity(Class<?> clss) {
        //如果沒有權限
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
                != PackageManager.PERMISSION_GRANTED) {
            mClss = clss;
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.CAMERA},
                    CUSTOM_NUMBER);
        } else {
            Intent intent = new Intent(this, clss);
            startActivity(intent);
        }
    }
}

PartTwoActivity
public class PartTwoActivity extends AppCompatActivity {

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


完成囉!




Demo:
https://drive.google.com/open?id=0Byk75IYx-dKXeV9nOWFWOHFIc1E







Android元件 ─ 要求權限 Permission (一)

前言:

權限其實沒有想像中的困難 。

在Android版本6.0以上,為了安全設計,就全面要求app要和使用者要求權限。

市面上還出現了像是EasyPermissions這類專門幫你拿取權限的第三方套件。

但我認為完全沒有必要使用這類的第三方,因為拿取權限並沒有想像中的那麼困難,也真的像那個第三方套件的名稱一樣,真的很Easy。

今日實作影片


這是今日要做的小範本。




重點程式碼:



if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
  //還沒獲取權限要做什麼呢

  //和使用者要求權限
  ActivityCompat.requestPermissions(MainActivity.this,
                   new String[]{Manifest.permission.CAMERA},
                   1);
}else{
  //以獲取權限要做的事情

  Toast.makeText(this, "已經拿到權限囉!", Toast.LENGTH_SHORT).show();
}
/**
*requestPermissions 是用來要求使用者給予權限的方法(method)
*第一個參數 此頁面
*第二個參數 要獲取的權限名稱
*第三個參數 自定義的請求代碼
*/




實作:

首先你要先想清楚這個App所要那些權限(permission)。

有分為一般權限和危險權限,也只有危險權限才會跳出視窗和使用者要求使用它。


這邊就先拿相機Camera權限來做示範。

今日要動到的地方main_activity.xml、MainActivity.java、Manifest
main_activity.xml、MainActivity.java、Manifest

STEP 1:在Manifest內設定權限

AndroidManifest
  
    //Manifest
  <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.spinner.a015865.permission">

    <uses-permission android:name="android.permission.CAMERA"/>
    <application
       ...
    </application>

</manifest>

STEP 2:實作activity_main.xml

簡單的在一開始的畫面給一個Button吧。
main_activity.xml
main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    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.spinner.a015865.qrmaker.MainActivity">

    <TextView
        android:layout_centerInParent="true"
        android:textSize="30dp"
        android:textColor="@android:color/black"
        android:onClick="button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="button" />

</RelativeLayout>




STEP 3:實作MainActivity.java

MainActivity.java
public class MainActivity extends AppCompatActivity {


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

    public void button(View view) {

        //檢查是否取得權限
        int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);

        //沒有權限時
        if (permissionCheck != PackageManager.PERMISSION_GRANTED) {

            ActivityCompat.requestPermissions(MainActivity.this,
                    new String[]{Manifest.permission.CAMERA},
                    1);
        } else {
            Toast.makeText(this, "已經拿到權限囉!", Toast.LENGTH_SHORT).show();
        }
    }
    
}

解析:

int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);

比較需要注意的是,這是一個int值。用來確定是否獲取權限。


如果使用者「同意權限」、「拒絕權限」

●已批准 PERMISSION_GRANTED 
//英文大補帖GRANTED已批准的

●已拒絕 PERMISSION_DENIED
//英文大補帖DENIED已拒絕的


int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);

if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
   //還沒獲取權限要做什麼呢
}else{
   //以獲取權限要做的事情
}

要求權限

如果使用者還沒給予權限,就要求使用者給予,跳視窗提醒它我要權限囉。
//自定義的請求代碼
//private static final int CUSTOM_NUMBER = 1;
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
   //還沒獲取權限要做什麼呢
     ActivityCompat.requestPermissions(MainActivity.this,
                    new String[]{Manifest.permission.CAMERA},
                    CUSTOM_NUMBER);
}else{
   //以獲取權限要做的事情
   Toast.makeText(this, "已經拿到權限囉!", Toast.LENGTH_SHORT).show();
}


/**
*requestPermissions 是用來要求使用者給予權限的方法(method)
*第一個參數 此頁面
*第二個參數 要獲取的權限名稱
*第三個參數 自定義的請求代碼(後面會用到)
*/
很簡單吧。

Demo:
https://drive.google.com/open?id=0Byk75IYx-dKXelNXaE05aTBMOUk



客製化用法 一:允許或拒絕之後的動作(onRequestPermissionsResult )

上面已經可以獲取你想要的權限無礙了。

再來講一些比較客製化獲取權限的方式。





















按下允許或是拒絕都可以幹些什麼事情。
我這邊是讓他們跳出Toast
 


在MainActivity.java內,多複寫一個繼承的方法。
/**
     * public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
     * 複寫請求授權後執行的方法
     * 第一個參數是請求代碼
     * 第二個參數是請求授權的名稱
     * 第三個參數是請求授權的結果,PERMISSION_GRANTED或PERMISSION_DENTED
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        //這個"CUSTOM_NUMBER"就是上述的自訂意義的請求代碼
        // private static final int CUSTOM_NUMBER = 1;
        if (requestCode == CUSTOM_NUMBER) {
            //假如允許了
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                //do something
                Toast.makeText(this, "已經拿到CAMERA權限囉!", Toast.LENGTH_SHORT).show();
            } 
            //假如拒絕了
            else {
                //do something
                Toast.makeText(this, "CAMERA權限FAIL", Toast.LENGTH_SHORT).show();
            }
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

客製化用法 二 :半客製化要求使用者給予權限(shouldShowRequestPermissionRationale)

為什麼前面加一個「半」呢?

因為不是真正的你想的那樣。
這是當你第一次和使用者伸手要權限被拒絕時,第二次要求的時刻,才會跳出的視窗。

大致上的用法就是請你再詳細解釋一下為什麼需要用到這個權限。



在MainActitivy.java內Button裡面的requestPermissions方法
//
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
   //在這裡面做文章
 }

Button方法
//
    public void button (View view) {
        //檢查是否取得權限
        int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA);

        //沒有權限時
        if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
            //如果使用者第二次點擊功能呼叫權限視窗,就會跳出shouldShowRequestPermissionRationale
            if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
                    Manifest.permission.CAMERA)) {
                //創建Dialog解釋視窗
                new AlertDialog.Builder(MainActivity.this)
                        .setMessage("單純使用在拍照功能,如果您不給我相機的權限,您將無法使用此功能")
                        .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                ActivityCompat.requestPermissions(MainActivity.this,
                                        new String[]{Manifest.permission.CAMERA},
                                        CUSTOM_NUMBER);
                            }
                        })
                        .setNegativeButton("No", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                finish();
                            }
                        })
                        .show();
            } else {
                ActivityCompat.requestPermissions(MainActivity.this,
                        new String[]{Manifest.permission.CAMERA},
                        CUSTOM_NUMBER);
            }
        } else {
            Toast.makeText(this, "已經拿到權限囉!", Toast.LENGTH_SHORT).show();
        }
    }



Demo:
https://drive.google.com/open?id=0Byk75IYx-dKXR2dtMmdFNVJndXM

總結:

下一篇講一下我最常用的方法,一個按鈕解決切畫面和要求權限雙重效果。
其實就是封裝一下Permission和Intent而已。
在第二篇做說明。

有問題歡迎提出唷!

文獻:
https://developer.android.com/reference/android/Manifest.permission.html
https://developer.android.com/guide/topics/permissions/index.html
https://developer.android.com/guide/topics/manifest/uses-permission-element.html

協程(coroutine) - 協程為什麼要學它?

 Coroutine 協程 再強調一次 協程就是由kotlin官方所提供的線程api //Thread Thread { }.start() //Executor val execu...