Categories
discuss

Start a new Activity from Fragment

Using Android Studio, I have my MainActiviy class with a Placeholder fragment. This fragment has buttons, but one has to load an Activity. How does one do this? I was told to try something like the below, but the new Intent does not work.

Button button = (Button) rootView.findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
          Intent intent = new Intent(MainActivity.class, AnotherActivity.class);
          startActivity(intent);
        }
 });

Answer

If you have a look at the documentation you can see that to start an activity you’ll want to use the following code

Intent intent = new Intent(getActivity(), AnotherActivity.class);
startActivity(intent);

Currently you’re using MainActivity.class in a place that requires a context object. If you’re currently in an activity, just passing this is enough. A fragment can get the activity via the getActivity() function.

Your full code above should look like this

Button button = (Button) rootView.findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        Intent intent = new Intent(getActivity(), AnotherActivity.class);
        startActivity(intent);
    }
});
Categories
discuss

Localytics – Programmatically set app key

Is it possible to programmatically set the app key for Localytics? From the integration guide (https://support.localytics.com/Android_SDK_integration), it seems like you must set it in the Manifest file as meta-data.

<meta-data android:name="LOCALYTICS_APP_KEY" android:value="APP KEY FROM STEP 2"/>

From the following post, it also seems like it’s impossible to dynamically set Android meta-data. How to add metadata dynamically (Not in manifest but inside code)?

I’d like to be able to set the app key dynamically based on Gradle buildType so I can have a release app key and a debug app key.

Answer

You can use manifest merging to support different app keys for your build types (e.g. debug versus release) or your product flavors (e.g. free versus paid).

To support different app keys for your builds types:

  1. Create src/debug/AndroidManifest.xml and src/release/AndroidManifest.xml.
  2. Remove the meta-data tag from src/main/AndroidManifest.xml.
  3. Add the appropriate meta-data tag to your build type specific manifest.

src/debug/AndroidManifest.xml

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

        <application>

            <meta-data
                android:name="LOCALYTICS_APP_KEY"
                android:value="DEBUG_APP_KEY" />

        </application>

    </manifest>

src/release/AndroidManifest.xml

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

        <application>

            <meta-data
                android:name="LOCALYTICS_APP_KEY"
                android:value="RELEASE_APP_KEY" />

        </application>

    </manifest>

For different app keys based on your product flavors, just replace debug and release above with your product flavor names.

Categories
discuss

Mongoose schema reference and undefined type ‘ObjectID’

I’m trying to do some relations between my schemas and I have some problems with my solution. Here is my device schema:

var deviceSchema = schema({
    name : String,
    type : String,
    room: {type: mongoose.Types.ObjectId,  ref: 'Room'},
    users: [{type:mongoose.Types.ObjectId, ref: 'User'}]
});

and here room schema:

var roomSchema = schema({
    name : String,
    image : String,
    devices: [{type: mongoose.Types.ObjectId, ref: 'Device'}]
});

Mongoose throws error

TypeError: Undefined type ObjectID at room Did you try nesting Schemas? You can only nest using refs or arrays.

If I change room: {type: mongoose.Types.ObjectId, ref: 'Room'}, to room: {type: Number, ref: 'Room'}, everything works. Could you explain me why this is happening?

Answer

mongoose.Types.ObjectId is the ObjectId constructor function, what you want to use in schema definitions is mongoose.Schema.Types.ObjectId (or mongoose.Schema.ObjectId).

So deviceSchema should look like this instead:

var deviceSchema = schema({
    name : String,
    type : String,
    room: {type: mongoose.Schema.Types.ObjectId,  ref: 'Room'},
    users: [{type:mongoose.Schema.Types.ObjectId, ref: 'User'}]
});
Categories
discuss

Which data from a CMSSignedData object must I pass to generate a valid Timestamp?

I have a valid PKCS7 file loaded into a CMSSignedData object. This PKCS7 file includes a plain text message and a valid attached digital signature (all in the same file).

Now I want to timestamp this file. This is the code I’m using (source):

 private static CMSSignedData addTimestamp(CMSSignedData signedData)
throws Exception {
        Collection ss = signedData.getSignerInfos().getSigners();
        SignerInformation si = (SignerInformation) ss.iterator().next();

        TimeStampToken tok = getTimeStampToken();

        ASN1InputStream asn1InputStream = new ASN1InputStream
(tok.getEncoded());
        DERObject tstDER = asn1InputStream.readObject();
        DERSet ds = new DERSet(tstDER);

        Attribute a = new Attribute(new
DERObjectIdentifier("1.2.840.113549.1.9.16.2.14"), ds);
        DEREncodableVector dv = new DEREncodableVector();
        dv.add(a);
        AttributeTable at = new AttributeTable(dv);
        si = SignerInformation.replaceUnsignedAttributes(si, at);
        ss.clear();
        ss.add(si);
        SignerInformationStore sis = new SignerInformationStore(ss);

        signedData = CMSSignedData.replaceSigners(signedData, sis);
        return signedData;
    }


 private static TimeStampToken getTimeStampToken() throws
Exception {
        Security.addProvider (new
org.bouncycastle.jce.provider.BouncyCastleProvider());

        PostMethod post = new PostMethod("http://My-TrustedTimeStampProvier.com");

// I'm omitting the part where I pass the user and password

        TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator();
        //request TSA to return certificate
        reqGen.setCertReq (true); // In my case this works

        //make a TSP request this is a dummy sha1 hash (20 zero bytes)
        TimeStampRequest request =
            reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(100));

        byte[] enc_req = request.getEncoded();
        ByteArrayInputStream bais = new ByteArrayInputStream(enc_req);

        post.setRequestBody(bais);
        post.setRequestContentLength (enc_req.length);
        post.setRequestHeader("Content-type","application/timestamp-query");

        HttpClient http_client = new HttpClient();
        http_client.executeMethod(post);
        InputStream in = post.getResponseBodyAsStream();

        //read TSP response
        TimeStampResponse resp = new TimeStampResponse (in);

        resp.validate(request);

        TimeStampToken  tsToken = resp.getTimeStampToken();       
        return tsToken;
    }  

