由于miui的一个广播的权限是SignatureOrSystem,所以我想拿到这个广播就要系统签名,所以我从网上找到了一个根据系统签名文件生成keystore的方法。

系统签名APP

首先你要找的系统的签名存放地址:
/build/target/product/security/

如果直接用这个签名给APP签名可以用一下命令:

java -jar signapk.jar platform.x509.pem platform.pk8 XXX.apk XXXNew.apk

如果想生成keystore,需要一下命令

# 
openssl pkcs8 -inform DER -nocrypt -in platform.pk8 -out platform.pem

# 设置的密码是android name是androiddebugkey
openssl pkcs12 -export -in platform.x509.pem -out platform.p12 -inkey platform.pem -password pass:android -name androiddebugkey

#生成platform.keystore
keytool -importkeystore -deststorepass android -destkeystore ./platform.keystore -srckeystore platform.p12 -srcstoretype PKCS12 -srcstorepass android

参考:

https://blog.csdn.net/QQxiaoqiang1573/article/details/52252843
http://www.cnblogs.com/blairsProgrammer/p/4220904.html
权限相关 https://blog.csdn.net/jltxgcy/article/details/48288467

然后你就可以配置gradle实现自动签名了,配置如下:

android {
    signingConfigs {
        androiddebugkey {
            keyAlias 'you key name'
            keyPassword 'you password'
            storeFile file('../testkey-signer/platform.keystore')
            storePassword 'you password'
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.androiddebugkey
        }
        debug {
            signingConfig signingConfigs.androiddebugkey
        }
    }

注意 signingConfigs 必须放到buildTypes前面,不然会报错,原因和声明顺序有关。

RemoteView的一个坑

RemoteView被使用在notification和widget中,可以设置点击事件,一般有两种setOnClickPendingIntent和setOnClickFillInIntent。
其中setOnClickPendingIntent是传入PendingIntent,setOnClickFillInIntent传入Intent。
但是!!!
setOnClickPendingIntent是不支持LisetView的。
如果在listview的情况在使用setOnClickFillInIntent,传入的intent只会被AppWidgetProvider(其实这是个BroadcastReceiver)接收。

一下是SDK中的代码:

package android.widget;
public class RemoteViews implements Parcelable, Filter {

     /**
     * Equivalent to calling
     * {@link android.view.View#setOnClickListener(android.view.View.OnClickListener)}
     * to launch the provided {@link PendingIntent}.
     *
     * When setting the on-click action of items within collections (eg. {@link ListView},
     * {@link StackView} etc.), this method will not work. Instead, use {@link
     * RemoteViews#setPendingIntentTemplate(int, PendingIntent)} in conjunction with
     * {@link RemoteViews#setOnClickFillInIntent(int, Intent)}.
     *
     * @param viewId The id of the view that will trigger the {@link PendingIntent} when clicked
     * @param pendingIntent The {@link PendingIntent} to send when user clicks
     */
    public void setOnClickPendingIntent(int viewId, PendingIntent pendingIntent) {
        addAction(new SetOnClickPendingIntent(viewId, pendingIntent));
    }

    /**
     * When using collections (eg. {@link ListView}, {@link StackView} etc.) in widgets, it is very
     * costly to set PendingIntents on the individual items, and is hence not permitted. Instead
     * this method should be used to set a single PendingIntent template on the collection, and
     * individual items can differentiate their on-click behavior using
     * {@link RemoteViews#setOnClickFillInIntent(int, Intent)}.
     *
     * @param viewId The id of the collection who's children will use this PendingIntent template
     *          when clicked
     * @param pendingIntentTemplate The {@link PendingIntent} to be combined with extras specified
     *          by a child of viewId and executed when that child is clicked
     */
    public void setPendingIntentTemplate(int viewId, PendingIntent pendingIntentTemplate) {
        addAction(new SetPendingIntentTemplate(viewId, pendingIntentTemplate));
    }

    /**
     * When using collections (eg. {@link ListView}, {@link StackView} etc.) in widgets, it is very
     * costly to set PendingIntents on the individual items, and is hence not permitted. Instead
     * a single PendingIntent template can be set on the collection, see {@link
     * RemoteViews#setPendingIntentTemplate(int, PendingIntent)}, and the individual on-click
     * action of a given item can be distinguished by setting a fillInIntent on that item. The
     * fillInIntent is then combined with the PendingIntent template in order to determine the final
     * intent which will be executed when the item is clicked. This works as follows: any fields
     * which are left blank in the PendingIntent template, but are provided by the fillInIntent
     * will be overwritten, and the resulting PendingIntent will be used. The rest
     * of the PendingIntent template will then be filled in with the associated fields that are
     * set in fillInIntent. See {@link Intent#fillIn(Intent, int)} for more details.
     *
     * @param viewId The id of the view on which to set the fillInIntent
     * @param fillInIntent The intent which will be combined with the parent's PendingIntent
     *        in order to determine the on-click behavior of the view specified by viewId
     */
    public void setOnClickFillInIntent(int viewId, Intent fillInIntent) {
        addAction(new SetOnClickFillInIntent(viewId, fillInIntent));
    }
}

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

WDYDT-11-Android Signature Version V1 V2 上一篇
WDYDT-9-Java性能优化权威指南 下一篇