搜尋此網誌

顯示具有 Intent 標籤的文章。 顯示所有文章
顯示具有 Intent 標籤的文章。 顯示所有文章

2018年3月11日 星期日

【Android O】about between implicit and explicit intents (Broadcast Receiver) (Notification)

因為Android 8.0(O)的關係,讓原先的Notification上的custom button失效。
原因為Implicit Broadcast Exceptions這篇文章。
擷取開頭描述
As part of the Android 8.0 (API level 26) Background Execution Limits, apps that target the API level 26 or higher can no longer register broadcast receivers for implicit broadcasts in their manifest. However, several broadcasts are currently exempted from these limitations. 
....

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) 
不能在manifest中broadcast receivers註冊broadcasts為implicit 。這段話浪費我好久久。


原來intent 有分為 implicit 和 explicit。
  1. Explicit Intent: Explicit intent names the component.
  2. Implicit Intent: Implicit Intents have not specified a component.
光從字面上,根本搞不懂發生什麼。還是從範例來了解:

Implicit activity call

With an intent filter you create action for your activity so other apps can call your activity via an action:
<activity android:name=".BrowserActivitiy" android:label="@string/app_name">
  <intent-filter>
     <action android:name="android.intent.action.VIEW" />
     <category android:name="android.intent.category.DEFAULT" />
     <data android:scheme="http"/> 
  </intent-filter>
</activity>
.
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.example.com"));
startActivity(intent);

Explicit activity call

You make a call that indicates exactly which activity class to use:
Intent intent = new Intent(this, ActivityABC.class);
startActivity(intent);
解讀後,從上面例子同理反推,



Build Version >Android 8.0,在manifest.xml <receiver>時自己定義<intent-filiter> action(Implicit Receiver),更改成Explicit Receiver

若要合法使用<intent-filiter> action,只能參考Implicit Broadcast Exceptions文章下面列的這些反應動作。

github找到的例子
 manifest.xml中修改註冊為Explicit Receiver

在activity中把intent改為explicit intent


補充 下面連結有提到 為什麼要限制Implicit Broadcast的解釋
JobIntentService for background processing on Android O

再補上簡體中文的機制說明和解決辦法
从源码角度看Android_O_AMS新特性

Android O 8.0 BroadcastReceiver 注册工具


2015年1月13日 星期二

【Android】Intent & Bundle傳遞資料(含傳自定義物件及全域變數)

ref:http://goo.gl/nrAX9g

[方法一]從A.class傳到B.class

比喻: 某人要從 A地到B地  靠的是交通工具(Intent )

A.class 目前的Class
B.class 目的Class

Intent i = new Intent();
i.setClass(A.this,B.class)
startActivity(i);
or
Intent i = new Intent(A.this,B.class);
startActivity(i);//開始跳往要去的Activity

如果要結束A.class 要加上這行

A.this.finish();//結束目前Activity

[方法二]傳遞資料從A傳到B
比喻: 某人要從 A地帶東西(Bundle)到B地  靠的是交通工具(Intent), 所以他把東西(Bundle) 放在交通工具上(Intent)一起帶去
1.Intent

A.class(傳送資料)
//new一個intent物件,並指定Activity切換的class
Intent intent = new Intent();
intent.setClass(A.this,B.class);
intent .putExtra("name",name);//可放所有基本類別
//切換Activity
startActivity(intent);

B.class(接收資料)
Intent intent = this.getIntent();
//取得傳遞過來的資料  
String name = intent.getStringExtra("name"); 

2.Bundle+Intent

用法簡介:

A.class(傳送資料)
//new一個intent物件,並指定Activity切換的class
Intent intent = new Intent();
intent.setClass(A.this,B.class);
//new一個Bundle物件,並將要傳遞的資料傳入
Bundle bundle = new Bundle();
bundle.putDouble("age",age );//傳遞Double
bundle.putString("name",name);//傳遞String
//將Bundle物件傳給intent
intent.putExtras(bundle);
//切換Activity
startActivity(intent);

B.class(接收資料)
Bundle bundle = getIntent().getExtras(); 
String name = bundle.getString("name");
double age = bundle.getDouble("age");
[方法三]傳遞資料從A傳到B後,再由B傳參數回去A
比喻: 甲拜託乙 從A地到B地買東西回來 ,靠的是交通工具(Intent),

乙回來的話東西送到甲的地址(requestCode/resultCode)

A.class
Intent intent = new Intent(A.this,B.class);
//requestCode(識別碼) 型別為 int ,從B傳回來的物件將會有一樣的requestCode
startActivityForResult(intent,requestCode);
?
B.class

Intent intent = getIntent();
Bundle bundle = new Bundle();
bundle.putString("name",name); 
intent.putExtras(bundle);
setResult(requestCode, intent); //requestCode需跟A.class的一樣
B.this.finish();

然後要在A.class裡複寫onActivityResult 才能接收B傳回的值
Intent intent = getIntent();
@Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
        
        switch(resultCode){//resultCode是剛剛妳A切換到B時設的resultCode 
        case requestCode://當B傳回來的Intent的requestCode 等於當初A傳出去的話
            String result = data.getExtras().getString("name");
             
            break;
        
        }
      
    }
[方法四]傳遞自定義物件
1.利用Serializable or Parcelable

Bundle.putSerializable(Key,Object);
Bundle.putParcelable(Key, Object);
這兩種都必須時做接口
今天講Serializable
要利用 Serializable 傳遞物件的話 
妳的物件必須  implements Serializable
public class CustomObject implements Serializable {
private static final long serialVersionUID = -7060210544600464481L;
//省略以下 為你class的內容
}
然後在要傳資料的B.class裡

CustomObject co_b = new CustomObject ();

Intent i=new Intent();
Bundle bundle=new Bundle();
bundle.putSerializable("CustomObject ", co_b); 
i.putExtras(bundle);
startActivity(i);

2.利用全域變數 簡單使用別的class的自定義物件
在A.class裡
public class A extends Activity{
   public static CustomObject co_a = null; //一定要加static 且 public
   //以下intent從A到B的內容省略
}
在B.class裡
CustomObject co_b = A.co_a;//直接使用A的static物件