I can get a valid TimeStamp, and I could put it into my CMSSignedData object and save it to a file writting the bytes from signedData.getEncoded() to the harddisk. But when I validate my new shinny timestamped file with a third party software, this software tells the original signature is ok, but the Timestamp doesn’t correspond with the signature. This software also can show me the original plain text message.

I think the problem is in this line:

TimeStampRequest request =
    reqGen.generate(TSPAlgorithms.SHA1, new byte[20], BigInteger.valueOf(100));

I think I have to pass a digest instead of a dummy byte array, but I don’t know which digest, or what are the right bytes I have to timeStamp. I successfully could get and verify a SignerInformation object from my signedData. Then I tried to pass to the reqGen.generate() function the bytes from mySignerInformation.getSignature(). The timestamp verification failed. Then I passed a Sha1 digest of mySignerInformation.getSignature(), but my timestamp verification failed again.

The RFC3161 specification says:

2.4.1. Request Format

A time-stamping request is as follows:

TimeStampReq ::= SEQUENCE { version INTEGER { v1(1) }, messageImprint MessageImprint, –a hash algorithm OID and the hash value of the data to be

(…)

The messageImprint field SHOULD contain the hash of the datum to be time-stamped. The hash is represented as an OCTET STRING. Its
length MUST match the length of the hash value for that algorithm
(e.g., 20 bytes for SHA-1 or 16 bytes for MD5).

MessageImprint ::= SEQUENCE { hashAlgorithm AlgorithmIdentifier, hashedMessage OCTET STRING }

But it doesn’t tell me where or how I get the MessageImprint data if I want to TimeStamp the bytes inside a CMSSignedData object.

I’m a newbie in this digital signature stuff.

Answer

You’re right, the problem is that you’re timestamping the incorrect data. The rest of the code seems correct to me.

So the thing is that you’ve to timestamp the hash of the signature. To get the signature from your CMSSignedData and hash it; you can use the follow code (supposing that you’ve only one signer in your PKCS7 and you’re using SHA1 hash algorithm):

CMSSignedData signedData = ...
// get the signers of your CMSSignedData signedData
Collection ss = signedData.getSignerInfos().getSigners();
SignerInformation si = (SignerInformation) ss.iterator().next();
// hash the signature
byte[] signDigest = MessageDigest
      .getInstance(TSPAlgorithms.SHA1, new BouncyCastleProvider())
      .digest(si.getSignature()); // since you're adding the bc provider with Security.addProvider you can use "BC" instead of passing the new BouncyCastleProvider() 
TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator();
// generate the TSRequest
TimeStampRequest request =
            reqGen.generate(TSPAlgorithms.SHA1, signDigest, BigInteger.valueOf(100));
...

Hope this helps,

Categories
discuss

execCommand() doesn’t “unbold” text

I made my own WYSIWYG text-editor.

The contenteditable-field is a div, see code below:

<div spellcheck="false" id="textEditorField" contenteditable="true"></div>

The button-events look like this:

boldButton.onclick = function() {
    document.execCommand('bold', false, null); 
    return false; 
}

The texteditor is working fine. It italics and un-italics the text, underlining works. But with bold there is a problem: it bolds the text, but doesn’t unbold it. This is in every browser on both OS X and Windows.

I’m using a custom font which is imported using @font-face.

In the css I do the following:

b {
    font-family: "Caviar Dreams Bold";
    font-weight: normal;
}
b i, i b {
    font-family: "Caviar Dreams Bold Italic";
    font-weight: normal;
}

If I remove the font-weight property the text gets the font-family “Caviar Dreams Bold” AND it is made bold via CSS, so extra bold.

There are some similar questions, but without an answer I can use. I also have to note that I can’t use jQuery for this.

Answer

The execCommand('bold'... works as expected, i.e. toggles the surrounding of the text in tag. The problem is that you set 'font-weight: normal' style for the b tag in the following CSS classes. It means that you explicitly want the text in the <b> tag to be normal and it’s what you get.

b {
    font-family: "Caviar Dreams Bold";
    font-weight: normal;
}
b i, i b {
    font-family: "Caviar Dreams Bold Italic";
    font-weight: normal;
}

So, you should remove this property and everything work fine.

UPDATE:

It’s important to understand how in certain circumstances the method may “bold but not unbold”. In fact, execCommand makes something more smart than just surrounding the text. It also normalizes it taking in account that there may be a mix of crossing tags like <b> or <strong> together with <i>, <u>, etc. The browser algorithm analyses the text styles to understand what is actually bold and why. When you redefine bold to normal it may cause the algorithm to decide: “OK, although it’s inside <b> tag, the text is not bold and so there is nothing to change” and keeps the tag.

Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..