Giter Club home page Giter Club logo

cpt's Introduction

This is the Wi-Fi / Wi-Fi Direct based peer to peer communication framework for Android. It stands for "Croconaut Public Transport", Croconaut was a "startup" from the times when we thought we can finish the product in three months. :)

Checkout the wiki for detailed description and information or follow the quick step-by-step guide and surely take a look at WiFON mini with a small demonstration how to put all together:

Gradle

repositories {
    maven {
        url "https://mymavenrepo.com/repo/fsD4SRhSQewcguNLyevk"
    }
    maven {
        url "https://s3.amazonaws.com/repo.commonsware.com"
    }
}

dependencies {
    compile 'com.croconaut:cpt:1.0.16'
}

Add the broadcast receiver

AndroidManifest.xml:

<receiver android:name=".MyBroadcastReceiver" />

MyBroadcastReceiver.java:

import com.croconaut.cpt.ui.CptReceiver;

public class MyBroadcastReceiver extends CptReceiver {
    // implement the interface, most important functions are:
    @Override
    protected void onNearbyPeers(Context context, ArrayList<NearbyUser> nearbyUsers) {
        // NearbyUser.crocoId shall be used as the recipient's ID
    }
    @Override
    protected void onNewMessage(Context context, long messageId, Date receivedTime, IncomingMessage incomingMessage) {
        // read / request attachments and get your app data (like a text message)
    }
}

Register the broadcast receiver and username

Communication.register(this, "Miro Kropacek", MyBroadcastReceiver.class);

Enable CPT

Technically speaking, you don't have to enable CPT if you don't want to transmit it immediately, the message will be stored anyway.

CptController cptController = new CptController(this);
cptController.setMode(LinkLayerMode.FOREGROUND);

Send a message

OutgoingPayload outgoingPayload = new OutgoingPayload("Hi there from the other device");    // can be anything Serializable, not only a string
OutgoingMessage outgoingMessage = new OutgoingMessage(targetCrocoId);
outgoingMessage.setPayload(outgoingPayload);
Communication.newMessage(getContext(), outgoingMessage);

Source code release

Please note that you need to supply your own google-services.json file and possibly myMavenRepoWriteUrl if you want to deploy the archive.

Also, the library isn't 100% ready for targetting API > 22 because it still relies on the static permission model (among other things, there seem to be some issues with notifications, too). So if you plan to release your app on the Play Store, you need to change CPT internals in a way that you can use the dynamic model. Pull requests welcome. :)

cpt's People

Contributors

mikrosk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

spili

cpt's Issues

Infinite Loop of Tries on FileNotFoundException

Steps to reproduce:
1.Select a file cached by the "Documents" app but has been actually deleted.
2.Share it via Cpt

It keeps looping. Quick fix doesn't help too.

exception
java.io.FileNotFoundException: No such file or directory
at android.database.DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(DatabaseUtils.java:144)
at android.content.ContentProviderProxy.openTypedAssetFile(ContentProviderNative.java:692)
at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1155)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:991)
at android.content.ContentResolver.openFileDescriptor(ContentResolver.java:844)
at android.content.ContentResolver.openFileDescriptor(ContentResolver.java:798)
at com.croconaut.cpt.network.AttachmentsHelper.writeUri(AttachmentsHelper.java:366)
at com.croconaut.cpt.network.ServerSyncAttachmentsRunnable.sendAttachments(ServerSyncAttachmentsRunnable.java:185)
at com.croconaut.cpt.network.ServerSyncAttachmentsRunnable.run(ServerSyncAttachmentsRunnable.java:51)
at com.croconaut.cpt.network.ServerCommandThread.run(ServerCommandThread.java:63)

HTC 10 can't create group

Absolutely no clue why:

