Skip to content
This repository has been archived by the owner on Feb 19, 2020. It is now read-only.

Commit

Permalink
Merge pull request #14 from bitstadium/release/4.0.0-beta.1
Browse files Browse the repository at this point in the history
Add 4.0.0-beta.1 Public Beta Version
  • Loading branch information
matthiaswenz committed Mar 31, 2016
2 parents b09138a + 574ea62 commit ff11bfd
Show file tree
Hide file tree
Showing 52 changed files with 6,179 additions and 64 deletions.
71 changes: 38 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[![Build Status](https://travis-ci.org/bitstadium/HockeySDK-Android.svg?branch=develop)](https://travis-ci.org/bitstadium/HockeySDK-Android)

## Version 3.7.2
## Version 4.0.0-beta.1
=======

## Introduction

Expand All @@ -10,12 +11,16 @@ The following features are currently supported:

1. **Collect crash reports:** If your app crashes, a crash log is written to the device's storage. If the user starts the app again, they will be asked asked to submit the crash report to HockeyApp. This works for both beta and live apps, i.e. those submitted to Google Play or other app stores! Crash logs contain viable information for you to help resolve the issue. Furthermore, you as a developer can add additional information to the report as well.

2. **Update alpha/beta apps:** The app will check with HockeyApp if a new version for your alpha/beta build is available. If yes, it will show a dialog to the user and let him see the release notes, the version history and start the installation process right away. You can even force the installation of certain updates.
2. **Collect user metrics:** Get nice statistics about how many users you have and how they are using your app. This feature requires a minimum API level of 14 (Android 4.x Icecream Sandwich).

3. **Feedback:** Besides crash reports, collecting feedback from your users from within your app is a great option to help with improving your app. You act and answer feedback directly from the HockeyApp backend.
3. **Update alpha/beta apps:** The app will check with HockeyApp if a new version for your alpha/beta build is available. If yes, it will show a dialog to the user and let him see the release notes, the version history and start the installation process right away. You can even force the installation of certain updates.

4. **Authentication:** To help you stay in control of closed tester groups you can identify and authenticate users against your registered testers with the HockeyApp backend. The authentication feature supports several ways of authentication.

5. **Feedback:** Besides crash reports, collecting feedback from your users from within your app is a great option to help with improving your app. You act and answer feedback directly from the HockeyApp backend.

6. **Authenticate:** To help you stay in control of closed tester groups you can identify and authenticate users against your registered testers with the HockeyApp backend. The authentication feature supports several ways of authentication.

This document contains the following sections:

1. [Requirements](#requirements)
Expand All @@ -24,9 +29,10 @@ This document contains the following sections:
2. [Get the SDK](#get-sdk)
3. [Integrate HockeySDK](#integrate-sdk)
4. [Add crash reporting](#crashreporting)
5. [Add update distribution](#updatedistribution)
6. [Add in-app feedback](#feedback)
7. [Add authentication](#authentication)
5. [Add user metrics](#user-metrics)
6. [Add Update Distribution](#updatedistribution)
7. [Add in-app feedback](#feedback)
8. [Add authentication](#authentication)
3. [Changelog](#changelog)
4. [Advanced setup](#advancedsetup)
1. [Manual library dependency](#manualdependency)
Expand Down Expand Up @@ -69,36 +75,21 @@ Please see the "[How to create a new app](http://support.hockeyapp.net/kb/about-
Add the SDK to your app module's dependencies in Android Studio by adding the following line to your `dependencies { ... }` configuration:

```groovy
compile 'net.hockeyapp.android:HockeySDK:3.7.2'
```
also make sure your repository configuration contains

```java
repositories {
mavenCentral()
}
```

or

```java
repositories {
jcenter()
}
compile 'net.hockeyapp.android:HockeySDK:4.0.0-beta.1'
```

<a id="integrate-sdk"></a>
### 2.3 Integrate HockeySDK

1. Open your module's build.gradle file.
1. Open your module's `build.gradle` file.
2. Add the following manifest placeholder to your configuration (typically the `defaultConfig`):

```groovy
manifestPlaceholders = [HOCKEYAPP_APP_ID: "$APP_ID"]
```

3. The param $APP_ID must be replaced by your HockeyApp App Identifier. The app identifier can be found on the app's page in the "Overview" section of the HockeyApp backend.
4. Save your build.gradle file and make sure to trigger a Gradle build sync.
3. The param `$APP_ID` must be replaced by your HockeyApp App Identifier. The app identifier can be found on the app's page in the "Overview" section of the HockeyApp backend.
4. Save your `build.gradle` file and make sure to trigger a Gradle sync.
5. Open your AndroidManifest.xml file and add a `meta-data`-tag for the HockeySDK.

```xml
Expand Down Expand Up @@ -139,8 +130,22 @@ public class YourActivity extends Activity {

When the activity is resumed, the crash manager is triggered and checks if a new crash was created before. If yes, it presents a dialog to ask the user whether they want to send the crash log to HockeyApp. On app launch the crash manager registers a new exception handler to recognize app crashes.

<a id="user-metrics"></a>
### 2.5 Add User Metrics

This will add the user metrics feature to your app.

1. Open your app's main activity.
2. Add the following line to the activity's `onCreate`-callback:

```java
MetricsManager.register(this, getApplication());
```

Your app will now send metrics which you can use to count your active and overall usage numbers.

<a id="updatedistribution"></a>
### 2.5 Add update distribution
### 2.6 Add update distribution
This will add the in-app update mechanism to your app. For more configuration options of the update manager module see the section about [advanced setup](#advancedsetup).

1. Open the activity where you want to inform the user about eventual updates. We'll assume you want to do this on startup of your main activity.
Expand Down Expand Up @@ -187,7 +192,7 @@ public class YourActivity extends Activity {
When the activity is created, the update manager checks for new updates in the background. If it finds a new update, an alert dialog is shown and if the user presses Show, they will be taken to the update activity. The reason to only do this once upon creation is that the update check causes network traffic and therefore potential costs for your users.

<a id="feedback"></a>
### 2.6 Add in-app feedback
### 2.7 Add in-app feedback
This will add the ability for your users to provide feedback from right inside your app. Detailed configuration options are in [advanced setup](#advancedsetup).

1. You'll typically only want to show the feedback interface upon user interaction, for this example we assume you have a button `feedback_button` in your view for this.
Expand Down Expand Up @@ -221,7 +226,7 @@ public class YourActivity extends Activitiy {
When the user taps on the feedback button it will launch the feedback interface of the HockeySDK, where the user can create a new feedback discussion, add screenshots or other files for reference, and act on their previous feedback conversations.

<a id="authentication"></a>
### 2.7 Add authentication
### 2.8 Add authentication
You can force authentication of your users through the `LoginManager` class. This will show a login screen to users if they are not fully authenticated to protect your app.

1. Retrieve your app secret from the HockeyApp backend. You can find this on the app details page in the backend right next to the "App ID" value. Click "Show" to access it.
Expand Down Expand Up @@ -279,7 +284,7 @@ If you don't want to use Gradle or Maven dependency management you can also down
4. Configure your development tools to use the .aar/.jar file.
5. In Android Studio, create a new module via `File > New > New Module`
6. Select **Import .JAR/.AAR Package** and click **Next**.
7. In the next menu select the .aar/.jar file you just copied to the libs folder. You can rename the module to whatever you want, but we in general recommend leaving it as is. If you don't rename the module, it will match the name of the .aar/.jar file, in this case **HockeySDK-3.7.2**. This way you'll quickly know which version of the SDK you are using in the future.
7. In the next menu select the .aar/.jar file you just copied to the libs folder. You can rename the module to whatever you want, but we in general recommend leaving it as is. If you don't rename the module, it will match the name of the .aar/.jar file, in this case **HockeySDK-4.0.0-beta.1**. This way you'll quickly know which version of the SDK you are using in the future.
8. Make sure Android Studio added the necessary code to integrate the HockeySDK:

Head over to your app's `build.gradle` to verify the dependency was added correctly. It should look like this:
Expand All @@ -289,19 +294,19 @@ dependencies {
//your other dependencies
//...
compile project(':HockeySDK-3.7.2')
compile project(':HockeySDK-4.0.0-beta.1')
}
```
Next, make sure your `settings.gradle` contains the new module:

```groovy
include ':app', ':HockeySDK-3.7.2'
include ':app', ':HockeySDK-4.0.0-beta.1'
```

Finally, check the `build.gradle` of the newly added module:
```groovy
configurations.maybeCreate("default")
artifacts.add("default", file('HockeySDK-3.7.2.aar'))
artifacts.add("default", file('HockeySDK-4.0.0-beta.1.aar'))
```

Once you have verified that everything necessary has been added, proceed with [SDK integration](#integrate-sdk).
Expand Down Expand Up @@ -444,7 +449,7 @@ However, if you provide a custom user interface fragment for the update distribu
<a id="documentation"></a>
## 5. Documentation

Our documentation can be found on [HockeyApp](http://hockeyapp.net/help/sdk/android/3.7.2/index.html).
Our documentation can be found on [HockeyApp](http://hockeyapp.net/help/sdk/android/4.0.0-beta.1/index.html).

<a id="troubleshooting"></a>
## 6.Troubleshooting
Expand Down
10 changes: 7 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,12 @@ allprojects {
repositories {
jcenter()
}
}

tasks.withType(Javadoc) {
options.addStringOption('Xdoclint:none', '-quiet')
options.addStringOption('encoding', 'UTF-8')
}
}


//The bintray-release plugin doesn't write the following attributes to the artifact's pom.xml:
Expand All @@ -31,8 +35,8 @@ allprojects {

ext {
ARTIFACT_ID = 'HockeySDK'
VERSION_NAME = '3.7.2'
VERSION_CODE = 7
VERSION_NAME = '4.0.0-beta.1'
VERSION_CODE = 9
SITE_URL = 'https://github.com/bitstadium/hockeysdk-android'
GIT_URL = 'https://github.com/bitstadium/HockeySDK-Android.git'
BINTRAY_USER = HOCKEYAPP_BINTRAY_USER
Expand Down
3 changes: 2 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@
org.gradle.daemon=true

HOCKEYAPP_BINTRAY_USER=
HOCKEYAPP_BINTRAY_KEY=
HOCKEYAPP_BINTRAY_KEY=
HOCKEY_SDK_VERSION=4.0.0-beta.1
4 changes: 2 additions & 2 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Mon Aug 24 13:43:45 CEST 2015
#Fri Jan 29 15:01:22 PST 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.5-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
17 changes: 9 additions & 8 deletions hockeysdk/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,20 @@ publish {
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])

//Mocking
androidTestCompile 'org.mockito:mockito-core:2.0.40-beta'
androidTestCompile 'com.google.dexmaker:dexmaker:1.2'
androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'
androidTestCompile 'org.mockito:mockito-core:1.10.19'
// androidTestCompile 'org.mockito:mockito-core:2.0.36-beta'
androidTestCompile 'com.crittercism.dexmaker:dexmaker:1.4'
androidTestCompile 'com.crittercism.dexmaker:dexmaker-dx:1.4'
androidTestCompile 'com.crittercism.dexmaker:dexmaker-mockito:1.4'

androidTestCompile 'org.hamcrest:hamcrest-core:1.3'
androidTestCompile 'org.hamcrest:hamcrest-library:1.3'
testCompile 'junit:junit:4.12'

//Integration testing
androidTestCompile "com.android.support:support-annotations:$supportLibVersion"
androidTestCompile 'com.android.support.test:runner:0.4.1'
androidTestCompile 'com.android.support.test:rules:0.4.1'

testCompile 'junit:junit:4.12'
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package net.hockeyapp.android;

import junit.framework.Assert;
import junit.framework.TestCase;

import net.hockeyapp.android.utils.Util;

public class UtilTests extends TestCase {

public void testValidAppIdentifierGetsConvertedToGuid() {
String appIdentifier = " ca2aba1482cb9458a67b917930b202c8 ";
String expected = "ca2aba14-82cb-9458-a67b-917930b202c8";

String actual = Util.convertAppIdentifierToGuid(appIdentifier);
Assert.assertEquals(expected, actual);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package net.hockeyapp.android.metrics;

import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import android.test.InstrumentationTestCase;

import junit.framework.Assert;

import net.hockeyapp.android.metrics.model.Data;
import net.hockeyapp.android.metrics.model.Domain;
import net.hockeyapp.android.metrics.model.Envelope;
import net.hockeyapp.android.metrics.model.SessionState;
import net.hockeyapp.android.metrics.model.SessionStateData;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.HashMap;

import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@RunWith(AndroidJUnit4.class)
public class ChannelTests extends InstrumentationTestCase {

// Helper
private static final String MOCK_APP_ID = "appId";
private static final String MOCK_APP_VER = "appVer";
private static final String MOCK_IKEY = "iKey";
private static final String MOCK_OS_VER = "osVer";
private static final String MOCK_OS = "os";
private static final String MOCK_TAGS_KEY = "tagsKey";
private static final String MOCK_TAGS_VALUE = "tagsValue";
private PublicChannel sut;
private PublicTelemetryContext mockTelemetryContext;
private PublicPersistence mockPersistence;

private static PublicTelemetryContext getMockTelemetryContext() {
HashMap<String, String> tags = new HashMap<String, String>();
tags.put(MOCK_TAGS_KEY, MOCK_TAGS_VALUE);

PublicTelemetryContext mockContext = mock(PublicTelemetryContext.class);
when(mockContext.getPackageName()).thenReturn(MOCK_APP_ID);
when(mockContext.getContextTags()).thenReturn(tags);
when(mockContext.getAppVersion()).thenReturn(MOCK_APP_VER);
when(mockContext.getInstrumentationKey()).thenReturn(MOCK_IKEY);
when(mockContext.getOsVersion()).thenReturn(MOCK_OS_VER);
when(mockContext.getOsName()).thenReturn(MOCK_OS);

return mockContext;
}

@Before
public void setUp() throws Exception {
super.setUp();

injectInstrumentation(InstrumentationRegistry.getInstrumentation());

mockTelemetryContext = getMockTelemetryContext();
mockPersistence = mock(PublicPersistence.class);
sut = new PublicChannel(mockTelemetryContext, mockPersistence);
}

@Test
public void testInstanceInitialisation() {
Assert.assertNotNull(sut);
Assert.assertNotNull(sut.mTelemetryContext);
Assert.assertEquals(mockTelemetryContext, sut.mTelemetryContext);
Assert.assertNotNull(sut.mQueue);
Assert.assertEquals(0, sut.mQueue.size());
}

@Test
public void testLoggingItemAddsToQueue() {
Data<Domain> data = new Data<Domain>();
Channel.mMaxBatchCount = 3;
Assert.assertEquals(0, sut.mQueue.size());

sut.enqueueData(data);
Assert.assertEquals(1, sut.mQueue.size());
}

@Test
public void testQueueFlushesWhenMaxBatchCountReached() {
PublicChannel.mMaxBatchCount = 3;
Assert.assertEquals(0, sut.mQueue.size());

sut.enqueueData(new Data<Domain>());
Assert.assertEquals(1, sut.mQueue.size());

sut.enqueueData(new Data<Domain>());
Assert.assertEquals(2, sut.mQueue.size());

sut.enqueueData(new Data<Domain>());
Assert.assertEquals(0, sut.mQueue.size());

verify(mockPersistence).persist(any(String[].class));
}

@Test
public void testCreateEnvelopeForTelemetryData() {
SessionStateData sessionStateData = new SessionStateData();
sessionStateData.setState(SessionState.START);
Data<Domain> testData = new Data<Domain>();
testData.setBaseData(sessionStateData);
testData.setBaseType(sessionStateData.getBaseType());
testData.QualifiedName = sessionStateData.getEnvelopeName();

Envelope result = sut.createEnvelope(testData);

Assert.assertNotNull(result);
Assert.assertNotNull(result.getTime());
Assert.assertEquals(MOCK_IKEY, result.getIKey());
Assert.assertNotNull(result.getTags());
Assert.assertEquals(1, result.getTags().size());
Assert.assertTrue(result.getTags().containsKey(MOCK_TAGS_KEY));
Assert.assertEquals(MOCK_TAGS_VALUE, result.getTags().get(MOCK_TAGS_KEY));
Assert.assertNotNull(result.getData());
SessionState actualState = ((SessionStateData) ((Data<Domain>) result.getData()).getBaseData()).getState();
Assert.assertEquals(SessionState.START, actualState);
String actualBaseType = result.getData().getBaseType();
Assert.assertEquals(new SessionStateData().getBaseType(), actualBaseType);
}
}
Loading

0 comments on commit ff11bfd

Please sign in to comment.