10-26 10:49:13.010 V/link (32198): Adding device to create group for: User{crocoId='a2:32:99:7c:1c:ba', hash='1qubQf', ssid='null', passphrase='null', networkAddress='null', port=59443, isGroupOwner=false, username='Lenovo YT3 PRO', targetAp='null'}
10-26 10:49:13.010 V/data (32198): data.getLocalMessagesRecipients
10-26 10:49:13.016 I/link (32198): Nobody (nor we) have local messages to exchange
10-26 10:49:13.016 D/link (32198): We expect 1 peer(s) to connect to our group
10-26 10:49:13.016 D/link (32198): groupFor: User{crocoId='a2:32:99:7c:1c:ba', hash='1qubQf', ssid='null', passphrase='null', networkAddress='null', port=59443, isGroupOwner=false, username='Lenovo YT3 PRO', targetAp='null'}
10-26 10:49:13.017 V/link.group(32198): GroupHandler.GroupHandler
10-26 10:49:13.019 I/link (32198): Current handler: GroupHandler
10-26 10:49:13.024 V/link.service(32198): P2pHandler.stop
10-26 10:49:13.025 V/link.service(32198): com.croconaut.cpt.link.handler.p2p.UpdatedTargetAp in state: DISCOVERY
10-26 10:49:13.025 V/link.notify(32198): com.croconaut.cpt.link.handler.notification.PublishProgress in state: null
10-26 10:49:13.025 V/link.notify(32198): NotificationHandlerReceiver.publishProgress: CREATING_GROUP
10-26 10:49:13.039 V/link.service(32198): com.croconaut.cpt.link.handler.p2p.Stop in state: DISCOVERY
10-26 10:49:13.039 V/link.service(32198): DISCOVERY.stopPeerDiscovery
10-26 10:49:13.039 D/link.service(32198): DISCOVERY -> DISCOVERY_STOPPING
10-26 10:49:13.057 D/link.service(32198): DISCOVERY_STOPPING -> READY
10-26 10:49:13.057 V/link.notify(32198): Wi-Fi P2P discovery state: WIFI_P2P_DISCOVERY_STOPPED in state: null
10-26 10:49:13.057 V/link.notify(32198): NotificationHandlerReceiver.publishProgress: CREATING_GROUP
10-26 10:49:13.078 V/link (32198): com.croconaut.cpt.link.handler.main.HandlerFinished in state: DISCOVERY
10-26 10:49:13.078 V/link (32198): DISCOVERY.onFinished
10-26 10:49:13.078 V/link.group(32198): GroupHandler.start
10-26 10:49:13.080 D/link (32198): DISCOVERY -> GROUP
10-26 10:49:13.081 V/link.group(32198): android.net.wifi.p2p.CONNECTION_STATE_CHANGE in state: READY
10-26 10:49:13.081 V/link.group(32198): READY.createGroup
10-26 10:49:13.081 D/link.group(32198): READY -> CREATING
10-26 10:49:13.091 E/link.group(32198): createGroup() failed: 0
10-26 10:49:13.100 D/link.group(32198): CREATING -> READY
10-26 10:49:13.100 V/link (32198): com.croconaut.cpt.link.handler.main.HandlerFailed in state: GROUP
10-26 10:49:13.100 E/link (32198): onFailure() in state: GROUP
10-26 10:49:13.100 D/link (32198): GROUP -> RESTART

Replace the discovery thread with JobScheduler

Right now the job is done using Handler.postDelayed(DISCOVERY_PERIOD_IN_SECS ), i.e. withing a thread which is running all the time as a foreground service. This could be replaced with JobScheduler however there's the question what happens to stuff added via WifiP2pManager.addLocalService() -- I would imagine that such device wont be available for discovery in the Doze mode anymore but who knows, it's worth a try. The Doze mode would kill/put asleep the device after some time anyway.

Also, considering https://developer.android.com/preview/features/background.html and https://developer.android.com/preview/features/background-location-limits.html it's clear that we have to maintain the foreground service when using CPT (the client app can go to background but we still want to receive p2p messages)

Dynamic permissions

It would be nice to finally get rid of targetSdkVersion 22 in cpt. Offer some way for the client app to request permissions needed for CPT.

For instance for non-P2P we certainly don't need all the wifi/location/network permissions, maybe GCM doesn't need Internet permission at all, ... each one could be reevaluated.

Huawei P8lite & friends don't work

Huawei has an obsolete wifi chipset, it can't easily switch between normal wifi and wifi direct connections. Nothing to be done here except to detect it and tell the user. :-/

Use JobScheduler similarly as GcmNetworkManager

Right now we don't have any policy for failed a) wifi connects b) p2p network connects -- basically we just keep trying, on and on.

While there are many reasons why a) could not work, there's a few rare cases also for b) (i.e. wifi is connected but socket timed out or similar).

Both could be solved with JobScheduler, similarly as GcmNetworkManager.getInstance(context).schedule() works and how #7 is proposed.

Adjust the way foreground service is created

https://developer.android.com/preview/features/background.html:

Prior to Android O, the usual way to create a foreground service was to create a background service, then promote that service to the foreground. With Android O, there is a complication; the system doesn't allow a background app to create a background service. For this reason, Android O introduces the new method Context.startForegroundService() to start a new service in the foreground. After the system has created the service, the app has five seconds to call the service's startForeground() method to show the new service's user-visible notification. If the app does not call startForeground() within the time limit, the system stops the service and declares the app to be ANR.

Perhaps not such a big deal, CPT calls startForeground() nearly immediately but all right, we can use startForegroundService() for that, sure.

Offer 100% user-filled hash-map for P2P announcements

WifiP2pDnsSdServiceInfo.newInstance() could take something as "_user" + "_wifon._tcp" and the client app would be able to announce any data for faster negotiation. Maybe it could even serve as a way for bypassing CPT's storage framework entirely, using just the P2P part?

Conflict between local network and p2p discovery

There's (sometimes) conflict between local network and p2p discovery. Symptoms:

  • the device is discovering and "network state connected" never arrives (discovery reset helps)
  • the device is suddenly disconnected during p2p discovery and/or after a p2p transfer

Ideally, we shouldn't do any discovery at all (we can announce our hash etc without discovery) but there's a problem if we want to send files to multiple recipients -- we don't know who is around us and therefore to whom give priority.

Bad Notification for startForeground

I am getting this isssue again and again
android.app.RemoteServiceException: Bad notification for startForeground: java.lang.RuntimeException: invalid channel for service notification: Notification(channel=null pri=0 contentView=null vibrate=null sound=null defaults=0x0 flags=0x40 color=0x00000000 actions=2 number=0 vis=PRIVATE semFlags=0x0 semPriority=0 semMissedCount=0)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.